JPA: как переопределить таблицу сбора коллекции элементов в подклассе

#java #hibernate #jpa #collections

#java #спящий режим #jpa #Коллекции

Вопрос:

Ситуация: у меня есть абстрактный класс Java и два подкласса. Абстрактный класс содержит коллекцию строк. Каждый из двух подклассов имеет свою собственную таблицу БД, также коллекция строк в ней должна быть сохранена в своих собственных таблицах БД, в зависимости от подкласса. Здесь я работаю с коллекцией элементов jpa. Настройка работает нормально для класса ActiveResult. Но для ArchivedResult я не смог понять, как переопределить таблицу коллекции, чтобы она могла считывать данные из своей собственной таблицы archived_result_values.

Результат с этой настройкой: при чтении из ArchivedResult он не находит значения коллекции, потому что он пытается найти их в таблице active_result_values из суперкласса вместо поиска их в таблице archived_result_values.

Я надеюсь, что это возможно без изменения классов Java (потому что я не должен этого делать), поэтому меня интересует, как изменить режим гибернации orm.xml отображение соответствующим образом.

подсказка: в реальных таблицах archived_result / active_result есть еще несколько (идентичных столбцов), но они не имеют отношения к проблеме.

следующий код Java

 public abstract class AbstractResult {
  protected String Id;
  protected List<String> values;
}

public class ArchivedResult extends  AbstractResult {
  public ArchivedResult() {
    super();
  }
}

public class ActiveResult extends  AbstractResult {
  public ActiveResult() {
    super();
  }
}
 

здесь orm.xml сопоставления

 <entity-mappings .... >
  <mapped-superclass class="com.test.AbstractResult" access="FIELD">
    <attributes>
        <id name="Id">
            <column name="ar_id" />
        </id>
        
        <element-collection name="values" fetch="EAGER">
            <order-column name="item_index" />
            <column name="result_value" />
            <collection-table name="active_result_values">
                <join-column name="ar_id" />
            </collection-table>
        </element-collection>
        
    </attributes>
</mapped-superclass>
    
<entity name="ActiveResult" class="com.test.ActiveResult" access="FIELD">
    <table name="active_result" />
    <inheritance strategy="TABLE_PER_CLASS"/>
</entity>

<entity name="ArchivedResult" class="com.test.ArchivedResult"
        access="FIELD">
    <table name="archived_result" />
    <inheritance strategy="TABLE_PER_CLASS"/>
    <attributes>
        <element-collection name="values" fetch="EAGER">
            <order-column name="item_index" />
            <column name="result_value" />
            <collection-table name="archived_result_values">
                <join-column name="ar_id" />
            </collection-table>
        </element-collection>
    </attributes>
</entity>
</entity-mappings>
 

Комментарии:

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

2. спасибо за комментарий. это верно, этот способ возможен. Я надеялся, что будет другой способ, но, похоже, нет (на данный момент).

Ответ №1:

Если вы хотите повторно использовать контракт, определите геттеры и сеттеры как абстрактные методы в базовом классе и реализуйте их в подклассах.

Комментарии:

1. спасибо, но это в основном то же самое, о чем уже упоминал Криззи, смотрите Мой комментарий там.

2. Если подумать, вы уже пробовали использовать модель аннотаций с @AssociationOverride помощью ? Это может сработать для вас, но я понятия не имею, как смоделировать это в hbm.xml

3. это точно так же, как когда вы пишете это в xml …. и нет, это тоже не работает, я это уже проверял.