Hibernate 有时不提取 uuid 引用的实体

Hibernate sometimes doesn't extract uuid referenced entity

我有两个实体,我们将它们命名为 UniversityStudentStudent 是单向的 ManyToOneUniversity 它们都扩展了基础 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;
    }
}

StudentUniversity的结构并不重要,重要的是: 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.
}

table的创建方式如下:

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;

问题有时是,在极少数情况下,Hibernate 不会将 University 实体与 Student 一起提取,这意味着当我 student.getUniversity() 它 return s null,在调试器中也是null。但是 students table 包含与此 student 的预期 University 完全相同的 univ_id,大学也包含 id。我完全确定 hibernate 会话没有关闭,并且我尝试执行与 hibernate 完全相同的查询,并且它确实 return expected id of the university,加入他们等等。事情是大多数时候它确实运行良好,并且由于未知原因这种问题很少发生,更奇怪的是 table 确实包含该 ID,所以它似乎不是 MySQL 问题。 另外值得一提的是,我正在使用 Spring Data JPA。 有没有人遇到过这种行为?难道是因为 Inheritance/Data JPA/Java 9/还有其他原因吗?

PS。 请忽略代码中的任何错字,这只是一个例子

版本:

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

终于解决了

tl;dr

fetch = FetchType.LAZYManyToOne 关系,所以在我的示例中它变为:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "univ_id", referencedColumnName = "id")
public University getUniversity() {
    return univ;
}

描述

我仍然不确定它为什么会这样,但似乎 Hibernate 根本不提取 many-to-one 关系,如果它们很急切的话。它有一定的意义,因为这样会有循环依赖,但我认为 PersistenceSet 会处理这样的问题。更奇怪的是 - 如果我使用 Long 而不是 UUID,实际上相同的结构无需急切提取即可工作。