Спящая сумка с несколькими элементами - PullRequest
1 голос
/ 01 октября 2010

У меня есть сумка, структура которой выглядит следующим образом:

<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 с барами, чтобы моя таблица содержала три столбца.Затем я хочу получить доступ к этой информации в своем веб-приложении.

К сожалению, не похоже, что я могу добавить свойство или элемент в сумку.Я хочу сделать что-то вроде этого:

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

Как лучше всего это сделать?

Ответы [ 2 ]

3 голосов
/ 01 октября 2010

Если вашей присоединенной таблице требуется дополнительный столбец, отличный от ее (составного) первичного ключа, , вы должны реализовать дополнительный объединенный класс .

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>

Если вы хотите, вы также можете отобразить составной элемент вместо объединенного класса (компонентный элемент не нуждается в (составном) первичном ключе, и его жизненный цикл имеет свой жизненный цикл, соответствующий его собственному экземпляру Entity . Помните об этом)

Создайте свой составной элемент (теперь без идентификатора)

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>
0 голосов
/ 29 ноября 2012

Мне не удалось заставить работать эти карты, как написано Артур Рональд Ф.Д. Гарсия .Этот код не работал и привел к исключению 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.Больше информации здесь .

...