2015-06-02 40 views
1

我有下面的類自我引用@OneToMany

@Entity 
public class Comment extends Base { 

@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
private Comment inReplyTo; 

@OneToMany(mappedBy = "inReplyTo", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
private Collection<Comment> replies; 

public Comment() { 
} 

public Collection<Comment> getReplies() { 
    return replies; 
} 

public void setReplies(Collection<Comment> comments) { 
    this.replies = comments; 
} 

public Comment getInReplyTo() { 
    return inReplyTo; 
} 

public void setInReplyTo(Comment inReplyTo) { 
    this.inReplyTo = inReplyTo; 
} 

} 

添加一個新的註釋,並設置inReplyTo作品和註釋保存到數據庫。但inReplyTo評論的答覆字段爲空。

而且在做這個錯誤

org.datanucleus.store.types.IncompatibleFieldTypeException: Incompatible type requested for field "Comment.replies" : was java.util.Collection but should be java.util.Collection 

任何想法

c.setReplies(new ArrayList<Comment>()); 
c.getReplies().add(x); 
repo.save(c); 

結果?

+1

最初,這個異常的文本看起來像無稽之談,因爲這兩種類型似乎是相同的。但是,您可能正在考慮datanucleus從另一個jar(版本)獲取'java.util.Collection'到您的代碼引用的可能性。檢查你沒有某種類加載器的問題。 – DuncanKinnear

+0

您是否在使用Maven構建此項目?如果是這樣,也許你可以做一個Maven依賴關係樹來查看java.util是否存在多個依賴關係。 – DuncanKinnear

+0

Adrian,是類加載器的問題嗎? –

回答

0

我升級到DataNucleus 4.1.1,做了清理工作,它開始工作。

2

應設置關係的兩個部分:

c.setReplies(new ArrayList<Comment>()); 
c.getReplies().add(x); 
c.setInReplyTo(x);//this is the most imporant 
repo.save(c); 

如果不工作,它可能是在DataNucleus將一個錯誤:試圖彙報,並把一個鏈接在這裏的某個地方。

+0

@AdrianBer除了這個答案,我認爲是正確的,我想問你:你是否在同一個事務中增加了一個快速檢查和原始評論的答覆集合? –

+0

這就是我所做的,我在問題中得到了錯誤。試圖保存時出現錯誤。 –

2

如果我正確理解你的問題,你有類似下面的代碼:

Comment parent = //... 

Comment reply = new Comment(); 
reply.setInReplyTo(parent); 
reply = commentRepository.save(reply); 

Collection<Comment> parentReplies = parent.getReplies(); 

和你想知道爲什麼parentRepliesnull

因爲JPA 2.0規範的§2.9實體關係說,這將預期:

Note that it is the application that bears responsibility for maintaining the consistency of runtime relationships—for example, for insuring that the 「one」 and the 「many」 sides of a bidirectional relationship are consistent with one another when the application updates the relationship at runtime.

DataNucleus將不負責實例化一個新的集合包含新reply評論和設置parent的回覆屬性此採集。我檢查了DataNucleus 4.1.0和Hibernate 4.3.10,並驗證了這兩者都不會更新評論的答覆屬性。

您的應用程序需要確保運行時間關係是一致的。例如,你可以添加一個addReply()方法來註釋類:

public void addReply(Comment reply) { 
     if (this == reply) throw new IllegalArgumentException("`reply' cannot be `this' Comment object because a comment cannot be a reply to itself."); 
     if (replies == null) replies = new ArrayList<>(); 
     replies.add(reply); 
     reply.setInReplyTo(this); 
    } 

然後添加回復代碼將是這樣的:

Comment parent = //... 

Comment reply = new Comment(); 
parent.addReply(reply); 
reply = commentRepository.save(reply); 

Collection<Comment> parentReplies = parent.getReplies(); 

而且,我不再現錯誤:

 
org.datanucleus.store.types.IncompatibleFieldTypeException: Incompatible type requested for field "Comment.replies" : was java.util.Collection but should be java.util.Collection 
+0

即使我試圖保存父項,也會得到相同的錯誤。 –