I was using HQL DML to delete entities in batch, but noticed the longer the process ran, the # of entities I was deleting per second was decreasing. When I dumped the stack, was always in MySQL transmission, not in hibernate code. When I enabled SQL dumps, I saw sql from previously deleted entities being re-fired, which explained the exponential slowdown of my application. I traced it to code that is invoked when a BulkIdStrategy is required. In my case, I'm using InlineIdsInClauseBulkIdStrategy and had a joined inheritance mapping requiring multiple deletes from child tables. It appears the DML query is being cached and within AbstractInlineIdsDeleteHandlerImpl, there is a "deletes" member variable that is being appended to on each execution.
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name="test_entity")
public class TestEntity {
@Id
int id;
}
@Entity
@Table(name="test_entity_type1")
public class TestEntityType1 extends TestEntity {
}
@Entity
@Table(name="test_entity_type2")
public class TestEntityType2 extends TestEntity {
}
create table test_entity (id integer not null auto_increment, primary key (id)) engine=InnoDB;
create table test_entity_type1 (id integer not null auto_increment, primary key (id)) engine=InnoDB;
create table test_entity_type2 (id integer not null auto_increment, primary key (id)) engine=InnoDB;
alter table test_entity_type1 add constraint FKnup5qde9q5309bofv03i80kg1 foreign key (id) references test_entity (id);
alter table test_entity_type2 add constraint FKnup5qde9q5309bofv03i80kg2 foreign key (id) references test_entity (id);
insert into test_entity values(1);
insert into test_entity_type1 values(1);
insert into test_entity values(2);
insert into test_entity_type1 values(2);
insert into test_entity values(3);
insert into test_entity_type2 values(3);
insert into test_entity values(4);
insert into test_entity_type2 values(4);
for (int i = 1; i <= 4; i++) {
Query deleteQuery = em.createQuery("delete TestEntity e where e.id = :id");
deleteQuery.setParameter("id", i);
deleteQuery.executeUpdate();
System.out.println("===================================================");
}
Output:
|