java - 如何让 hibernate 打印出命名查询有什么问题?

标签 java spring hibernate jpa

在我的 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

如何配置 hibernate 以打印出命名查询的错误,而不仅仅是命名查询有错误?

UPDATE 例如 JPA 查询 SELECT f FROM Foo WHERE f.v := true 将失败,hibernate 会提示查询无效。 Hibernate 甚至没有尝试从中生成 SQL,查询是不正确的 JPQL。我想知道的是如何让 hibernate 状态说查询是错误的,因为使用了 := 而不是 = ?不确定这是否是可以在 hibernate 状态下打开的设置。

最佳答案

Hibernate 自定义查询加载程序位于 org.hibernate.loader.custom.sql(对于 Hibernate 3,似乎是 Hibernate 4 too)。如果使用 log4j , 这只是设置这个包的问题 its own category为了打印日志(我建议您使用文件附加程序,因为如果使用控制台附加程序,之后的错误日志可能会与您感兴趣的内容重叠)。

<category name="org.hibernate.loader.custom.sql" additivity="false">
    <priority value="trace" />
    <appender-ref ref="fileAppender" />
</category>

假设您的根记录器显示文件中的每个错误,这就是您在查询加载时获得的错误输出:

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)

该异常是在加载时引发的,但您在执行代码时也可能遇到查询错误。在那种情况下 HibernateException或类似的东西被抛出,你可以稍后检查。对于缺少冒号的情况,它实际上是一个 IllegalArgumentExceptionAbstractQueryImpl 抛出类:

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

关于java - 如何让 hibernate 打印出命名查询有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12004365/

相关文章:

java - Spring-Data-JPA - 查询返回 null - EmbeddedId

java - Spring集成中使用Hibernate触发事件

java - 如何将 YAML 配置映射到具有类对象的 POJO

java - Powermock ExceptionInInitializerError 与 Junit

java - 添加第二个 '$or' 表达式失败

java - Spring Thymeleaf Hibernate 验证自定义消息在页面上不可用

spring - 使用 Spring Boot 的 starter web parent 时出现 Invalid packaging 错误

java - 检查数据库中重复记录的最佳方法| hibernate

java - 在 Android 阅读器应用程序中利用 WordPress API

java - Scalatra 独立部署时找不到 View