我们有一些带有一些属性的实体,这些属性带有Hibernate的@Formula注释。注释中的SQL代码段主要运行标量子查询(例如COUNT查询)。例如,我们有一个深至四个级别的一对多关系层次结构:A <- B <- C <- D(其中<-表示一对多关联)。在获取类型为A的实体时,我们经常会想知道类型为D的关联实体的数量。为此,我们在@Formula中使用带A注释的属性。

由于我们不需要每次都使用这些值,因此我们将@Formula属性声明为延迟加载的(我们启用了Hibernate的字节码增强功能使之成为可能)。但是对于某些查询,我们希望尽快加载这些属性。我们经常在一个查询中加载数百个A类型的实体,因此从性能角度来说,动态控制这些属性的急切/延迟加载非常重要。我们已经使用JPA的实体图来控制为某些查询急切加载哪些属性,但是实体图在这里似乎不起作用。即使我们在实体图中列出了@Formula属性,它们仍然会延迟加载。

是否可以在每个查询的基础上动态控制@Formula列的延迟/急切加载?目前,我们仅限于JPA Criteria Query API,在这里不可能使用命名查询。

更新:

所讨论的属性不是与其他实体的关联,而只是一些计算值。这意味着例如提取配置文件在这里不适用,因为它们仅适用于实体关联(或者至少这就是我理解Hibernate manual的方式)。这是我们的@Formula属性之一的示例:

@Entity
public class A {

    @Basic(fetch = FetchType.LAZY)
    @Formula("(select count(*) from entity_D_table where ...)")
    private int associatedDCount;

    ...
}

最佳答案

您可以使用Critria api使其返回DTO而不是实体。

在条件查询中,使用“投影”仅选择所需的列。

ProjectionList properties = Projections.projectionList();
properties.add(Projections.property("id").as("id"));
properties.add(Projections.property("name").as("name"));
properties.add(Projections.property("lazyField").as("lazyField"));
criteria.setProjection(properties);
criteria.setResultTransformer(new AliasToBeanResultTransformer(MyEntityDTO.class));


这样,无论映射EAGER还是LAZY,select查询都将仅包含您要求的字段。

09-10 07:50
查看更多