Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何归档和恢复集合标记为“的Hibernate实体”;删除“孤立的”;_Java_Hibernate_Serialization - Fatal编程技术网

Java 如何归档和恢复集合标记为“的Hibernate实体”;删除“孤立的”;

Java 如何归档和恢复集合标记为“的Hibernate实体”;删除“孤立的”;,java,hibernate,serialization,Java,Hibernate,Serialization,我正在尝试创建一个归档系统,在这个系统中,我可以将一个复杂的Hibernate实体归档到文件中,然后(可能在我的web应用程序的另一个实例中)将该实例恢复为一个新实体 这是我当前尝试序列化的实体: @Entity @Table (name = "assessments") public class Assessment implements Serializable, Comparable<Assessment>{ @Id @GeneratedValue pr

我正在尝试创建一个归档系统,在这个系统中,我可以将一个复杂的Hibernate实体归档到文件中,然后(可能在我的web应用程序的另一个实例中)将该实例恢复为一个新实体

这是我当前尝试序列化的实体:

@Entity
@Table (name = "assessments")
public class Assessment implements Serializable, Comparable<Assessment>{
    @Id
    @GeneratedValue
    private Long id;

    [...]

    @OneToMany (cascade = CascadeType.ALL, orphanRemoval=true)
    @JoinColumn(name="assessment_id")
    @LazyCollection(LazyCollectionOption.FALSE)
    private Set<Module> modules = new TreeSet<Module>();

    [...]
}
执行此代码时,我得到以下错误:

org.springframework.orm.hibernate4.HibernateSystemException: Don't change the reference to a collection with delete-orphan enabled : thisproject.domain.template.Assessment.modules; nested exception is org.hibernate.HibernateException: Don't change the reference to a collection with delete-orphan enabled : thisproject.domain.template.Assessment.modules
    at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:218)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:730)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:592)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:521)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
    at thisproject.repository.AssessmentDAO$$EnhancerBySpringCGLIB$$dc4906d8.saveArchivedItem(<generated>)
    at thisproject.web.controller.SubmissionController.doSerial(SubmissionController.java:246)
    [...]
Caused by: org.hibernate.HibernateException: Don't change the reference to a collection with delete-orphan enabled : thisproject.domain.template.Assessment.modules
    at org.hibernate.engine.internal.Collections.prepareCollectionForUpdate(Collections.java:242)
    at org.hibernate.engine.internal.Collections.processReachableCollection(Collections.java:209)
    [...]
org.springframework.orm.hibernate4.HibernateSystemException:不更改对启用了删除孤立项的集合的引用:thisproject.domain.template.Assessment.modules;嵌套异常为org.hibernate.hibernate异常:不更改对启用了删除孤立项的集合的引用:thisproject.domain.template.Assessment.modules
位于org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:218)
位于org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:730)
位于org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:592)
位于org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
位于org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
位于org.springframework.transaction.interceptor.TransactionSpectSupport.commitTransactionAfterReturning(TransactionSpectSupport.java:521)
位于org.springframework.transaction.interceptor.TransactionSpectSupport.invokeWithinTransaction(TransactionSpectSupport.java:291)
位于org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
在org.springframework.aop.framework.ReflectiveMethodInvocation.procedue(ReflectiveMethodInvocation.java:179)上
位于org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
在thisproject.repository.AssessmentDAO$$EnhancerBySpringCGLIB$$dc4906d8.saveArchivedItem()中
位于thisproject.web.controller.SubmissionController.doSerial(SubmissionController.java:246)
[...]
原因:org.hibernate.hibernate异常:不更改对启用了删除孤立项的集合的引用:thisproject.domain.template.Assessment.modules
位于org.hibernate.engine.internal.Collections.prepareCollectionForUpdate(Collections.java:242)
位于org.hibernate.engine.internal.Collections.processReachableCollection(Collections.java:209)
[...]
无论我做什么,我似乎都无法让它意识到我没有改变最初的评估

评估对象实际上有几个其他可序列化实体的集合,但是它总是挂起在模块上。我不确定这是否仅仅是因为它是Hibernate第一个访问的模块(即使在源代码中它上面有一个几乎相同的集合),或者模块代码是否确实有问题

我知道当您设置集合而不是清空并添加到同一集合时,会发生此异常,但我没有这样做。以下是setModules方法供参考:

public void setModules(Collection<Module> modules) {
    for(Module module : this.modules) {
        module.setAssessment(null);
    }
    this.modules.clear();
    for(Modules module : modules) {
        addModule(module);
    }
}
public void setModules(收集模块){
for(模块:this.modules){
模块设置评估(空);
}
这是.modules.clear();
用于(模块:模块){
添加模块(模块);
}
}

我该如何正确地序列化和反序列化Hibernate实体,并将集合标记为“delete orphan”

您提到了
setModules
方法,但实际上您从未调用该方法并调用
clear

我的理论是,当您序列化它时,用于保存
模块的hibernate集合类型的某些内部状态正在被序列化,并且在您反序列化并尝试插入后,它处于非功能状态

在持久化之前,可能需要实际调用集合上的
clear
方法,例如:

Assessment clone=(Assessment)SerializationHelper.clone(Assessment);
Set modules=clone.getModules();
用于(模块m:模块){
m、 setId(null);
}
克隆.setModules(模块);
sessionFactory.getCurrentSession().persist(克隆);

将hibernate实体序列化为文件是一个有趣的边缘案例!边缘情况是我不再使用ORM的原因之一。在将评估及其整个实体图序列化到磁盘时,是否要从数据库中删除它?也就是说,当您试图反序列化并存储到数据库时,这是被视为插入还是对现有记录的更新?@Ben,对于这个特定的示例,我想在数据库中创建一个克隆,因此它应该是插入。原始评估应保持不变并保留在数据库中,而新评估应作为新评估插入(本例中为模块)。模块是否是唯一设置了
delete orphan=true
的关系?只是为了好玩,您是否尝试过先自行插入评估(通过清除所有与itse相关的集合),然后从数据库加载评估并尝试将集合添加回评估?只是好奇这是否真的解决了问题。@Ben,还有两个类似的集合标记为
delete orphan=true
。模块就是错误提到的模块。在我正在测试的情况下,modules集合实际上已经是空的,但是为了测试,我再次明确地清除了它。错误没有改变。我对此做了一些实验,显式调用
setModules
方法,它似乎没有改变。即使有,问题是我不想改变模块;我只想克隆并保存它们。这个对象图有多深?这些模块是什么
public void setModules(Collection<Module> modules) {
    for(Module module : this.modules) {
        module.setAssessment(null);
    }
    this.modules.clear();
    for(Modules module : modules) {
        addModule(module);
    }
}