2010-04-09 3 views
19

J'ai quelques vues sql avec des clés primaires composites que je veux interroger, et comme Hibernate me fait mal à travailler avec des clés composées, j'utilise createSQLQuery. Le problème est que cette méthode peut seulement renvoyer une liste, et j'ai besoin de se référer aux colonnes par leur index.Utilisation de noms de colonnes sql dans hibernate createSQlquery result

Y a-t-il une chance que je puisse faire quelque chose comme jdbc et me référer aux colonnes par leur nom sql au lieu de leur index?

Répondre

46
Query query=session.createSQLQuery("your query"); 
query.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE); 
List<Map<String,Object>> aliasToValueMapList=query.list(); 

Comme vous pouvez le trouver à partir du code, la liste contient des objets de la carte représentant chaque ligne. Chaque objet Map aura le nom de la colonne en tant que clé et la valeur en tant que valeur.

Remarque: Cela fonctionne pour SQLQuery, si vous utilisez AliasToEntityMapResultTransformer sur une requête hql sans spécifier d'alias, vous obtiendrez la valeur d'index en tant que clé.

Si vous transformez à nouveau aliasToValueMapList à votre liste de POJO, je vous conseille de créer votre propre ResultTransformer et retourner votre objet personnalisé de méthode « transformTuple ».

+0

btw, j'ai une requête sql sous la forme "select table1.price as price1 from ..." et pour une raison quelconque, le AliasToEntityMapResultTransformer n'est pas mappage price1. Si je fais "select (table1.prix * 1) comme prix1 à partir de ... "ça fonctionne donc je pense avoir trouvé un bug dans le transformateur .. – Ricardo

+0

N'oubliez pas d'ajouter des déclarations' addScalar' (par exemple 'query.addScalar (" myAlias ​​", IntegerType.INSTANCE) Sinon, vous risquez d'obtenir des alias incorrects (par exemple convertis en majuscules) ou des types de données incorrects –

+0

D'une certaine manière, je dois ajouter cette importation pour que cela fonctionne: import org.hibernate.transform.AliasToEntityMapResultTransformer – ian0411

1

Votre question est ambiguë - dans le premier paragraphe, vous voulez faire référence aux colonnes par index et dans la seconde, par nom de SQL. Puisque l'index est facile, je vais supposer par son nom.

Tout d'abord, vous pouvez utiliser la méthode doWork pour accéder à la connexion JDBC sous-jacente et de traiter comme vous le feriez avec JDBC pur:

session.doWork(new Work() { 
    public void execute(Connection connection) throws SQLException { 
    connection.prepareStatement(... 
    } 
}); 

Ou, vous pouvez utiliser query.getReturnAliases qui retourne une String[] de la colonne des noms. Pour l'effcacité, je construirais probablement un Map d'alias à indexer et alors vous pouvez faire quelque chose comme result[map.get("column name")]. Mais en réalité, Hibernate gère assez facilement les touches composites lors de l'utilisation des mappages xml (pas essayé avec les annotations). C'est un peu plus de travail à l'avance et il y a quelques problèmes avec des relations complexes (principalement lorsque les noms/intervalles de clés étrangers ne correspondent pas), mais une fois que vous créez la classe d'id, vous pouvez la faire avec HQL/Criteria et obtenir tous les avantages de chargement paresseux, jointures simples, la vérification sale, etc.

+0

@Brian, merci! oui, je voulais dire l'accès par nom, pas index;) @Adi, oui, c'est la réponse que je voulais, merci! – Ricardo

1

méthode décrite ci-dessus en commentaire:

query.getReturnAliases() 

ne fonctionne pas pour moi en fait:

Caused by: java.lang.RuntimeException: SQL queries do not currently support returning aliases in query: 
0

j'ai eu le même problème mais résolu quand je l'ai utilisé cette query = session.createSQLQuery ("votre requête"); query.setResultTransformer (AliasToEntityMapResultTransformer.INSTANCE); J'ai obtenu le résultat avec le nom de l'en-tête mais j'ai eu un nouveau problème quand j'ai créé une nouvelle colonne dans sql query Sélectionnez 'DCA5E3' comme Shipmentcolor from Employee.class Mais dans ce cas j'ai obtenu SHIPMENTCOLOR: "D". Comment obtenir la valeur entière de SHIPMENTCOLOR.

Questions connexes