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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 07:13:51  来源:igfitidea点击:

How to get hibernate to print out whats wrong with a named query?

javaspringhibernatejpa

提问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 := truewill 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 没有问题,数据库就会告诉您它不喜欢什么。在大多数情况下,一旦你知道了这一点,你就会清楚在休眠端需要改变什么。虽然时不时它可能是个谜,但大多数案例都记录在此处!