具有多个元素的 Hibernate 包

发布于 2024-09-26 05:23:25 字数 649 浏览 1 评论 0原文

我有一个包,其结构如下所示:

<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 关系的一些信息,以便我的表可以包含三列。然后,我希望能够在我的网络应用程序中访问此信息。

不幸的是,我似乎无法向包中添加属性或元素。我想做的是这样的:

<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>

完成此任务的最佳方法是什么?

I have a bag whose structure looks like this:

<bag name="foo" fetch="select" table="table_of_foos">
    <key column="foo_ids"/>
    <many-to-many class="Bar" column="bar_ids"/>
</bag>

My "table_of_foos" table has two columns: "foo_ids" and "bar_ids", neither of which is unique. I want to add another column to this table that holds some information about the relationship of foos to bars, so that my table would hold three columns. Then, I want to be able to access this information in my webapp.

Unfortunately, it doesn't seem as if I can add a property or an element to the bag. What I want to do is something like this:

<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>

What is the best way to accomplish this?

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

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

发布评论

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

评论(2

明媚如初 2024-10-03 05:23:25

如果您的连接表需要除(复合)主键之外的附加列,您必须实现附加连接类

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>

And 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>

如果需要,您还可以映射复合元素而不是连接类(A 组件元素不需要(复合)主键,并且将其生命周期绑定到其所属实体实例的生命周期

创建复合元素(现在没有标识符)

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>

If your joined Table needs an additional column other than its (composite) primary-key, you must implement an additional joined class.

public class Foo {

    Collection<FooBar> bar = new ArrayList<FooBar>();

}

public class Bar {

    Collection<FooBar> foo = new ArrayList<FooBar>();

}

The joined class (which needs a composite primary key - implemented as a static inner class) is described as follows

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();
        }

    }

}

re-write your mapping as

/* 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>

And FooBar mapping

<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>

If you want, you can also map a composite element instead of a joined class (A component element does not need a (composite) primary key and has its has its lifecycle bound to that of its owning Entity instance. Keep this in mind)

Create you composite element (now without identifier)

public class FooBar {

    private String additionalProperty;

    private Foo foo;
    private Bar bar;

}

And define the following mapping

/* 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>
揽月 2024-10-03 05:23:25

我无法按照 Arthur Ronald FD 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 方法。更多信息

I wasn't able to get these mapping to work as written by Arthur Ronald F D Garcia.
This code didn't work and resulted in a MappingException.

Invalid Attempt

<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

I was able to get it working with the following.

Valid Attempt

<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>

Additionally:

If nHibernate tries to update your set even if you don't modify it, try overriding the GetHasCode and Equals methods. More information here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文