Другой объект с таким же значением идентификатора уже был связан - PullRequest
0 голосов
/ 04 ноября 2018

в моем проекте Java у меня есть эти три класса и код для вставки данных:

@Entity(name = "Quiz")
@Table(name = "quiz")
public class Quiz implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToOne(cascade= CascadeType.ALL)
    private Skill skill;

    @ManyToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
    private List<StudentClass> stClasses= new ArrayList<>();


@Entity
public class Skill implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;


@Entity
@Table(name = "Student_Class")
@PrimaryKeyJoinColumn(name="id")
public class StudentClass implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    @OneToMany(fetch= FetchType.EAGER, cascade = { CascadeType.ALL })
    @JoinColumn(name = "stClass_id", referencedColumnName="id")
    private Set<User> students=new HashSet<>();

    @ManyToMany(fetch= FetchType.EAGER, mappedBy="stClasses", cascade=CascadeType.ALL)
    private Set<Quiz> quizzes= new HashSet<>();

@Transactional
public void save(Quiz quiz) {
    hibernateTemplate.saveOrUpdate(quiz);
}

но если я вставляю тест с StudentClass, который уже использует навык, я получаю эту ошибку:

GRAVE: Servlet.service() for servlet [appServlet] in context with path [/AutoQuiz3000] threw exception [Request processing failed; nested exception is org.springframework.dao.DuplicateKeyException: A different object with the same identifier value was already associated with the session : [fr.dawan.autoquiz3000.beans.Skill#10]; nested exception is org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [fr.dawan.autoquiz3000.beans.Skill#10]] with root cause
org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [fr.dawan.autoquiz3000.beans.Skill#10]
at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:648)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:284)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:227)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:92)

пример:

quiz.setName("what the capital...");
quiz.setSkill("geography");
quiz.addstClass("formation Java");

quiz.setName("what the money...");
quiz.setSkill("geography");
quiz.addstClass("formation Java");

У меня ошибка, потому что StudentClass уже использует Skill! если я изменю StudentClass, у меня нет проблем.

не знаю, как возникла проблема! У кого-то есть идея?

Большое спасибо!

1 Ответ

0 голосов
/ 04 ноября 2018

Ваша проблема в том, что из-за аннотации Cascade.ALL, когда вы пытаетесь использовать saveAndUpdate или persist, это приказывает Hibernate попытаться вставить новую сущность, которая в вашем случае уже существовала. Поэтому вместо использования одного из этих методов вам нужно объединить вашу сущность, которая сначала проверит, существует ли она, а затем попытается вставить, в противном случае она просто обновится.

Так что вам нужно будет сделать следующие изменения.

@Entity(name = "Quiz")
@Table(name = "quiz")
public class Quiz implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToOne(cascade= CascadeType.MERGE)
    private Skill skill;

    @ManyToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
    private List<StudentClass> stClasses= new ArrayList<>();
}

И в вашем хранилище вам нужно будет использовать merge(entity). Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...