如何确保OpenJPA中的非托管/托管对象标识?

时间:2011-05-10 11:22:34

标签: java gwt persistence openjpa dozer

我正在使用OpenJPA来持久化对象。我最初使用OpenJPA 1.2,但随后升级到OpenJPA 2.1。对象保存在内存中的服务器上,并且它们被序列化到客户端,并且可以作为无人值守的方式接收回来。推土机用于删除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试图保留一个非托管对象,请添加一个注释。总结:

图形尚未保留,也不是A或B.图形一旦发送到服务器,它们都是持久的。 持久化的新图形具有不同的A但相同的B.它没有意识到B已经被持久化并重新创建它,即使它具有相同的@Id。

我觉得JPA没有看到对象与内存中的对象相同。

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

我该如何解决这个问题?

  • 我正在使用GWT的序列化,并且工作正常。 GWT能引起这种情况吗?我认为这是一个JPA问题。

1 个答案:

答案 0 :(得分:0)

现在是时候使用DTO了,考虑到在将对象送回服务器之后会有一些参考逻辑。

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

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