2011-10-13 43 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