在我的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);
}
但是如果我插入一个已经使用了Skill的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,我没问题。
不知道问题出在哪里!有人有主意吗?
非常感谢您!
答案 0 :(得分:1)
您的问题是,由于使用了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)
。希望这会有所帮助!