我有一个包的结构如下:
<bag name="foo" fetch="select" table="table_of_foos">
<key column="foo_ids"/>
<many-to-many class="Bar" column="bar_ids"/>
</bag>
我的“table_of_foos”表有两列:“foo_ids”和“bar_ids”,两者都不是唯一的。我想在这个表中添加另一个列,其中包含有关foos与bars之间关系的一些信息,以便我的表将包含三列。然后,我希望能够在我的webapp中访问此信息。
不幸的是,似乎我不能在包中添加属性或元素。我想做的是这样的事情:
<bag name="foo" fetch="select" table="table_of_foos">
<key column="foo_ids"/>
<many-to-many class="Bar" column="bar_ids"/>
<element column="still_valid" type="integer"/>
</bag>
实现这一目标的最佳方法是什么?
答案 0 :(得分:3)
如果您的已加入的表需要除其(复合)主键之外的其他列,则必须实现其他已加入的类。
public class Foo {
Collection<FooBar> bar = new ArrayList<FooBar>();
}
public class Bar {
Collection<FooBar> foo = new ArrayList<FooBar>();
}
连接类(需要复合主键 - 实现为静态内部类)描述如下
public class FooBar {
private FooBarId fooBarId;
private String additionalProperty;
public static class FooBarId implements Serializable {
private Integer fooId;
private Integer barId;
private Foo foo;
private Bar bar;
// getter's and setter's
public FooBarId() {}
public FooBarId(Integer fooId, Integer barId) {
this.fooId = fooId;
this.barId = barId;
}
public boolean equals(Object o) {
if(!(o instanceof FooBarId))
return false;
FooBarId other = (FooBarId) o;
return new EqualsBuilder()
.append(getFooId(), other.getFooId())
.append(getBarId(), other.getBarId())
.isEquals();
}
public int hashCode() {
return new HashCodeBuilder()
.append(getFooId())
.append(getBarId())
.hashCode();
}
}
}
将您的映射重写为
/* Foo.class */
<bag name="bar" table="table_of_foos">
<key column="BAR_ID" insert="false" update="false"/>
<one-to-many class="FooBar" table="table_of_foos"/>
</bag>
/* Bar.class */
<bag name="foo" table="table_of_foos">
<key column="FOO_ID" insert="false" update="false"/>
<one-to-many class="FooBar" table="table_of_foos"/>
</bag>
和FooBar映射
<class name="FooBar">
<composite-id name="fooBarId" class="FooBar$FooBarId">
<key-property name="fooId" column="FOO_ID"/>
<key-property name="barId" column="BAR_ID"/>
</composite-id>
<property name="additionalProperty" type="string"/>
<many-to-one name="foo" column="FOO_ID" class="Foo" insert="false" update="false"/>
<many-to-one name="bar" column="BAR_ID" class="Bar" insert="false" update="false"/>
</class>
如果需要,还可以映射复合元素而不是连接类(组件元素不需要(复合)主键,的生命周期与其拥有的实体实例的生命周期绑定< / strong>。记住这一点)
创建复合元素(现在没有标识符)
public class FooBar {
private String additionalProperty;
private Foo foo;
private Bar bar;
}
并定义以下映射
/* Foo.class */
<bag name="bar" table="table_of_foos">
<key column="BAR_ID"/>
<composite-element class="FooBar">
<property name="additionalProperty" type="string"/>
<many-to-one name="foo" column="FOO_ID" class="Foo" insert="false" update="false"/>
<many-to-one name="bar" column="BAR_ID" class="Bar"/>
</composite-element>
</bag>
/* Bar.class */
<bag name="foo" table="table_of_foos">
<key column="FOO_ID"/>
<composite-element class="FooBar">
<property name="additionalProperty" type="string"/>
<many-to-one name="foo" column="FOO_ID" class="Foo" insert="false" update="false"/>
<many-to-one name="bar" column="BAR_ID" class="Bar"/>
</composite-element>
</bag>
答案 1 :(得分:0)
我无法按照Arthur Ronald F D Garcia的说法使这些映射工作。 此代码不起作用并导致MappingException。
无效尝试
<set name="StoreDepartments" table="`ou_store_org_unit`">
<key column="`ou_id`" />
<composite-element class="NHibernate.Map.OrganizationUnit+StoreDepartment+Relation, CentralDataLayer">
<property name="Id" column="`ou_store_id`" type="Int32" />
<many-to-one name="OrganizationUnit" column="`ou_id`" class="NHibernate.Map.OrganizationUnit, CentralDataLayer" />
<many-to-one name="StoreDepartment" column="`store_ou_id`" class="NHibernate.Map.OrganizationUnit+StoreDepartment, CentralDataLayer" />
</composite-element>
</set>
Resulting Error: Repeated column in mapping for collection:
NHibernate.Map.OrganizationUnit.StoreDepartments column: ou_id
我能够使用以下内容。
有效尝试
<set name="StoreDepartments" table="`ou_store_org_unit`">
<key column="`ou_id`" />
<composite-element class="NHibernate.Map.OrganizationUnit+StoreDepartment+Relation">
<parent name="OrganizationUnit" />
<property name="Id" column="`ou_store_id`" type="Int32" />
<many-to-one name="StoreDepartment" column="`store_ou_id`" class="NHibernate.Map.OrganizationUnit+StoreDepartment" />
</composite-element>
</set>
<强> 此外: 强>
如果nHibernate尝试更新您的设置,即使您没有修改它,请尝试覆盖GetHasCode
和Equals
方法。更多information here。