使用JDO在GAE中进行双向一对一映射?

时间:2014-08-24 18:20:38

标签: rest google-app-engine google-cloud-datastore jdo

如何使用Google Application Engine GAEJava Data Objects)使用JDOUser)实现双向一对一映射?

我有一个contactInfo类,其中包含ContactInfo个对象,另一个user类包含@PersistenceCapable(identityType ="APPLICATION", detachable = "true") public class User{ @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Long id; private String name; @Persistent(dependent = "true") private ContactInfo child; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public ContactInfo getChild() { return child; } public void setChild(ContactInfo child) { this.child = child; } } @PersistenceCapable(identityType ="APPLICATION", detachable = "true") public class ContactInfo { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Key id; @Persistent(mappedBy = "child") private User parent; private String contactDetail; public Key getId() { return id; } public void setId(Key id) { this.id = id; } public String getContactDetail() { return contactDetail; } public void setContactDetail(String contactDetail) { this.contactDetail = contactDetail; } } 个对象

com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.demo.jdo.ContactInfo[\"user\"]->com.demo.jdo.User[\"contactInfo\"]->com.demo.jdo.ContactInfo[\"user\"]-

我在从API资源管理器测试API时遇到错误

{{1}}

2 个答案:

答案 0 :(得分:2)

标准JDO 1-1 bidir只能从http://www.datanucleus.org/products/accessplatform_3_1/jdo/orm/one_to_one.html#bi找到 GAE在这方面应该没有什么不同;上次我使用它(也许3年前)他们进行了一些测试,想想那些在这里http://code.google.com/p/datanucleus-appengine/source/browse/#svn%2Ftrunk%2Ftests%2Fcom%2Fgoogle%2Fappengine%2Fdatanucleus

您的问题没有提供您在注释方面所尝试的内容的定义

答案 1 :(得分:0)

得到了解决方案,问题在于错误地使用了mappedBy&在孩子中存在父对象的getter和setter。

  • @Persistent(mappedBy ="")注释应该只在非所有者方面
  • 在所有者/子方面,不应该为所有者/父对象提供任何getter / setter。

工作代码:

<强> User.java

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class User {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
private String name;

@Persistent(dependent = "true")
private ContactInfo contactInfo;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public ContactInfo getContactInfo() {
    return contactInfo;
}

public void setContactInfo(ContactInfo contactInfo) {
    this.contactInfo = contactInfo;
}
}

<强> ContactInfo.java

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Key;

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class ContactInfo {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key id;

    @Persistent(mappedBy = "contactInfo")
    /*
     * Important: Do not create getter and setters for this object else
     * bidirectional mapping gives error
     */
    private User user;

    private String contactDetail;

    public Key getId() {
        return id;
    }

    public void setId(Key id) {
        this.id = id;
    }

    public String getContactDetail() {
        return contactDetail;
    }

    public void setContactDetail(String contactDetail) {
        this.contactDetail = contactDetail;
    }
}