2013-02-22 76 views
3

我一直在试图让一个关系与2个实体的AppEngine,使用JPA的工作,和我目前遇到了此问题:如何使用AppEngine使用JPA设置ManyToOne关系?

java.io.IOException: com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain 

我的实体是这样的:

@Entity 
public class MyUser { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Key key; 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL) 
    private List<MyMessage> messages; 
} 

和这样的:

@Entity 
public class MyMessage { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Key key; 

    @ManyToOne(optional=false) 
    private MyUser user; 

} 

用户已经存在,而这里就是我插入一个新的消息,并得到了递归错误:

EntityManager mgr = getEntityManager(); 
MyUser myuser = mgr.find(MyUser.class, KeyFactory.createKey("MyUser", user.getEmail())); 
mymessage.setUser(myuser); 
myuser.addMessage(mymessage); 
mgr.persist(myuser); 
mgr.persist(mymessage); 

我该如何在JPA和AppEngine指南中建立这种关系?谢谢!

UPDATE

我的问题是涉及杰克逊,而不是JPA。 JPA关系很好,但我需要删除关系,并通过代码进行管理,因为它导致序列化消息中的无限递归,指向引用消息的用户等等。我还必须确保我将MyMessage中的用户属性注释为@Transient,以避免持久抱怨持久化已存在的子项所拥有的父项。

回答

1

我不知道端点序列化这些类的合理方法。从当前的代码产生的JSON看起来smiilar以下:

// 1 
{ 
    "key": "foo", 
    "messages": [ 
    { 
     "key": "bar", 
     "user": { 
     // repeat 1 
    }, 
    // and so on... 
} 

最好的办法是定义一个类(或类),以通过网络发送的,而不是你的JPA实体,它定义JSON无限,深层次的数目。

+0

我不确定我明白为什么。基于示例,我使用支持的注释。你为什么说这些数据类不被支持?另外,我得到的错误与持久性有关,而不是云端点。任何帮助表示赞赏,谢谢! https://github.com/branflake2267/CloudEndPoints/blob/master/DemoCloudEndpoints/src/org/gonevertical/server/data/User.java – piusvelte 2013-02-23 02:10:52

+0

对不起,我回想起看到一个包含列表或集合的类的例子财产,但我现在找不到一个。尽管AppEngine的数据存储让人望而却步,但我想我必须将数据rdbms风格变平。 – piusvelte 2013-02-23 02:21:09

+1

您可以返回一个列表(作为返回类型或在实体类中)。不支持的类是无限地相互引用的类(这是错误的含义)。您应该定义一个不同的类,以不会导致此类递归的方式对您的响应进行建模,并在将数据存储实体中的数据返回到这些新的类之前,将它们返回到Endpoint中。我会更新我的答案以反映这一点。 – 2013-02-24 01:09:40

1

很明显,你的消息与JPA持久性无关,这与杰克逊有关(可能与你如何传递这些对象有关?)。只有你知道从哪里调用。无论您的实际持久性操作是否成功,您的帖子都不清楚,因为您不会生成堆栈跟踪,而剩余的持久性代码(如杰克逊呼叫发起的地方)

+0

你有一个1-N的bidir关系(对我来说似乎没问题),并且坚持一个用户和一条消息(由于连接到用户后第一次呼叫持久化,pm.makePersistent(消息)是不必要的)。如果你确实想看看事件是否持续,那么应该在DEBUG级别配置“日志”。但是,我希望任何图书馆(包括杰克逊)都会抛出堆栈跟踪的例外情况,否则人们将无法看到软件在哪里丢失了情节......可能它与bidir关系有一些问题,所以无限递归。 – DataNucleus 2013-02-23 15:04:12

+0

我使用了带有appengine的云端点,并通过该SDK处理了Jackson细节。所以你说我的注释,结构和实体管理器代码都很好看?不幸的是,日志中没有更多的错误。 – piusvelte 2013-02-23 15:06:21

+0

感谢您的补充见解。我再次查看日志,并尝试删除持久(mymessage)调用。 – piusvelte 2013-02-23 15:09:46

相关问题