Hibernate双向多对一关系
废话不多说,先说说这两个对象。
帐号,就是用户了;相册,当然是用户的相册。用户与相册是一对多关系,反之,相册与用户是多对一关系。现在我们看两个对象的代码。
Account
要注意@OneToMany中的cascade,还有@JoinColumn中的updatable
Album
同样注意@ManyToOne中的cascade,与Account中保持一致。
由此生成的sql语句:
在执行新建用户的时候,同时新建相册,如果没有设定级联,会出 save the transient instance before flushing 异常
生成的执行语句
如果 Account中 @JoinColumn(name = "account_id", updatable = true)的updatable设置为false,则不会有 Hibernate: update album set account_id=? where album_id=? 执行,也就是说级联操作时不会做更新操作。
废话不多说,先说说这两个对象。
帐号,就是用户了;相册,当然是用户的相册。用户与相册是一对多关系,反之,相册与用户是多对一关系。现在我们看两个对象的代码。
Account
- import java.io.Serializable;
- import java.util.Date;
- import java.util.LinkedList;
- import java.util.List;
- import javax.persistence.CascadeType;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.FetchType;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import javax.persistence.JoinColumn;
- import javax.persistence.OneToMany;
- import javax.persistence.Table;
- import org.hibernate.annotations.CacheConcurrencyStrategy;
- import org.hibernate.annotations.GenericGenerator;
- @Entity
- @Table(name = "account")
- public class Account implements Serializable {
- @Id
- @GeneratedValue(generator = "hilo")
- @GenericGenerator(name = "hilo", strategy = "hilo")
- @Column(name = "account_id")
- private long id;// 主键
- @Column(name = "name", nullable = false, unique = true)
- private String name; // 用户名
- @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = Album.class)
- @JoinColumn(name = "account_id", updatable = true)
- private List<Album> albumList = new LinkedList<Album>(); // 相册
- }
要注意@OneToMany中的cascade,还有@JoinColumn中的updatable
Album
- import java.io.Serializable;
- import java.util.Date;
- import javax.persistence.CascadeType;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.FetchType;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import javax.persistence.JoinColumn;
- import javax.persistence.ManyToOne;
- import javax.persistence.Table;
- import org.hibernate.annotations.Cache;
- import org.hibernate.annotations.CacheConcurrencyStrategy;
- import org.hibernate.annotations.GenericGenerator;
- @Entity
- @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
- @Table(name = "album")
- public class Album implements Serializable {
- private static final long serialVersionUID = -159468065798255466L;
- @Id
- @GeneratedValue(generator = "hilo")
- @GenericGenerator(name = "hilo", strategy = "hilo")
- @Column(name = "album_id")
- private long id;
- @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = Account.class)
- @JoinColumn(name = "account_id")
- private Account account;
- }
同样注意@ManyToOne中的cascade,与Account中保持一致。
由此生成的sql语句:
- alter table album drop foreign key FK5897E6F68D52691
- drop table if exists account
- drop table if exists album
- drop table if exists hibernate_unique_key
- create table account (account_id bigint not null, email varchar(255) not null unique, enabled bit not null, gender bit not null, sign_in_date datetime, name varchar(255) not null unique, password varchar(255) not null, point integer not null, sign varchar(255), sign_up_date datetime not null, primary key (account_id))
- create table album (album_id bigint not null, create_date datetime not null, url varchar(255) not null unique, account_id bigint, primary key (album_id))
- alter table album add index FK5897E6F68D52691 (account_id), add constraint FK5897E6F68D52691 foreign key (account_id) references account (account_id)
- CREATE TABLE hibernate_unique_key (next_hi int(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (next_hi))
- INSERT INTO hibernate_unique_key(next_hi) VALUES(1)
在执行新建用户的时候,同时新建相册,如果没有设定级联,会出 save the transient instance before flushing 异常
- Account a = new Account("wolf" + System.currentTimeMillis(), "snow");
- a.setEmail("snowolf@wolf.org" + System.currentTimeMillis());
- a.setGender(true);
- // 执行新建用户
- long id = accountService.signUp(a);
- List<Album> list = new LinkedList<Album>();
- list.add(new Album("" + System.currentTimeMillis()));
- a.setAlbumList(list);
- // 更新相册
- accountService.update(a);
生成的执行语句
- Hibernate: insert into account (email, enabled, gender, sign_in_date, name, password, point, sign, sign_up_date, account_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- Hibernate: insert into album (account_id, create_date, url, album_id) values (?, ?, ?, ?)
- Hibernate: update album set account_id=? where album_id=?
如果 Account中 @JoinColumn(name = "account_id", updatable = true)的updatable设置为false,则不会有 Hibernate: update album set account_id=? where album_id=? 执行,也就是说级联操作时不会做更新操作。