动态控制@Formula列的延迟/急切加载

时间:2016-08-04 08:01:20

标签: java hibernate jpa

我们有一些实体带有一堆用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;

    ...
}

2 个答案:

答案 0 :(得分:1)

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

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

TextView termsText = (TextView)findViewById(R.id.terms_text);
    termsText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.yoururl.com"));
            startActivity(browserIntent);
        }
    });

这样,选择查询将只包含您要求的字段,无论映射为EAGER还是LAZY。

答案 1 :(得分:0)

您可以尝试查看Hibernate的抓取配置文件https://docs.jboss.org/hibernate/orm/4.2/manual/en-US/html/ch20.html#performance-fetching-profiles

例如,您可以注释像这样的实体

@Entity
@FetchProfile(name = "country_states", fetchOverrides = {
           @FetchProfile.FetchOverride(entity = Country.class, association = "states", mode = FetchMode.JOIN)
})
public class Country implements Serializable {...

并在查询时激活JOIN模式,如下所示:

 session=getSession();
 session.beginTransaction();
 //enable fetch profile for EAGER fetching
 session.enableFetchProfile("country_states");

http://www.concretepage.com/hibernate/fetchprofile_hibernate_annotation

所示