【问题标题】:Hibernate eager collection is not getting loadedin Many to One RelationHibernate Eager Collection 未在多对一关系中加载
【发布时间】:2016-10-02 09:09:32
【问题描述】:

我有两个实体类,其中我有休眠多对一映射。但是,当某个类 (QueryEntity) 被获取时,即使它的获取类型是急切的,一对多集合 SetlookUpCols(属于 LookUpCols 类)也不会被加载。我得到 queryEntity.getLookUpCols().size() = 0。在后端,HQL 查询按预期生成。主实体和急切实体查询都被触发,但对象没有被加载。谁能指出为什么会发生这种情况。

QueryEntity.java

package entity;
import java.util.Date;
import java.util.Set;

public class QueryEntity {
  Long queryId;
  ColumnMeta queryColumnMeta;
  QueryType queryType;
  String paramNames;
  String mainQuery;
  Date lastUpdtTS;
  public Set < LookUpCols > lookUpCols;
  String queryName;

  //getters and setters

}

QueryEntity.hbm.xml

<hibernate-mapping>
  <class name="entity.QueryEntity" table="QueryEntity">
    <meta attribute="class-description">
    </meta>
    <id name="queryId" type="long" column="queryId">
      <generator class="increment" />
    </id>
    <property name="paramNames" column="paramNames" type="string" />
    <property name="mainQuery" column="mainQuery" type="string" />
    <property name="queryName" column="queryName" type="string" />
    <many-to-one name="queryColumnMeta" column="queryColumnMeta" class="entity.ColumnMeta" />
    <set name="lookUpCols" table="LookUpCols" inverse="false" lazy="false" cascade="all" fetch="join">
      <key>
        <column name="queryId" />
      </key>
      <one-to-many class="entity.LookUpCols" />
    </set>
    <property name="queryType" column="queryType">
      <type name="org.hibernate.type.EnumType">
        <param name="enumClass">entity.QueryType</param>
        <param name="useNamed">true</param>
      </type>
    </property>
  </class>
</hibernate-mapping>

LookUpCols.java

package entity;
import java.util.Date;
public class LookUpCols {
Long lookUpId;
QueryEntity query;
String lookUpColName;
String lookUpQuery;
Date lastUpdtTS;

// getters and setters

}

LookUpCols.hbm.xml

<hibernate-mapping>
  <class name="entity.LookUpCols" table="LookUpCols">
    <meta attribute="class-description">
    </meta>
    <id name="lookUpId" type="long" column="lookUpId">
      <generator class="increment" />
    </id>
    <many-to-one name="query" column="query" class="entity.QueryEntity" fetch="select" not-null="true" />
    <property name="lookUpColName" column="lookUpColName" type="string" />
    <property name="lookUpQuery" column="lookUpQuery" type="string" />
    <property name="lastUpdtTS" column="lastUpdtTS" type="date" />
  </class>
</hibernate-mapping>

HQL 查询

Hibernate:
  select
queryentit0_.queryId as queryId104_,
  queryentit0_.paramNames as paramNames104_,
  queryentit0_.mainQuery as mainQuery104_,
  queryentit0_.queryName as queryName104_,
  queryentit0_.queryColumnMeta as queryCol5_104_,
  queryentit0_.queryType as queryType104_
from
QueryEntity queryentit0_
Hibernate:
  select
lookupcols0_.queryId as queryId104_1_,
  lookupcols0_.lookUpId as lookUpId1_,
  lookupcols0_.lookUpId as lookUpId102_0_,
  lookupcols0_.query as query102_0_,
  lookupcols0_.lookUpColName as lookUpCo3_102_0_,
  lookupcols0_.lookUpQuery as lookUpQu4_102_0_,
  lookupcols0_.lastUpdtTS as lastUpdtTS102_0_
from
LookUpCols lookupcols0_
where
lookupcols0_.queryId = ?

添加运行的代码会获取实体。这是我用来读取所有数据的通用函数。我将类名(在本例中为 QueryEntity)传递给该函数,该函数又获取数据。

GenericDAOImpl.java

package daoImpl;
import java.io.File;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import dao.GenericDAO;
import exceptions.EntityNotPresent;

public class GenericDAOImpl<T, ID extends Serializable> implements GenericDAO<T, ID> {

SessionFactory factory;

public GenericDAOImpl() {
    super();
            Configuration cfg = new Configuration();
    File f = new File(
            "path to my persistence.xml");
    cfg.configure(f);
    factory = cfg.buildSessionFactory();

}

@Override
public T save(T t) {

    Session session = factory.openSession();
    session.beginTransaction().begin();
    session.persist(t);
    session.flush();
    session.beginTransaction().commit();
    session.close();
    return t;
}

//  This is the generic function that i call to read all data. I pass 
//  the class name (in this case QueryEntity) to this function which in turn    fetches the data. 
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public List<T> readAll(Class clazz) {
    Session session = factory.openSession();
    session.beginTransaction().begin();

    Query query = session.createQuery("from " + clazz.getName());
    List<T> listT = query.list();
    session.beginTransaction().commit();
    session.close();
    return listT;
}

@SuppressWarnings("unchecked")
@Override
public T readById(@SuppressWarnings("rawtypes") Class clazz, ID id) {
    /*
     * entityTransaction.begin(); T t = (T) entityManager.find(clazz, id);
     * entityTransaction.commit(); return t;
     */
    Session session = factory.openSession();
    session.beginTransaction().begin();
    T t = null;
    t = (T) session.load(clazz, id);
    session.beginTransaction().commit();
    session.close();
    return t;
}

@Override
public void delete(@SuppressWarnings("rawtypes") Class clazz, ID removeId) {

    if (isEntityExists(clazz, removeId)) {
        T old = readById(clazz, removeId);
        entityTransaction.begin();
        entityManager.remove(old);
        entityTransaction.commit();
    }
}

@SuppressWarnings("unchecked")
@Override
public boolean isEntityExists(@SuppressWarnings("rawtypes") Class clazz, ID id) {
    return entityManager.find(clazz, id) != null;
}

@SuppressWarnings("unchecked")
@Override
public T getFirstRecord(Class<?> clazz) {
    entityTransaction.begin();
    Session session = entityManager.unwrap(Session.class);
    Criteria queryCriteria = session.createCriteria(clazz);
    queryCriteria.setFirstResult(0);
    queryCriteria.setMaxResults(1);
    T t = (T) queryCriteria.list().get(0);
    entityTransaction.commit();
    return t;

}

@Override
public List<T> getByQuery(String queryExecute, Object[] pars, @SuppressWarnings("rawtypes") Class clazz) {

    entityTransaction.begin();
    @SuppressWarnings("unchecked")
    TypedQuery<T> query = entityManager.createQuery(queryExecute, clazz);
    for (int i = 0; i < pars.length; i++) {
        query.setParameter("arg" + i, pars[i]);
    }
    List<T> results = query.getResultList();
    entityTransaction.commit();
    return results;

}

@Override
public T update(@SuppressWarnings("rawtypes") Class clazz, ID id, T t) throws EntityNotPresent {
    return null;
}
}

所以查询正在正确执行,但集合没有被加载。请帮忙

【问题讨论】:

  • 您是否确认您拥有期望查询返回的数据?此外,您还缺少运行查询的代码。
  • 嗨,Bhesh,感谢您的回复。是的,我已经检查了数据。我正在输入依赖表的数据,看到它持久存在,然后将持久对象与也成功持久的 QueryEntity 对象相关联。但是在获取时,包含一对多关系的集合没有被填充。我仍然会再次检查并让您知道。同时,我更新了获取数据的 DAO 类。我正在使用 hibernate 和 Derby 数据库。
  • 这不应该是表的唯一标识符吗?
  • 啊..谢谢@terpinmd..它是正确的。我对休眠有点陌生。不知道我怎么错过了。再次感谢。您可以将此评论添加为答案,我会将其标记为答案。

标签: java hibernate eager-loading


【解决方案1】:

根据 OP 中的注释,键是该集合的错误列。应该是:

<key> 
  <column name="lookUpId" /> 
</key> 

对未来有帮助的一件事是打开调试,让您查看查询中绑定的值。这可能会向您显示错误的值被传递给“where lookupcols0_.queryId = ?" 子句。

【讨论】:

  • 是的,我在 HQL 查询中也错过了它。我假设 LookUpCols.java 也有 QueryEntity,连接将使用这个 QueryEntity 的 id。以后会更加注意。非常感谢:)
  • 碰巧,你能帮我解决这个问题吗 - stackoverflow.com/questions/37481321/…
猜你喜欢
  • 1970-01-01
  • 2014-03-27
  • 1970-01-01
  • 2021-02-16
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 2015-02-05
  • 2016-08-17
相关资源
最近更新 更多