我的Spring+Hibernate学习笔记(二)

Hibernate双向多对一关系
废话不多说,先说说这两个对象。
帐号,就是用户了;相册,当然是用户的相册。用户与相册是一对多关系,反之,相册与用户是多对一关系。现在我们看两个对象的代码。
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("[email protected]" + 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=? 执行,也就是说级联操作时不会做更新操作。

你可能感兴趣的:(java,spring,sql,Hibernate,UP)