在Hibernate JPA 的Entity實體關係中,可分為 Bidirectional(雙向)或 Unidirectional(單向)。Bidirectional的意思如下。
Bidirectional Relationships(雙向關係)指兩個關聯實體都有參考到另一個實體的屬性,也就是兩個實體彼此"知道"彼此的存在,所以兩實體都可透過其有關聯設定的屬性物件來存取被關聯的實體。
Bidirectional雙向關係中一邊為owning side,另一邊為inverse side。
inverse side必須使用@OneToOne
,@OneToMany
或@ManyToMany
的mappedBy
屬性來指明owning side的參照外鍵的屬性名稱。所以設定Hibernate JPA實體的雙向關係時,要先了解哪一邊是owning side,哪一邊是inverse side。
在一對多/多對一(One To Many / Many To One)的雙向關係中,多邊(many side)總是為owning side。多邊不應設定mappedBy
。
在一對一(One To One)的雙向關係中,owning side為持有外鍵屬性的那一邊。
在多對多(Many To Many)的雙向關係中,因為多對多關係會有一個中介資料表,所以任一邊都可以是owning side(只能設定一邊為owning side)。
例如兩個關聯實體分別為「作者」及「書」,假設關係為作者(Author)有多本書(Book),為一對多(One To Many)的關係。若兩實體設為bidirectional雙向關係,則表示Author
物件知道Book
物件,Book
物件也知道Author
物件。
依照上面所述,Author
為單邊(one side),Book
為多邊(many side),
所以Author
為inverse side,Book
為owning side,
則程式中設定如下。
Author
@Entity
@Table(name="Author")
public class Author {
@Id
@Column(name="AuthorId")
private Integer authorId;
@Column(name="AuthorName")
private String authorName;
@OneToMany(mappedBy="author")
private Set bookSet;
// getter and setter ommitted...
}
Book
@Entity
@Table(name="Book")
public class Book {
@Id
@Column(name="BookId")
private Integer bookId;
@Column(name="BookName")
private String bookName;
@ManyToOne
@JoinColumn(name="AuthorId") // 外鍵欄位名稱
private Author author; // 外鍵的屬性
// getter and setter ommitted...
}
上面範例中,兩個實體都有參考到另一個實體的關聯屬性,Author
為bookSet
;Book
為author
。
Author
為inverse side,所以在關聯屬性bookSet
使用@OneToMany
的mappedBy
指明owning side實體中參考外鍵的屬性名稱,所以設為@OneToMany(mappedBy="author")
。
以下節錄自The Java EE 6 Tutorial - Direction in Entity Relationships
Bidirectional Relationships
In a bidirectional relationship, each entity has a relationship field or property that refers to the other entity. Through the relationship field or property, an entity class’s code can access its related object. If an entity has a related field, the entity is said to “know” about its related object. For example, if
Order
knows whatLineItem
instances it has and ifLineItem
knows whatOrder
it belongs to, they have a bidirectional relationship.Bidirectional relationships must follow these rules.
- The inverse side of a bidirectional relationship must refer to its owning side by using the
mappedBy
element of the@OneToOne
,@OneToMany
, or@ManyToMany
annotation. ThemappedBy
element designates the property or field in the entity that is the owner of the relationship.- The many side of many-to-one bidirectional relationships must not define the
mappedBy
element. The many side is always the owning side of the relationship.- For one-to-one bidirectional relationships, the owning side corresponds to the side that contains the corresponding foreign key.
- For many-to-many bidirectional relationships, either side may be the owning side.
參考:
- Direction in Entity Relationships
- Hibernate JPA 雙向一對多/多對一設定 Bidirectional One To Many / Many To One
- Hibernate JPA Entity 生命週期 (JPA Entity Lifecycle)
- Annotation Type ManyToMany
- Annotation Type OneToMany
- Annotation Type OneToOne
- Spring Data JPA @OneToMany LazyInitializationException could not initialize proxy - no Session
沒有留言:
張貼留言