Java NHibernate一对多实体映射-键列是否需要为空?
在《Java持久化与Hibernate》一书中标题为“多值关联”的部分中,有一个示例,其中父对象(项)包含关联实体对象(Bid)的列表。示例见我的版本第290页Java NHibernate一对多实体映射-键列是否需要为空?,java,.net,hibernate,nhibernate,Java,.net,Hibernate,Nhibernate,在《Java持久化与Hibernate》一书中标题为“多值关联”的部分中,有一个示例,其中父对象(项)包含关联实体对象(Bid)的列表。示例见我的版本第290页 <hibernate-mapping> <class name="com.shane.Hibernate1.Item" table="Item"> <id name="ItemId" column="ItemId"> <generator class="increment
<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首先在Item中插入一个新行,然后尝试在Bid中插入一行,但是失败了,因为如果表的ItemId和Sequence列设置为NOTNULL,那么它不包括这些列。如果我使这些列可以为null,它会工作,因为它会在Bid上进行更新以设置它们,但我不希望它们可以为null
我使用Hibernate 3.1.rc2尝试了这一点,它工作了——当它插入时,它提供了所有的值,但奇怪的是,之后它仍然会更新Bid表上的ItemId和Sequence
这是NHibernate中的一个bug吗?我希望java和.Net版本的这种行为是相同的。我的解决方案似乎是这样的 投标=新投标(); 保存(投标) 项目=新项目(); item.getBids().add(新出价(Bid.getBidId()); 会话。保存(项目) BID()类中的where应该有一个参数化构造函数
我希望它能很好地工作…我认为条目clas应该有多对一的参考。所以你们应该保存这个项目。然后在bid中设置引用(bit.setItem(item))并保存bid。使用NHibernate,如果集合中不需要空外键,则需要双向关系。阅读本书结尾的注释a 这当然是对NH请求最多的更改之一,它不一定100%地匹配Hibernate;这只是基于它
更新:不幸的是,这一限制使得使用
列表
实际上不可能做到这一点
解决方法是使用
bag
或set
代替,并将索引映射为常规属性。Bid可以使用多对一映射来实现双向映射,但正如书中所述,它必须使用update=“false”和insert=“false”来模拟将其作为关系的反向端。然而,这只是一个方便,因为对于映射列表,parant必须进行更新,因为只有它知道索引列的值。经过进一步的实验,我发现(bizarely)我可以通过在列表映射上设置casacade=“save update”使其在java上工作,但在NHibernate上仍然不起作用。将相应地修改我的问题。我阅读了您提到的注释,并且如果我正确理解if,则表示我的集合映射需要是双向关系的反向端,以避免出现可为空的FK列。但是,这在这种情况下不起作用,因为我想要一个列表。它不能映射为反向,因为一对多端不知道索引列需要设置为什么值。因此,看起来具有可为空的FK和索引列是不可避免的。
Item item = new Item();
item.setSynopsis("Item 1");
Bid bid = new Bid();
bid.setSynopsis("Bid1");
item.getBids().add(bid);
session.save(item);