Search code examples
javamysqlhibernatespring-data-jpahikaricp

Hibernate sometimes doesn't extract uuid referenced entity


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

Solution

  • Solved, finally

    tl;dr

    Put fetch = FetchType.LAZY to ManyToOne relation, so in my example it becomes:

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

    Description

    I am not still sure why it behaves like this, but it seems that Hibernate does not extract many-to-one relations at all, if they're eager. It have some sense as this way there will be circular dependencies, but I thought that PersistenceSet will deal with such issues. What is even more strange - just the same structure actually works without eager extraction if I use Long instead of UUID.