使用sql查询在hibernate中创建一个新的对象实例 [英] Creating a new object instance in hibernate using a sql query
问题描述
从hbm.xml文件摘录:
< class name =MyClasstable =MY_TABLE>
< id column =IDname =ID>
< generator class =sequence>
< param name =sequence> MY_SEQ< / param>
< / generator>
< / id>
< property column =VALname =valtype =string/>
< / class>
< sql-query name =myQuery>
< return class =MyClass/>
SELECT MY_SEQ.nextval ID,来自DUAL
的'something'VAL< / sql-query>
测试用例的代码片段:
<$ p $(MyClass)session.getNamedQuery(MyQuery)。list()。get(0);
Transaction t = session.beginTransaction();
session.save(myClass);
t.commit();
我的目标是在表MY_TABLE中现在应该有一条新记录,但插入不会发生,我认为这是由于Hibernate不知道该实例没有被保存在数据库中。
我试图将查询改为:
SELECT NULL ID,DUAL $ b $中的'something'VAL
但是这导致Hibernate没有实例化一个对象。
那么我怎样才能从一个查询中创建一个新的对象实例是否与持久化的类实例关联并使用它来创建持久实例?
/ strong>我测试了以下建议的方法,并且我无法在这个特定场景中使用它,Hibernate希望您为所有属性选择列,而我们绝对不需要该ID。然而,使用 ResultTransformer
确实有效:
16.1.5。返回非托管实体
可以将
ResultTransformer
应用于本机SQL
查询,允许它返回
非托管实体。sess.createSQLQuery(SELECT NAME,BIRTHDATE FROM CATS)
.setResultTransformer(Transformers.aliasToBean(CatDTO.class))
此查询指定:
- SQL查询字符串
- 结果转换器
上面的查询将返回已经实例化的
CatDTO列表,
注入了NAME和$ b $的值b BIRTHNAME到相应的
属性或字段中。
文档提到了返回非托管实体,但它也可以与实体(没有理由不起作用),我可以
请参阅还有
为了清晰起见,我将离开初始答案。 b
也许下面的内容会有所帮助:
16.1.2。实体查询
以上查询都是关于
返回的标量值,基本上是
返回$ b中的原始值$ b结果集。以下显示了如何通过addEntity()
从本地sql
查询中获取
的实体对象。sess.createSQLQuery(SELECT * FROM CATS)。addEntity(Cat.class);
sess.createSQLQuery(SELECT ID,NAME,BIRTHDATE FROM CATS)。addEntity(Cat.class);
此查询指定:
- SQL查询字符串
- 查询返回的实体
假设Cat被映射为类
与列ID,NAME和
的关系BIRTHDATE上述查询都将
返回一个List,其中每个元素都是
Cat实体。
如果实体与
多对一映射到另一个实体,则
也需要
,以便在
执行本地查询,否则
a数据库特定的未找到列
将发生错误。当使用*符号时,额外的
列将自动返回
,但我们
更愿意显式地在
中显式表示,例如多对一到
a Dog:
sess.createSQLQuery(SELECT ID,NAME,BIRTHDATE,DOG_ID FROM CATS)。addEntity(Cat。类);
这将允许
cat.getDog()
但是我认为你不应该设置ID,如果你想保存它并且想要Hibernate执行插入。
I am attempting to create an object in hibernate using a query, which will then be saved back to the table representing the class.
Excerpt from hbm.xml file:
<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>
Code snippet from test case:
MyClass myClass = (MyClass) session.getNamedQuery("myQuery").list().get(0);
Transaction t = session.beginTransaction();
session.save(myClass);
t.commit();
My aim is that there should now be a new record in table MY_TABLE, but the insert does not occur, I assume that this is due the fact that Hibernate does not know that the instance has not been persisted in the db.
I have tried changing the query to read:
SELECT NULL ID, 'something' VAL from DUAL
But this results in Hibernate not instantiating an object.
So how can i create a new object instance from a query that is not associated with a persisted instance of the class and use this to create a persisted instance?
Update: I tested the approach suggested below and I couldn't get it working for this particular scenario, Hibernate expects you to select columns for all attributes while we definitely don't want the id. However, using a ResultTransformer
did work:
16.1.5. Returning non-managed entities
It is possible to apply a
ResultTransformer
to native SQL queries, allowing it to return non-managed entities.sess.createSQLQuery("SELECT NAME, BIRTHDATE FROM CATS") .setResultTransformer(Transformers.aliasToBean(CatDTO.class))
This query specified:
- the SQL query string
- a result transformer
The above query will return a list of CatDTO which has been instantiated and injected the values of NAME and BIRTHNAME into its corresponding properties or fields.
The documentation mentions returning non-managed entities but it also work with an entity (there is no reason it wouldn't work) and I could persist
the transient entity successfully.
See also
I'm leaving the initial answer for clarity sake.
Maybe the following will help:
16.1.2. Entity queries
The above queries were all about returning scalar values, basically returning the "raw" values from the resultset. The following shows how to get entity objects from a native sql query via
addEntity()
.sess.createSQLQuery("SELECT * FROM CATS").addEntity(Cat.class); sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").addEntity(Cat.class);
This query specified:
- the SQL query string
- the entity returned by the query
Assuming that Cat is mapped as a class with the columns ID, NAME and BIRTHDATE the above queries will both return a List where each element is a Cat entity.
If the entity is mapped with a many-to-one to another entity it is required to also return this when performing the native query, otherwise a database specific "column not found" error will occur. The additional columns will automatically be returned when using the * notation, but we prefer to be explicit as in the following example for a many-to-one to a Dog:
sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE, DOG_ID FROM CATS").addEntity(Cat.class);
This will allow
cat.getDog()
to function properly.
But I don't think you should set the ID if you want to save it and want Hibernate to perform an insert.
这篇关于使用sql查询在hibernate中创建一个新的对象实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!