为什么一对多在 NHibernate 中不能按预期工作?

发布于 2024-09-25 07:10:12 字数 3137 浏览 1 评论 0原文

我的情况非常简单,真的不知道为什么这不起作用。

这是我的架构:

**[item]**
id (PK)
symbol

**[item_version]**
id (PK)
item_id (FK->ITEM)
symbol

这些是我的映射:

item.hbm.xml

<class name="Core.Model.Entities.Item, Core.Model" table="item" lazy="false">
    <id name="Id" column="id" type="long">
        <generator class="native" />
    </id>
    <property name="Symbol" column="symbol"/>

    <bag name="ItemVersions" lazy="false" table="item_version" inverse="true" cascade="save-update">
        <key column="item_id" />
        <one-to-many class="Core.Model.Entities.ItemVersion, Core.Model"/>
    </bag>
</class>

*item_version.hbm.xml*

<class name="Core.Model.Entities.ItemVersion, Core.Model" table="item_version" lazy="false">
    <id name="Id" column="id" type="long">
        <generator class="native" />
    </id>

    <many-to-one name="Item" class="Core.Model.Entities.Item, Core.Model" column="item_id" cascade="save-update"/>
    <property name="Symbol" column="symbol"/>
    </class>

这些是类:

Item.cs

public class Item : Entity<IItemDao>
{
   private long id;
   virtual public long Id
   {
       get { return this.id; }
       set { this.id = value; }
   }
   private string symbol;
   virtual public string Symbol
   {
       get { return this.symbol; }
       set { this.symbol = value; }
   }
   private IList<ItemVersion> item_versions = new List<ItemVersion>();
   virtual public IList<ItemVersion> ItemVersions
   {
       get { return this.item_versions; }
       set { this.item_versions = value; }
   }
}

ItemVersion.cs

public class ItemVersion : Entity<IItemVersionDao>
{
    private long id;
    virtual public long Id
    {
         get { return this.id; }
         set { this.id = value; }
    }
    private Item item = null;
    virtual public Item Item
    {
         get { return this.item; }
         set { this.item = value; }
    }
    private long item_id = 0;
    virtual public long ItemId
    {
         get { return this.item_id; }
         set { this.item_id = value; }
    }
    private string symbol;
    virtual public string Symbol
    {
         get { return this.symbol; }
         set { this.symbol = value; }
    }
}

而且这段代码......

Item item = new Item();
item.Name = "test";

ItemVersion v = new ItemVersion();
v.Symbol = "test version";
item.ItemVersions.Add(v);

Item.Dao.Save(tmp);

不起作用。它插入一个项目并在插入 item_version 行时引发异常,该 item_version.item_id 不能为 null。因此 NHibernate 不会在 ItemVersion 对象中自动设置 item_id 属性。为什么在这种情况下cascade =“save-update”和inverse =“true”不起作用?

当我手动设置时,通过添加以下代码:

v.Item = item;

然后调用 save,一切正常,但这不是我从 NHibernate 中除外的内容 - 调用

item.ItemVersions.Add(v);

应该足够了。

我做错了什么还是这根本不可能?预先感谢您的回答:)

I have very simple situation and really don't have a clue why this isn't working.

This is my schema:

**[item]**
id (PK)
symbol

**[item_version]**
id (PK)
item_id (FK->ITEM)
symbol

These are my mappings:

item.hbm.xml

<class name="Core.Model.Entities.Item, Core.Model" table="item" lazy="false">
    <id name="Id" column="id" type="long">
        <generator class="native" />
    </id>
    <property name="Symbol" column="symbol"/>

    <bag name="ItemVersions" lazy="false" table="item_version" inverse="true" cascade="save-update">
        <key column="item_id" />
        <one-to-many class="Core.Model.Entities.ItemVersion, Core.Model"/>
    </bag>
</class>

*item_version.hbm.xml*

<class name="Core.Model.Entities.ItemVersion, Core.Model" table="item_version" lazy="false">
    <id name="Id" column="id" type="long">
        <generator class="native" />
    </id>

    <many-to-one name="Item" class="Core.Model.Entities.Item, Core.Model" column="item_id" cascade="save-update"/>
    <property name="Symbol" column="symbol"/>
    </class>

These are the classes:

Item.cs

public class Item : Entity<IItemDao>
{
   private long id;
   virtual public long Id
   {
       get { return this.id; }
       set { this.id = value; }
   }
   private string symbol;
   virtual public string Symbol
   {
       get { return this.symbol; }
       set { this.symbol = value; }
   }
   private IList<ItemVersion> item_versions = new List<ItemVersion>();
   virtual public IList<ItemVersion> ItemVersions
   {
       get { return this.item_versions; }
       set { this.item_versions = value; }
   }
}

ItemVersion.cs

public class ItemVersion : Entity<IItemVersionDao>
{
    private long id;
    virtual public long Id
    {
         get { return this.id; }
         set { this.id = value; }
    }
    private Item item = null;
    virtual public Item Item
    {
         get { return this.item; }
         set { this.item = value; }
    }
    private long item_id = 0;
    virtual public long ItemId
    {
         get { return this.item_id; }
         set { this.item_id = value; }
    }
    private string symbol;
    virtual public string Symbol
    {
         get { return this.symbol; }
         set { this.symbol = value; }
    }
}

And this code...

Item item = new Item();
item.Name = "test";

ItemVersion v = new ItemVersion();
v.Symbol = "test version";
item.ItemVersions.Add(v);

Item.Dao.Save(tmp);

... does not work. It inserts an item and throws an exception while inserting item_version row, that item_version.item_id cannot be null. So item_id property isn't automatically set by NHibernate in ItemVersion object. Why cascade="save-update" and inverse="true" does not work in this case?

When I set manually, by adding this code:

v.Item = item;

and than call save, everything works fine, but this is not what I except from NHibernate - calling

item.ItemVersions.Add(v);

should be sufficient.

Am I doing something wrong or this is simply imposible? Thanks in advance for the answers :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜空下最亮的亮点 2024-10-02 07:10:12

您必须设置 v.Item,因为 ItemVersions 是反向。这意味着“另一方”(多对一)负责维持这种关系。

这是标准做法;为了更容易使用,只需向 Item 添加一个方法:

public void AddItemVersion(ItemVersion itemVersion)
{
    ItemVersions.Add(itemVersion);
    itemVersion.Item = this;
}

You have to set v.Item because ItemVersions is inverse. That means the "other side" (the many-to-one) is in charge of maintaining the relationship.

This is standard practice; to make it easier to use just add a method to Item:

public void AddItemVersion(ItemVersion itemVersion)
{
    ItemVersions.Add(itemVersion);
    itemVersion.Item = this;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文