Hibernate eager collection 未加载到多对一关系中
Hibernate eager collection is not getting loadedin Many to One Relation
我有两个实体 classes,我在其中休眠了多对一映射。但是,当获取 class (QueryEntity) 之一时,一对多集合 Set lookUpCols(class LookUpCols)不会被加载,即使它的获取类型是急切的。我得到 queryEntity.getLookUpCols().size() = 0。在后端,HQL 查询按预期生成。主实体和急切实体查询都被触发,但对象没有得到 loaded.Can 任何人都提出了为什么会发生这种情况。
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 = ?
添加运行的代码以获取实体。这是我调用来读取所有数据的通用函数。我将 class 名称(在本例中为 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;
}
}
因此查询正确执行,但集合未加载。请帮忙
根据 OP 中的评论,该键是该集合的错误列。应该是:
<key>
<column name="lookUpId" />
</key>
将来会有帮助的一件事是打开调试,让您看到查询中绑定的值。这可能会向您表明为“where”传递了错误的值
lookupcols0_.queryId = ?" 子句。
我有两个实体 classes,我在其中休眠了多对一映射。但是,当获取 class (QueryEntity) 之一时,一对多集合 Set lookUpCols(class LookUpCols)不会被加载,即使它的获取类型是急切的。我得到 queryEntity.getLookUpCols().size() = 0。在后端,HQL 查询按预期生成。主实体和急切实体查询都被触发,但对象没有得到 loaded.Can 任何人都提出了为什么会发生这种情况。
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 = ?
添加运行的代码以获取实体。这是我调用来读取所有数据的通用函数。我将 class 名称(在本例中为 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;
}
}
因此查询正确执行,但集合未加载。请帮忙
根据 OP 中的评论,该键是该集合的错误列。应该是:
<key>
<column name="lookUpId" />
</key>
将来会有帮助的一件事是打开调试,让您看到查询中绑定的值。这可能会向您表明为“where”传递了错误的值 lookupcols0_.queryId = ?" 子句。