Java JPA Hibernate意外地获取了@OneToOne映射实体的记录,我应该将映射更改为@ManyToOne还是执行其他操作?
我有一个实体,其映射子实体为Java JPA Hibernate意外地获取了@OneToOne映射实体的记录,我应该将映射更改为@ManyToOne还是执行其他操作?,java,hibernate,jpa,one-to-one,many-to-one,Java,Hibernate,Jpa,One To One,Many To One,我有一个实体,其映射子实体为@OneToOne: @Entity @Table public class BaseEntity { @Id private String key; @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private InnerEntity inner; } @Entity @Table public class InnerEntity { pri
@OneToOne
:
@Entity @Table
public class BaseEntity {
@Id
private String key;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private InnerEntity inner;
}
@Entity @Table
public class InnerEntity {
private String data;
}
在我决定获取命名查询中的所有记录之前(从BaseEntity e中选择e
),它在持久化和合并操作上一直工作得很好。问题在于,在调用它之后,Hibernate从BaseEntity获取所有记录,然后对每个InnerEntity执行不同的查询。因为桌子很大,它需要很多时间和内存
首先,我开始研究在运行代码的任何地方是否调用了getInner()
。然后,我尝试将fetchType
更改为EAGER
,以检查Hibernate是否将通过一个查询获取所有内容。没有。另一个尝试是将映射更改为@ManyToOne
。为此,我在@JoinColumn
注释中添加了updateable/insertable=false
。抓取开始工作得很好-一个选择
而没有任何加入
(我将渴望
改回懒惰
),但更新开始出现问题。Hibernate希望首先持久化InnerEntity
,但没有主键属性。当然,我可以先调用setKey()
,然后显式地持久化InnerEntity
,但我宁愿不用它来解决这个问题
当使用HQL Hibernate不考虑注释时,你应该告诉它如何工作。 在您的情况下,您应该像这样纠正HQL:
选择e FROM BaseEntity作为e left join fetch e.inner如果您希望按需加载
inner
字段,并且您的关系是@ontone
,您可以尝试此操作
@OneToOne(fetch=FetchType.LAZY,optional=false)
请参阅相关问题:、、@AdamMichalik,谢谢链接。我已经找到了这个解决方案,但它引发了新的级联类型“无父密钥”问题。现在看来有必要在DAO层显式地持久化这两个实体。我认为确实如此。我设法改变了行为,只是改变了注释,而没有修改查询中的任何内容。这是最好的一个,但是cascade仍然存在一些问题。无论如何,我解决了添加optional=false的问题。谢谢