java - Hibernate OneToMany 关系是 PersistentBag 而不是 List

标签 java hibernate ejb wildfly rmi

我正在 javafx 中开发一个应用程序,该应用程序通过 RMI 与 EAR 连接。该 EAR 连接到 SQLServer DB 并使用 hibernate 映射 POJOS。

这些 POJOS 包含双向 OneToMany 和 ManyToOne 关系。因此,这些关系被映射为 List 。

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   

}

Client.java

@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   

}

当我执行此操作时,T 是公司:

public default T selectById(Serializable id, Class<T> entityClass,Session session)throws HibernateException {
    T obj = null;
    obj = session.get(entityClass, id);
    return obj;
}

结果是带有所有相应信息的 POJO,但在调试 View 中看到:

screen

该对象已成功实例化,并且我的桌面应用程序完美地接收了该对象,但是如果该对象使用接收对象 Company 作为参数的方法再次将其发送到服务器,则会出现此错误。

javax.ejb.EJBException: java.io.StreamCorruptedException: serialVersionUID does not match!
at org.jboss.as.ejb3.remote.AssociationImpl.receiveInvocationRequest(AssociationImpl.java:128)
at org.jboss.ejb.protocol.remote.EJBServerChannel$ReceiverImpl.handleInvocationRequest(EJBServerChannel.java:450)
at org.jboss.ejb.protocol.remote.EJBServerChannel$ReceiverImpl.handleMessage(EJBServerChannel.java:188)
at org.jboss.remoting3.remote.RemoteConnectionChannel.lambda$handleMessageData$3(RemoteConnectionChannel.java:430)
at org.jboss.remoting3.EndpointImpl$TrackingExecutor.lambda$execute$0(EndpointImpl.java:926)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Caused by: java.io.StreamCorruptedException: serialVersionUID does not match!
    at org.jboss.marshalling.AbstractClassResolver.resolveClass(AbstractClassResolver.java:108)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadClassDescriptor(RiverUnmarshaller.java:1025)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1354)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:275)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:223)
at org.jboss.marshalling.river.RiverUnmarshaller.readFields(RiverUnmarshaller.java:1856)
at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1769)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1397)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:275)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:208)
at org.jboss.marshalling.AbstractObjectInput.readObject(AbstractObjectInput.java:41)
at org.jboss.ejb.protocol.remote.EJBServerChannel$RemotingInvocationRequest.getRequestContent(EJBServerChannel.java:805)
at org.jboss.as.ejb3.remote.AssociationImpl.receiveInvocationRequest(AssociationImpl.java:126)
... 7 more
Caused by: an exception which occurred:
    in field com.persistence.pojo.Company.Clients
in object com.persistence.pojo.Company@47368172
in object of type com.persistence.pojo.Company

我正在使用 Wildfly10.x 服务器。 hibernatecore的版本是5.2.17.Final

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

最佳答案

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

一般来说,直接序列化/发送实体类对象不是一个好习惯,因为这样的问题,而且还因为延迟初始化的问题以及所有与将对象绑定(bind)到实体管理器上下文相关的问题。

最常见的解决方案是创建“数据传输对象”或 DTO,它们可能具有相同的字段(或非常相似 - 例如用字符串替换枚举等,具体取决于您的需要),仅此而已。根据您的示例,您可以拥有这样的类(class):

public class CompanyDTO implements Serializable {

private static final long serialVersionUID = 1L;

private int id;

private List<ClientDTO> Clients;

//GETTERS&SETTERS   

}

(以此类推,您也需要创建 ClientDTO 类)。

使用此类来进行外部(外部不一定是远程的,只要您需要与 EM 上下文分离的地方)通信。

您可以手动填充它,或通过任何其他方式(例如使用 BeanUtils 进行反射,带有复制属性的 Company 参数的构造函数 [我不建议这样做,因为它会中断应用程序层分离,但出于本次对话的目的这是一种有效的方法])。唯一重要的是您从实体管理器上下文中填充它

关于java - Hibernate OneToMany 关系是 PersistentBag 而不是 List,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50328616/

相关文章:

java - 线程 "main"java.lang.NoClassDefFoundError : xxxxx (wrong name: xxxxx) error when running program 中的异常

java - 致命异常 : java. lang.SecurityException RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED 之一 (com.google.android.play:core

java - 使用优先级队列作为最小堆

java - 使用 Hibernate 的 Java Web 服务中的内存泄漏

java - 如何在 EJB 模块启动时执行一些代码

java - 阿基利安 : Could not setup GlassFish Embedded Bootstrap

java - sbt:导入 resteasy-client 时出错

java - 阻止 Hibernate 尝试从数据库中获取计算字段

java - JPA 2 : how to declare primary-key columns in @ElementCollection tables

java jboss 无法处理部署的阶段 PARSE