2010-12-10 3 views
1

Article entité est une sous-classe de l'entité Product. La stratégie d'héritage pour eux est joined. Article#flag est un attribut booléen que je veux définir comme faux pour tous les articles. Par conséquent, jeHibernate mise à jour en vrac conduit à en-requête qui prend pour toujours compléter

Query query = entityManager.createQuery("update Article set flag=:flagValue"); 
query.setParameter("flagValue", false); 
query.executeUpdate(); 

Je me attendais cela conduit à une seule instruction SQL sur la base de données qui devrait terminer assez rapidement. Au lieu de cela, Hibernate remplit une table temporaire (qui n'existe pas physiquement dans la base de données) et exécute une requête in-query. la mise à jour plus tard:

insert into HT_article select article0_.id as id from schema.article article0_ inner join schema.product article0_1_ on article0_.id=article0_1_.id 

update schema.article set flag=0 where (id) IN (select id from HT_article) 

La déclaration de mise à jour réelle prend « pour toujours » à remplir et verrouille les articles concernés provoquant ainsi des exceptions de blocage dans d'autres transactions. Pour toujours, je veux dire plus d'une heure pour 130000 articles.

Quelle est l'explication de ce comportement et comment pourrais-je le résoudre? Autre que l'exécution d'une requête native que je veux dire ...

Mise à jour 2011-05-12: il est lent terriblement parce que la requête en est lente, j'ai déposé un bug pour que ->http://opensource.atlassian.com/projects/hibernate/browse/HHH-5905

+0

Il convient de mentionner que aussi 'query = getEntityManager(). CreateQuery ( « mise à jour l'article set flag = false où articleNumber dans (: articleNumbers) "); query.setParameter (" articleNumbers ", articleNumbers);' aboutit au même traitement terriblement lent dans la table HT_article. –

Répondre

0

Parce que vous utilisez InheritanceType.JOINED, Hibernate n'a pas d'autre choix que d'unifier la sous-classe et sa classe de base.

Si vous passez à InheritanceType.TABLE_PER_CLASS (http://openjpa.apache.org/builds/1.0.2/apache-openjpa-1.0.2/docs/manual/jpa_overview_mapping_inher.html), vous éviterez ceci et obtiendrez votre performance retour. Mais je suis sûr que vous utilisez JOINED pour une raison :-(

+0

Je ne comprends pas cette affirmation. Si le 'flag' est un membre de l'article (la sous-classe) et non du produit pourquoi Hibernate devrait-il unifier les classes? Btw, de retour dans Decemeber, j'ai commencé http://lists.jboss.org/pipermail/hibernate-dev/2010-December/005873.html. L'une des réponses pointe vers http://in.relation.to/Bloggers/MultitableBulkOperations et http://in.relation.to/Bloggers/BulkOperations qui expliquent ce qui pourrait se passer dans les coulisses. –

1

J'utilise InheritanceType.JOINED d'hibernate et j'ai rencontré un problème similaire où hibernate s'insérait dans la table temporaire et prenait des âges pour supprimer les entités. en utilisant createQuery et executeUpdate pour supprimer les enregistrements qui ont causé le problème. a commencé à utiliser session.delete(entity) qui a résolu le problème pour moi.

Questions connexes