休眠删除的对象将被级联重新保存
Posted
技术标签:
【中文标题】休眠删除的对象将被级联重新保存【英文标题】:Hibernate deleted object would be re-saved by cascade 【发布时间】:2017-09-15 02:07:18 【问题描述】:我正在尝试在休眠中删除一个子实体,但出现此异常:
org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.epic.ecommerce.core.model.Customer#newnameTest]
at org.hibernate.internal.SessionImpl.forceFlush(SessionImpl.java:1236)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:187)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:114)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:684)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:676)
at org.hibernate.engine.spi.CascadingActions$5.cascade(CascadingActions.java:235)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)...
这些是我的实体:
@Entity
@Table(name="客户") 公共类客户
@Id
@Column(name="customer_id")
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign",parameters=@Parameter(name="property", value="user"))
private String id;
@OneToMany(cascade=CascadeType.ALL,mappedBy="customerId",orphanRemoval=true) 私有设置 quoteConfigs;
public Set<QuoteConfiguration> getQuoteConfigs()
return quoteConfigs;
public void setQuoteConfigs(Set<QuoteConfiguration> quoteConfigs)
this.quoteConfigs = quoteConfigs;
public String getId()
return id;
public void setId(String id)
this.id = id;
@OneToOne
@PrimaryKeyJoinColumn
private User user;
public User getUser()
return user;
public void setUser(User user)
this.user = user;
@Entity
@Table(name="quote_configuration")
public class QuoteConfiguration implements java.io.Serializable
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "quote_id",unique = true, nullable = false)
private Integer quoteId;
@Column(name = "base_product", nullable = false)
private String baseProduct;
@Column(name = "quote_name")
private String quoteName;
/*
@Column(name = "customer_customer_id")
private String customerId;
public String getCustomerId()
return customerId;
public void setCustomerId(String customerId)
this.customerId = customerId;
*/
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "customer_customer_id")
private Customer customerId;
public Customer getCustomerId()
return customerId;
public void setCustomerId(Customer customerId)
this.customerId = customerId;
这是我尝试删除的部分
Session session = this.sessionFactory.getCurrentSession();
Query q = session.createQuery("from QuoteConfiguration where quoteId = :quoteId ");
q.setParameter("quoteId", quoteId);
QuoteConfiguration quote = (QuoteConfiguration)q.list().get(0);
Query qc=session.createQuery("from Customer where id=:id");
qc.setParameter("id", quote.getCustomerId().getId());
Customer customer=(Customer)qc.list().get(0);
customer.getQuoteConfigs().remove(quote);
session.delete(quote);
session.save(customer);
我的问题是如何删除子实体 QuoteConfiguration,而不会在 Customer 中获得该关联异常。谢谢
【问题讨论】:
【参考方案1】:只需从您的代码中删除 session.delete(quote)
。
您的@OneToMany
集合是您记录的主,并且它已设置为删除孤立 元素。因此,当您执行customer.getQuoteConfigs().remove(quote)
时,它已经告诉 Hibernate 从数据库中删除记录。
附带说明,您应该尝试session.get(class, id)
,而不是使用 HQL 来获取单个实例。
您不需要save(customer)
,因为 Hibernate 始终跟踪持久化实例。它们将在交易关闭时自动保存(除非您的会话设置为手动,否则不应如此)。
【讨论】:
感谢 Guillaume F. 的回复,但仍然给了我同样的例外,您知道我可以通过其他方式删除这个孩子吗? 确保您的所有@OneToMany 和@ManyToOne 关系都设置为(fetch=FetchType.LAZY)
loading。此外,请确认您的 Session 中没有加载其他集合。
看看这个帖子,有意思:***.com/questions/24257449/…
我做了另一个修复,更改了两个实体中的 fetchType 并更改了我的 DAO 中的删除以上是关于休眠删除的对象将被级联重新保存的主要内容,如果未能解决你的问题,请参考以下文章