Hibernate JPA создает таблицу для каждого класса с InheritanceType.JOINED

1

У меня есть следующие классы:

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? Если это причина ошибки, почему не допускается смешивать типы наследования? Я не вижу, как это может вызвать какие-либо проблемы?

  • 0
    Это смешанное наследование, поэтому зависит от поставщика. Вы перепроверяли с другими поставщиками постоянства?
Теги:
hibernate
jpa
jpa-2.1
wildfly

2 ответа

2
Лучший ответ

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;
...
}
0

Будет ли это работать для вас, если вы удалите аннотации @Entity/Inheritance из класса AbstractEntity?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню