Hibernate inverse =''true'和获得一对多时的问题

时间:2011-06-04 13:17:13

标签: hibernate lazy-loading hibernate-onetomany

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

<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()); 
}

3 个答案:

答案 0 :(得分:1)

如果存在双向关系,则仅将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>

答案 1 :(得分:0)

我怀疑你忘了映射项目,但你没有显示映射,所以我无法确认。

此外,反向意味着Hibernate不会从这一侧更新关系信息。确保还设置了item.setCategory(类别)以正确触发数据库更新。

答案 2 :(得分:0)

将类别与3个项目保存到数据库之后,您是否检查了所有项目是否都正确写入(如与其他工具连接并选择了项目,检查category_id列)?

如果是:您是否检查了Hibernate-Logs生成的SQL语句?

如果是:这些可以吗?

作为旁注:

public void setCategory(Category category) {
    this.category = category;
    category.getItems().add(this);
}

我一直在看这些地方。事实上,我从来没有这样做,只是简单地将项目添加到集合中,Hibernate做了其余的工作。总是为我工作,我不记得在我的一本Hibernate书籍中看到了另一个版本,但现在无法检查。