【问题标题】:NHibernate one-to-many entity mapping - does the key column need to be nullable?NHibernate 一对多实体映射 - 键列是否需要为空?
【发布时间】:2011-04-02 08:29:10
【问题描述】:

在 Java Persistence with Hibernate 一书中标题为“许多值关联”的部分中,有一个示例,其中父对象 (Item) 包含关联实体对象 (Bid) 的列表。该示例在我的版本中的第 290 页。

<hibernate-mapping>
  <class name="com.shane.Hibernate1.Item" table="Item">
    <id name="ItemId" column="ItemId">
      <generator class="increment"/>
    </id>

    <property name="Synopsis" column="Synopsis"/>

    <list name="bids" cascade="save-update">
      <key column ="ItemId" not-null="true"/>
      <list-index column="Sequence"/>
      <one-to-many class="com.shane.Hibernate1.Bid"/>
    </list>    
  </class>
</hibernate-mapping>  

<hibernate-mapping>
  <class name="com.shane.Hibernate1.Bid" table="Bid">
    <id name="BidId" column="BidId">
      <generator class="increment"/>
    </id>    
    <property name="synopsis" column="Synopsis"/>
  </class>
</hibernate-mapping>

我在 NHibernate 2.1.2.GA 和 3.1.0.GA 中都尝试了以下操作:

 Item item = new Item();
 item.setSynopsis("Item 1");

 Bid bid = new Bid();
 bid.setSynopsis("Bid1");     
 item.getBids().add(bid);

 session.save(item);

NHibernate 首先在 Item 中插入一个新行,然后尝试在 Bid 中插入一行,但如果表中的 ItemId 和 Sequence 列设置为不为空,则它不包括 ItemId 和 Sequence 列,因此失败。如果我使这些列可以为空,它会起作用,因为它会更新 Bid 以设置它们,但我不希望它们可以为空。

我使用 Hibernate 3.1.rc2 进行了尝试,它可以工作 - 当它进行插入时,它会提供所有值,但奇怪的是,之后它仍然会更新 Bid 表上的 ItemId 和 Sequence。

这是 NHibernate 中的错误吗?我希望这种 fo 行为对于 java 和 .Net 版本都是相同的。

【问题讨论】:

    标签: java .net hibernate nhibernate


    【解决方案1】:

    使用 NHibernate,如果您需要集合中的非空外键,则需要双向关系。阅读http://www.nhforge.org/doc/nh/en/index.html#collections-onetomany末尾的注释

    这无疑是对 NH 最需要的更改之一,它不一定 100% 匹配 Hibernate;它只是基于它。


    更新:不幸的是,这个限制使得使用list 几乎不可能做到这一点。

    解决方法是改用bag 或set,并将索引映射为常规属性。

    【讨论】:

    • 我阅读了您提到的注释,如果我理解正确的话,如果说我的集合映射需要是双直肠关系的反端以避免可为空的 FK 列。但是,在这种情况下这不起作用,因为我想要一个列表。它不能反向映射,因为一对多端不知道索引列需要设置为什么值。所以看起来有可以为空的 FK 和索引列是不可避免的。
    【解决方案2】:

    我似乎是这样的解决方案......

    Bid bid = new Bid(); session.save(出价);

    项目 item = new Item(); item.getBids().add(新出价(bid.getBidId())); session.save(项目)。

    在 BID() 类中应该有一个参数化构造函数。

    希望一切顺利……

    【讨论】:

      【解决方案3】:

      我认为 Item 类应该有多对一的引用。所以你应该保存项目。然后在出价(bit.setItem(item))中设置参考并保存出价。

      【讨论】:

      • Bid 可以有一个多对一的映射来进行双向映射,但正如书中提到的,它必须有 update="false" 和 insert="false" 来模拟使其成为关系的反向结束。然而,这只是一个方便的列表映射,因为只有它知道索引列的值,所以它必须进行更新。经过进一步的实验,我发现(奇怪的是)我可以通过在列表映射上设置 casacade="save-update" 使其在 java 上工作,但它仍然不能在 NHibernate 上工作。将相应地修改我的问题。
      猜你喜欢
      • 2011-07-07
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 2020-04-14
      • 1970-01-01
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      相关资源
      最近更新 更多