I have two entities, let's name them University
and Student
, Student
is unidirectional ManyToOne
with University
they both extends base class BasicUUIDEntity
:
@MappedSuperclass
public class BasicUUIDEntity implements Serializable {
protected UUID id;
@Id
@Column(name = "id", columnDefinition = "binary(16)")
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BasicUUIDEntity that = (BasicUUIDEntity) o;
return id == null || id.equals(that.id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
}
The structure of Student
and University
doesn't really matters, the important things is:
Student.class:
@Entity
@Table(name = "students")
public static class Student extends BasicUUIDEntity {
private University univ;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "univ_id", referencedColumnName = "id")
public University getUniversity() {
return univ;
}
public void setUniversity(University univ) {
this.univ = univ;
}
}
University.class:
@Entity
@Table(name = "universities")
public static class University extends BasicUUIDEntity {
//of course it does contain some fields, but they are strings, etc.
}
The tables are created as follows:
CREATE TABLE students
(
id BINARY(16) NOT NULL,
univ_id BINARY(16),
PRIMARY KEY (id),
CONSTRAINT FK_STUDENT_UNIV
FOREIGN KEY (univ_id) REFERENCES memory_type (id)
ON DELETE SET NULL
)
ENGINE = InnoDB
DEFAULT CHARSET = utf8;
CREATE TABLE universities
(
id BINARY(16) NOT NULL,
PRIMARY KEY (id)
)
ENGINE = InnoDB
DEFAULT CHARSET = utf8;
The Issue is sometimes, on really rare occasions Hibernate doesn't extract that University
entity along with Student
, meaning that when I do student.getUniversity()
it returns null
, and in debugger it is also null
. BUT the students
table contains exactly the same univ_id
as expected University
of this student
, and so does university contains that id
. I am completely sure that hibernate session is not closed, and I've tried to execute exactly the same query as hibernate does, and it does return expected id
of the university, joins them, etc. The thing is that most of the time It does work well, and such issue happens very rarely due to unknown reasons, what is more strange is that the table does contains that id, so it seems like it is not an MySQL issue.
Also worth mention, I am using Spring Data JPA.
Have anyone encountered such behavior? Could it be due to Inheritance/Data JPA/Java 9/Anything other?
PS. Please ignore any typo in the code, it is just an example
Versions:
Hibernate: 5.2.12.Final,
Spring Data JPA: 2.0.5.RELEASE,
HikariCP: 2.7.8,
MySQL connector: 6.0.6,
Java: 9
MySQL: Ver 14.14 Distrib 5.7.21
答案 0 :(得分:0)
解决,最后
<强> TL;博士强>
将fetch = FetchType.LAZY
置于ManyToOne
关系,因此在我的示例中它变为:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "univ_id", referencedColumnName = "id")
public University getUniversity() {
return univ;
}
<强>描述强>
我仍然不确定为什么它会像这样,但似乎Hibernate根本不提取many-to-one
关系,如果他们渴望的话。它有一定的意义,因为这样会有循环依赖,但我认为PersistenceSet
将处理这些问题。更奇怪的是 - 如果我使用Long而不是UUID,那么相同的结构实际上无需提取即可。