【问题标题】:A different object with the same identifier value was already associated已关联具有相同标识符值的不同对象
【发布时间】:2018-11-04 11:00:36
【问题描述】:

在我的 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 我没有问题。

不知道怎么来的问题!有人出主意吗?

非常感谢!

【问题讨论】:

  • 使用 hibernateTemplate.evict(quiz) 可能会有所帮助;在 hibernateTemplate.saveOrUpdate(quiz); 之前

标签: hibernate jpa


【解决方案1】:

您的问题是,由于Cascade.ALL 注释,当您尝试使用saveAndUpdatepersist 时,这命令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)。希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-16
    • 2013-08-30
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多