2012-09-05 31 views
0

我正在使用XStream对遗留系统进行序列化对象以保持两个数据库同步。一个新的对象首先被存储在一个数据库中,然后被存储的对象被序列化并被发送以存储在另一个数据库中。XStream - 处理具有相同标识符的对象

直到最近,有关对象的结构是这样的:

public class Project { 
    List<Milestone> milestones; 
    [...] 
} 

但是,变化的要求后,结构应该是这样的:

public class Project { 
    List<Goal> goals; 
} 

public class Goal { 
    List<Milestone> milestones; 
} 

为了保持对目标一无所知的传统数据的里程碑,项目的最终结构是这样的:

public class Project { 
    List<Goal> goals; 
    List<Milestone> milestones; 
} 

因此,从项目到里程碑有两条路径,一条直接通过目标。当这个结构被反序列化并存储时,就会出现问题。当它被XStream反序列化时,连接到项目的里程碑的对象直接成为与通过目标连接的对象不同的对象,即使它们具有相同的ID。

只要Hibernate的Session#merge()被用来保存这个对象,这是没问题的,因为merge()不关心对象标识符,只要db标识符是相同的。

但是,我不能再使用merge()来达到这个目的,而必须依靠Session#save()来代替。 save()DO关心对象标识符!所以现在当我试图存储反序列化的对象时,我得到了一个org.hibernate.NonUniqueObjectException。

我认为解决这个问题最少的方法是,如果可能的话,让XStream为每个数据库ID创建一个对象。但是这可能吗?

+0

我一直认为应该可以通过[Object References](http://xstream.codehaus.org/graphs。 HTML)。你可以添加用于序列化和反序列化对象的代码吗? – DB5

+0

XML文件是否使用对象引用?检查以确保您期望的两个里程碑实例相同,在XML中被引用。可以明确定义一个,并且在项目 - >目标 - >里程碑中,它应该反向引用已经定义的那个。 – eipark

+0

我认为它实际上有反向引用机制,经过一些考虑后,问题不是由于序列化本身,它由于项目的另一个不错的“特征” - 我会创建一个答案解释。 – Tobb

回答

0

经过一番考虑后,我发现问题不是XStream,因为它具有对象引用的机制。问题是我正在研究的项目的另一个漂亮的“特征” - 它具有每个域类的两个版本,一个用于与Hibernate通信,另一个用于“逻辑使用”(不要问我为什么......)在这两个版本(基本上是将值从一个对象移动到另一个对象)之间的转换中,对象是不加批判地新建的,导致相同的“Hibernate对象”被转换为多个“Java对象”。然后,我不能指责XStream不理解这些应该是相同的:)

相关问题