Мы используем одиночное наследование таблиц для каждой таблицы в нашем приложении. Это позволяет различным экземплярам одного и того же стека приложений работать с одними и теми же DAO, в то время как их объекты могут немного отличаться, потенциально содержа информацию, уникальную для этого экземпляра. Абстрактный класс определяет базовую структуру таблицы, а расширение определяет дополнительные столбцы, если это необходимо для этого экземпляра:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "client")
public abstract class Client extends AbstractPersistable<Long> {
// ...
}
приложение A:
@Entity
public class ClientSimple extends Client {
private String name;
// getter, setter
}
приложение B:
@Entity
public class ClientAdvanced extends Client {
private String description;
// getter, setter
}
Теперь DAO может работать с Client
объектами для приложений A и B, но приложение B может определять дополнительную информацию для своего клиентского объекта, которая может быть прочитана методом менеджера, уникальным для приложения B:
приложение A:
Client client = new ClientSimple();
clientDao.save(client);
приложение B:
Client client = new ClientAdvanced();
clientDao.save(client);
К сожалению, это означает, что в каждой таблице есть столбец DTYPE (или любое другое имя, которое я могу выбрать). Есть ли способ избавиться от этого? Нам это не нужно, и оно использует пространство БД ...
Спасибо!
EDIT
Важно отметить: @MappedSuperclass
не будет работать. Мы используем QueryDSL в качестве уровня абстракции HQL. Это требует автоматически сгенерированных классов Query Type для запросов сохранения типа. Однако они будут сгенерированы правильно, только если абстрактный класс помечен @Entity
.
Это не обязательно, потому что мы хотим выполнить запрос к абстрактному классу Client
, в то время как в действительности запрашиваем ClientSimple
в приложении A и ClientAdvanced
в приложении B:
Так что в любом приложении это будет работать:
query.where(QClient.client.name.equals("something");
и в приложении B это будет работать:
query.where(QClientSimple.client.description.equals("something else");
EDIT2 - выкинуть
Кажется, что все сводится к следующему: можно ли настроить hibernate во время развертывания, чтобы установить тип дискриминатора для унаследованной сущности на фиксированное значение. Итак, в моем примере Client
всегда будет ClientSimple
в одном приложении и ClientAdvanced
в другом, чтобы мне не приходилось хранить эту информацию в базе данных?
Как я уже сказал: каждое приложение будет экземпляром стека базовых приложений. Каждое приложение может определять дополнительные столбцы для своей локальной базы данных, но ВСЕ объекты будут одного типа для этого экземпляра, поэтому мы гарантируем, что дискриминатор всегда одинаков, что делает его избыточным в базе данных и сценарии использования для конфигурации гибернации.