9

when querying Oracle views with Hibernate 4 I get back a list with a size bigger than 0, representing the count of elements I get when running the same query in SQL Developer for example. When I loop through the list, I however only get null values.

My hibernate.cfg.xml looks like:

<?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>

The VwPersoneelslid.hbm.xml looks like:

<?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>

The function with the query is:

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;
}

The function transformed to native 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;
}

If you guys need more information in order to know what might be the problem, please let me know and I add more code. The VwPersoneelslid.hbm.xml file is auto generated by Eclipse. Thanks.

4

4 回答 4

4

我设法创建了一个解决方法。至少对我来说,问题在于 Hibernate 工具创建了 composite-id 的事实。如果不跳过几圈,我就无法正常工作。所以我设法摆脱了 composite-id 。在我的 reveng.xml 文件中,我添加了:

<table name="VW_PERSONEELSLID">
    <primary-key>
        <key-column name="PK_VW_PERSONEELSLID" />
    </primary-key>
</table>

这会生成一个 id (PK_VW_PERSONEELSLID),它允许我继续使用 Hibernate 工具。我不知道这是否是一个肮脏的修复。可能会在几天内发现。

于 2013-08-19T13:16:09.553 回答
2

Hibernate HQL 查询处理实体。视图是数据库或 SQL 模式的概念。当我们使用 HQL 查询数据时,我们会提到实体名称和实体属性。因此,如果您想从 Views 查询,请使用带有 Hibernate 的 Core SQL 查询而不是 HQL 查询。

于 2013-08-13T06:49:41.827 回答
2

首先:抱歉格式不佳,但在我的 3" 屏幕手机上写 e 很痛苦......)
IMO 的问题是您的实体仅由 id 组成。Hibernate 可能在查询期间获取 id 并找到有效数量的对象(您的列表大小),但是在脱水期间何时将 id 转换为映射实体时,它在获取真实数据和构建您的实体时遇到问题(也许 hibernate 正在获取其他属性排除那些是 id 的一部分并遇到一种 select null from table where id-fields = prefetched id - 只是一个想法;这就是为什么你会得到一个充满空值的列表的原因)。如果您可以重新考虑您的复合 ID 或尝试向实体添加更多属性。希望可以帮助解决或指出解决方案。Hibernate 工具有时会生成奇怪的映射...否则使用本机查询,

使用 SQL 查询:

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;有关检查SO 答案的任何问题。

于 2013-08-13T10:10:53.623 回答
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")

这解决了我的问题。

如果我错了,请纠正我。

于 2016-05-03T02:46:48.933 回答