Описание
Каждая из перечисленных выше стратегий и приемов имеет свои преимущества и недостатки. Общие рекомендации по выбору конкретной стратегии будут выглядеть так:
Стратегия TABLE_PER_CLASS на основе UNION
Данную стратегию лучше выбирать, если полиморфные запросы и ассоциации не требуются. Если ты редко выполняешь (или не выполняешь вообще) “select user from User user”. Если у тебя нет Entity-классов, ссылающихся на User, этот вариант будет лучшим (поскольку возможность добавления оптимизированных полиморфных запросов и ассоциаций сохранится).
Стратегия SINGLE_TABLE
Данную стратегию стоит использовать:
а) Только для простых задач. В ситуациях, когда нормализация и ограничение NOT NULL являются критическими, следует отдать предпочтение стратегии №3 (JOINED). Имеет смысл задуматься, не стоит ли в данном случае полностью отказаться от наследования и заменить его делегированием.
б) Если требуются полиморфные запросы и ассоциации, а также динамическое определение конкретного класса во время выполнения. При этом подклассы объявляют относительно мало новых полей, и основная разница с суперклассом заключается в поведении.
И вдобавок к этому, тебе предстоит серьезный разговор с администратором БД.
Стратегия JOINED
Данная стратегия самая эффективная по скорости и CONSTRAINTS. Она подойдет в случаях, когда требуются полиморфные запросы и ассоциации, но подклассы объявляют относительно много новых полей.
Здесь стоит оговориться: решение между JOINED и TABLE_PER_CLASS требует оценки планов выполнения запросов на реальных данных, поскольку ширина и глубина иерархии наследования могут сделать стоимость соединений (и, как следствие, производительность) неприемлемыми.
Отдельно стоит принять во внимание, что аннотации наследования невозможно применить к интерфейсам.
EXPLICIT
Еще может быть ситуация, когда у тебя есть иерархия Entity-классов с совместной стратегией хранения в базе банных. Но по каким-либо причинам ты не хочешь, чтобы некий класс иерархии возвращался, когда делается запрос по базовому классу.
Для этого есть аннотация:
@Polymorphism(type = PolymorphismType.EXPLICIT)
Если мы добавим ее к классу Client:
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
@Entity
class Employee extends User {
String occupation;
int salary;
LocalDate join;
}
@Entity
@Polymorphism(type = PolymorphismType.EXPLICIT)
class Client extends User {
String address;
}
То HQL-запросы будут игнорировать объекты этого класса при запросе базового класса:
List<User> accounts = session.createQuery("from User").getResultList();
Данный запрос вернет список объектов User и Employee, но не Client.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ