合并现有的Hibernate模型对象时是否得到UnsupportedOperationException?

时间:2012-06-04 22:40:31

标签: java hibernate list h2

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

问题是Hibernate似乎在向AbstractList

添加对象

这似乎只发生在一个特定的对象类型中,当保存在我们的DAO中时,但最好我们可以告诉:

  1. 我们没有使用任何会导致创建不可变实例的sublist()或asList()方法。
  2. 检查正在保存的对象(这个对象很庞大并且有很多孩子)我不会认为它的任何子项都是AbstractList类型。
  3. 以下是堆栈点周围的代码片段:

    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类有其他类似注释的子项,但所有内容都已定义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以某种方式行动,导致它试图创建不可修改的对象实例?

3 个答案:

答案 0 :(得分:1)

@OneToMany(cascade = CascadeType.ALL) @LazyCollection(LazyCollectionOption.FALSE) private Map associatedProjects = new HashMap();

如何添加此内容。

@OneToMany(cascade = CascadeType.ALL)

* @ JoinColumn(name =“”) *

@LazyCollection(LazyCollectionOption.FALSE) private Map associatedProjects = new HashMap();

答案 1 :(得分:0)

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

答案 2 :(得分:0)

使用此交易类型:

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