web-dev-qa-db-fra.com

Hibernate: impossible d'exécuter une requête native de manipulation en bloc

J'ai eu cette erreur en essayant de mettre à jour des données en utilisant le SQL natif. Ceci est mon script:

update weight_note_receipt set pledge_id =:pledge  where wn_id in (:wns)

wns est la chaîne qui contient plus de 1 wn_id comme ceci:

222,226,228,251,256,262,263,264,265,266,267,272,281,286,294,296,299,301,302,303,306,307,330,332,333,337,338,339,341,368,371,376,377,378,379,380,381,385,391,397,423,424,443,452,454,461,462,463,464,490,503,504,521,525,528,529,530,532,533,549,554,560,561,564,565,566,567,569,570,595,598,600,603,605,606,607,644,646,649,653,661,662,663,667,669,678,683,752,1039,1075,258,259,260,261,268,269,270,287,304,305,308,325,334,604,643,647,648,659,660,664,665,666,704,709,753,754,757,758,809,834,846,861,872,879,882,911,913,916,919,920,164

Lorsque je mets à jour (en utilisant query.executeUpdate()), l'erreur suivante est générée:

Le traitement de la demande a échoué. L'exception imbriquée est org.hibernate.exception.DataException: impossible d'exécuter la requête de manipulation en bloc native avec la cause racine com.mysql.jdbc.MysqlDataTruncation: Troncation de données: Troncée valeur DOUBLE incorrecte: '222,226,228,251,256,262,263,264,265,266,267,272,286,294,296,299,301,302,303,306,307,332,333,337,338,339,341,368,371,376,'

Est-ce parce que la chaîne d'entrée est trop longue?

5
Kien Dang Ngoc

Lorsque vous avez des requêtes paramétrées dans des bases de données (instructions préparées), l'attribution de valeurs aux paramètres NE DOIT PAS changer la structure et le chemin d'exécution de la requête (sinon les bases de données ne les traitent pas comme des requêtes paramétrées et génèrent une exception).

C'est pourquoi vous ne pouvez pas avoir d'instructions préparées pour des requêtes telles que:

  • select * from myTable order by ?
  • select id, f1, ? from myTable
  • select * from ?.

parce que l'attribution d'une valeur à chaque paramètre modifie le chemin d'exécution de la requête (rappelez-vous que la requête des instructions préparées est analysée une fois et qu'il en résulte un seul chemin d'exécution).

Les mêmes règles s'appliquent à l'analyseur de requête Hibernate, vous ne devez pas attribuer à un paramètre une valeur qui modifie la structure de la requête.

L'attribution d'une chaîne avec les valeurs 1, 2, 3 à un paramètre SHOULD-TO-BE-A-NUMBER est identique, en fait, la première requête sera traduite de la même manière que update weight_note_receipt set pledge_id =:pledge where wn_id = :wns, mais la seconde sera traduite par update weight_note_receipt set pledge_id =:pledge where (wn_id = :x1 or wn_id = :x2 or wn_id = :x3), des requêtes évidemment différentes avec différents chemins d'exécution.

Donc, même si Hibernate ne lançait pas d'exception, votre base de données le ferait.

10
Amir Pashazadeh

Si vous utilisez l'API SQLQuery Hibernate, vous pouvez utiliser la méthode setParameterList(PARAM, COLLECTION).

Votre chaîne de requête peut rester la même avec sa clause in et ses accolades.

2
Karthikeyan M

Si le client envoie des données dont la taille est supérieure à celle spécifiée dans la base de données, il envoie alors org.hibernate.exception.GenericJDBCException: impossible d'exécuter une requête de manipulation en bloc native à org.hibernate.exception.SQLStateConverter.handledNonSpecificException ..

0
Biswajit Sahu