Java 已在没有父级的情况下保留一对多子级

Java 已在没有父级的情况下保留一对多子级,java,google-app-engine,persistence,Java,Google App Engine,Persistence,我正在使用GoogleAppEngine和GoogleWebToolkit来编写一个bug跟踪器(看看这些技术有什么功能) 以谷歌代码的问题跟踪器为模型,我决定一个问题可以有0个或更多的标签,这些标签可以预先定义(比如在设置中) 标签类(CustomLabel): 现在,父类(问题): 如何解决这个问题?我无法使用Key并创建无主关系,因为我正在将对象发送到GWT前端(不支持编译为Javascript和com.google.appengine.api.datastore.Key)。此外,这会破坏

我正在使用GoogleAppEngine和GoogleWebToolkit来编写一个bug跟踪器(看看这些技术有什么功能)

以谷歌代码的问题跟踪器为模型,我决定一个问题可以有0个或更多的标签,这些标签可以预先定义(比如在设置中)

标签类(CustomLabel):

现在,父类(问题):


如何解决这个问题?我无法使用Key并创建无主关系,因为我正在将对象发送到GWT前端(不支持编译为Javascript和com.google.appengine.api.datastore.Key)。此外,这会破坏引用完整性,这是不可取的

不能将现有的CustomLabel作为子元素分配给新问题。由于datanucleus处理关系的方式,每个CustomLabel实体只能属于一个问题对象。它将父对象和子对象放在同一个实体组中。一个实体只能属于一个实体组。假设您创建了一个名为“nastybug”的自定义标签并将其持久化。它现在属于某个实体组X。当您创建一个新的问题并将其持久化时,它将属于某个实体组Y。Datanucleus(以及实际的google数据存储)不允许您尝试将一个实体从组X存储到组Y中

如果希望在问题之间共享标签,则需要使用无主关系。您是正确的,您不能通过GWT的RPC机制传递密钥,因此您可能需要在发送JDO对象之前将其转换为其他形式


您可以阅读有关实体组的信息

在列表中使用@Unowned:

import com.google.appengine.datanucleus.annotations.Unowned;
...
@Persistent
@Unowned
private List<Category> categories;

谢谢,这解释了很多,尽管它有点奇怪,有一个关系数据库背景:)只需注意:主键不必是
Long
类型。
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Issue implements Serializable {
    private static final long serialVersionUID = 1L;

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id;

    // Replacing the Long key by this key doesn't make a difference
    // @PrimaryKey
    // @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    // @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
    // private String encodedKey;

    @Persistent
    private String summary;

    @Persistent
    private String description;

    @Persistent 
    private ArrayList<CustomLabel> labels;

    // Other details
}
org.datanucleus.exceptions.NucleusUserException: Detected attempt to establish Issue(11) as the parent of CustomLabel(1) but the entity identified by CustomLabel(1) has already been persisted without a parent.  A parent cannot be established or changed once an object has been persisted.
import com.google.appengine.datanucleus.annotations.Unowned;
...
@Persistent
@Unowned
private List<Category> categories;
@Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
@PrimaryKey
private Long id;