懒惰加载-Hibernate反向=''真“;以及获得一对多时的问题



我正在尝试使用以下映射:

<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书中看到过另一个变体,但现在无法查看。

最新更新