繁体   English   中英

合并现有 Hibernate model object 时出现 UnsupportedOperationException?

[英]UnsupportedOperationException when merging an existing Hibernate model object?

从 Hibernate 3 升级到 4 后,我们正在解决沿途出现的一些问题。 一个让我们特别难过的是 UnsupportedOperationException,其中现有的 object 从数据库中提取、调整和合并。

问题是 Hibernate 似乎将 object 添加到AbstractList

当保存在我们的 DAO 中时,这似乎只发生在一种特定的 object 类型上,但据我们所知:

  1. 我们没有使用任何会导致创建不可变实例的 sublist() 或 asList() 方法。
  2. 检查正在保存的 object(它很大并且有很多子项)我认为它的任何子项都不是AbstractList类型。

以下是堆栈点周围的代码片段:

HibernateDao.save():

@Transactional
public void save(T item) {
    try {
        getSessionFactory().getCurrentSession().merge(item);
    } catch (Exception ex) {
        LOGGER.debug("Unable to merge", ex);
        LOGGER.warn("Unable to merge item, saving instead. (Of type " + item.getClass() + ")");
        getSessionFactory().getCurrentSession().saveOrUpdate(item);
    }
}

我们正在保存的用户项目有许多子项目定义如下:

@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
private Map<String, Project> associatedProjects = new HashMap<String, Project>();

Project class 有其他类似注释的子项,但所有内容都定义了CascadeType.ALLLazyCollectionOption.FALSE

这是(相当高的)堆栈跟踪:

请注意,我们的代码以com.company.application

06/04 18:15:45 DEBUG [Thread-19258] hibernate.HibernateDao.save- Unable to merge
java.lang.UnsupportedOperationException
        at java.util.AbstractList.add(AbstractList.java:148)
        at java.util.AbstractList.add(AbstractList.java:108)
        at org.hibernate.collection.internal.PersistentBag.add(PersistentBag.java:292)
        at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:496)
        at org.hibernate.type.CollectionType.replace(CollectionType.java:563)
        at org.hibernate.type.AbstractType.replace(AbstractType.java:178)
        at org.hibernate.type.TypeHelper.replaceAssociations(TypeHelper.java:261)
        at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:398)
        at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:221)
        at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:282)
        at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
        at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914)
        at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:896)
        at org.hibernate.engine.spi.CascadingAction$6.cascade(CascadingAction.java:288)
        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.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:439)
        at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:308)
        at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
        at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914)
        at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:896)
        at org.hibernate.engine.spi.CascadingAction$6.cascade(CascadingAction.java:288)
        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.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:439)
        at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:308)
        at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
        at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914)
        at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:896)
        at org.hibernate.engine.spi.CascadingAction$6.cascade(CascadingAction.java:288)
        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.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:439)
        at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:308)
        at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
        at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:76)
        at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:904)
        at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:888)
        at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:892)
        at com.company.hibernate.HibernateDao.save(HibernateDao.java:129)
        at sun.reflect.GeneratedMethodAccessor62.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at $Proxy53.save(Unknown Source)
        at com.company.application.UserManager.save(UserManager.java:46)
        at sun.reflect.GeneratedMethodAccessor67.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at $Proxy66.save(Unknown Source)
        at com.company.application.UserOperationController.saveUser(UserOperationController.java:533)

我们不确定 AbstractList 来自哪里,或者我们如何负责。 使用 Hibernate 4(这个问题是升级后的新问题)时是否存在任何可能导致部分不可修改的对象的潜在陷阱? 或者这会导致 Hibernate 的行为方式导致它尝试创建不可修改的对象实例?

在这个代码块中:

@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
private Map<String, Project> associatedProjects = new HashMap<String, Project>();

怎么加这个。

@OneToMany(cascade = CascadeType.ALL)

*****@JoinColumn(name="")***** 

@LazyCollection(LazyCollectionOption.FALSE)
private Map<String, Project> associatedProjects = new HashMap<String, Project>();

我遇到了同样的问题(使用Sets而不是Lists ),似乎有问题的集合的 Hibernate 的 Persistent 变体试图委托给一个没有实现add方法的抽象基类。 我找到的解决方案是将数据成员设置为 null,进行merge ,然后将数据成员设置回我希望它包含的新列表。 相当明显的缺点是,即使我只想添加或删除一个记录,我也会吹掉所有记录。 好处是它确实有效......

我最近有同样的效果 - 我在我的测试用例中使用java.util.Arrays#asList

很容易错过,因为返回的 class 被命名为ArrayList ,但它不是java.util.ArrayList ,而是java.util.Arrays.ArrayList

使用此交易类型:

@javax.transaction.Transactional(Transactional.TxType.REQUIRES_NEW)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM