java - 如何确保 OpenJPA 中的非托管/托管对象身份?

标签 java gwt persistence openjpa dozer

我正在使用 OpenJPA 来保存对象。我最初使用 OpenJPA 1.2,但后来升级到 OpenJPA 2.1。对象保存在服务器的内存中,它们被序列化到客户端,并且可以按未修改的方式接收回来。 Dozer 用于删除 JPA 内容并且一直如此。之前没有造成任何问题。我依赖 JPA 在保存推土机映射的 JPA 对象时能够识别 @Id。

所以本质上我有一个大的对象嵌套图,其中一些具有双向(循环)引用。该结构具有客户端更改的数据和未更改的数据。它被发送到客户端,之前可能或可能没有被持久化。只有当它至少被发送回服务器一次时,它才会被持久化。我有一个对象以 OneToOne 关系引用另一个对象:

class A {
    @Column("b_id")
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    int id;
    @OneToOne
    @JoinColumn(name="b_id")
    B something
    @OneToOne
    Graph owner;
}

class B {
    @Column("b_id")
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    int id;
}

class Graph {
    @Column("graph_id")
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    int id;
    @OneToOne
    @Column
    A item;
}

问题是,当我收到返回的对象*时,它是存储在服务器上的对象的不同实例,并且它是非托管的。如果我添加cascade = CascadeStrategy.ALL,当它再次将对象添加到数据库时,我会得到重复的插入。如果我保留它,我会得到一个异常,JPA 试图保留非托管对象,请添加注释。总结一下:

Graph 尚未持久化,A 或 B 也未持久化。一旦 Graph 发送到服务器,它们就会全部持久化。 一个新的 Graph 被持久化,它具有不同的 A 但相同的 B。它没有意识到 B 已经被持久化并重新创建它,即使它具有相同的 @Id。

我有一种感觉,JPA 看到的对象与内存中的对象不同。

我确信 OpenJPA 1.2 似乎根据 @Id 注释将对象识别为等效对象。我尝试手动修复引用,并尝试将引用从非托管对象更改为服务器内存中加载的托管对象。不幸的是,这一直有效,直到我重新启动服务器,并且它无法修复之前所做的引用。我知道这不是正确的解决方案。

我该如何解决这个问题?

  • 我正在使用 GWT 的序列化,效果很好。 GWT 会导致这种情况吗?我认为这是一个 JPA 问题。

最佳答案

考虑到您在将对象返回到服务器后应该发生一些引用逻辑,是时候使用 DTO 了。

您可以创建 Graph_Model、A_Model 和 B_Model 类(这些是数据传输对象),并在与客户端 GWT 代码对话时使用它们。当 Graph_Model 到达服务器时,您可以从 Graph_Model 创建托管 Graph 对象,并通过查询设置正确的引用。

此外,类 A 和 Graph 根本没有 ID 属性,这有点奇怪,因此每当您保存 Graph 类型的对象时都会创建它们。我没有足够的信息来建议其他任何事情,不知道你想要做什么,目标是什么。

关于java - 如何确保 OpenJPA 中的非托管/托管对象身份?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5949237/

相关文章:

java - 将整数从一种方法传递到另一种方法

java - 如何正确使用ExecutorService来管理并发运行的SwingWorker数量?

java - 管理 1 个项目中的多个 Google Web Toolkit 页面

c# - 如何使用存储库持久化聚合?

java - 使用 hibernate 条件更新多行

java - 从 WAR 文件中打包的类路径加载 PNG 文件

java - Eclipse 中带有 WindowBuilder 的应用程序窗口

css - GWT UiBinder 样式主名称不起作用

sharepoint - 在 SharePoint 中保留本地配置数据

java - 我需要用用户指定的数字创建一个数组,它可以工作,但一直给我0