有人可以在JPA和Hibernate中解释MapdBy吗?


174

我刚冬眠,需要使用一对多和多对一关系。这是我对象中的双向关系,因此我可以从任一方向来回移动。mappedBy是推荐的解决方法,但是,我听不懂。有人可以解释:

  • 推荐的使用方式是什么?
  • 它解决什么目的?

就我的示例而言,这是带有注释的类:

  • Airline 拥有许多 AirlineFlights
  • 许多 AirlineFlights属于一个 Airline

航空公司

@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;
    }
}

航空公司航班:

@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,而Airline没有idAirlineFlights。这使得AirlineFlights作为所有者/识别实体?

从理论上讲,我希望航空公司成为airlightFlights的所有者。

在此处输入图片说明

Answers:


150

通过@JoinColumn在两个模型上都指定,您就没有双向关系。您有两个单向关系,并且在那个位置有一个非常混乱的映射。您要告诉这两个模型“拥有” IDAIRLINE列。实际上,实际上其中只有一个!“正常”的事情是完全@JoinColumn脱颖而出@OneToMany,而是将maptedBy添加到@OneToMany

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

这告诉Hibernate:“在我有一个用来查找配置的集合上,查看名为'airline'的bean属性。”


1
最后,关于您的被映射的描述我有些困惑。事情在db中的组织方式是否重要?@DB:AirlineFlights将idAirline作为外键。航空公司仅将idAirline作为主键,而不保留有关AirlineFlights @ DB的信息。
brainydexter'2

10
是的,这很重要。appedBy中的名称告诉Hibernate在哪里可以找到JoinColumn的配置。(在AirlineFlight的getAirline()方法)的方式将它映射把JoinColumn的航空公司,你告诉航空公司,它负责在另一个表中保持的值。可以告诉实体“拥有”另一个表中的一列并负责对其进行更新。这不是您通常要执行的操作,它可能会导致执行SQL语句的顺序出现问题。
2012年

请查看编辑。在数据库级别,airlineFlight表拥有idAirline作为外键列。因此,JoinColumn应该放在相应的ManytoOne中的airlineFlight类/表上,因为它拥有该列?
brainydexter'2

是的,我建议您这样做。这是最简单的选择,您似乎不需要其他任何东西。
2012年

“完全将@JoToColumn从@OneToMany一侧移开”是您的意思,对@ManyToOne吧?
nbro
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.