这是显示我的问题的虚拟代码示例。
我有两个与ManyToMany有关系的实体。
@Entity
public class Class implements Serializable {
private static final long serialVersionUID = 2721854845989429844L;
@Id
@Type(type = "uuid-char")
private UUID id;
private String name;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Entity
public class Student implements Serializable {
private static final long serialVersionUID = -1203104744560316339L;
@Id
@Type(type = "uuid-char")
private UUID id;
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer number;
private String name;
@ManyToMany
@JoinTable(name = "student_class",
joinColumns = @JoinColumn(name = "student_number", referencedColumnName = "number"),
inverseJoinColumns = @JoinColumn(name = "class_id", referencedColumnName = "id"))
private Set<Class> classes;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Class> getClasses() {
return classes;
}
public void setClasses(Set<Class> classes) {
this.classes = classes;
}
}
Join Table以其编号引用Student,该编号由MySQL自动生成,并通过其id引用Class。
当我尝试插入带有类的Student时,hibernate尝试在student表中插入行后直接在student_class中插入记录,但是在插入后生成学号,然后抛出异常,该列student_number不能为null。
如何在连接表中插入之前告诉hibernate在连接列中选择生成的值?
包含逻辑的类具有以下代码。 其中classRepository和studentRepository是扩展spring CrudRepository的接口。其中没有自定义代码。
Class class1 = new Class();
class1.setId(UUID.randomUUID());
class1.setName("Math");
classRepository.save(class1);
Class class2 = new Class();
class2.setId(UUID.randomUUID());
class2.setName("Chemistry");
classRepository.save(class2);
Set<Class> classes = new HashSet<>();
classes.add(class1);
classes.add(class2);
Student student = new Student();
student.setId(UUID.randomUUID());
student.setName("Student 1");
student.setClasses(classes);
studentRepository.save(student);
控制台输出:
Hibernate:
/* load com.perksCamp.hello.Class */ select
class0_.id as id1_0_0_,
class0_.name as name2_0_0_
from
class class0_
where
class0_.id=?
Hibernate:
/* insert com.perksCamp.hello.Class
*/ insert
into
class
(name, id)
values
(?, ?)
Hibernate:
/* load com.perksCamp.hello.Class */ select
class0_.id as id1_0_0_,
class0_.name as name2_0_0_
from
class class0_
where
class0_.id=?
Hibernate:
/* insert com.perksCamp.hello.Class
*/ insert
into
class
(name, id)
values
(?, ?)
Hibernate:
/* load com.perksCamp.hello.Student */ select
student0_.id as id1_1_0_,
student0_.name as name2_1_0_,
student0_.number as number3_1_0_
from
student student0_
where
student0_.id=?
Hibernate:
/* insert com.perksCamp.hello.Student
*/ insert
into
student
(name, number, id)
values
(?, ?, ?)
Hibernate:
/* insert collection
row com.perksCamp.hello.Student.classes */ insert
into
student_class
(student_number, class_id)
values
(?, ?)
2018-04-07 12:42:44.268 WARN 5508 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1048, SQLState: 23000
2018-04-07 12:42:44.268 ERROR 5508 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Column 'student_number' cannot be null
2018-04-07 12:42:44.268 INFO 5508 --- [nio-8080-exec-2] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2018-04-07 12:42:44.362 ERROR 5508 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'student_number' cannot be null