hibernate one to many
1.Unidirectionalwithjointable
参考例子
http://www.vaannila.com/hibernate/hibernate-example/hibernate-mapping-one-to-many-using-annotations-1.html
2.Unidirectionalwithforeignkey
PERSON
PERSON_ID
PERSON_NAME
ADDRESS
ADDRESS_ID
ADDRESS_NAME
P_ID
P_ID字段在ADDRESS表中,但其定义在PERSONentity中
@Entity @Table(name = "PERSON") public class Person { private Integer id; private String name; private Set<Address> addressSet = new HashSet<Address>(0); public Person() { } public Person(String name, Set<Address> addSet) { this.name = name; this.addressSet = addSet; } @Id @GeneratedValue @Column(name = "PERSON_ID") public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(name = "PERSON_NAME") public String getName() { return name; } public void setName(String name) { this.name = name; } @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "P_ID") public Set<Address> getAddressSet() { return addressSet; } public void setAddressSet(Set<Address> addressSet) { this.addressSet = addressSet; } @Override public String toString() { return this.id + "\t" + this.name; } }
@Entity @Table(name = "ADDRESS") public class Address { private Integer addressId; private String name; public Address() { } public Address(String name) { this.name = name; } @Id @GeneratedValue @Column(name = "ADDRESS_ID") public Integer getAddressId() { return addressId; } public void setAddressId(Integer addressId) { this.addressId = addressId; } @Column(name = "ADDRESS_NAME") public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return this.addressId + "\t" + this.name; } }
插入数据时,hibernate会生成如下sql
Hibernate:insertintoPERSON(PERSON_ID,PERSON_NAME)values(null,?)
Hibernate:insertintoADDRESS(ADDRESS_ID,ADDRESS_NAME)values(null,?)
Hibernate:insertintoADDRESS(ADDRESS_ID,ADDRESS_NAME)values(null,?)
Hibernate:updateADDRESSsetP_ID=?whereADDRESS_ID=?
Hibernate:updateADDRESSsetP_ID=?whereADDRESS_ID=?
hibernatedoc不建议使用此中连接,参考
http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html#d0e1517
3.bidirectional
表结构
PERSON
PERSON_ID
PERSON_NAME
ADDRESS
ADDRESS_ID
ADDRESS_NAME
P_ID
A.manytoone端是owner
@Entity @Table(name = "PERSON") public class Person { private Integer id; private String name; private Set<Address> addressSet = new HashSet<Address>(0); public Person() { } public Person(String name, Set<Address> addSet) { this.name = name; this.addressSet = addSet; } @Id @GeneratedValue @Column(name = "PERSON_ID") public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(name = "PERSON_NAME") public String getName() { return name; } public void setName(String name) { this.name = name; } @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, [color=red]mappedBy = "person"[/color]) public Set<Address> getAddressSet() { return addressSet; } public void setAddressSet(Set<Address> addressSet) { this.addressSet = addressSet; } @Override public String toString() { return this.id + "\t" + this.name; } }
@Entity @Table(name = "ADDRESS") public class Address { private Integer addressId; private String name; private Person person; public Address() { } public Address(String name) { this.name = name; } @Id @GeneratedValue @Column(name = "ADDRESS_ID") public Integer getAddressId() { return addressId; } public void setAddressId(Integer addressId) { this.addressId = addressId; } @Column(name = "ADDRESS_NAME") public String getName() { return name; } public void setName(String name) { this.name = name; } @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "P_ID") public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @Override public String toString() { return this.addressId + "\t" + this.name; } }
B.onetomany端是owner
注意address中joincolumn的insertable和updatable 为false
@Entity @Table(name = "PERSON") public class Person { private Integer id; private String name; private Set<Address> addressSet = new HashSet<Address>(0); public Person() { } public Person(String name, Set<Address> addSet) { this.name = name; this.addressSet = addSet; } @Id @GeneratedValue @Column(name = "PERSON_ID") public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(name = "PERSON_NAME") public String getName() { return name; } public void setName(String name) { this.name = name; } @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "P_ID") public Set<Address> getAddressSet() { return addressSet; } public void setAddressSet(Set<Address> addressSet) { this.addressSet = addressSet; } @Override public String toString() { return this.id + "\t" + this.name; } }
@Entity @Table(name = "ADDRESS") public class Address { private Integer addressId; private String name; private Person person; public Address() { } public Address(String name) { this.name = name; } @Id @GeneratedValue @Column(name = "ADDRESS_ID") public Integer getAddressId() { return addressId; } public void setAddressId(Integer addressId) { this.addressId = addressId; } @Column(name = "ADDRESS_NAME") public String getName() { return name; } public void setName(String name) { this.name = name; } @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "person_fk", insertable=false, updatable=false) public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @Override public String toString() { return this.addressId + "\t" + this.name; } }
测试
1.插入Person及关联的Address,hibernate生成的的sql语句为
manytoone端为owner时
Hibernate: insert into PERSON (PERSON_ID, PERSON_NAME) values (null, ?) Hibernate: insert into ADDRESS (ADDRESS_ID, ADDRESS_NAME, person_fk) values (null, ?, ?) Hibernate: insert into ADDRESS (ADDRESS_ID, ADDRESS_NAME, person_fk) values (null, ?, ?)
onetomany端为owner时
Hibernate: insert into PERSON (PERSON_ID, PERSON_NAME) values (null, ?) Hibernate: insert into ADDRESS (ADDRESS_ID, ADDRESS_NAME) values (null, ?) Hibernate: insert into ADDRESS (ADDRESS_ID, ADDRESS_NAME) values (null, ?) Hibernate: update ADDRESS set person_fk=? where ADDRESS_ID=? Hibernate: update ADDRESS set person_fk=? where ADDRESS_ID=?
2.删除Address时,
manytoone端为owner时
Hibernate: delete from ADDRESS where ADDRESS_ID=? Hibernate: delete from ADDRESS where ADDRESS_ID=? Hibernate: delete from PERSON where PERSON_ID=?
onetomany端为owner时
Hibernate: update ADDRESS set person_fk=null where person_fk=? Hibernate: delete from ADDRESS where ADDRESS_ID=? Hibernate: delete from ADDRESS where ADDRESS_ID=? Hibernate: delete from PERSON where PERSON_ID=?
3.删除Person同删除Address相同
显然,onetomany端为owner时,会生成更多sql, 故hibernatedoc有如下说明:
参考:
http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html#d0e949