我知道有很多关于这个主题的条目。我已经阅读了所有他们正在寻找我面临的问题。
我有一个带有自引用的类/表。这是班级
public class Comment {
private Integer id;
private Comment parent;
private Issue issue;
private User author;
private String body;
private Date created;
private Date updated;
private Set<Comment> childs;
// All setters and getters
}
在这里你可以看到hbm.xml文件:
<hibernate-mapping>
<class name="Comment" table="COMMENTS">
<id name="id" type="java.lang.Integer">
<column name="ID"/>
<generator class="native"/>
</id>
<many-to-one cascade="all"
class="Comment" fetch="join" name="parent">
<column name="PARENT" not-null="false"/>
</many-to-one>
<many-to-one class="Issue"
fetch="join" name="issue">
<column name="ISSUE" not-null="true"/>
</many-to-one>
<many-to-one class="User"
fetch="join" name="author">
<column name="AUTHOR" not-null="true"/>
</many-to-one>
<property generated="never" lazy="false" name="body" type="java.lang.String">
<column name="BODY" not-null="true"/>
</property>
<property generated="never" lazy="false" name="created" type="java.util.Date">
<column name="CREATED"/>
</property>
<property generated="never" lazy="false" name="updated" type="java.util.Date">
<column name="UPDATED"/>
</property>
<set cascade="delete" fetch="select" inverse="true" lazy="true"
name="childs" sort="unsorted" table="COMMENTS">
<key>
<column name="ID" not-null="true"/>
</key>
<one-to-many class="Comment"/>
</set>
</class>
</hibernate-mapping>
到目前为止一切都很好。但是我必须在某个地方出错,因为当我运行这个单元测试时
Session session = sessionFactory.getCurrentSession();
User user = new User("loginName", "password", "firstName", "lastName", "eMail");
session.save(user);
session.flush();
session.clear();
Issue issue = new Issue();
session.save(issue);
session.flush();
session.clear();
Comment parent = new Comment(issue, user, "body_parent");
session.save(parent);
Comment child = new Comment(issue, user, "body_child_1");
child.setParent(parent);
parent.getChilds().add(child);
session.save(child);
session.flush();
session.clear();
parent = (Comment) session.createQuery("from Comment comment where comment.body='body_parent'").uniqueResult();
System.out.println(parent);
System.out.println(parent.getChilds().iterator().next());
我添加了最后两行,以便向您展示我现在面临的问题:
COMMENT = [id=1, parentId=<root>, issueId=1, authorId=1, body=body_parent, created=2014-03-08 19:28:54.832, updated=2014-03-08 19:28:54.832, numChilds=1]
COMMENT = [id=1, parentId=<root>, issueId=1, authorId=1, body=body_parent, created=2014-03-08 19:28:54.832, updated=2014-03-08 19:28:54.832, numChilds=1]
父母和孩子都是一样的!我真的不明白这里的问题。 当我通过查询检索孩子时,结果是正确的,但是当我通过getChild()获取孩子时,没有查询来检索孩子。
你有什么想法吗?任何线索?我在这里看不到隧道尽头的灯光: - /
提前多多感谢!
答案 0 :(得分:2)
我终于意识到问题是什么!好吧,有几个问题。
首先,DB和类中都没有parent_id
字段。
其次,没有例外,因为我将inverse
属性激活到了集合。
两个问题的结合是问题。
下面,我发布工作解决方案。
<强> Comment.java 强>
public class Comment {
private Integer id;
private Integer parentId; // Parent ID was missing
private Issue issue;
private User author;
private String body;
private Date created;
private Date updated;
private Comment parent; // Reference to parent though parentId
private Set<Comment> childs = new HashSet<Comment>(0);
protected Comment () {
}
// All setters and getters
}
<强> Comment.hbm.xml 强>
<hibernate-mapping>
<class name="es.kazbeel.geckobugtracker.model.Comment" table="COMMENTS">
<id name="id" type="java.lang.Integer">
<column name="ID"/>
<generator class="native"/>
</id>
<property name="parentId" type="java.lang.Integer" update="false" insert="false" column="PARENT_ID" />
<many-to-one class="es.kazbeel.geckobugtracker.model.Issue"
fetch="join" name="issue">
<column name="ISSUE"/>
</many-to-one>
<many-to-one class="es.kazbeel.geckobugtracker.model.User"
fetch="join" name="author">
<column name="AUTHOR"/>
</many-to-one>
<property generated="never" lazy="false" name="body" type="java.lang.String">
<column name="BODY"/>
</property>
<property generated="never" lazy="false" name="created" type="java.util.Date">
<column name="CREATED"/>
</property>
<property generated="never" lazy="false" name="updated" type="java.util.Date">
<column name="UPDATED"/>
</property>
<many-to-one name="parent" class="es.kazbeel.geckobugtracker.model.Comment" column="PARENT_ID" not-null="false" />
<set name="childs" table="COMMENTS" lazy="false" cascade="all-delete-orphan" inverse="false">
<key column="PARENT_ID" />
<one-to-many class="es.kazbeel.geckobugtracker.model.Comment"/>
</set>
</class>
</hibernate-mapping>
我希望这有助于将来的某些人。这是我第一次发布自我解决方案:)
答案 1 :(得分:1)
使用以下代码拍摄:
Comment parent = new Comment(issue, user, "body_parent");
Comment child = new Comment(issue, user, "body_child_1");
child.setParent(parent);
parent.getChilds().add(child);
session.save(parent);
session.flush();
session.clear();
答案 2 :(得分:1)
来自this
通过正确定义级联依赖关系可以解决您的问题 或者在保存实体之前保存引用的实体 引用。定义级联是非常棘手的,因为 它们如何被使用的所有微妙变化。
级联= “删除”
检查选项all | none | save-update | delete | all-delete-orphan
session.save(child);
代替此try cascade="all" and session.save(parent)
,以便所有子对象都将与父级一起保存。