2011-10-13 41 views
0

我有兩張表由JPA映射到一對多關係。我想將Set添加到Blog實體,但由於BlogNodes條目還沒有保留,所以他們沒有Id字段,所以當我嘗試向Collection添加第二個元素時,我有nulpointer異常。我試圖使用GenerationType.TABLE作爲id生成器,但它沒有幫助。 Id仍然爲空。這裏是我的實體類,其中一些字段已經過濾。如何處理一組尚未保留的實體? Java JPA

的Blog.java

@Entity 
@Table(name = "t_blog") 
public class Blog extends VersionedEntity{ 
(Identified id generation) 
    private static final Logger log = LoggerFactory.getLogger(Blog.class); 
    //@ToDo: pass actual value to serialVersionUID 
    //private static final long serialVersionUID = 1882566243377237583L; 

... 

    @OneToMany(mappedBy = "parentBlog", fetch = FetchType.LAZY, orphanRemoval=true, cascade = { CascadeType.PERSIST, CascadeType.MERGE}) 
    private Set<BlogNode> blogNodes; 

的BlogNode.java

@Entity 
@Table(name = "t_blog_node") 
public class BlogNode{ 
    /***************************************************************************************/ 
    @TableGenerator(name="tab", initialValue=0, allocationSize=5) 
    @GeneratedValue(strategy=GenerationType.TABLE, generator="tab") 
    @Column(name = "id", nullable = false, updatable = false) 
    @Id 
    private Long id; 

    public Long getId() { 
     return id; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (!(o instanceof BlogNode)) return false; 
     BlogNode that = (BlogNode) o; 
     return that.id.equals(id); 

    } 

    @Override 
    public int hashCode() { 
     return id == null ? 0 : id.hashCode(); 
    } 
/*************************************************************************************/ 

    @OneToOne 
    @JoinColumn(name="parent_blog_fk", referencedColumnName="id", nullable = true) 
    private Blog parentBlog; 

主要類

public List<Blog> createBlog(int n){ 
    params.put("BlogName","SampleBlogName"); 
    params.put("BlogAlias","defaultAlias"); 
    params.put("BlogDescription","defaultBlog description"); 
    List<Blog> newBlogs = new ArrayList<Blog>(); 
    while(n-->0){ 
     Blog entry = new Blog(); 
     entry.setBlogName(params.get("BlogName")+n); 
     entry.setBlogAlias(params.get("BlogAlias")+n); 
     entry.setBlogDescription(params.get("BlogDescription")+n); 
     entry = blogDAO.save(entry); 
     entry.setBlogNodes(createBlogNodes(entry, NUM_OF_NODES)); 
     entry = blogDAO.save(entry); 
     newBlogs.add(entry); 
    } 

    return newBlogs; 
} 

private Set<BlogNode> createBlogNodes(Blog blog, int numOfNodes) { 
    params.put("nodeTitle","SamplenodeName"); 
    params.put("nodeAlias","defaultAlias"); 
    params.put("nodeTeaser","default node teaser"); 
    params.put("nodeText","default node text"); 
    Set<BlogNode> nodes = new HashSet<BlogNode>();; 
    while (numOfNodes-->0){ 
     BlogNode node = new BlogNode(); 
     node.setNodeTitle(params.get("nodeTitle")+numOfNodes); 
     node.setNodeAlias(params.get("nodeAlias")+numOfNodes); 
     node.setNodeText(params.get("nodeText")+numOfNodes); 
     node.setParentBlog(blog); 
     node.setNodeTeaser(params.get("nodeTeaser")+numOfNodes); 
        //Exception raises on the second iteration 
     nodes.add(node); 
    } 
    return nodes; 
} 

我能打敗這個另一種方式,比單獨堅持BlogNode的單一實體來說?

回答

1

您正在將節點添加到純HashSet。如果它來自hashCodeequals方法,導致NPE的唯一方法。再次,我會指出你在這個問題上的Hibernate manual。簡而言之,這些方法不應該因爲這個原因使用持久性ID(等等)。

+0

增加了方法,我初始化博客類和博客節點添加到主類部分 – Pilgrim

+0

@Pilgrim,我更新了答案,以反映我在原始代碼中看到的另一個潛在問題。 – Mac

+0

好的,謝謝。將改變equals和hashcode方法 – Pilgrim