【问题标题】:Using a NamedQuery with a composite class将 NamedQuery 与复合类一起使用
【发布时间】:2009-03-02 15:29:03
【问题描述】:

我在映射 XML 文件中定义了以下类:

<class name="com.data.StateRefData" table="STATE_REF">
   <composite-id name="primaryKey" class="com.data.StateRefPkData">
       <key-property name="countryCode">
           <column name="COUNTRY_CODE"  />
        </key-property>

        <key-property name="state">
            <column name="STATE"  />
        </key-property>
    </composite-id>

   <property name="dialingCode" column="DIALING_CODE"></property>
   <property name="isActive" column="IS_ACTIVE"></property>
   <property name="localeCode" column="LOCALE_CODE"></property>
   <property name="stName" column="ST_NAME"></property>
</class> 

我正在尝试为此类定义一个 NameQuery。我尝试的是:

<query name="findState">
    <![CDATA[ from
      com.data.StateRefData
        WHERE primaryKey = :primaryKey
    ]]>
 </query> 

我用来调用它的 Java 代码是:

Query stateQuery = null;
List<StateRefData> stateList = null;
StateRefPkData primaryKey = new StateRefPkData();
StateRefData filter = new StateRefData();

primaryKey.setCountryCode(inCountryCode);
primaryKey.setState(inStateProvince);
filter.setPrimaryKey(primaryKey);

stateQuery = session.getNamedQuery("findState");
stateQuery.setProperties(filter);

但是,我在“stateQuery.list()”部分得到了这些错误:

[ERROR JDBCExceptionReporter:72] Line 1: Incorrect syntax near ','.
org.hibernate.exception.SQLGrammarException: could not execute query

        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:59)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.loader.Loader.doList(Loader.java:1596)
   at org.hibernate.loader.Loader.list(Loader.java:1577)
   at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:395)
   at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:271)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:844)
   at org.hibernate.impl.QueryImpl.list(QueryImpl.java:74) 

知道如何将 NamedQuery 与复合材料一起使用吗?

注意:我也试过这样做:

stateQuery.setParameter("primaryKey", primaryKey);

它仍然有错误。

新(编辑): 这是我执行代码时发生的 HQL 和 SQL:

[DEBUG AST:223] --- HQL AST ---
 \-[QUERY] 'query'
    +-[SELECT_FROM] 'SELECT_FROM'
    |  \-[FROM] 'from'
    |     \-[RANGE] 'RANGE'
    |        +-[DOT] '.'
    |        |  +-[DOT] '.'
    |        |  |  +-[DOT] '.'
    |        |  |  |  +-[DOT] '.'
    |        |  |  |  |  +-[IDENT] 'com'
    |        |  |  \-[IDENT] 'data'
    |        |  \-[IDENT] 'StateRefData'
    |        \-[ALIAS] 'd'
    \-[WHERE] 'WHERE'
       \-[EQ] '='
          +-[DOT] '.'
          |  +-[IDENT] 'd'
          |  \-[IDENT] 'primaryKey'
          \-[COLON] ':'
             \-[IDENT] 'primaryKey'

[DEBUG AST:193] --- SQL AST ---
 \-[SELECT] QueryNode: 'SELECT'  querySpaces (STATE_REF)
    +-[SELECT_CLAUSE] SelectClause: '{derived select clause}'
    |  +-[SELECT_EXPR] SelectExpressionImpl: 'statere0_.COUNTRY_CODE as COUNTRY1_, statere0_.STATE as STATE' {FromElement{explicit,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=d,role=null,tableName=STATE_REF,tableAlias=statere0_,colums={,className=com.data.StateRefData}}}
    |  \-[SQL_TOKEN] SqlFragment: 'statere0_.DIALING_CODE as DIALING3_60_, statere0_.IS_ACTIVE as IS4_60_, statere0_.LOCALE_CODE as LOCALE5_60_, statere0_.ST_NAME as ST6_60_'
    +-[FROM] FromClause: 'from' FromClause{level=1, fromElementCounter=1, fromElements=1, fromElementByClassAlias=[d], fromElementByTableAlias=[statere0_], fromElementsByPath=[], collectionJoinFromElementsByPath=[], impliedElements=[]}
    |  \-[FROM_FRAGMENT] FromElement: 'STATE_REF statere0_' FromElement{explicit,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=d,role=null,tableName=STATE_REF,tableAlias=statere0_,colums={,className=com.data.StateRefData}}
    \-[WHERE] SqlNode: 'WHERE'
       \-[EQ] SqlNode: '='
          +-[DOT] DotNode: '(statere0_.COUNTRY_CODE, statere0_.STATE)' {propertyName=primaryKey,dereferenceType=2,propertyPath=primaryKey,path=d.primaryKey,tableAlias=statere0_,className=com.data.StateRefData,classAlias=d}
          |  +-[ALIAS_REF] IdentNode: '(statere0_.COUNTRY_CODE, statere0_.STATE)' {alias=d, className=com.data.StateRefData, tableAlias=statere0_}
          |  \-[IDENT] IdentNode: 'primaryKey' {originalText=primaryKey}
          \-[NAMED_PARAM] SqlNode: '?' 

【问题讨论】:

  • 您能否将sql语句的调试级别设置为DEBUG,如下所述:javalobby.org/java/forums/t44119.html 从日志中可以明显看出查询已构建。如果您知道它的外观,就会更容易意识到出了什么问题
  • @Boris - 我查看了生成的 HQL 和 SQL 语句。他们仍然没有提供太多帮助。
  • 我已经更新了我的答案。同样为了将来参考,不带 BNF 的 SQL 查询([方括号]之间的东西)应该在日志中进一步打印。当数据库以上面的“树”格式显示时,很难读取和确定对数据库运行的真实 SQL。
  • @matt:抱歉,log4j 就是这样显示的。所以我只是在这里复制/粘贴。

标签: java hibernate


【解决方案1】:

能否提供开启 SQL 日志记录生成的 SQL 代码?

如果您使用的是 log4j.properties,这里是一个示例:

log4j.logger.org.hibernate.SQL=DEBUG

更新 #1

我不确定为什么现有查询不起作用,但您也应该尝试一下。无需更新任何其他代码,因为传递 POJO 应该会自动将 getter 绑定到命名参数。

<query name="findState">
    <![CDATA[ from
      com.data.StateRefData
        WHERE primaryKey.countryCode = :countryCode AND primaryKey.state = :state
    ]]>
</query>

【讨论】:

  • @matt:我今天会试试这个,让你知道它是如何工作的。谢谢!
  • 我确实不得不更改一些 Java 代码。而不是 filter.setProperty(),我删除了过滤器并做了“stateQuery.setProperties(primaryKey)”。感谢您的指导。
【解决方案2】:

inCountryCode 或 inStateProvince 是否有可能为空或 null?

【讨论】:

  • 不,没有。我总是确保这里有一个价值。我还使用 Eclipse Debugger 仔细检查了这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-24
相关资源
最近更新 更多