双向@OneToOne的效率低于与父表共享主键的单向@OneToOne。因此,不要使用双向@OneToOne,最好是依靠单向@OneToOne和@MapsId。
第一步:在子实体这边使用@MapsId
@Entity <b>public</b> <b>class</b> Desk implements Serializable { <b>private</b> <b>static</b> <b>final</b> <b>long</b> serialVersionUID = 1L; @Id <b>private</b> Long id; @OneToOne(fetch = FetchType.LAZY) @MapsId <b>private</b> Employee employee;
基本上,上面@OneToOne关联,它将与父表共享主键,父实体见如下,父实体中没有@OneToOne,这说明是从子实体指向父实体的单向关联:
@Entity <b>public</b> <b>class</b> Employee implements Serializable { <b>private</b> <b>static</b> <b>final</b> <b>long</b> serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) <b>private</b> Long id; <b>private</b> String name; <b>public</b> Long getId() { <b>return</b> id; } <b>public</b> <b>void</b> setId(Long id) { <b>this</b>.id = id; } <b>public</b> String getName() { <b>return</b> name; } <b>public</b> <b>void</b> setName(String name) { <b>this</b>.name = name; } }
源代码可以在 这里 找到 。
如果使用DDD聚合设计,Desk和Employee谁是聚合根?无论谁是聚合根,都是聚合根实体要指向引用子实体,这时会与JPA的设计有冲突,需要权衡业务设计和性能的平衡。