java 如何让休眠打印出命名查询有什么问题?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12004365/
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
How to get hibernate to print out whats wrong with a named query?
提问by ams
In my Spring / Hibernate / JPA application I use a lot of named queries and when I have a typo in one of those queries the see errors in my application start-up log file similar to the one below.
在我的 Spring / Hibernate / JPA 应用程序中,我使用了很多命名查询,当我在其中一个查询中出现拼写错误时,会在我的应用程序启动日志文件中看到类似于下面的错误。
Caused by: org.hibernate.HibernateException: Errors in named queries: FindAllCompanyFileTypes
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:426)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1872)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:906)
... 70 more
How do configure hibernate to print out what is wrong with the named query and not just the named query has an error?
如何配置休眠以打印出命名查询有什么问题,而不仅仅是命名查询有错误?
UPDATEfor example the JPA query SELECT f FROM Foo WHERE f.v := true
will fail with hibernate complaining that the query is invalid. Hibernate has not even tried to generate SQL from it, the query is not correct JPQL. What I want to know is how to get hibernate to say the query is wrong because := was used instead of = ? not sure if this is a setting that can be turned on in hibernate or not.
UPDATE例如 JPA 查询SELECT f FROM Foo WHERE f.v := true
将失败,休眠抱怨查询无效。Hibernate 甚至没有尝试从中生成 SQL,查询是不正确的 JPQL。我想知道的是如何让 hibernate 说查询是错误的,因为 := 被使用而不是 = ?不确定这是否是可以在休眠状态下打开的设置。
回答by Xtreme Biker
Hibernate custom query loader stuff is located into org.hibernate.loader.custom.sql
(for Hibernate 3 and seems that Hibernate 4 too). If using log4j, it's only a matter of setting this package its own categoryin order to get the logs printed (I recommend you to use the file appender because the afterwards error logs can overlap what you're interested in if using console appender).
Hibernate 自定义查询加载器的内容位于org.hibernate.loader.custom.sql
(对于 Hibernate 3 和Hibernate 4似乎也是)。如果使用log4j,只需将此包设置为自己的类别即可打印日志(我建议您使用文件附加程序,因为如果使用控制台附加程序,之后的错误日志可能会与您感兴趣的内容重叠)。
<category name="org.hibernate.loader.custom.sql" additivity="false">
<priority value="trace" />
<appender-ref ref="fileAppender" />
</category>
Supposing your root logger displays every error in file, that's the output you get for an error while query loading:
假设您的根记录器显示文件中的每个错误,这就是您在查询加载时获得的错误输出:
17:27:18,348 TRACE SQLCustomQuery:85 - starting processing of sql query [SELECT equipment.*, det.*
FROM tdetectable_equipment equipment JOIN
tdetectable det
ON det.id = equipment.id_detectable
WHERE
equipment.id_detectable=det.id and det.active=1 and
equipment.id_warehouse_container = :_Id]
17:27:18,358 TRACE SQLCustomQuery:85 - starting processing of sql query [select line.* from tpacking_slip_line line join tpacking_slip slip on line.id_packing_slip = slip.id where line.id_detectable = :detectableId and line.id_related_packing_slip_line is null and slip.`type`= :slipType order by slip.date desc;]
17:27:18,359 TRACE SQLQueryReturnProcessor:387 - mapping alias [line] to entity-suffix [0_]
17:27:18,364 TRACE SQLCustomQuery:85 - starting processing of sql query [select res.* from tdetectable det join tpacking_slip_line line on det.id=line.id_detectable and line.id_related_packing_slip_line is null join tpacking_slip slip on line.id_packing_slip = slip.id and slip.`type`='OUT' join vreservation res on slip.id_reservation=res.id where det.id in ( :detIds ) group by(res.id) order by count(res.id) desc;]
17:27:18,365 TRACE SQLQueryReturnProcessor:387 - mapping alias [res] to entity-suffix [0_]
17:27:18,368 ERROR SessionFactoryImpl:424 - Error in named query: equipmentWarehouseQuery
org.hibernate.MappingException: Unknown collection role: com.mycompany.model.container.Container.detectables
at org.hibernate.impl.SessionFactoryImpl.getCollectionPersister(SessionFactoryImpl.java:701)
at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.addCollection(SQLQueryReturnProcessor.java:393)
at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.processCollectionReturn(SQLQueryReturnProcessor.java:428)
at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.processReturn(SQLQueryReturnProcessor.java:358)
at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.process(SQLQueryReturnProcessor.java:171)
at org.hibernate.loader.custom.sql.SQLCustomQuery.<init>(SQLCustomQuery.java:87)
at org.hibernate.engine.query.NativeSQLQueryPlan.<init>(NativeSQLQueryPlan.java:67)
at org.hibernate.engine.query.QueryPlanCache.getNativeSQLQueryPlan(QueryPlanCache.java:166)
at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:589)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:413)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1872)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:863)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:782)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:188)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1541)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1479)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
That exception is being raised at loading time, but you can also have query errors while executing your code. In that case an HibernateExceptionor similar is thrown, which you can inspect later. For the case of missing colon it is actually an IllegalArgumentExceptionthrown by AbstractQueryImplclass:
该异常是在加载时引发的,但在执行代码时也可能出现查询错误。在这种情况下,会抛出HibernateException或类似的异常,您可以稍后对其进行检查。对于缺少冒号的情况,它实际上是AbstractQueryImpl类抛出的IllegalArgumentException:
java.lang.IllegalArgumentException: No positional parameters in query: SELECT equipment.*, det.*
FROM tdetectable_equipment equipment JOIN
tdetectable det
ON det.id = equipment.id_detectable
WHERE
equipment.id_detectable=det.id and det.active=1 and
equipment.id_container = _Id
回答by colin
I was working on a similar problem and I discovered that, if you're using Spring Data JPA, you can use @Query in the DAO interface instead of @NamedQuery in the entity object and you get a much more detailed error message. So, instead of:
我正在研究一个类似的问题,我发现,如果您使用的是 Spring Data JPA,则可以在 DAO 接口中使用 @Query 而不是实体对象中的 @NamedQuery,并且您会得到更详细的错误消息。所以,而不是:
@Entity
@Table
@NamedQueries({@NamedQuery(name="MyEntity.myQuery" query="select blah blah blah")})
public class MyEntity
{
...
}
you would say
你会说
@Entity
@Table
public class MyEntity
{
...
}
public interface MyEntityDao
extends JpaRepository...
{
@Query("select blah blah blah")
MyEntity findByMyQuery();
}
This uses the same query language and expressions but, for whatever quirk of implementation, delivers a much more expressive error message.
这使用相同的查询语言和表达式,但是,无论实现方式如何,都会提供更具表现力的错误消息。
回答by Vivek
You can try to print the HSQL by setting the
您可以尝试通过设置
<property name="show_sql">true</property>
then add proper log levels in log4j to display the DEBUG or TRACE level logging for org.hibernate.*
然后在 log4j 中添加适当的日志级别以显示 org.hibernate.* 的调试或跟踪级别日志记录
more info here: http://docs.jboss.org/hibernate/core/3.5/reference/en/html/session-configuration.html#configuration-logging
更多信息:http: //docs.jboss.org/hibernate/core/3.5/reference/en/html/session-configuration.html#configuration-logging
回答by JoeG
If I take a guess at what you are asking, I don't think it is hibernate that can tell you what is wrong. The only way I have had success with this is rather painful, but at least it works!
如果我猜测您在问什么,我认为休眠不能告诉您出了什么问题。我成功的唯一方法是相当痛苦,但至少它有效!
So you need the database itself to tell you what is wrong with the query. To do this you enable the sql output from hibernate as described above. Then you connect to the DB via your favorite tool: squirrelSQL, toad, eclipse-plugin, etc. Now if you don't have parameters in your sql, then you just cut and paste in there, execute the sql and it should help you debug.
因此,您需要数据库本身来告诉您查询出了什么问题。要做到这一点,您可以如上所述启用 hibernate 的 sql 输出。然后你通过你最喜欢的工具连接到数据库:squirrelSQL、toad、eclipse-plugin 等。 现在如果你的 sql 中没有参数,那么你只需在那里剪切和粘贴,执行 sql,它应该会帮助你调试。
If you do have parameters, the process is the same, just way more tedious! However, once you have the SQL ok, the database should tell you what it doesn't like. On most occasions, once you know this, it will be clear what you need to change on the hibernate side. Every now and then it can be a mystery though, but most of those cases are documented out here!
如果你有参数,过程是一样的,只是更乏味!但是,一旦您的 SQL 没有问题,数据库就会告诉您它不喜欢什么。在大多数情况下,一旦你知道了这一点,你就会清楚在休眠端需要改变什么。虽然时不时它可能是个谜,但大多数案例都记录在此处!