【问题标题】:Mapping NativeQuery results when using inner join使用内部联接时映射 NativeQuery 结果
【发布时间】:2017-06-09 19:53:18
【问题描述】:

我有以下情况:

@Entity
@XmlRootElement
@Table(name = "TB_A")
public class A implements Serializable {

    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "CD_B")
    private B b;

}

@Entity
@XmlRootElement
@Table(name = "TB_B")
public class B implements Serializable {

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "CD_B")
    @JsonIgnore
    private Set<C> c = new HashSet<>();

}

@Entity
@XmlRootElement
@Table(name = "TB_C")
public class C implements Serializable {

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "CD_B")
    private B b;

}

我需要运行以下代码:

String sql = "SELECT * FROM TB_A a "
            + "INNER JOIN TB_B b ON ... "
            + "LEFT JOIN TB_C c ON ... ";

Query query = em.createNativeQuery(sql, A.class);

List<A> AList = query.getResultList();

for(A a : AList) {
    List<c> CList = a.getB().getC();
}

分析执行的查询,我注意到 JPS 每次访问元素 B 和 C 时都在运行 SELECT。

如何正确映射此 nativeQuery 以使用lazyLoad?

  • Obs:我必须使用 NativeQuery,因为在我的 WHERE 子句中,我需要使用 Oracle 的特定函数。所以 JPQL 对我来说不是一个选择(如果我可以使用它,我的生活会轻松很多!)。

【问题讨论】:

    标签: java eclipselink jpa-2.0


    【解决方案1】:

    简短的回答:你不能。

    这条线会做什么:

    Query query = em.createNativeQuery(sql, A.class);
    

    执行你的 SQL,然后扔掉任何与 A.class 无关的东西。

    然后你的 for 循环:

    for(A a : AList) {
        List<c> CList = a.getB().getC();
    }
    

    再次获取所有内容。
    在这里您再次使用 JPA,它对您之前执行的查询一无所知。

    在某些情况下,您可以尝试映射到 C.class
    这样您就可以完全避免循环。
    如果在您的情况下您需要 A.class 和 C.class,则可以查看 ResultSetMapping:http://www.java2s.com/Tutorial/Java/0355__JPA/SqlResultSetMappingForHierarchicalEntity.htm

    【讨论】:

    • 感谢您的回答!我来看看 ResultSetMapping。
    猜你喜欢
    • 2014-10-01
    • 2015-06-25
    • 2019-09-03
    • 2018-11-04
    • 2017-01-13
    • 1970-01-01
    • 2020-05-30
    • 2016-08-08
    • 1970-01-01
    相关资源
    最近更新 更多