【问题标题】:Hibernate relations fetch profile休眠关系获取配置文件
【发布时间】:2015-09-13 15:47:33
【问题描述】:

我正在使用 Struts2、Spring 和 Hibernate 开发一个应用程序,并且我正在研究模型获取优化。对于此示例,请考虑“example_table”可能有超过 500k 条记录,而他的所有 OneToMany 关系可能有更多记录(例如,document 表与 document_row 的关系)。

示例代码如下:

@Entity
@Table(name = "example")
public class Example extends BaseModel { // Base Model is mapped as superclass and contains the Id column and create,update,delete timestamps
    private String exampleName;

    /*
     * ...
     */

    /* 
     * This relation contains another relation inside it  
     * (ex. Set<ExampleRelationRelation> exampleRelationRelations)
     */
    private ExampleRelation1 exampleRelation1;

    private Set<ExampleRelation2> exampleRelations2;

    // COSTRUCTORS --------------------------------------------------------
    /*
     * Entity constructors
     */

    // GETTER AND SETTER --------------------------------------------------
    @Column(name = "exampleName")
    public String getExampleName() {
        return exampleName;
    }

    public void setExampleName(String exampleName) {
        this.exampleName = exampleName;
    }

    /*
     * ...
     */

    @OneToOne(mappedBy = "example_relation_1", cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = ExampleRelation1.class)
    @NotFound(action = NotFoundAction.IGNORE)
    public ExampleRelation1 getExampleRelation1() {
        return exampleRelation;
    }

    public void setExampleRelation1(ExampleRelation1 exampleRelation1) {
        this.exampleRelation1 = exampleRelation1;
    }

    @OneToMany(mappedBy = "example", targetEntity = ExampleRelation2.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @NotFound(action = NotFoundAction.IGNORE)
    public Set<ExampleRelation2> getExampleRelation2() {
        return exampleRelation2;
    }

    public void setExampleRelation2(Set<ExampleRelation2> exampleRelation2) {
        this.exampleRelation2 = exampleRelation2;
    }
}

在我的应用程序中,我可能需要使用ExampleRelation1 和他的子关系exampleRelationRelations 加载Example,但并非总是如此。也许下次我必须加载没有关系的Example,或者只加载exampleRelation1exampleRelation2

我发现的最佳解决方案是实现Fetch profiles,以便动态地将表与我需要的关系连接起来。有了这个解决方案,我可以告诉 Struts2 控制器检索我需要的数据。

这是一个好的解决方案吗?还是我应该使用其他策略?

* 编辑 *

我也找到了this question,这可能是一个解决方案?

【问题讨论】:

  • 两个主题都具有相反的延迟加载特性。顺便说一句,为什么要加载超过 50 万条记录,很难处理它们。
  • 我可能已经用不好的方式解释了自己... 500k 是表大小,当然对于 Web 应用程序来说,在单个视图中显示 500k 记录与关系而不对其进行分页会很疯狂.. .
  • 如果相关对象有 1:n 或 n:n 关系?
  • 感谢您的建议!

标签: java hibernate fetch


【解决方案1】:

Fetch Profiles 可以解决您的问题。

但是您可以在代码上控制此行为,只需在事务中每次延迟加载您想要调用正确方法的实体。

我可能需要使用 ExampleRelation1 和他的子关系 exampleRelationRelations 加载示例

所以,你可以使用类似的东西:

@Transactional // from Spring
public Example getExampleWithExampleRelation1AndExampleRelationRelations(String exampleName) {

    Example example = em.find(Example.class, exampleName);
    ExampleRelation1 exampleRelation1 = example.getExampleRelation1(); //lazy load
    exampleRelation1.exampleRelationRelations().size(); //lazy load list
    return example;
}

也许下次我必须加载没有关系的示例,或者只加载 exampleRelation1 和 exampleRelation2。

只需创建另一个方法并调用它:

@Transactional // from Spring
public Example getExampleWithExampleRelation1AndExampleRelation2(String exampleName) {

    Example example = em.find(Example.class, exampleName);
    example.getExampleRelation1(); //lazy load
    example.getExampleRelation2(); //lazy load
    return example;
}

您还可以使用 JPQL 并使用 FETCH 字词加入,以仅使用一个查询来引入实体,例如:

String jpql = "SELECT e FROM Example e " + 
    "JOIN FETCH e.ExampleRelation1" + 
    "JOIN FETCH e.ExampleRelation2 ";

【讨论】:

    猜你喜欢
    • 2013-04-26
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 2013-03-03
    • 2017-06-23
    • 2014-09-21
    相关资源
    最近更新 更多