EJB实体的Java序列化不是序列化多个集合的一个成员,而是有时序列化

EJB实体的Java序列化不是序列化多个集合的一个成员,而是有时序列化,java,serialization,jboss,ejb,Java,Serialization,Jboss,Ejb,对于服务器到服务器的同步过程,我正在网络上序列化EJB实体对象。服务器是JBoss5,使用Hibernate进行持久化。在这个开发场景中,我的远程服务器使用sun-java6-jdk 1.6.0_24-b07运行在Ubuntu Linux上,而我的开发机器使用Java 1.6.0_24-b07-334-10M3326运行OS X 我的一个类是User,它可以属于一个或多个组。我遇到的问题是,对于一个特定的用户,并不是所有关联的组对象都通过序列化:该用户被分配到两个组,但只有一个通过序列化。其他用

对于服务器到服务器的同步过程,我正在网络上序列化EJB实体对象。服务器是JBoss5,使用Hibernate进行持久化。在这个开发场景中,我的远程服务器使用sun-java6-jdk 1.6.0_24-b07运行在Ubuntu Linux上,而我的开发机器使用Java 1.6.0_24-b07-334-10M3326运行OS X

我的一个类是User,它可以属于一个或多个组。我遇到的问题是,对于一个特定的用户,并不是所有关联的组对象都通过序列化:该用户被分配到两个组,但只有一个通过序列化。其他用户的情况很好,可以分配给两个组(类似于受影响的用户),也可以只分配给缺少的组或其他组

用户是多人关系的“所有者”,与组的关系如下

用户

公共类用户实现可序列化、可克隆、动态、可识别、可比较{
//其他东西省略了。。。
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name=“tbl\u user\u group”,joinColumns=@JoinColumn(name=“user\u id”,referencedColumnName=“id”),inverseJoinColumns=@JoinColumn(name=“group\u id”,referencedColumnName=“id”))
@XmlTransient
私有集组=新HashSet();
}
集团

public类组实现可序列化、可识别、可比较的{
//其他东西省略了。。。
@许多(mappedBy=“组”)
@XmlTransient
私有集用户=新树集();
}
在远程服务器端,我有一个收集对象并将其作为
列表[]
返回的服务。下面是客户端调用的服务方法

公共列表[]getSyncData(){
最终EntityManager em=emf.createEntityManager();
列表[]数据=null;
试一试{
数据=getLocalData(em、toSlaveServices);
}最后{
em.close();
}
返回数据;
}
在getLocalData方法中,我记录正在处理的对象

 User masteruser: [Group [899d07bf-28f9-437a-8811-6d53b8f2df5d, master62]]
 User admin: [Group [899d07bf-28f9-437a-8811-6d53b8f2df5d, master62], Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62]]
 User allgroups: [Group [899d07bf-28f9-437a-8811-6d53b8f2df5d, master62], Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62]]
 User slave62: [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62]]
 User d8a0f514-0930-41fb-8028-5db9e8a2824c: [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62]]
 User px: [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62]]
 Sending [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62], Group [899d07bf-28f9-437a-8811-6d53b8f2df5d, master62]]
我已经将所有用户和组包括在上下文中:我感兴趣的是第三行的Userallgroups。如您所见,所有组都属于两个组:master62和slave62

在客户端,我还记录从服务器接收回来的对象

 User masteruser: [Group [899d07bf-28f9-437a-8811-6d53b8f2df5d, master62]]
 User admin: [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62], Group [899d07bf-28f9-437a-8811-6d53b8f2df5d, master62]]
 User allgroups: [Group [899d07bf-28f9-437a-8811-6d53b8f2df5d, master62]]
 User slave62: [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62]]
 User d8a0f514-0930-41fb-8028-5db9e8a2824c: [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62]]
 User px: [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62]]
 Received [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62], Group [899d07bf-28f9-437a-8811-6d53b8f2df5d, master62]]
正如您所看到的,除了allgroups用户之外,一切都按预期进行,该用户只在一个组中拥有成员资格

为了查看是否可以跟踪所发生的情况,我决定手动尝试序列化到受影响的用户对象的文件中,然后是整个列表数组。下面是修改后的
getSyncData
方法:

公共列表[]getSyncData(){
最终EntityManager em=emf.createEntityManager();
列表[]数据=null;
试一试{
数据=getLocalData(em、toSlaveServices);
}最后{
em.close();
}
长时间=System.currentTimeMillis();
对于(列表基准:数据){
fgLogger.debug(“发送”+数据);
if(datum!=null&&datum.size()>0&&datum.get(0.getClass()==User.class){
用于(用户:((列表)数据)){
调试(“User”+User.getUser_id()+”:“+User.getGroups());
if(“allgroups”.equals(user.getUser_id())){
试一试{
ObjectOutputStream oos=新的ObjectOutputStream(新的FileOutputStream(“/tmp/user-”+time+“.ser”);
oos.writeObject(用户);
oos.close();
}捕获(例外e){
e、 printStackTrace();
}
}
}
}
}
试一试{
ObjectOutputStream oos=新的ObjectOutputStream(新的FileOutputStream(“/tmp/ssi-”+time+“.ser”);
oos.writeObject(数据);
oos.close();
}捕获(例外e){
e、 printStackTrace();
}
返回数据;
}
然后,我将两个序列化文件从远程服务器复制到我的客户机,并尝试使用一个简单的Groovy脚本(即不是从JBoss中读取),首先是user-xxx.ser文件,然后是ssi-xxx.ser文件

*** USER ***
User allgroups: [Group [899d07bf-28f9-437a-8811-6d53b8f2df5d, master62], Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62]]
*** SSI ***
User masteruser: [Group [899d07bf-28f9-437a-8811-6d53b8f2df5d, master62]]
User admin: [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62], Group [899d07bf-28f9-437a-8811-6d53b8f2df5d, master62]]
User allgroups: [Group [899d07bf-28f9-437a-8811-6d53b8f2df5d, master62]]
User slave62: [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62]]
User d8a0f514-0930-41fb-8028-5db9e8a2824c: [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62]]
User px: [Group [0d293aa6-c5af-4a03-a8ce-edea9b05acb7, slave62]]
SSI位下的结果反映了我在网上序列化的经验。但是,序列化用户单独包含这两个组,这是我想要的!这两个序列化文件是使用相同的原始数据以相同的方法生成的,尽管用户显然嵌套在另一个数据结构中


allgroups用户的结果如何不同??我很困惑,如果有人对此感兴趣,我将非常感谢您的澄清。

我还没有找到这个问题的答案。我怀疑这与链接组对象存储在Hibernate
PersistentSet
中的方式有关(尽管
PersistentSet
和支持它的
HashSet
都是可序列化的)。我已经放弃了调试——时间就是金钱


我通过向我的用户实体添加一个额外的字段来解决这个问题,
setgroupids
。我在
User.writeObject
中填充此集合,当用户被序列化时调用此集合。在接收端,我清除了组集,然后根据groupIds字段中存储的id手动搜索组。然后,我将这些组添加到用户的组集中。这很麻烦,而且需要我先同步这些组,以便能够重新分配它们-但它可以工作。

如果有人感兴趣:

我还没有找到这个问题的答案。我怀疑这与链接组对象存储在Hibernate
PersistentSet
中的方式有关(尽管
PersistentSet
和支持它的
HashSet
都是可序列化的)。我已经放弃了调试——时间就是一切