Hibernate/JPA中@OneToOne和@MapsId的使用
雙向@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的設計有衝突,需要權衡業務設計和效能的平衡。