如何使用在 where 子句中具有父属性的休眠查询更新数据
Posted
技术标签:
【中文标题】如何使用在 where 子句中具有父属性的休眠查询更新数据【英文标题】:how to update data using hibernate query having parent property in where clause 【发布时间】:2013-05-08 09:04:59 【问题描述】:我正在使用 hibernate 和 oracle 开发 java web 应用程序。我设置了两个这样的实体
@Entity
public class Student
@Id
Long id;
String name;
@Entity
public class Exam
@Id
Long id;
String status;
@ManyToOne
Student student;
当我像这样在休眠中使用选择查询时
String hql="from Exam exam where exam.student.name=:name"
效果很好 但是当我像这样在休眠中使用更新查询时
String hql="update Exam exam set status=:status where exam.student.name=:name"
它会产生以下错误
org.hibernate.exception.SQLGrammarException: ORA-00971: missing SET keyword
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:122)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at $Proxy154.executeUpdate(Unknown Source)
at org.hibernate.hql.internal.ast.exec.BasicExecutor.execute(BasicExecutor.java:103)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:413)
at org.hibernate.engine.query.spi.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:282)
at org.hibernate.internal.SessionImpl.executeUpdate(SessionImpl.java:1267)
at org.hibernate.internal.QueryImpl.executeUpdate(QueryImpl.java:116)
我做错了吗?
【问题讨论】:
状态字段是否映射到任何东西? 你试过update Exam exam set exam.status=:status where exam.student.name=:name
吗?
没有。它没有映射到任何东西。
sanbhat:是的,我试过了。
【参考方案1】:
检查你是否有 getter 和 setter。
如果名称在数据库中,也使用注释@Column
:
@Entity
public class Student
@Id
Long id;
@Column(name="studentName")
String name;
如果您有一些未映射到数据库表的“标识标志”,请使用@Transient
,这意味着:http://docs.oracle.com/javaee/5/api/javax/persistence/Transient.html
【讨论】:
【参考方案2】:我找到了答案。
根据http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html#batch-direct
不能在批量 HQL 查询中指定隐式或显式连接。子查询可以用在 where 子句中,子查询本身可能包含连接。
所以为了解决我的问题,我将查询更新为
String hql = "update Exam exam set exam.status=:status where exam.id in(select e.id from Exam e where e.student.name=:name)"
【讨论】:
【参考方案3】:获取一个对象并尝试修改它的值并更新它。
Query q = session.createQuery("from Exam exam where exam.student.name=:name");
q.setParameter("name", "xyz");
Exam exam = (Exam)q.list().get(0);
考试。状态(“完成”); session.update(考试);
如果您确定要更新一个且只有一个记录,请使用此选项。否则,您可以根据您的要求使用它来实现
【讨论】:
以上是关于如何使用在 where 子句中具有父属性的休眠查询更新数据的主要内容,如果未能解决你的问题,请参考以下文章
如何合并具有不同 WHERE 子句的两个 SELECT 查询
如何从 Firestore 7.24.0 实例中查询具有多个 where 子句的数据?
如何在子查询的 WHERE 子句中使用来自 UNNEST 的多个值?
使用具有一个条件的 WHERE 子句运行 100 个 SQL 查询,还是使用具有 100 个条件的 WHERE 子句的一个查询更好?