#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