当我尝试在一些删除操作之后进行读操作时,我得到了这个hibernate断言错误。
我找不到任何关于这个“无法执行取消删除”的错误,except the soure code,所以我想,也许我做的事情明显是错的……
堆栈跟踪在下面,
AssertionFailure:43 - - HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: Unable to perform un-delete for instance X
org.hibernate.AssertionFailure: Unable to perform un-delete for instance X
at org.hibernate.engine.spi.ActionQueue.unScheduleDeletion(ActionQueue.java:508)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:157)
at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:870)
at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:863)
at org.hibernate.engine.spi.CascadingAction$8.cascade(CascadingAction.java:346)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:423)
at org.hibernate.event.internal.DefaultPersistEventListener.justCascade(DefaultPersistEventListener.java:190)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsDeleted(DefaultPersistEventListener.java:229)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:158)
at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:870)
at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:863)
at org.hibernate.engine.spi.CascadingAction$8.cascade(CascadingAction.java:346)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:423)
at org.hibernate.event.internal.DefaultPersistEventListener.justCascade(DefaultPersistEventListener.java:190)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsPersistent(DefaultPersistEventListener.java:183)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:147)
at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:870)
at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:863)
at org.hibernate.engine.spi.CascadingAction$8.cascade(CascadingAction.java:346)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:409)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:350)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:160)
at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:151)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:58)
at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1186)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1241)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:257)
at org.hibernate.ejb.criteria.CriteriaQueryCompiler$3.getResultList(CriteriaQueryCompiler.java:254)
致以敬意,
发布于 2013-06-12 17:52:52
我也有同样的问题。发生的情况是,我删除了相关的bean,我们称它们为A和B。我删除了B,然后继续查找链接到As的实体C,并将类型为A的bean作为参数进行查询,查询导致了此异常。我最好的猜测是,实体D上的Cascade注释引用了A和B,在我删除B时删除了As,然后将一个已经在DB级删除的实体作为参数提供给查询,从而导致了问题。
重新排列代码,以便我首先删除从C到A的引用,然后继续删除B和A,这似乎解决了这个问题。
发布于 2013-11-20 11:40:29
我今天也面临着同样的堆栈跟踪,使用Hibernate 4.x作为JPA 2.x提供程序。以下是我了解到的需要更改以修复此引发的异常的内容。
在我的JPA映射域模型中,我有一个基于深度OneToMany的图,A有很多B,B有很多C,C有很多D,D有很多E。所有“一对多”的级联类型就是全部。回指ManyToOne存在于每个级别,并且当这些ManyToOne关系都是默认的(即,急切地加载)时,我们编写的代码工作得很好。
在我今天诊断的有问题的用例中,我们使用JPQL查询读取D的离散集合,当我们迭代该集合时,我们调用EntityManager.remove(c),其中我们通过向D实例请求其父实例/所有者C实例来获得c实例。
如果c实例是通过延迟加载D到C关系获得的,则对EntityManager.remove(c)的调用不会报错,但随后对EntityManager.flush()的调用会导致subject异常。
如果在JPQL查询中,通过添加"join fetch d.c c“来急切地加载从D到C关系,则不会引发subject异常。
所以,我想我会分享这些结果,以防其他人面临这个问题,上面的内容让他们知道他们可能会做出哪些改变来解决这个问题。
发布于 2013-12-05 22:26:33
这是为所有通过搜索不能取消删除断言而来到这里的人(像我一样)。
我在承包商留给我们的一些代码中的断言也有同样的问题,但对我来说,问题不是级联,它工作得很好。
由于某些原因,Hibernate在同一会话中加载同一实体两次。我是在深入研究Hibernate内部时才发现这一点的。
我使用org.hibernate.stat.SessionStatistics和PersistenceContext,前者可以从会话中获得,后者可以从SessionImpl中获得
Session session = (Session)this.entityManager.unwrap(Session.class);
persistenceContext = ((SessionImpl)session).getPersistenceContext();
来找出Hibernate加载了什么。
打印出完整的实体列表时
public void printSessionInfo(String where,HashSet<String> printClasses){
Log log = Logging.getLog(PersistentSesionInfo.class);
Session session = (Session)this.entityManager.unwrap(Session.class);
SessionStatistics stats = session.getStatistics();
HashMap<String,Counter> entityMap = new HashMap<String,Counter>();
if(stats!=null){
log.info("EntityManager #0 has #1 managed entities and #2 collections at #3", getHash(entityManager),stats.getEntityCount(),stats.getCollectionCount(),where);
List<EntityKey> entities = com.google.common.collect.Lists.newArrayList(stats.getEntityKeys());
Iterator<EntityKey> iter = entities.iterator();
while(iter.hasNext()){
EntityKey ek = iter.next();
if(entityMap.containsKey(ek.getEntityName())){
entityMap.get(ek.getEntityName()).increase();
}else{
entityMap.put(ek.getEntityName(), new Counter());
}
if(printClasses!=null && printClasses.contains(ek.getEntityName())){
try{
Object o = ((HibernateSessionProxy)session).get(ek.getEntityName(), ek.getIdentifier());
if(o!=null){
log.info("Entity #0 of type #1 id=#2 System hash=#3 object hash #4", o,Hibernate.getClass(o).getSimpleName(),ek.getIdentifier(),Integer.toHexString(System.identityHashCode(o)),Integer.toHexString(o.hashCode()));
}
}catch(javax.persistence.EntityNotFoundException e ){
log.error("Entity #0 with id #1 cannot be found anymore", ek.getEntityName(),ek.getIdentifier());
}
}
}
for(Entry<String,Counter> entry : entityMap.entrySet()){
log.info("Entity #0 count #1", entry.getKey(),entry.getValue());
}
}
}
public class Counter {
int count = 1;
public void increase(){
count++;
}
public int getCount(){
return count;
}
public String toString(){
return String.valueOf(count);
}
}
我的实体在那里列出,但是当我使用
persistenceContext.getEntry(myEntity)
返回null (entityManager.contains(myEntity)返回true)!
我迭代了persistenceContext.getEntitiesByKey()中的所有EntityKeys (在迭代之前,您可能需要复制列表)
List<EntityKey> list = new ArrayList<EntityKey>();
list.addAll(persistenceContext.getEntitiesByKey().keySet());
在那里,myEntity的EntityKey在那里,但它指向不同的实例(不同的System.identiyHashCode)。
我必须假设最终问题出在实体的equals和hashCode方法上(实体问题经常出现)。我注意到相似的实体实例将具有相同的hashCode,即使它们的父实例不同。
我使用了‘必须假定’,因为问题并没有马上消失(我没有重启服务器,因为我正在使用liverebel)。只有在Hibernate上启用跟踪的情况下重新启动服务器后,问题才会消失。在回滚所有其他调试更改并只保留equals/hashCode方法后,它仍在工作。
所以,当你的实体出现奇怪的无法解释的问题时--检查equals和hashCode方法!并使用Hibernate类PersistenceContext和SessionStatistics对其进行调试。
https://stackoverflow.com/questions/16778785
复制相似问题