HQL多参数更新语句报错:QuerySyntaxException,期望EOF却发现逗号
HQL多参数更新抛出QuerySyntaxException异常(expecting EOF, found ',')
在使用Hibernate执行HQL多参数更新操作时,意图根据旧参数匹配数据并更新多个字段,却抛出org.hibernate.hql.internal.ast.QuerySyntaxException异常,提示expecting EOF, found ','。以下为相关配置、代码、运行日志,已尝试相关方案仍未解决:
相关配置文件
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/database</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <property name="current_session_context_class">thread</property> <property name="show_sql">true</property> <property name="connection.pool_size">4</property> </session-factory> </hibernate-configuration>
Hibernate代码
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.query.Query; servlet method { SessionFactory factory = new Configuration() .configure("hibernate.cfg.xml") .addAnnotatedClass(BollyWood.class) .addAnnotatedClass(HollyWood.class) .buildSessionFactory(); Session se = factory.getCurrentSession(); try { se.beginTransaction(); String query1 = "update hollywood set " + "name = :m_name ," + "timing = :m_timing ," + "price = :m_price " + "where name = :mname ," + "timing = :mtiming ," + "price = :mprice"; // Generating error for `,` separating different parameters Query query = se.createQuery(query1); query.setParameter("m_name", m_name); query.setParameter("m_timing", m_timing); query.setParameter("m_price", m_price); query.setParameter("mname", mname); query.setParameter("mtiming", mtiming); query.setParameter("mprice", mprice); query.executeUpdate(); } catch (Exception e) { System.out.println(e); } finally { se.close(); factory.close(); } }
运行日志
18-Mar-2023 19:28:37.722 INFO [http-nio-18080-exec-9] org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.stop HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost:3306/database] 18-Mar-2023 19:29:09.594 WARN [http-nio-18080-exec-8] org.hibernate.boot.jaxb.internal.stax.LocalXmlResourceResolver.resolveEntity HHH90000012: Recognized obsolete hibernate namespace http://hibernate.sourceforge.net/hibernate-configuration. Use namespace http://www.hibernate.org/dtd/hibernate-configuration instead. Support for obsolete DTD/XSD namespaces may be removed at any time. 18-Mar-2023 19:29:09.674 WARN [http-nio-18080-exec-8] org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure HHH10001002: Using Hibernate built-in connection pool (not for production use!) 18-Mar-2023 19:29:09.674 INFO [http-nio-18080-exec-8] org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildCreator HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/database] 18-Mar-2023 19:29:09.675 INFO [http-nio-18080-exec-8] org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildCreator HHH10001001: Connection properties: {user=root, password=****} 18-Mar-2023 19:29:09.675 INFO [http-nio-18080-exec-8] org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildCreator HHH10001003: Autocommit mode: false 18-Mar-2023 19:29:09.676 INFO [http-nio-18080-exec-8] org.hibernate.engine.jdbc.connections.internal.PooledConnections.<init> HHH000115: Hibernate connection pool size: 4 (min=1) 18-Mar-2023 19:29:09.684 INFO [http-nio-18080-exec-8] org.hibernate.dialect.Dialect.<init> HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect 18-Mar-2023 19:29:09.740 INFO [http-nio-18080-exec-8] org.hibernate.hql.internal.QueryTranslatorFactoryInitiator.initiateService HHH000397: Using ASTQueryTranslatorFactory 18-Mar-2023 19:29:09.746 ERROR [http-nio-18080-exec-8] org.hibernate.hql.internal.ast.ErrorCounter.reportError line 1:95: expecting EOF, found ',' 18-Mar-2023 19:29:09.746 ERROR [http-nio-18080-exec-8] org.hibernate.hql.internal.ast.ErrorCounter.reportError line 1:95: expecting EOF, found ',' line 1:95: expecting EOF, found ',' java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: expecting EOF, found ',' near line 1, column 95 [update hollywood set name = :m_name ,timing = :m_timing ,price = :m_price where name = :mname ,timing = :mtiming ,price = :mprice] at antlr.Parser.match(Parser.java:211) at org.hibernate.hql.internal.antlr.HqlBaseParser.statement(HqlBaseParser.java:215) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:284) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:186) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141) at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77) at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153) at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:553) at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:662) at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:103) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:355) at com.sun.proxy.$Proxy31.createQuery(Unknown Source) at com.example.AdminChangeServlet.doGet(AdminChangeServlet.java:61) at javax.servlet.http.HttpServlet.service(HttpServlet.java:670) at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:750) 18-Mar-2023 19:29:09.838 INFO [http-nio-18080-exec-8] org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.stop HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost:3306/database]
使用的Jar包
- hibernate-search-5.8.0.Final
- mysql-connector-java-5.1.14
已尝试的方案
- 参考多列更新的Hibernate Query相关解决方案
- 参考QuerySyntaxException异常排查相关方案
问题解决
报错的核心原因是HQL的WHERE子句中错误地使用逗号分隔查询条件,HQL语法要求WHERE子句的多个条件必须用逻辑运算符AND或OR连接,而非逗号。
修改后的HQL语句如下:
String query1 = "update hollywood set " + "name = :m_name ," + "timing = :m_timing ," + "price = :m_price " + "where name = :mname AND " + "timing = :mtiming AND " + "price = :mprice";
另外需要注意:HQL中更新的实体名称需要与映射的Java类名一致(如果你的实体类是HollyWood,首字母大写,那么HQL中应该使用HollyWood而非hollywood,这是潜在的语法问题,但当前报错由逗号导致)。
内容的提问来源于stack exchange,提问作者Aniket
相关产品推荐
相关产品推荐

