簡體   English   中英

Hibernate中沒有組合鍵的一對多關聯

[英]One to many association in Hibernate without composite key

表:

tradeId | actionTradeId | type | date

其中tradeId+actionTradeId復合鍵

休眠映射:

<class name="Trade" table="TRADE">
 <composite-id name="id" class="TradePK">
        <key-property name="tradeId" type="long" column="trade_id"/>
        <key-property name="actionTradeId" type="long"        column="action_trade_id"/>
  </composite-id>
<property name="type" length="1"/>
<property name="date"/>
</class>

我需要的

我想在同一表上進行映射,例如以下查詢:

select * 
from Trade 
where action_trade_id = trade_id and type = 'S'

首先,我嘗試過這種方式,但是由於我擁有復合鍵,因此失敗了:

<set name="sellTrades" inverse="false" lazy="true" where="type='S'">
            <key>
                <column name="action_trade_id" not-null="true" />
            </key>
            <one-to-many class="Trade" />
</set>

樣本數據:

 tradeId| actionTradeId | type| date 
 --------------------------------------
    11         22          S    date (so for this entity I need list with <55, 66>)
    33         44          S    date 
    55         11          S    date
    66         11          S    date
public class ClassWithCompositeKey
{
    private int id1;
    private int id2;

    public ClassWithCompositeKey()
    {
        Children = new List<ClassWithCompositeKey>();
    }

    public virtual int Id1
    {
        get { return id1; }
        set { id1 = value; }
    }
    public virtual int Id2
    {
        get { return id2; }
        set { id2 = value; }
    }

    public virtual string Type { get; set; }

    public virtual ICollection<ClassWithCompositeKey> Children { get; protected set; }

    public override bool Equals(object obj)
    {
        var other = obj as ClassWithCompositeKey;
        return other != null && Id1 == other.Id1 && Id2 == other.Id2;
    }

    public override int GetHashCode()
    {
        return (Id1 << 16) | Id2;  // optimized for Id's < 16 bit
    }
}

制圖

public class ClassWithCompositeKeyMap : ClassMap<ClassWithCompositeKey>
{
    public ClassWithCompositeKeyMap()
    {
        CompositeId()
            .KeyProperty(x => x.Id1)
            .KeyProperty(x => x.Id2);

        Map(x => x.Type);

        Map(x => id1).Column("Id1").Access.Using("field").ReadOnly();

        HasMany(x => x.Children)
            .Where("Type = 'S'")
            .PropertyRef("id1")
            .KeyColumns.Add("Id2")
            .Inverse();
    }

    public virtual int id1 { get; set; }
}

和查詢

using (var tx = session.BeginTransaction())
{
    session.Save(new ClassWithCompositeKey { Id1 = 11, Id2 = 22, Type = "F" });
    session.Save(new ClassWithCompositeKey { Id1 = 55, Id2 = 11, Type = "S" });
    session.Save(new ClassWithCompositeKey { Id1 = 66, Id2 = 11, Type = "S" });
    tx.Commit();
}
session.Clear();

var x = session.Get<ClassWithCompositeKey>(new ClassWithCompositeKey { Id1 = 11, Id2 = 22 });
Assert.Equal(2, x.Children.Count);

注意

  • 由於property-ref,禁用了集合的延遲加載
  • 注意將Children集合與應屬於代碼的實例同步,這樣您就不會出現模型損壞的情況

更新為HBM

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" name="ClassWithCompositeKey">
    <composite-id>
      <key-property name="Id1" column="Id1"/>
      <key-property name="Id2" column="Id2"/>
    </composite-id>
    <bag inverse="true" lazy="true" name="Children" where="Type = 'S'">
      <key property-ref="id1">
        <column name="Id2" />
      </key>
      <one-to-many class="ClassWithCompositeKey" />
    </bag>
    <property name="Type" column="Type" />
    <property access="field" name="id1" column="id1" insert="false" update="false"/>
  </class>
</hibernate-mapping>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM