как обрабатывать набор еще не сохраненных объектов? Java JPA

#java #jpa

#java #jpa

Вопрос:

у меня есть две таблицы, сопоставленные JPA с отношением «Один ко многим». Я хочу добавить Set к объекту Blog, но поскольку запись в блогнодах еще не сохранялась, у них нет поля Id, поэтому при попытке добавить второй элемент в коллекцию у меня возникает исключение nulpointer. Я пытался использовать GenerationType.ТАБЛИЦА для генератора идентификаторов, но это не помогает. Идентификатор по-прежнему равен нулю. Вот мои классы сущностей с некоторыми пропущенными полями.

The 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; 
  

The 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;
}
  

Могу ли я обойти это другим способом, чем сохранять отдельные объекты блогнода отдельно?

Ответ №1:

Вы добавляете узел в обычный HashSet. Единственный способ, которым это вызывает NPE, — это если он поступает из методов hashCode или equals . Опять же, я укажу вам на руководство по гибернации по этому вопросу. Короче говоря, эти методы не должны использовать постоянный идентификатор именно по этой причине (среди прочих).

Комментарии:

1. Добавлен метод, в котором я инициализирую класс Blog и добавляю узлы блога в раздел Main class

2. @Pilgrim, я обновил ответ, чтобы отразить другую потенциальную проблему, которую я видел в исходном коде.

3. хорошо, спасибо. будет работать над изменением методов equals и hashcode