Двунаправленные отношения гибернации с собственной коллекцией композитных элементов - PullRequest
0 голосов
/ 04 декабря 2018

Я хотел бы создать очень классические двунаправленные родительско-дочерние отношения между двумя сущностями.Код:

public class History {
    public Long id;
    public List<HistoryField> fields;
}

public class HistoryField {
    public History history;
    public String foo, bar;
}

HistoryField принадлежит его History родителю.

Для моделирования этого я использую следующее отображение hibernate:

<class name="History" table="history">
    <id name="id" type="long" />
    <list name="fields" cascade="all" table="fields">
        <key column="history_id" />
        <list-index column="order_index" />
        <composite-element class="HistoryField">
            <property name="foo" />
            <property name="bar" />
        </composite-element>
    </list>
</class>

Но как мне указать в отображении ссылки между HistoryField::history обратно на сущность-владельца History?

Хитрость в том, что коллекция принадлежит и определяется каксоставной элемент (для HistoryField нет идентификатора, первичным ключом является пара history_id + order_index).Классические примеры двунаправленных родительско-дочерних отношений здесь не применимы;поскольку они объясняют связь между двумя классами с идентификаторами, тогда как здесь у принадлежащего класса нет ни одного.

1 Ответ

0 голосов
/ 04 декабря 2018

В документации отмечается, что вы можете определить элемент <parent/> для <component/>, и хотя он явно не упоминает об этом в контексте набора компонентов, указанных в <composite-element/>, я бы предположил, что он должен работать.

https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/components.html

Элемент <component> допускает подэлемент <parent>, который отображает свойство класса компонента как ссылку обратно на содержащую сущность.

Следовательно:

<class name="History" table="history">
    <id name="id" type="long" />
    <list name="fields" cascade="all" table="fields">
        <key column="history_id" />
        <list-index column="order_index" />
        <composite-element class="HistoryField">
            <!-- name of the property refeencing the containing entity -->
            <parent name="history"/>
            <property name="foo" />
            <property name="bar" />
        </composite-element>
    </list>
</class>

При использовании аннотаций аннотацию @Parent можно использовать аналогично:

https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#mapping-Parent

Hibernate-специфическая аннотация @Parent позволяет вам ссылаться на сущность владельца из встраиваемого объекта.

@Embeddable
public class HistoryField {

    @Parent
    public History history;
    public String foo, bar;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...