自己的代码修正,记着避免忘记
一方:User.java
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
@Entity
@Table
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Integer uid;
private String email;
private String password;
private String signature;
private String image;
private Integer sex;
private String username;
private String verifyCode;
private List<Log> logList = new ArrayList<Log>();
/**
* @return the logList
*/
@OneToMany(targetEntity=Log.class, orphanRemoval=true)
@JoinColumn(name = "ulid")
public List<Log> getLogList() {
return logList;
}
/**
* @param logList
* the logList to set
*/
public void setLogList(List<Log> logList) {
this.logList = logList;
}
/**
* @return the verifyCode
*/
@Transient
public String getVerifyCode() {
return verifyCode;
}
/**
* @param verifyCode
* the verifyCode to set
*/
public void setVerifyCode(String verifyCode) {
this.verifyCode = verifyCode;
}
/**
* @return the uid
*/
@Id
@Column(name = "uid")
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getUid() {
return uid;
}
/**
* @param uid
* the uid to set
*/
public void setUid(Integer uid) {
this.uid = uid;
}
/**
* @return the email
*/
@Column(name = "email")
public String getEmail() {
return email;
}
/**
* @param email
* the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* @return the password
*/
@Column(name = "password")
public String getPassword() {
return password;
}
/**
* @param password
* the password to set
*/
public void setPassword(String password) {
this.password = password;
}
/**
* @return the signature
*/
@Column(name = "signature")
public String getSignature() {
return signature;
}
/**
* @param signature
* the signature to set
*/
public void setSignature(String signature) {
this.signature = signature;
}
/**
* @return the image
*/
@Column(name = "image")
public String getImage() {
return image;
}
/**
* @param image
* the image to set
*/
public void setImage(String image) {
this.image = image;
}
/**
* @return the sex
*/
@Column(name = "sex")
public Integer getSex() {
return sex;
}
/**
* @param sex
* the sex to set
*/
public void setSex(Integer sex) {
this.sex = sex;
}
/**
* @return the username
*/
@Column(name = "username")
public String getUsername() {
return username;
}
/**
* @param username
* the username to set
*/
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "User [uid=" + uid + ", email=" + email + ", password=" + password + ", signature=" + signature
+ ", image=" + image + ", sex=" + sex + ", username=" + username + ", verifyCode=" + verifyCode
+ ", logList=" + logList + "]";
}
}
多方: Log.java
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.apache.struts2.json.annotations.JSON;
@Table
@Entity
public class Log implements Serializable{
private static final long serialVersionUID = 1L;
private Integer lid;
private String ip;
private String device;
private Date loginTime;
private User user;
@ManyToOne
@JoinColumn(name="ulid")
public User getUser() {
return user;
}
/**
* @param user the user to set
*/
public void setUser(User user) {
this.user = user;
}
/**
* @return the lid
*/
@Id
@Column(name="lid")
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Integer getLid() {
return lid;
}
/**
* @param lid the lid to set
*/
public void setLid(Integer lid) {
this.lid = lid;
}
/**
* @return the ip
*/
@Column(name="ip")
public String getIp() {
return ip;
}
/**
* @param ip the ip to set
*/
public void setIp(String ip) {
this.ip = ip;
}
/**
* @return the device
*/
@Column(name="device")
public String getDevice() {
return device;
}
/**
* @param device the device to set
*/
public void setDevice(String device) {
this.device = device;
}
/**
* 设置日期类类型为timestamp
* @return the loginTime
*/
@Column(name="loginTime")
@Temporal(TemporalType.TIMESTAMP)
@JSON(format="yyyy-MM-dd HH:mm:ss")
public Date getLoginTime() {
return loginTime;
}
/**
* @param loginTime the loginTime to set
*/
public void setLoginTime(Date loginTime) {
this.loginTime = loginTime;
}
@Override
public String toString() {
return "Log [lid=" + lid + ", ip=" + ip + ", device=" + device + ", loginTime=" + loginTime + "]";
}
}
底层dao文件:UserDaoImpl.java
public void deleteUserByUid(User user) {
// 此时的user2为持久态,如果是托管态或瞬时态,不能进行级联删除
User user2 = hibernateTemplate.get(User.class, user.getUid());
hibernateTemplate.delete(user2);
// 同步数据库与session缓存
hibernateTemplate.flush();
}
测试结果:
1. 去掉一的一方的@JoinColumn注解,报错Cannot delete or update a parent row: a foreign key constraint fails (`test/log`, CONSTRAINT `FK1clr7t8a6pnwpwjndqr5d12ce` FOREIGN KEY (`ulid`) REFERENCES `user` (`uid`))
2. 去掉一的一方的@OneToMany(targetEntity=Log.class, orphanRemoval=true)中的orphanRemoval=true,数据库不级联删除,多的一方中的外键会被置空
2.1 ***********orphanRemoval在一对多关系中,可以看做是是否级联删除***********
3. 如果底层删除的实体类的对象的状态不是持久态,会报错
3.1. 如果底层删除的实体类对象的状态是托管态,报错A different object with the same identifier value was already associated with the session : [pdsu.xps.ssh.pojo.User#2]
3.2. 如果底层删除的实体类对象的状态是顺势态,报错java.lang.IllegalArgumentException: id to load is required for loading
参考:
- 三种持久化对象的状态
Transient瞬时态
特点:持久化对象没有唯一标识OID.没有纳入Session的管理.
Persistent持久态:
特点:持久化对象有唯一标识OID.已经纳入到Session的管理.
结论:持久化持久态对象有自动更新数据库的能力.
Detached脱管态:
特点:持久化对象有唯一标识OID,没有纳入到Session管理.- Hibernate中的级联取值
none :不使用级联
dave-update :保存或更新的时候级联
delete :删除的时候级联
all :除了孤儿删除以外的所有级联.
delete-orphan :孤儿删除(孤子删除).
仅限于一对多.只有一对多时候,才有父子存在.认为一的一方是父亲,多的一方是子方.
当一个客户与某个订单解除了关系.将外键置为null.订单没有了所属客户,相当于一个孩子没有了父亲.将这种记录就删除了.
all-delete-orphan:包含了孤儿删除的所有的级联.
参考链接:https://www.jianshu.com/p/95f597050ab4