我有一个实体,该实体具有简单的String列以及许多ElementCollections(列表和映射)。我注意到查看我的postgres日志时,查询该实体时PostGres正在连续执行一堆SELECT查询以获取所有ElementCollections。
为了提高效率,我想用一些内部JOIN进行一个SELECT查询可能会更好,以避免所有单独的SELECT查询。有没有一种方法可以不用所有INNER JOIN手动编写一个非常冗长的select查询?
我一直在研究FetchTypes和Spring QueryData语言以及DTO Projection,但我想可能会有更直接的方法。我一直想当然的好处是,如果我添加一个新字段,则明确地执行JOIN,那么我将不得不继续更新查询,如果Spring正在为我生成查询,那么我就不需要做任何事情。>
// Person.java
@Entity
public Person {
@Id
long personId;
@Column
String firstName;
@Column
String lastName;
@ElementCollections
Set<String> someField;
@ElementCollections
Map<String, String> otherField;
@ElementCollections
Set<String> anotherField;
@ElementCollections
Map<String, String> yetAnotherField;
}
现在发生的事情是
SELECT firstName, lastName FROM Person WHERE personId=$1
SELECT someField FROM Person_SomeField WHERE someField.personId=$1
SELECT otherField.key otherField.value FROM Person_OtherField WHERE otherField.personId=$1
对于所有ElementCollections表,这种情况继续存在,从而导致大量查询。
答案 0 :(得分:0)
将注释更改为@ElementCollection(fetch = FetchType.EAGER)
。
听起来好像这些字段正在延迟加载(Hibernate正在等待,直到它们被访问才能加载它们),这会导致您看到N + 1个查询。 LAZY
加载是此类成员的默认行为,这是有道理的,因为加载它并不便宜。但是,如果您始终希望加载这些成员,可以将其设置为EAGER
。将抓取设置为EAGER
将迫使Hibernate将它们与实体本身一起加载。这是fetch
上@ElementCollection
选项的文档:
(可选)是否应该延迟加载集合或必须 急切地拿来。 EAGER策略是对 持久性提供程序运行时集合元素必须为 急切地拿来。 LAZY策略暗示了持久性 提供程序运行时。