Utilisation d'une requête nommée avec une classe composite
Question
La classe suivante est définie dans mon fichier XML de mappage:
<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>
J'essaie de définir un NameQuery pour cette classe. Ce que j'ai essayé était:
<query name="findState">
<![CDATA[ from
com.data.StateRefData
WHERE primaryKey = :primaryKey
]]>
</query>
Le code Java que j'appelle est le suivant:
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);
Cependant, ces erreurs se produisent directement à l’emplacement "stateQuery.list ()". partie:
[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)
Avez-vous une idée de la façon d'utiliser une requête nommée avec un composite?
Remarque: j'ai également essayé de faire:
stateQuery.setParameter("primaryKey", primaryKey);
et il a toujours l'erreur.
Nouveau (modifié): Voici le code HQL et SQL qui se produit lorsque j'exécute le code:
[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: '?'
La solution
Pouvez-vous fournir le code SQL généré en activant la journalisation SQL?
Voici un exemple si vous utilisiez log4j.properties:
log4j.logger.org.hibernate.SQL = DEBUG
UPDATE # 1
Je ne sais pas pourquoi la requête existante ne fonctionne pas, mais vous devriez également essayer. Il n'est pas nécessaire de mettre à jour tout autre code, car le passage d'un POJO devrait automatiquement lier les accesseurs aux paramètres nommés.
<query name="findState">
<![CDATA[ from
com.data.StateRefData
WHERE primaryKey.countryCode = :countryCode AND primaryKey.state = :state
]]>
</query>
Autres conseils
Existe-t-il une chance que inCountryCode ou inStateProvince soit vide ou nul?