Субтипированный объект запроса Hibernate по натуральному идентификатору

Я использую Hibernate и хочу запросить сущности по их естественному идентификатору. Однако, кажется, невозможно иметь естественные идентификаторы для подтипов. У меня есть два класса A и B, где B расширяет A:

class A {
  long id;
}

class B extends A {
  String naturalId;
}

A отображается в Hibernate со своим собственным идентификатором. B отображается как объединенный подкласс. Однако невозможно отобразить естественный идентификатор B в спящем, потому что отображение B является отображением подкласса.

  • Почему невозможно иметь естественный идентификатор в подклассе B? Обратите внимание, что я не хочу, чтобы Hibernate генерировал мою схему базы данных, я просто хочу иметь естественные идентификаторы для быстрых попаданий в кэш.

  • Есть ли способ / лучший способ иметь естественные идентификаторы для подтипов для быстрых запросов к кэшу второго уровня?

    • Возможно ли это по-прежнему, когда естественные идентификаторы могут обновляться (изменяться) в редких случаях и кэш должен поддерживаться в кластерной среде Java EE?

1 ответ

  1. NaturalId имеет смысл только для базовых классов, потому что вы не можете получить подкласс без информации о базовом классе.

    Допустим, вы можете отобразить карту как базового класса, так и подкласса с помощью Natural-ID:

    class A {
      long id;
      String baseId;
    }
    
    class B extends A {
      String naturalId;
    }
    
    A a = session.bySimpleNaturalId( A.class ).load( "abc" );
    

    Если сущность, которую мы получаем, если имеет тип B, не ясно, какой из вариантов Natural-id будет использоваться.

  2. Вы не можете получить подкласс без получения информации о базовом классе. Таким образом, когда вы загружаете подкласс из кэша, информация о базовом классе также извлекается. Поэтому вы можете иметь базовый класс для хранения естественного идентификатора или просто использовать первичный ключ для кэширования.

  3. Вы можете обновить натуральный идентификатор, хотя бизнес-ключ должен быть неизменным. Для изменяемых натуральных идентификаторов вам нужно использовать атрибут mutable.

Согласно 13.3. Наследование сущностей и отображение кэша второго уровня:

Начиная с Hibernate ORM 5.3, теперь вы можете переопределить определение базового класса @Cacheable или @Cache на уровне подкласса.

так что у вас может быть шанс, сбросив аннотации кеширования на B.
Я никогда не пробовал, поэтому, пожалуйста, подтвердите решение с помощью комментария.

Другие вопросы по тегам