Hibernate,JPA,当并非所有子类都有自己的表时会导致循环依赖性错误,从而加入了表继承

时间:2013-03-25 21:09:52

标签: hibernate inheritance jpa

我正在尝试使用JPA和Hibernate从现有架构中读取数据。我无法修改架构。有一个带有多个子类的User类。其中一些子类具有存储在连接表中的其他数据,而另一些则没有。作为一个具体示例,请考虑以下3个类和2个表。 (实际上,有十几种变体和十几种表格。)

  • User是常见的基类。它包括一个名为userType的鉴别器列。表格USER包含所有User类共有的数据,包括数字USERID值。
  • StandardUser是一种没有其他数据的变体。
  • LoginUser是另一种具有用户名和密码的变体,存储在LOGIN_USER USER USERID加入的表@Entity @Table(name="USER") @Inheritance(strategy=InheritanceType.JOINED) @DiscriminatorColumn(name="USERTYPEID", discriminatorType=DiscriminatorType.INTEGER) public class User { private @Id long userId; private String userName; private int userTypeId; ... } @Entity @Table(name="USER") @DiscriminatorValue("1") public class StandardUser extends User { } @Entity @Table(name="LOGIN_USER") @DiscriminatorValue("2") public class LoginUser extends User { private String login; private String password; .... } 中。

以下适用于OpenJPA:

USER

它生成在LOGIN_USER上连接USERIDCaused by: org.hibernate.AnnotationException: Foreign key circularity dependency involving the following tables: (带有左外连接)的SQL代码,并根据userTypeId值是否为1正确创建StandardUser或LoginUser或2.

当我用Hibernate而不是OpenJPA链接相同的代码时,我收到错误消息

{{1}}

错误消息中未列出任何表。我在异常上设置了一个断点,它试图解决“USER”和“USER”之间的“依赖关系”,或者它出现。我用Hibernate版本3.6和4.1.7尝试过这个。

(为什么不坚持使用OpenJPA?我在那里遇到一个单独的问题,与加载时间代码重写与JAXB的冲突有关。)

1 个答案:

答案 0 :(得分:1)

我应该花更多时间查看相关问题。 Changing the inheritance strategy in branches of the class hierarchy via JPA annotations中提出的策略似乎可以满足我的需求。

具体来说,如果我将代码更改为如下所示,它会编译并运行并通过我的单元测试。

@Entity
@Table(name="USER")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="USERTYPEID", discriminatorType=DiscriminatorType.INTEGER)
@DiscriminatorValue("1")
public class User {
    private @Id long userId;
    private String userName;
    private int userTypeId;
    ...
}

@Entity
@DiscriminatorValue("1")
public class StandardUser {
}

@Entity
@SecondaryTable(name="LOGIN_USER")
@DiscriminatorValue("2")
public class LoginUser extends User {
    @Column(table="LOGIN_USER")
    private String login;
    @Column(table="LOGIN_USER")
    private String password;
    ....
}