您的位置:首页 > Web前端

hibernaer--(fetch=FetchType.EAGER带来的问题)级联删除

2017-09-01 20:12 316 查看
Exception in thread "main" org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.bean.User#7]
at org.hibernate.internal.SessionImpl.forceFlush(SessionImpl.java:1226)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:182)
Group.java:

package com.bean;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="t_group")
public class Group {
private int id;
private String name;
private Set<User> users = new HashSet<User>();

@OneToMany(mappedBy="group",
cascade={CascadeType.ALL},
fetch=FetchType.EAGER
)
public Set<User> getUsers() {
return users;
}

public void setUsers(Set<User> users) {
this.users = users;
}

@Id
@GeneratedValue
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}
User.java:
package com.bean;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;

@Entity
@Table(name="t_user")
public class User {
private int id;
private String name;
private Group group;

@ManyToOne(cascade={CascadeType.ALL})
public Group getGroup() {
return group;
}

public void setGroup(Group group) {
this.group = group;
}

@Id
@GeneratedValue
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}
测试类:
Configuration cfg = new Configuration();
cfg.configure(); //加载hibernate配置文件
SessionFactory sessionFactory = cfg.buildSessionFactory(new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry());
Session session = sessionFactory.getCurrentSession();

session.beginTransaction();  //开启事务

User user = (User)session.get(User.class, 7);
user.setGroup(null);
session.delete(user);
session.getTransaction().commit(); // 事务提交


解决方法:将@oneToMany中的fetch=FetchType.EAGER注释掉就可了。

不注释的情况下发出的hql语句:

Hibernate:
select
user0_.id as id1_1_,
user0_.group_id as group3_1_1_,
user0_.name as name1_1_,
group1_.id as id0_0_,
group1_.name as name0_0_
from
t_user user0_
left outer join
t_group group1_
on user0_.group_id=group1_.id
where
user0_.id=?
Hibernate:
select
users0_.group_id as group3_0_1_,
users0_.id as id1_,
users0_.id as id1_0_,
users0_.group_id as group3_1_0_,
users0_.name as name1_0_
from
t_user users0_
where
users0_.group_id=?


可以看出通过session.get进行获取User对象的时候,由于级联关系会对user的属性group进行select查询,又由于在一的一方(oneToMany)设置了fetch的eager权限,故对group的属性uesr又会产生级联效应(发出select查询)。当我们在对user对象的group取消关联(置为null),就会报错。

对于增删查改(CRUD)的能产生级联效应的配置分别:

读(R)为fetch的属性,其余均为cascade来设置。

如有不当,请指出,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: