我正在尝试使用以下映射:
<class name="Category" table="CATEGORY" lazy="false">
<id name="id" type="java.lang.Long" >
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String"/>
<set name="items" inverse="true" lazy="false" access="field" cascade="all">
<key column="id" not-null="true"></key>
<one-to-many class="Item" />
</set>
</class>
但当inverse设置为true时,项目集总是空的。然而,当我将inverse设置为false时,它可以正常工作。我好像错过了什么。非常感谢您的任何解释。
添加:
很抱歉延迟,我对代码做了一些更改,但我仍然面临一个问题:我将包含3个项目的类别保存到数据库中,但当我检索回该类别时,它只包含一个项目。这是代码:
public class Category {
private long id;
private int version;
private String name;
private Set<Item> items;
public Category() {
this.items = new HashSet<Item>();
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void addItem(Item item) {
this.items.add(item);
item.setCategory(this);
}
public Set<Item> getItems() {
return items;
}
}
<hibernate-mapping >
<class name="Category" table="HIA_CATEGORY" lazy="false">
<id name="id" type="java.lang.Long" >
<column name="ID" />
<generator class="native" />
</id>
<version name="version" column="VERSION" ></version>
<property name="name" type="java.lang.String"/>
<set name="items" inverse="true" lazy="false" access="field" cascade="all" outer-join="false">
<key column="id" not-null="true"></key>
<one-to-many class="Item" />
</set>
</class>
</hibernate-mapping>
public class Item {
protected long id;
protected String name;
protected Category category;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
category.getItems().add(this);
}
}
<hibernate-mapping>
<class name="Item" table="HIA_ITEM" lazy="false"
abstract="false" polymorphism="implicit">
<id name="id" type="java.lang.Long">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String" />
<many-to-one name="category" update="true" cascade="save-update" access="field" lazy="false" outer-join="false"
class="Category" column="CATEGORY">
</many-to-one>
<joined-subclass name="ExtItem"
table="EXT_ITEM" >
<key column="id"></key>
<property name="extProperty" column="EXT_PROPERTY"></property>
</joined-subclass>
</class>
</hibernate-mapping>
提前谢谢。
编辑(作者Stefan Steinegger根据作者评论)
测试用例:
@Test public void lazyInitTest()
{
Category cat = new Category();
cat.setName("CTAEGORY_WITH_ITEMS");
Item item = new Item();
item.setName("ITEM1");
Item item2 = new Item();
item2.setName("ITEM2");
Item item3 = new Item();
item3.setName("Test");
cat.addItem(item);
cat.addItem(item2);
cat.addItem(item3);
categoryDao.persistCategory(cat);
Category category = categoryDao.getCategory(cat.getId());
System.out.println(cat.getId() + "--" + category.getId());
Assert.assertEquals(cat.getItems().size(), category.getItems().size());
}
如果存在双向关系,则仅将inverse设置为true。反向意味着由于内存中存在冗余关系,所以不存储集合。
编辑当然,它必须映射到同一个数据库字段:
集合进入id
:
<set name="items" ...>
<key column="id" not-null="true"/>
<one-to-many class="Item" />
</set>
多对一进入CATEGORY
:
<many-to-one ... column="CATEGORY">
</many-to-one>
将设置更改为CATEGORY
也可以解决问题:
<set ...>
<key column="CATEGORY" not-null="true"/>
<one-to-many class="Item" />
</set>
我怀疑您忘记映射in Item,但您没有显示映射,所以我无法确认。
相反,意味着Hibernate不会从这一边更新关系信息。请确保还设置了item.setCategory(category)以正确触发数据库更新。
将Category及其3个条目保存到数据库后,是否检查所有条目是否正确写入(如与另一个工具连接并选择条目,检查Category_id列)?
如果是:您是否检查了生成的SQL语句的Hibernate日志?
如果是:这些还好吗?
附带说明:
public void setCategory(Category category) {
this.category = category;
category.getItems().add(this);
}
我到处都能看到这些。事实上,我从来没有这样做过,只是简单地将项目添加到集合中,并让Hibernate完成其余的工作。一直对我有效,我不记得在我的一本Hibernate书中看到过另一个变体,但现在无法查看。