Article
entity is a sub-class of the Product
entity. The inheritance strategy for them is joined
. Article#flag
is a boolean attribute which I want to set false for all articles. Hence, I do
Query query = entityManager.createQuery("update Article set flag=:flagValue");
query.setParameter("flagValue", false);
query.executeUpdate();
I expected this to lead to a single SQL statement against the database which should complete fairly quickly. Instead Hibernate populates a temporary table (which does not physically exist in the database) and runs an in-query ie. the update later:
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)
The actual update statement takes "forever" to complete and locks the affected articles thereby causing lock exceptions in other transactions. By forever I mean more than an开发者_运维技巧 hour for 130000 articles.
What's the explanation for this behavior and how could I solve it? Other than running a native query I mean...
Update 2011-05-12: it's terribly slow because the in-query is slow, I filed a bug for that -> http://opensource.atlassian.com/projects/hibernate/browse/HHH-5905
I am using InheritanceType.JOINED
of hibernate and faced a similar issue where hibernate was inserting into the temp table and was taking ages to delete the entities. I was using createQuery
and executeUpdate
to delete the records which caused the issue.
Started using session.delete(entity)
which solved the issue for me.
Because you're using InheritanceType.JOINED
, Hibernate has no choice but to unify the subclass and its base class.
If you switched to InheritanceType.TABLE_PER_CLASS
(http://openjpa.apache.org/builds/1.0.2/apache-openjpa-1.0.2/docs/manual/jpa_overview_mapping_inher.html) you'd avoid this and get your performance back. But I'm sure you're using JOINED
for a reason :-(
精彩评论