【问题标题】:List of entity inside a hibernate entity with @NamedNativeQueries带有@NamedNativeQueries 的休眠实体中的实体列表
【发布时间】:2021-03-12 21:55:21
【问题描述】:

我有一种情况,我在休眠状态下获得实体列表,但在主实体内部我有另一个实体列表。我使用的实体:

EmpListBean.java

@NamedNativeQueries({
 @NamedNativeQuery(
         name = "EmpList",
         //Actual query involves lot of joins
         query = " SELECT ID , NAME FROM EMPLOYEE WHERE EMP_ID=:EMPID"    
             ,resultClass = EmpListBean.class
         )
})

@Entity
public class EmpListBean {



@Column(name = "ID")
private int id;    

@Column(name = "NAME")
private String empName;

// This is the list i need to retreive
@ManyToOne
@Column(name="workList")   
private List<WorkListBean> workList;

//Getters & Setters

}

WorkListBean.java

@NamedNativeQueries({
 @NamedNativeQuery(
         name = "WorkListBeanList",
         query = " SELECT ID , NAME FROM Work_List WHERE EMP_ID=:EMPID"    
             ,resultClass = WorkListBean.class
         )
})

@Entity
public class WorkListBean {



@Column(name = "ID")
private int id;    

@Column(name = "NAME")
private String workName;

//Getters & Setters

}

DAO 层

Query query = session.getNamedQuery("EmpList");             
query.setParameter("EMPID", myObj.getEmpId());
List<EmpListBean> oEmpListBean = query.list();

当在 DAO 层代码下面执行时,我得到“workList”对象为空,我知道这可以通过单独迭代 EmpListBean 并单独调用 WorkListBean 的命名查询来实现,但是由于数据很大,所以需要太多时间这样做,所以想知道是否有任何方法可以在 EmpList Bean 中获取 WorkListBean。这里使用的两个实体仅供参考,我使用的实际查询很复杂,无法在本论坛中显示,并且涉及很多表连接,所以请告诉我如何在 hibernate 中实现。

【问题讨论】:

  • workList 中的EmpListBean 怎么可能是ManyToOne?应该是OneToMany
  • 是的。我尝试了两种方式,即使我将一对多相同的问题存在。它仍然返回 null
  • 好吧,你只获取ID, NAME
  • 为了说明问题,我只使用了 id 和 name,但在实际查询中我获取了大量数据,而且命名查询中也很少发生复杂的连接
  • 您应该获取整个实体或执行 dto 投影 vladmihalcea.com/… 。您正在尝试做的是对实体本身执行 dto 投影并期望正确填写剩余字段,这是不正确的。

标签: java spring spring-boot hibernate jpa


【解决方案1】:

我知道这可以通过单独迭代 EmpListBean 并单独调用 WorkListBean 的命名查询来实现,但是由于数据量很大,这样做会花费太多时间

我知道您想合并这两个查询以包含两个实体的数据,然后呢?

一旦EmpListBeanWorkListBean 之间的关联被正确定义,即您有:

class EmpListBean {
    ...

    @OneToMany
    @JoinColumn(name = "EMP_ID")
    private List<WorkListBean> workList;
}

您应该能够使用以下方法:

session.createNativeQuery(
    "SELECT employee.* FROM EMPLOYEE employee JOIN Work_List wl JOIN ... WHERE wl.EMP_ID=emp.id AND employee.EMP_ID=:EMPID AND ..." )
.addEntity("employee", EmpListBean.class )
.addJoin( "wl", "employee.workList")
.setResultTransformer( Criteria.ROOT_ENTITY )
.list();

不确定它是否适用于命名的原生查询,但您需要检查一下。

【讨论】:

    【解决方案2】:

    正如@Javalerner 所说,您应该使用@OneTomany 并使用 fetch="FetchType.EAGER" 添加 Eager Loading

    并删除列注释

    @OneToMany(fetch = FetchType.EAGER)
    private List<WorkListBean> workList;
    

    【讨论】:

      【解决方案3】:

      如果您正在寻找简单的@OneToMany,我喜欢 Abd 的回复。

      您可能希望使用 FETCH JOIN 样式将此概念合并到 NamedNative 查询中,而不是强制 bean 总是预先加载。使用这种方法,您可以在关联为惰性的对象上创建 EAGER 查询。在这种情况下,Hibernate 只会通过您的查询急切地获取并且通常是懒惰的,我认为这是大多数人想要的。

      随意用谷歌搜索。这是一篇写得很好的文章,可能会让你开始。

      http://www.basilv.com/psd/blog/2008/improving-performance-via-eager-fetching-in-hibernate

      祝你好运!

      【讨论】:

        【解决方案4】:

        要得到FetchType.LAZY 是什么,你必须在句子中使用JOIN FETCH。当你使用JOIN 时,你会得到所有FetchType.EAGER 是什么,但不是FetchType.LAZY 是什么

        EmpListBean.java

        @OneToMany(fetch = FetchType.LAZY, mappedBy="empListBean")
        private List<WorkListBean> workList;
        

        WorkListBean.java

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name="EMP_ID")  
        private EmpListBean empListBean;
        

        String hql = "SELECT empListBean "
                    + "FROM EmpListBean empListBean "
                    + "JOIN FETCH empListBean.workList workList "           
                    + "WHERE empListBean.id = :EMPID";
        
                Query q = sessionFactory.getCurrentSession().createQuery(hql);
                q.setParameter("EMPID", myObj.getEmpId());
                List<EmpListBean> empListBean = query.list();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-15
          • 2015-04-22
          • 1970-01-01
          相关资源
          最近更新 更多