У меня есть следующие классы:
AbstractEntity, которая является суперклассом для всех моих объектов и хранит общие поля, используемые всеми объектами, такими как id:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
...
}
AbstractUser, который является суперклассом для всех пользовательских объектов (admin, standard и т.д.) И сохраняет поля, общие для всех учетных записей пользователей, такие как имя пользователя и пароль и т. Д.:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class AbstractUser extends AbstractEntity implements Serializable
Пример не абстрактного класса пользователя, AdminUser:
@Entity
public class AdminUser extends AbstractUser implements Serializable {
То, что я хотел бы иметь, это то, что у меня есть одна таблица для класса AbstractUser, которая содержит только столбцы в классе AbstractUser, а затем для каждой отдельной таблицы подкласса, содержащей все значения класса. Я думал, что аннотация @Inheritance (strategy = InheritanceType.JOINED) в AbstractUser должна это сделать. Однако Hibernate создает для меня схему с таблицей для каждого класса (AbstractUser и все классы, которые ее расширяют), а таблицы для не-абстрактных классов содержат все столбцы абстрактного класса.
Когда я сохраняю объект одного из классов, расширяющих AbstractUser, все значения записываются в более конкретную таблицу, т.е. Таблица AbstractUser остается пустой.
Чтобы уточнить:
Скажем, у меня есть классы AbstractUser и AdminUser и StandardUser, которые расширяют AbstractUser. И затем я сохраняю один объект AdminUser с идентификатором 1 и именем "A" и одним стандартнымUser с id 2, именем "B" и номером учетной записи "001", в итоге я получаю следующее:
AbstractUser:
| ID | NAME |
empty table
AdminUser:
| ID | NAME |
| 1 | A |
StandardUser:
| ID | NAME | AccountNum |
| 2 | B | 001 |
Я бы хотел получить:
AbstractUser:
| ID | NAME |
| 1 | A |
| 2 | B |
AdminUser:
| ForeignKey |
| 1 |
StandardUser:
| ForeignKey | AccountNum |
| 2 | 001 |
Что не так с аннотацией, которую я использую? Как я могу это достичь?
На всякий случай, мой persistence.xml:
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="cfadbPU" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/cfadbDS</jta-data-source>
<properties>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/cfadb"/>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.connection.username" value="*****"/>
<property name="hibernate.connection.password" value="*****"/>
<property name="hibernate.default_schema" value="public"/>
<property name="hibernate.connection.autocommit" value="false"/>
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
</properties>
</persistence-unit>
</persistence>
ОБНОВИТЬ:
Я просмотрел журнал сервера и увидел эти сообщения:
WARN [org.hibernate.cfg.AnnotationBinder] (ServerService Thread Pool -- 187) HHH000138: Mixing inheritance strategy in a entity hierarchy is not allowed, ignoring sub strategy in: entities.users.AbstractUser
WARN [org.hibernate.cfg.AnnotationBinder] (ServerService Thread Pool -- 187) HHH000137: Root entity should not hold an PrimaryKeyJoinColum(s), will be ignored
WARN [org.hibernate.cfg.AnnotationBinder] (ServerService Thread Pool -- 187) HHH000137: Root entity should not hold an PrimaryKeyJoinColum(s), will be ignored
Является ли ошибка Смешивание стратегии наследования там, потому что у меня сначала есть TABLE_PER_CLASS для AbstractEntity, а затем JOINED для AbstractUser? Если это причина ошибки, почему не допускается смешивать типы наследования? Я не вижу, как это может вызвать какие-либо проблемы?
AbstractEntity должен быть MappedSuperclass, а не Enity.
http://en.m.wikibooks.org/wiki/Java_Persistence/Inheritance#Mapped_Superclasses
Наложенное наследование суперкласса позволяет использовать наследование в объектной модели, если оно не существует в модели данных.
@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
...
}
Будет ли это работать для вас, если вы удалите аннотации @Entity/Inheritance из класса AbstractEntity?