2012-02-02 19 views
132

我是hibernate的新手,需要使用一對多和多對一的關係。這是我的對象中的雙向關係,所以我可以從任一方向進行遍歷。 mappedBy是推薦的方式,但是,我無法理解它。有人請向我解釋:有人可以請解釋映射在休眠?

  • 什麼是使用它的推薦方式?
  • 它解決了什麼目的?

在我的例子起見,這裏有我的課與註釋:

  • Airline擁有許多AirlineFlights
  • 許多AirlineFlights屬於ONEAirline

航空公司

@Entity 
@Table(name="Airline") 
public class Airline { 
    private Integer idAirline; 
    private String name; 

    private String code; 

    private String aliasName; 
    private Set<AirlineFlight> airlineFlights = new HashSet<AirlineFlight>(0); 

    public Airline(){} 

    public Airline(String name, String code, String aliasName, Set<AirlineFlight> flights) { 
     setName(name); 
     setCode(code); 
     setAliasName(aliasName); 
     setAirlineFlights(flights); 
    } 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @Column(name="IDAIRLINE", nullable=false) 
    public Integer getIdAirline() { 
     return idAirline; 
    } 

    private void setIdAirline(Integer idAirline) { 
     this.idAirline = idAirline; 
    } 

    @Column(name="NAME", nullable=false) 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = DAOUtil.convertToDBString(name); 
    } 

    @Column(name="CODE", nullable=false, length=3) 
    public String getCode() { 
     return code; 
    } 
    public void setCode(String code) { 
     this.code = DAOUtil.convertToDBString(code); 
    } 

    @Column(name="ALIAS", nullable=true) 
    public String getAliasName() { 
     return aliasName; 
    } 
    public void setAliasName(String aliasName) { 
     if(aliasName != null) 
      this.aliasName = DAOUtil.convertToDBString(aliasName); 
    } 

    @OneToMany(fetch=FetchType.LAZY, cascade = {CascadeType.ALL}) 
    @JoinColumn(name="IDAIRLINE") 
    public Set<AirlineFlight> getAirlineFlights() { 
     return airlineFlights; 
    } 

    public void setAirlineFlights(Set<AirlineFlight> flights) { 
     this.airlineFlights = flights; 
    } 
} 

AirlineFlights:

@Entity 
@Table(name="AirlineFlight") 
public class AirlineFlight { 
    private Integer idAirlineFlight; 
    private Airline airline; 
    private String flightNumber; 

    public AirlineFlight(){} 

    public AirlineFlight(Airline airline, String flightNumber) { 
     setAirline(airline); 
     setFlightNumber(flightNumber); 
    } 

    @Id 
    @GeneratedValue(generator="identity") 
    @GenericGenerator(name="identity", strategy="identity") 
    @Column(name="IDAIRLINEFLIGHT", nullable=false) 
    public Integer getIdAirlineFlight() { 
     return idAirlineFlight; 
    } 
    private void setIdAirlineFlight(Integer idAirlineFlight) { 
     this.idAirlineFlight = idAirlineFlight; 
    } 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="IDAIRLINE", nullable=false) 
    public Airline getAirline() { 
     return airline; 
    } 
    public void setAirline(Airline airline) { 
     this.airline = airline; 
    } 

    @Column(name="FLIGHTNUMBER", nullable=false) 
    public String getFlightNumber() { 
     return flightNumber; 
    } 
    public void setFlightNumber(String flightNumber) { 
     this.flightNumber = DAOUtil.convertToDBString(flightNumber); 
    } 
} 

編輯:

數據庫模式:

AirlineFlights有idAirline爲ForeignKey的和航空公司沒有idAirlineFlights。這使得AirlineFlights成爲所有者/識別實體?

從理論上講,我希望航空公司是航空公司的所有者。

enter image description here

回答

107

通過在兩個模型上指定@JoinColumn,您沒有雙向關係。你有兩個單向關係,並且在這個關係上有一個非常混亂的映射。您告訴兩個模型他們「擁有」IDAIRLINE列。真的只有其中一個應該! 「正常」的做法是完全關閉@OneToMany側的@JoinColumn,並將mappedBy添加到@OneToMany

@OneToMany(cascade = CascadeType.ALL, mappedBy="airline") 
public Set<AirlineFlight> getAirlineFlights() { 
    return airlineFlights; 
} 

這就告訴Hibernate「查看名爲'airline'的bean屬性,我有一個集合來查找配置。

+0

最後,我對你的描述有點困惑,因爲這裏描述的是mappedBy。它在db中如何組織事件有關係嗎? @DB:AirlineFlights將idAirline作爲外鍵。航空公司只有idAirline作爲主鑰匙,並且不支持有關AirlineFlights @ DB的信息。 – brainydexter 2012-02-02 07:43:07

+7

是的,這很重要。 mappedBy中的名字告訴Hibernate在哪裏找到JoinColumn的配置。 (在AirlineFlight的getAirline()方法上。)您將FlightColumn映射到航空公司的方式,您告訴Airline它*負責維護另一個表中的值。有可能告訴實體它在不同的表中擁有一列,並負責更新它。這不是您通常想要執行的操作,並且可能會導致執行SQL語句的順序問題。 – Affe 2012-02-02 07:51:11

+0

請參閱編輯。在數據庫級別,airlineFlight表擁有idAirline作爲外鍵列。因此,JoinColumn應放在相應的ManytoOne中的airlineFlight類/表上,因爲它擁有該列? – brainydexter 2012-02-02 09:43:58

211

的mappedBy信號冬眠,對於關係的關鍵是在另一側上。

這意味着雖然您將兩個錶鏈接在一起,但只有其中一個表具有另一個表的外鍵約束。 MappedBy允許您仍然將不包含約束的錶鏈接到另一個表。

+23

這應該是被接受的答案。 – azizunsal 2013-09-30 07:30:45

+2

你能否澄清一點? – 2013-11-12 13:55:23

+1

@Kurt杜Bois,你爲什麼要使用'mappedBy'而不是定義一個雙向(每邊都有foreign_key約束)? – 2014-01-25 15:23:45

6

mappedby它爲自己說話,它告訴休眠不要映射這個字段,它已經準備好映射這個字段[name =「field」]。
場中的其他實體(name of the variable in the class not the table in database) ..

如果你不這樣做,Hibernate會因爲它不是 同一關係

所以我們需要告訴Hibernate映射做這兩關係僅在一側的映射和它們之間的協調。

+0

是mappedBy是可選的嗎?因爲沒有使用mappedBy我得到了相同的結果,即雙向對象映射 – 2016-11-23 17:31:39

+0

你不能使用on2many和many2one而不使用mappedBy在許多方面相同的事情之一你必須使用mappedBy在一側 – Cherif 2016-11-25 06:53:58

+0

不清楚!請你能舉個例子嗎? – 2016-11-25 07:09:53

4

的mappedBy =

注「在另一個類中創建同一類的實體對象」:由只能在一個類中使用,因爲一個表必須包含外鍵約束-Mapped如果通過映射可以應用在兩側則來自兩個表,並沒有外鍵刪除外鍵是沒有關係的b/W兩個表

注: - 它可以爲以下注釋使用: - 1. @ OneTone 2. @一對多 3. @ ManyToMany

注意---它可以不可用於以下注釋: - 1. @ ManyToOne

在一對一中: - 在任何一側執行映射,但僅在一側執行。 它將刪除應用了哪個類的表上額外的外鍵約束列。

例如,如果我們將應用映射到僱員對象的Employee類中,那麼Employee表中的外鍵將被刪除。

0

您從ManyToOne映射開始,然後將OneToMany映射以及BiDirectional方式。 然後在OneToMany方面(通常是你的父表/類),你必須提到「mappedBy」(映射是由child table/class完成的),所以hibernate不會在DB中創建EXTRA映射表(如TableName = parent_child) 。