Can someone please explain mappedBy in hibernate?

来源:互联网 发布:用dos命令调试java程序 编辑:程序博客网 时间:2024/05/24 06:30

I am new to hibernate and need to use 1-Many and Many-1 relation. It is a bi-directional relationship in my objects, so that I can traverse from either direction. mappedBy is the recommended way to go about it. However, I couldn’t understand it. Can someone please explain it to me,

what is the recommended way to use it ?
what purpose does it solve ?
For the sake of my example, here are my classes with annotations:

Airline OWNS many AirlineFlights
Many AirlineFlights belong to ONE Airline
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;    }}

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

By specifying the @JoinColumn on both models you don’t have a two way relationship. You have two one way relationships, and a very confusing mapping of it at that. You’re telling both models that they “own” the IDAIRLINE column. Really only one of them actually should! The ‘normal’ thing is to take the @JoinColumn off of the @OneToMany side entirely, and instead add mappedBy to the @OneToMany.

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

That tells Hibernate “Go look over on the bean property named ‘airline’ on the thing I have a collection of to find the configuration.”

The name in mappedBy is telling Hibernate where to find the configuration for the JoinColumn. (On the getAirline() method of AirlineFlight.) The way you mapped it putting the JoinColumn on airline, you are telling Airline that it is responsible for maintaining the values over in the other table. It is possible to tell an Entity it “owns” a column in a different table and is responsible for updating it. It’s not something you usually want to do and can cause problems with the order SQL statements are executed.

MappedBy signals hibernate that the key for the relationship is on the other side.

This means that although you link 2 tables together, only 1 of those tables has a foreign key constraint to the other one. MappedBy allows you to still link from the table not containing the constraint to the other table.

Because sometimes it just doesn’t make sense to put a key on both sides. Say for example you have a company and a portable. A portable will only belong to one company, but a company will have multiple portables.

0 0
原创粉丝点击