Мы используем однонаправленное наследование таблицы для каждой таблицы в нашем приложении. Это позволяет различным экземплярам одного и того же стека приложений работать с одними и теми же DAO, в то время как их сущности могут немного отличаться, потенциально содержащие информацию, уникальную для этого экземпляра. Абстрактный класс определяет базовую структуру таблицы и расширение определяет дополнительные столбцы, если это необходимо с помощью этого экземпляра:Можно ли удалить столбец дискриминатора в наследовании одиночной таблицы Hibernate?
@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
}
Приложение Б:
@Entity
public class ClientAdvanced extends Client {
private String description;
// getter, setter
}
Теперь DAO может работать с объектами Client
для приложений A и B, но приложение B может определять дополнительную информацию для своего клиентского объекта, который может быть прочитан методом менеджера uniqu е к применению В:
приложения A:
Client client = new ClientSimple();
clientDao.save(client);
Приложение B:
Client client = new ClientAdvanced();
clientDao.save(client);
К сожалению, это означает, что есть столбец DTYPE в каждой таблице (или любое другое имя, которое я мог бы выбрать) , Есть ли способ избавиться от этого? Нам это не нужно, и он использует пространство БД ...
Спасибо!
EDIT
Важно отметить: @MappedSuperclass
не будет работать. Мы используем QueryDSL как наш слой абстракции HQL. Для этого требуются автоматически создаваемые классы типа запроса для запроса типа сохранения. Однако они будут генерироваться только правильно, если абстрактный класс аннотируется @Entity
.
Это neccessairy потому что мы хотим, чтобы запрос от абстрактного класса Client
в то время как на самом деле запрашивая ClientSimple
в приложении А и ClientAdvanced
в заявке B:
Так что в любом приложении, это будет работать:
query.where(QClient.client.name.equals("something");
и в заявке на патент B это будет работать:
query.where(QClientSimple.client.description.equals("something else");
EDIT2 - сводиться
Это, кажется, сводится к следующему: Могу ли я настроить спящий режим во время развертывания, чтобы установить тип дискриминатора для inhertited в сущности фиксированное значение. Итак, идя с моим примером, Client
всегда будет ClientSimple
в одном приложении и ClientAdvanced
в другом, так что мне не нужно хранить эту информацию в базе данных?
Как я уже сказал, каждое приложение будет экземпляром базового стека приложений. Каждое приложение может определять дополнительные столбцы для своей локальной базы данных, но ВСЕ объекты будут одного типа для этого экземпляра, поэтому мы гарантируем, что дискриминатор всегда будет тем же самым, что делает его избыточным в базе данных и прецедентом для конфигурации спящего режима.
Какая версия Querydsl вы используете? –
Мы используем QueryDSL 2.2.3, но можем обновлять, если новые версии поддерживают сопоставленные суперклассы в качестве целей запроса: например: @MappedSuperclass @Table public abstract class Client ... '+' @Entity public class ClientSimple extends Client' == > генерировать типы запросов ... ==> query: 'QClient.client.name' – Pete
Это не поддерживается напрямую, но вы можете добавить к нему билет на GitHub. Это легко реализовать. –