Linh tinh
Table of Contents

Mapping 1-1 relationship in Hibernate ORM


Update notes:


Context

Solution

When we model relationship as regular bidirectional one-to-one relationship like two entity below:

public class QuizEntity {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @OneToOne(fetch = LAZY, mappedBy = "quiz", optional = false)
  private QuizResultEntity result;

  // other fields
}

public class QuizResultEntity {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @OneToOne(fetch = LAZY, optional = false)
  @JoinColumn(name = "quiz_id")
  private QuizEntity quiz;

  // other fields
}

and fetch an entity of QuizEntity type, hibernate will trigger an additional query to check whether the associated QuizResultEntity object existing or not to provide appropriate strategy to initialize relationship. If QuizResultEntity object exists, hibernate will create a proxy, otherwise this field is set to null.

So if we add optional = false properties to @OneToOne annotation, will hibernate trigger additional query?

Unfortunately, based on [1], hibernate will still trigger additional query because the identifier of QuizResultEntity is unknown.

Query log:

select q1_0.id from quiz q1_0 where q1_0.id=?
select q1_0.id,q1_0.quiz_id from quiz_result q1_0 where q1_0.quiz_id=?

-> Use @OneToOne mapping with @MapIds at QuizResultEntity side can solve this problem. This will work because at QuizEntity side, hibernate knows the ID of associated QuizResult entity when it queries data.

public class QuizResultEntity {

  @Id
  // Note: we don't use auto generate strategy here.
  // @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @OneToOne(fetch = LAZY)
  @MapsId
  @JoinColumn(name = "quiz_id")
  private QuizEntity quiz;

  // other fields
}

Query log:

select q1_0.id from quiz q1_0 where q1_0.id=?

Use case

With these complex mappings, why on earth would you want to use them? Of course, it does not exist for fun. There are many cases in which one-to-one mappings are useful.

Appendix

Example source code: https://github.com/dntam00/learning-spring/tree/master/one-to-one