La bonne réponse serait d'utiliser l'instruction suivante :
INSERT INTO table (colA, colB) VALUES (?,?) ON DUPLICATE KEY
UPDATE colB = VALUES(colB);
Cependant, le problème apparaît alors que l'hibernation n'a pas reçu de valeur d'auto-incrémentation, une fois l'instruction de mise à jour effectuée.
J'ai trouvé le billet de blog suivant (http://www.jroller.com/mmatthews/entry/ get_hibernate_and_mysql_s ) et a modifié la requête comme suit :
INSERT INTO table (colA, colB) VALUES (?,?) ON DUPLICATE KEY
UPDATE colB = VALUES(colB), id = LAST_INSERT_ID(id);
qui fonctionne enfin.
Un problème insoluble avec cette approche est que l'insertion de deux entités égales dans la même transaction ne fonctionne pas. Même si la deuxième insertion provoquait la mise à jour correcte, l'em se retrouverait avec 2 instances d'entité représentant la même ligne de base de données - ce qui n'est pas autorisé.
Pour résoudre ce problème, il suffit de s'assurer que vous n'insérez pas 2 entités qui sont rendues égales en raison de leurs contraintes. (J'ai utilisé la même logique pour equals/hashcode que la contrainte composite-unique-key, donc je suis capable d'éliminer ces doublons lors de l'exécution d'insertions par lots)