2010-04-26 6 views
2

J'ai besoin d'utiliser une requête SQL native dans Hibernate avec l'utilisation de la variable.Comment utiliser les variables Mysql avec Hibernate?

Mais Mise en veille prolongée renvoie une erreur en disant: l'espace n'est pas autorisé après le préfixe des paramètres

Il y a donc un conflit avec la: = mysql affectation variable et mise en veille prolongée affectation variable.

Voici ma requête SQL:

SET @rank:=0; 
UPDATE Rank SET [email protected]:[email protected]+1 ORDER BY Level; 

le code de mise en veille prolongée (syntaxe JPA):

Query query = em.createNativeQuery(theQuery); 
query.executeUpdate(); 

Je ne peux pas utiliser une procédure stockée parce que ma requête SQL est généré dynamiquement ('Niveau 'peut être' int 'ou' force '...)

Comment est-ce que je peux faire ceci?

grâce

+0

Veuillez ajouter le code Hibernation. –

+0

Je viens de l'ajouter mais c'est un cas très simple commun –

+1

Vous n'êtes pas seul, https://forum.hibernate.org/viewtopic.php?f=1&t=992931&start=0 http: // opensource. atlassian.com/projects/hibernate/browse/HHH-2697 Peut-être avoir une procédure stockée par commande par clause. –

Répondre

4

Eh bien, je enfin utiliser la procédure stockée (oui, ce que je ne veux pas d'abord) à créer une requête dynamique (je ne pense pas que c'était possible).

Voici mon code: La procédure stockée:

DELIMITER | 

DROP PROCEDURE IF EXISTS UpdateRank | 

CREATE PROCEDURE UpdateRank(IN shortcut varchar(30)) 
BEGIN 
    SET @rank=0; 
    SET @query=CONCAT('UPDATE Rank SET ', shortcut, '[email protected]:[email protected]+1 ORDER BY ', shortcut);  

    PREPARE q1 FROM @query; 
    EXECUTE q1; 
    DEALLOCATE PREPARE q1; 
END; 

| 
DELIMITER ; 

La pointe est l'utilisation de la fonction CONCAT pour créer dynamiquement une requête dans la procédure stockée.

Ensuite, appelez la procédure en fonction de mise en veille prolongée classique:

Query q = em.createNativeQuery("CALL updateRank('lvl')"); 
q.executeUpdate(); 
+1

Assurez-vous d'éviter l'injection SQL. –

+0

Oui, vous avez raison, mais je l'ai déjà protégé (mon raccourci est seulement des lettres) –

+1

J'ai trouvé une meilleure approche de ce problème avec Hibernate Interceptor http://stackoverflow.com/questions/9460018/how-can-i -use-mysql-assign-opérateur-dans-hibernate-native-query. Je pense que l'utilisation de procédures stockées est une idée terrible s'il y a une alternative. –

0

Utilisez MySQL Proxy pour réécrire la requête après Hibernate a envoyé la requête à la base de données.

Par exemple l'offre mise en veille prolongée avec cela,

UPDATE Rank SET rank_Level=incr(@rank) ORDER BY Level; 

mais réécrire à cela,

UPDATE Rank SET [email protected]:[email protected]+1 ORDER BY Level; 
+0

C'est un peu compliqué ... –

+0

COMMENT STUPID EST HIBERNATE HUH? – droope

3

Je vais copier coller ma réponse de https://stackoverflow.com/a/25552002/3987202

Une autre solution pour ceux d'entre nous qui ne peuvent pas faire le saut à Hibernate 4.1. 3.
Utilisez simplement /*'*/:=/*'*/ dans la requête. Le code Hibernate traite tout ce qui se trouve entre ' comme une chaîne de caractères (l'ignore). Par contre, MySQL ignorera tout à l'intérieur d'un blockquote et évaluera l'ensemble de l'expression à un opérateur d'assignation.
Je sais que c'est rapide et sale, mais c'est faire le travail sans procédures stockées, intercepteurs, etc.

+0

Ceci l'a fixé pour moi. Merci! –

Questions connexes