我有以下继承链:
@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
作为预期实体。
答案 0 :(得分:1)
在使用生成的SQL语句进行进一步调试之后,我找到了解决问题的解决方法。
正如您在下面的ER图中所看到的,Answer
的一个子类与另一个实体有OneToOne
的关系。这种关系的默认fetchtype是EAGER
,结果证明是问题所在。
一旦我将hibernate配置为延迟加载这种关系,一切都按预期工作。
这是hibernate中的错误吗?