Java Hibernate OneToMany关系是PersistentBag而不是List

Java Hibernate OneToMany关系是PersistentBag而不是List,java,hibernate,ejb,wildfly,rmi,Java,Hibernate,Ejb,Wildfly,Rmi,我正在用javafx开发一个应用程序,它通过RMI与EAR连接。此EAR连接到SQLServerDB并使用hibernate映射POJO 这些POJO包含双向的一对一和多对一关系。因此,这些关系映射为列表 Company.java @Entity @Table(name = "Company") public class Company implements Serializable{ /** * */ private static final long serialVersionUID

我正在用javafx开发一个应用程序,它通过RMI与EAR连接。此EAR连接到SQLServerDB并使用hibernate映射POJO

这些POJO包含双向的一对一和多对一关系。因此,这些关系映射为列表

Company.java

@Entity
@Table(name = "Company")
public class Company implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = 1L;

@Id
@Column(name="id_company",nullable = false)
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;

@OneToMany(mappedBy = "company",cascade = CascadeType.ALL )
@ElementCollection
private List<Client> Clients;

//GETTERS&SETTERS   

}
@Entity
@Table(name = "Client")
public class Client implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = 1L;

@Id
@Column(name="id_client",nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id; 

@ManyToOne
private Company company;

//GETTERS&SETTERS   

}
当我执行此命令时,公司:

public default T selectById(Serializable id, Class<T> entityClass,Session session)throws HibernateException {
    T obj = null;
    obj = session.get(entityClass, id);
    return obj;
}
我使用的是Wildfly10.x服务器。 hibernatecore的版本是5.2.17.Final


如果解释得很糟糕,我很抱歉,但是项目非常复杂,本质上我需要hibernate映射到List对象而不是Persistentbag。

这里的问题是,从hibernate获得的对象属于某个hibernate代理类,而不是实际的实体类。这是hibernate的正常行为。 这个代理类是自动生成的,它的serialVersionUID也是自动生成的

通常,直接序列化/发送实体类对象不是一个好的做法,因为这样的问题,但也因为延迟初始化和所有与对象绑定到实体管理器上下文相关的问题

最常见的解决方案是创建“数据传输对象”或DTO,这些对象可能具有相同的字段(或非常类似的字段,如用字符串替换枚举等,这取决于您需要什么),而不是其他任何内容。根据您的示例,您可以有这样一个类:

public class CompanyDTO implements Serializable {

private static final long serialVersionUID = 1L;

private int id;

private List<ClientDTO> Clients;

//GETTERS&SETTERS   

}
公共类CompanyTo实现可序列化{
私有静态最终长serialVersionUID=1L;
私有int-id;
私人名单客户;
//接球手和接球手
}
(类似地,您也需要创建ClientDTO类)

相反,对于外部(外部不一定是远程的,只要您需要从EM上下文分离)通信,请使用该类


您可以手动填充,也可以通过任何其他方式填充(例如使用BeanUtils的反射,带有复制属性的公司参数的构造函数[我不建议这样做,因为它会中断应用程序层分离,但对于本次对话而言,这是一种有效的方式])。唯一重要的是,您可以从实体管理器上下文中填充它,在您的
客户机
实体中,您需要生成动态serialVersionUID,生成这样一个

private static final long serialVersionUID = -558553967080513790L;
您可以看到如何生成serialVersionUID。
有关更多信息,请参见此。

我也有您所说的serialVersionUID配置,并给出了相同的错误。始终使用相同的ID,如1L,意味着将来,如果类定义发生更改,从而导致序列化对象的结构发生更改,在尝试反序列化对象时,很可能会出现问题。因此,尝试使用generate serial version ID。不要使用1L。其思想是生成一个类的某个版本所独有的ID,当类中添加了新的详细信息(例如新字段)时,该ID将被更改,这将影响序列化对象的结构。我知道serialversionUID存在的原因,以及为什么它对于每个类都应该是唯一的。谢谢你告诉我,但正如我之前所说的,就像它是一个独特的序列,就像它是1L一样,我之前解释的错误不断出现。谢谢。使用不同的serialVersionUID不会改变任何事情。这里的问题是,OP试图序列化的对象实际上是另一个类(hibernate代理类)。我最初的想法是不使用DTO,而是使用延迟初始化。例如,如果我需要客户机提供的公司列表,我将调用一个方法,该方法返回一个公司列表,并且它们如何进行延迟初始化就不那么重要了。另一方面,如果我想输入其中一家公司以在屏幕上显示其数据,我会再次请求通过其id获取一家公司,该id将在发送客户列表之前初始化客户列表。根据您的评论,我理解没有代理无法强制hibernate创建列表。不?谢谢。不,据我所知,没有办法that@Zeromus如果我按照你在第二条评论中所说的做,那么这个收藏仍然是一个PersistentBag。第一句话我不太明白。
private static final long serialVersionUID = -558553967080513790L;