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

问题描述 投票:0回答:1

我有两个实体,让我们命名为UniversityStudentStudent是单向ManyToOneUniversity他们都扩展基类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.
}

表格创建如下:

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()它返回null,而在调试器中它也是null。但是students表包含与univ_id预期的University完全相同的student,大学也包含id。我完全相信hibernate会话没有关闭,我试图执行与hibernate完全相同的查询,它确实返回了大学的预期id,加入它们等等。事情就是大多数时候它确实运行良好,并且由于未知原因很少发生此类问题,更奇怪的是该表确实包含该id,因此看起来它不是MySQL问题。另外值得一提的是,我使用的是Spring Data JPA。有没有人遇到过这种行为?可能是由于继承/数据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
java mysql hibernate spring-data-jpa hikaricp
1个回答
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,那么相同的结构实际上可以在没有急切提取的情况下工作。

© www.soinside.com 2019 - 2024. All rights reserved.