Hibernate JPA 为每个 class 和 InheritanceType.JOINED 创建一个 table
Hibernate JPA creates a table per class with InheritanceType.JOINED
我有以下 classes:
AbstractEntity,它是我所有实体的超级 class 并存储所有实体使用的公共字段,例如 id:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
...
}
AbstractUser,它是所有用户实体(管理员、标准等)的超级class,存储所有用户帐户共有的字段,例如登录名和密码等:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class AbstractUser extends AbstractEntity implements Serializable
非抽象用户示例 class,AdminUser:
@Entity
public class AdminUser extends AbstractUser implements Serializable {
我想要的是我有一个 table 用于 AbstractUser class,它只包含 AbstractUser class 中的列,然后是每个子 class 一个 table 包含所有 class 特定值。我认为 AbstractUser 中的 @Inheritance(strategy = InheritanceType.JOINED) 注释应该这样做。但是,Hibernate 为我生成了一个模式,其中每个 class(AbstractUser 和扩展它的所有 classes)都有一个 table,非抽象 tables =86=]es 包含摘要的所有列 class。
当我持久化扩展 AbstractUser 的 classes 之一的对象时,所有值都写入更具体的 table,即 AbstractUser table 保持为空。
澄清一下:
假设我有一个 AbstractUser class 和扩展 AbstractUser 的 AdminUser 和 StandardUser classes。然后我保留一个 ID 为 1、名称为 'A' 的 AdminUser 对象和一个 ID 为 2、名称为 'B' 和帐号为“001”的 StandardUser,我最终会得到:
抽象用户:
| ID | NAME |
empty table
AdminUser:
| ID | NAME |
| 1 | A |
标准用户:
| ID | NAME | AccountNum |
| 2 | B | 001 |
我想得到的是:
抽象用户:
| ID | NAME |
| 1 | A |
| 2 | B |
AdminUser:
| ForeignKey |
| 1 |
标准用户:
| 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
是否存在错误 混合继承策略,因为我首先对 AbstractEntity 进行了 TABLE_PER_CLASS,然后对 AbstractUser 进行了 JOINED?如果这是错误的原因,为什么不允许混合继承类型?我不明白这会导致什么问题??
AbstractEntity 应该是 MappedSuperclass 而不是实体。
http://en.m.wikibooks.org/wiki/Java_Persistence/Inheritance#Mapped_Superclasses
Mapped superclass inheritance allows inheritance to be used in the
object model, when it does not exist in the data model.
@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
...
}
我有以下 classes:
AbstractEntity,它是我所有实体的超级 class 并存储所有实体使用的公共字段,例如 id:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
...
}
AbstractUser,它是所有用户实体(管理员、标准等)的超级class,存储所有用户帐户共有的字段,例如登录名和密码等:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class AbstractUser extends AbstractEntity implements Serializable
非抽象用户示例 class,AdminUser:
@Entity
public class AdminUser extends AbstractUser implements Serializable {
我想要的是我有一个 table 用于 AbstractUser class,它只包含 AbstractUser class 中的列,然后是每个子 class 一个 table 包含所有 class 特定值。我认为 AbstractUser 中的 @Inheritance(strategy = InheritanceType.JOINED) 注释应该这样做。但是,Hibernate 为我生成了一个模式,其中每个 class(AbstractUser 和扩展它的所有 classes)都有一个 table,非抽象 tables =86=]es 包含摘要的所有列 class。
当我持久化扩展 AbstractUser 的 classes 之一的对象时,所有值都写入更具体的 table,即 AbstractUser table 保持为空。
澄清一下:
假设我有一个 AbstractUser class 和扩展 AbstractUser 的 AdminUser 和 StandardUser classes。然后我保留一个 ID 为 1、名称为 'A' 的 AdminUser 对象和一个 ID 为 2、名称为 'B' 和帐号为“001”的 StandardUser,我最终会得到:
抽象用户:
| ID | NAME |
empty table
AdminUser:
| ID | NAME |
| 1 | A |
标准用户:
| ID | NAME | AccountNum |
| 2 | B | 001 |
我想得到的是:
抽象用户:
| ID | NAME |
| 1 | A |
| 2 | B |
AdminUser:
| ForeignKey |
| 1 |
标准用户:
| 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
是否存在错误 混合继承策略,因为我首先对 AbstractEntity 进行了 TABLE_PER_CLASS,然后对 AbstractUser 进行了 JOINED?如果这是错误的原因,为什么不允许混合继承类型?我不明白这会导致什么问题??
AbstractEntity 应该是 MappedSuperclass 而不是实体。
http://en.m.wikibooks.org/wiki/Java_Persistence/Inheritance#Mapped_Superclasses
Mapped superclass inheritance allows inheritance to be used in the object model, when it does not exist in the data model.
@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
...
}