java 使用 sql 查询在休眠中创建一个新的对象实例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3266492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 01:04:11  来源:igfitidea点击:

Creating a new object instance in hibernate using a sql query

javahibernateorm

提问by stjohnroe

I am attempting to create an object in hibernate using a query, which will then be saved back to the table representing the class.

我正在尝试使用查询在 hibernate 中创建一个对象,然后将其保存回表示该类的表中。

Excerpt from hbm.xml file:

摘自 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>

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.

我的目标是现在表 MY_TABLE 中应该有一个新记录,但不会发生插入,我认为这是由于 Hibernate 不知道该实例尚未保存在数据库中的事实。

I have tried changing the query to read:

我尝试将查询更改为:

SELECT NULL ID, 'something' VAL from DUAL

But this results in Hibernate not instantiating an object.

但这会导致 Hibernate 没有实例化一个对象。

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?

那么如何从与类的持久化实例无关的查询创建一个新的对象实例,并使用它来创建一个持久化实例呢?

回答by Pascal Thivent

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 ResultTransformerdid work:

更新:我测试了下面建议的方法,但我无法让它适用于这个特定场景,Hibernate 期望您为所有属性选择列,而我们绝对不想要 id。但是,使用ResultTransformer确实有效:

16.1.5. Returning non-managed entities

It is possible to apply a ResultTransformerto 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.

16.1.5. 返回非托管实体

可以将 a ResultTransformer应用于本机 SQL 查询,允许它返回非托管实体。

sess.createSQLQuery("SELECT NAME, BIRTHDATE FROM CATS")
        .setResultTransformer(Transformers.aliasToBean(CatDTO.class))

此查询指定:

  • SQL 查询字符串
  • 结果转换器

上述查询将返回已实例化的 CatDTO 列表,并将 NAME 和 BIRTHNAME 的值注入到其相应的属性或字段中。

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 persistthe transient entity successfully.

文档提到返回非托管实体,但它也可以与实体一起使用(没有理由它不起作用),我可以persist成功地创建临时实体。

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.

16.1.2. 实体查询

上面的查询都是关于返回标量值,基本上是从结果集中返回“原始”值。下面展示了如何通过addEntity().

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 实体。

如果实体通过多对一映射到另一个实体,则在执行本机查询时也需要返回此信息,否则将发生数据库特定的“未找到列”错误。使用 * 表示法时,额外的列将自动返回,但我们更愿意像以下示例中的多对一到狗一样明确:

sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE, DOG_ID FROM CATS").addEntity(Cat.class);

这将允许cat.getDog()正常运行。

But I don't think you should set the ID if you want to save it and want Hibernate to perform an insert.

但是我认为如果您想保存 ID 并希望 Hibernate 执行插入操作,则不应该设置 ID。