使用JPA(Hibernate)无法通过连接的继承链中的根类加载实体

时间:2014-12-22 01:50:17

标签: java hibernate jpa spring-data-jpa spring-data-rest

我有以下继承链:

@MappedSuperclass
public abstract class AbstractEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    Long id;
}

@Entity
@Table(name = "answers")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Answer extends AbstractEntity {

}

@Entity
@Table(name = "chosen_answers")
@PrimaryKeyJoinColumn
public class ChosenAnswer extends Answer {

    @ManyToOne(optional = false)
    @NotNull
    AnswerChoice answerChoice;

}

@Entity
@Table(name = "free_text_answers")
@PrimaryKeyJoinColumn
public class FreeTextAnswer extends Answer {

    String answerText;

}

我的数据库的(简化)示例内容如下所示:

答案:

- ID ---

| 100 |

free_text_answers:

- ID ---- ANSWER_TEXT -

| 100 | “一些文字”|

创建了从free_text_answers(id)answers(id)的外键。 问题是实体管理器返回null以获取以下语句:

em.find(Answer.class, 100l); // returns null

尽管如此,100是存储答案的有效ID。如果我在实体管理器中查询FreeTextAnswer的实例,我会得到预期的结果。

em.find(FreeTextAnswer.class, 100l) // returns stored entity

奇怪的是,只要我向实体管理器查询子类型,第一个语句也会返回请求的实体。

这是预期的结果吗?如果是,我如何设计我的继承链以我喜欢的方式工作?

我正在使用Spring Data Rest,我只通过RestRepository公开Answer - 实体,因此Spring Data Rest调用实体管理器,并以Answer作为预期实体。

1 个答案:

答案 0 :(得分:1)

在使用生成的SQL语句进行进一步调试之后,我找到了解决问题的解决方法。

正如您在下面的ER图中所看到的,Answer的一个子类与另一个实体有OneToOne的关系。这种关系的默认fetchtype是EAGER,结果证明是问题所在。 一旦我将hibernate配置为延迟加载这种关系,一切都按预期工作。

这是hibernate中的错误吗?

ER Diagram