2013-02-22 70 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

相關問題