2009-03-02 5 views
1

J'ai la classe suivante défini dans mon fichier XML de mapping:L'utilisation d'un NamedQuery avec une classe composite

<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> 

Je suis en train 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'utilise pour appeler c'est:

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, je reçois ces erreurs dès le "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) 

Une idée sur la façon d'utiliser un NamedQuery avec un composite?

Note: J'ai aussi essayé de faire:

stateQuery.setParameter("primaryKey", primaryKey); 

et il a toujours l'erreur.

Nouveau (édité): Voici le 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: '?' 
+0

Pourriez-vous définir le niveau de débogage des instructions SQL à DEBUG comme expliqué ici: http://www.javalobby.org/java/forums/t44119.html du journal, il est évident que la requête a été construite . Si vous aviez su à quoi cela ressemblait, il pourrait être plus facile de réaliser ce qui s'est passé. –

+0

@Boris - J'ai vu les instructions HQL et SQL produites. Ils ne montrent toujours pas grand-chose pour aider. – Ascalonian

+0

J'ai mis à jour ma réponse. Aussi pour référence future, la requête SQL sans la BNF (les choses entre les [crochets de squre]) devrait être imprimée plus bas dans les journaux. Il est difficile de lire et de déterminer le vrai SQL exécuté sur la base de données quand il est affiché dans le format "arbre" ci-dessus. –

Répondre

1

Pouvez-vous fournir le code SQL qui est généré en activant la journalisation SQL?

Voici un exemple si vous utilisez log4j.properties:

log4j.logger.org.hibernate.SQL = DEBUG

MISE À JOUR # 1

Je ne sais pas pourquoi la La requête existante ne fonctionne pas, mais vous devriez aussi essayer. Pas besoin de mettre à jour un autre code car le passage d'un POJO devrait automatiquement lier les getters aux paramètres nommés.

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

Je l'ai fourni comme un edit à ma question originale – Ascalonian

+0

@matt: Je vais essayer cela aujourd'hui et vous faire savoir comment cela fonctionne. Merci! – Ascalonian

+0

J'ai dû changer le code Java. Au lieu de filter.setProperty(), j'ai enlevé le filtre et ai fait "stateQuery.setProperties (primaryKey)". Merci pour vos conseils. – Ascalonian

0

Y at-il une chance que inCountryCode ou inStateProvince est vide ou nul?

+0

Non, il n'y en a pas. Je m'assure toujours qu'il y a une valeur ici. J'ai également vérifié cela en utilisant Eclipse Debugger. – Ascalonian

Questions connexes