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有如下说明:

引用
This solution is obviously not optimized from the number of needed statements

参考:

http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html#d0e949

相关推荐