我正在尝试使用查询在 hibernate 中创建一个对象,然后该对象将被保存回表示该类的表中。
hbm.xml 文件摘录:
<class name="MyClass" table="MY_TABLE">
<id column="ID" name="ID">
<generator class="sequence">
<param name="sequence">MY_SEQ</param>
</generator>
</id>
<property column="VAL" name="val" type="string"/>
</class>
<sql-query name="myQuery">
<return class="MyClass"/>
SELECT MY_SEQ.nextval ID, 'something' VAL from DUAL
</sql-query>
测试用例的代码片段:
MyClass myClass = (MyClass) session.getNamedQuery("myQuery").list().get(0);
Transaction t = session.beginTransaction();
session.save(myClass);
t.commit();
我的目标是表 MY_TABLE 中现在应该有一条新记录,但插入没有发生,我认为这是由于 Hibernate 不知道该实例尚未持久化在数据库中。
我尝试将查询更改为:
SELECT NULL ID, 'something' VAL from DUAL
但这会导致 Hibernate 无法实例化对象。
那么,我如何从与该类的持久实例无关的查询创建一个新的对象实例,并使用它来创建一个持久实例?
Update:我测试了下面建议的方法,但无法让它适用于这个特定的场景,Hibernate 希望您为所有属性选择列,而我们绝对不需要 id。然而,使用一个ResultTransformer
做了工作:
16.1.5。返回非托管实体 http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html#d0e13904
可以申请一个ResultTransformer
到本机 SQL
查询,允许它返回
非管理实体。
sess.createSQLQuery("SELECT NAME, BIRTHDATE FROM CATS")
.setResultTransformer(Transformers.aliasToBean(CatDTO.class))
该查询指定:
上面的查询将返回一个列表
已实例化的 CatDTO
注入 NAME 的值和
BIRTHNAME 成其对应的
属性或字段。
该文档提到返回非托管实体,但它也适用于实体(没有理由它不起作用),我可以persist
瞬态实体成功。
See also
- Hibernate 3.2:HQL 和 SQL 的转换器 http://relation.to/2133.lace
为了清楚起见,我将保留最初的答案。
也许以下内容会有所帮助:
16.1.2。实体查询 http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html#d0e13696
上述查询都是关于
基本上返回标量值
从返回“原始”值
结果集。下面展示了如何
从本机 sql 获取实体对象
查询通过addEntity()
.
sess.createSQLQuery("SELECT * FROM CATS").addEntity(Cat.class);
sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").addEntity(Cat.class);
该查询指定:
假设 Cat 被映射为一个类
列 ID、NAME 和
生日 上述查询都将
返回一个列表,其中每个元素都是
猫实体。
如果实体被映射为
与另一个实体的多对一
还需要返回此时
执行本机查询,否则
数据库特定的“未找到列”
将会发生错误。额外的
列将自动返回
当使用 * 符号时,但是我们
更喜欢明确如
以下是多对一的示例
一只狗:
sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE, DOG_ID FROM CATS").addEntity(Cat.class);
这将允许cat.getDog()
到
功能正常。
但我认为如果你想保存它并希望 Hibernate 执行插入,你不应该设置 ID。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)