在使用Hibernate 4查询Oracle视图时,我返回一个大小大于0的列表,表示在SQL Developer中运行相同查询时获得的元素数。当我遍历列表时,我只得到空值。
我的hibernate.cfg.xml如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:@127.0.0.1:1521:OUT</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.default_schema">schema</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="hibernate.connection.pool_size">1</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping resource="be/comp/model/db/VwPersoneelslid.hbm.xml"/>
</session-factory>
VwPersoneelslid.hbm.xml看起来像:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated 9-aug-2013 10:13:31 by Hibernate Tools 4.0.0 -->
<hibernate-mapping>
<class name="be.comp.model.db.VwPersoneelslid" table="VW_PERSONEELSLID">
<composite-id name="id" class="be.comp.model.db.VwPersoneelslidId">
<key-property name="pkVwPersoneelslid" type="double">
<column name="PK_VW_PERSONEELSLID" precision="126" scale="0" />
</key-property>
<key-property name="fkVwFunctie" type="double">
<column name="FK_VW_FUNCTIE" precision="126" scale="0" />
</key-property>
<key-property name="familienaam" type="string">
<column name="FAMILIENAAM" length="80" />
</key-property>
<key-property name="voornaam" type="string">
<column name="VOORNAAM" length="80" />
</key-property>
<key-property name="code" type="string">
<column name="CODE" length="10" />
</key-property>
</composite-id>
</class>
查询功能是:
public List<VwPersoneelslid> findByCode(String code)
{
Session session = HibernateUtil.getSessionFactoryNeptunus().getCurrentSession();
session.beginTransaction();
List<VwPersoneelslid> list = new ArrayList();
Query query = session.createQuery("FROM VwPersoneelslid WHERE code = :code");
query.setParameter("code", code);
list = query.list();
session.getTransaction().commit();
return list;
}
该函数转换为本机SQL:
public List<VwPersoneelslid> findByCode(String code)
{
Session session = HibernateUtil.getSessionFactoryNeptunus().getCurrentSession();
session.beginTransaction();
List<VwPersoneelslid> list = new ArrayList();
Query query = session.createSQLQuery("SELECT * FROM CIPALII.VW_PERSONEELSLID WHERE code = :code").addEntity(VwPersoneelslid.class)
.setParameter("code", code);
list = query.list();
session.getTransaction().commit();
return list;
}
如果您需要更多信息以了解可能存在的问题,请告诉我并添加更多代码。 VwPersoneelslid.hbm.xml文件由Eclipse自动生成。感谢。
答案 0 :(得分:4)
我设法创建了一种解决方法。对我来说,问题至少在于Hibernate Tools创建复合id的事实。没有跳过几个篮球,我无法正常工作。所以我设法摆脱了复合身份证。在我的reveng.xml文件中,我添加了:
<table name="VW_PERSONEELSLID">
<primary-key>
<key-column name="PK_VW_PERSONEELSLID" />
</primary-key>
</table>
这会生成一个id(PK_VW_PERSONEELSLID),它允许我继续使用Hibernate Tools。我不知道这是否是一个肮脏的修复。可能会在几天后发现。
答案 1 :(得分:2)
Hibernate HQL查询处理实体。视图是数据库或SQL模式的概念。当我们使用HQL查询数据时,我们提到了实体名称和实体属性。因此,如果要从Views查询,请使用带有Hibernate的Core SQL查询而不是HQL查询。
答案 2 :(得分:2)
在所有人之前:抱歉格式不佳,但在我的3“屏幕上移动写e是一种痛苦......)
IMO的问题是你的实体只由id组成。 Hibernate可能在查询期间获取id并找到有效数量的对象(列表大小),但是在脱水期间何时将id转换为映射实体,它会遇到问题,获取真实数据并构建实体(可能hibernate正在获取其他属性)排除那些是id的一部分并从表中运行一种select null,其中id-fields = prefetched id - 只是一个想法;这就是为什么你得到一个填充空值的列表)。如果您可以重新考虑复合ID或尝试向实体添加更多属性。希望可以帮助解决或指向解决方案。 Hibernate工具有时会产生奇怪的映射......
否则使用本机查询,addScalar()(而不是addEntity)和aliastobean resulttransformer可以解决(如果您正在映射只读视图,这可能是合理的)
使用SQLQuery:
session.createSQLQuery("select pkVwPersoneelslid, fkVwFunctie, familienaam, voornaam, code from VW_PERSONEELSLID where code = :code")
.setParameter("code", code)
.addScalar("pkVwPersoneelslid",DoubleType.INSTANCE)
.addScalar("fkVwFunctie",DoubleType.INSTANCE)
.addScalar("familienaam",StringType.INSTANCE)
.addScalar("voornaam".StringType.INSTANCE)
.addScalar("code".StringType.INSTANCE)
.setResultTransformer(new AliasToBeanResultTransformer(VwPersoneelslid.class))
.list();
你需要空的构造函数和setter / getter;有关支票this的任何问题,请回答。
答案 3 :(得分:0)
如果您知道要查询的列可能包含空值,那么我建议您将NVL(ColumnName,value)添加到查询中。
例如:
session.createSQLQuery("select NVL(size,0) as size from randomTable")
.addScalar("size",StandardBasicType.INTEGER)
.setResultTransformer(Transformers.aliasToBean(randomTableClass.class))
.list();
您也可以使用COALESCE
session.createSQLQuery("select COALESCE(size,0) as size from randomTable")
这解决了我的问题。
如果我错了,请纠正我。