【发布时间】: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