【问题标题】:HibernateException: Errors in named queryHibernateException:命名查询中的错误
【发布时间】:2013-05-07 17:33:27
【问题描述】:

在运行特定的单元测试时,我遇到了异常:

Caused by: org.hibernate.HibernateException: Errors in named queries: UPDATE_NEXT_FIRE_TIME
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:437)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:891)
... 44 more

对于此处定义的命名查询:

@Entity(name="fireTime")
@Table(name="qrtz_triggers")
@NamedQueries({
@NamedQuery(
        name="UPDATE_NEXT_FIRE_TIME",
        query= "update fireTime t set t.next_fire_time = :epochTime where t.trigger_name = 'CalculationTrigger'")
})
public class JpaFireTimeUpdaterImpl implements FireTimeUpdater {

@Id
@Column(name="next_fire_time", insertable=true, updatable=true)
private long epochTime;

public JpaFireTimeUpdaterImpl() {}

public JpaFireTimeUpdaterImpl(final long epochTime) {
    this.epochTime = epochTime;
}

@Override
public long getEpochTime() {
    return this.epochTime;
}

public void setEpochTime(final long epochTime) {
    this.epochTime = epochTime;
}

}

经过尽可能深入的调试,发现异常发生在QueryTranslatorImpl中的w.statement(hqlAst)中:

    private HqlSqlWalker analyze(HqlParser parser, String collectionRole) throws QueryException, RecognitionException {
    HqlSqlWalker w = new HqlSqlWalker( this, factory, parser, tokenReplacements, collectionRole );
    AST hqlAst = parser.getAST();

    // Transform the tree.
    w.statement( hqlAst );

    if ( AST_LOG.isDebugEnabled() ) {
        ASTPrinter printer = new ASTPrinter( SqlTokenTypes.class );
        AST_LOG.debug( printer.showAsString( w.getAST(), "--- SQL AST ---" ) );
    }

    w.getParseErrorHandler().throwQueryException();

    return w;
}

我的查询或注释有问题吗?

【问题讨论】:

    标签: sql hibernate annotations hibernateexception


    【解决方案1】:

    NamedQuery 应该使用 JPQL 编写,但查询似乎混合了持久属性的名称和数据库列的名称。 JPQL 中不能使用数据库列的名称。

    在这种情况下,应该使用持久属性 epochTime 的名称而不是 next_fire_timetrigger_name 看起来更像是数据库列的名称而不是持久属性的名称,但它似乎根本没有映射到您当前的类中。映射后查询如下:

    update fireTime t set t.epochTime = :epochTime 
    where t.triggerName = 'CalculationTrigger'
    

    如果首选 SQL 查询,则应使用 @NamedNativeQuery

    附带说明,JPA 2.0 规范不鼓励更改主键:

    应用程序不得更改主键的值[10]。这 如果发生这种情况,行为是不确定的。[11]

    一般实体不知道通过 JPQL 查询所做的更改。这在尝试刷新不再存在的实体时变得特别有趣(因为主键已更改)。

    另外命名有点混乱:

    1. 类的名称看起来更像服务类的名称 而不是实体的名称。
    2. 实体的起始名称 大写字母是比较少见的风格。
    3. 实体名称,名称 表和类名不太匹配。

    【讨论】:

      猜你喜欢
      • 2015-06-03
      • 2010-12-24
      • 2015-05-10
      • 2019-01-14
      • 2014-07-02
      • 2015-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多