NHibernate将0保存为多对一列而不是null

时间:2009-04-21 20:41:03

标签: nhibernate

我有一个表捐赠,其中有一个与广告系列表相关的CampaignID列。如果Campaign没有用于此捐赠,我需要在CampaignID列中插入0而不是Null。

我在Donations表中的映射如下所示:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true">
    <class name="Donation,Entities" lazy="true" table="Donations" dynamic-update="true" >
        <id name="DonationID" column="PledgeID" type="Int64">
            <generator class="native" />
        </id>
        <many-to-one name="FundraisingCampaign" class="Campaign, Entities" column="CampaignID" lazy="proxy" not-found="ignore" cascade="none" />

在我保存到数据库之前,我会检查我的捐赠实体上的广告系列实体是否为空。如果是,那么我将其设置为新的Campaign Entity并将CampaignID = 0设置为这样。

    if (null == donation.FundraisingCampaign)
    {
        donation.FundraisingCampaign = new Campaign() {CampaignID = 0};
    }

问题是我得到一个ErrorMessage“对象引用一个未保存的瞬态实例 - 在刷新之前保存瞬态实例。”在尝试保存时。

我不明白为什么它关注除CampaignID之外的Campaign对象上的任何内容,因为我有cascade =“none”它不应该尝试将任何内容保存到Campaign表。

我被当前系统强制设置为0而不是Null,因此保存Null不是一个选项。

2 个答案:

答案 0 :(得分:3)

尝试从数据库加载其DB标识为0的Campaign对象。它将成为一个完全持久的对象。然后,您应该能够设置它并坚持捐赠。

如果此方法有效,则需要更改Campaign对象的ID属性映射。 Nh无法确定您在此处创建的瞬态广告系列对象:

new Campaign() {CampaignID = 0};

实际上是一个分离的对象。你应该做的是在你的贴图中添加一个'未保存的值',-1。现在,Nh可以判断您的有效分离广告系列与数据库标识ID为0,以及ID为-1的短暂新广告系列。然后记得将新创建的广告系列的ID设置为-1。

答案 1 :(得分:2)

  1. NHibernate通过检查主键知道是否已存储实体。如果为0,则不存储。您可以在映射中更改此行为。
  2. 如果您尝试保存实体,则所有引用实体必须级联或已存储。这对于NHibernate获取外键很重要。它不能用外键指向你的内存,它必须在数据库中,所以它必须存储。如果不是这种情况,则会收到您的异常消息。
  3. 有了这些信息,你就应该明白为什么会遇到这个问题。

    CampaignID是否使用自动计数器生成?然后它无论如何都不起作用。 (您无法在应用程序中设置ID。)除非您使用CampaignID = 0存储Campaign(请参阅下文)。

    您可以将CampaignID设为可为空的int,默认情况下未保存的值为null。

    请注意,您在数据库中获得CampaignID = 0的Campaign。这是一个“空对象”。您需要存储它,例如在设置数据库之后。

    如果你想避免使用null对象,你会遇到麻烦。 NHibernate在概念上不允许您访问外键,它为您管理它。你可能可以做一些技巧(例如在拦截器中),但我认为这不值得麻烦。您还必须确保没有外键约束,这也不好。