I am trying to optimize a hibernation application, and one of the biggest problems I have encountered with Hibernates performance is its tendency to execute n + 1 queries for a simple crud operation with child objects. I was able to prevent n + 1 requests for selecting operations using @Fetch(FetchMode.JOIN)for the child object (many-one side), but this does not affect update / insert / delete requests. The following is an example of relevant objects and properties:
@Entity
@DynamicInsert
@Table(name = "belief")
public class Belief implements Serializable, Cloneable {
@Id
@GeneratedValue
@Column(name = "belief_id", unique = true, insertable = false, updatable = false)
private Integer id;
@Cascade(org.hibernate.annotations.CascadeType.ALL)
@OneToMany(mappedBy = "pk.beliefId", orphanRemoval = true, fetch = FetchType.LAZY)
private List<Mean> means = new ArrayList<>();
@Cascade(org.hibernate.annotations.CascadeType.ALL)
@OneToMany(mappedBy = "pk.beliefId", orphanRemoval = true, fetch = FetchType.LAZY)
private List<Covariance> covariances = new ArrayList<>();
}
@Entity
@DynamicInsert
@Table(name = "mean")
public class Mean implements Serializable, Cloneable {
@EmbeddedId
private MeanPK pk = new MeanPK(this);
@Fetch(FetchMode.JOIN)
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
@JoinColumn(name = "belief_id", insertable = false, nullable = false, updatable = false)
private Belief belief;
}
@Entity
@DynamicInsert
@Table(name = "covariance")
public class Covariance implements Serializable, Cloneable {
@EmbeddedId
private CovariancePK pk = new CovariancePK(this);
@Fetch(FetchMode.JOIN)
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
@JoinColumn(name = "belief_id", insertable = false, nullable = false, updatable = false)
private Belief belief;
}
So, when I execute session.delete(belief);, the logs show that for each covariance a separate delete instruction is executed and means that the object of faith can be referenced. Here is an example log:
Hibernate: select belief0_.belief_id as belief_i1_0_0_, belief0_.after_comb as after_co2_0_0_, belief0_.description as descript3_0_0_, belief0_.name as name4_0_0_, belief0_.project_id as project_7_0_0_, belief0_.type as type5_0_0_, belief0_.version as version6_0_0_ from belief belief0_ where belief0_.belief_id=?
Hibernate: select covariance0_.belief_id as belief_i1_0_0_, covariance0_.belief_id as belief_i1_1_0_, covariance0_.col_variable_id as col_vari2_1_0_, covariance0_.row_variable_id as row_vari3_1_0_, covariance0_.belief_id as belief_i1_1_1_, covariance0_.col_variable_id as col_vari2_1_1_, covariance0_.row_variable_id as row_vari3_1_1_, covariance0_.variance as variance4_1_1_, covariance0_.version as version5_1_1_, variable1_.variable_id as variable1_5_2_, variable1_.definition as definiti2_5_2_, variable1_.description as descript3_5_2_, variable1_.name as name4_5_2_, variable1_.project_id as project_6_5_2_, variable1_.version as version5_5_2_, variable2_.variable_id as variable1_5_3_, variable2_.definition as definiti2_5_3_, variable2_.description as descript3_5_3_, variable2_.name as name4_5_3_, variable2_.project_id as project_6_5_3_, variable2_.version as version5_5_3_ from covariance covariance0_ inner join variable variable1_ on covariance0_.col_variable_id=variable1_.variable_id inner join variable variable2_ on covariance0_.row_variable_id=variable2_.variable_id where covariance0_.belief_id=?
Hibernate: select means0_.belief_id as belief_i1_0_0_, means0_.belief_id as belief_i1_2_0_, means0_.variable_id as variable2_2_0_, means0_.belief_id as belief_i1_2_1_, means0_.variable_id as variable2_2_1_, means0_.mean as mean3_2_1_, means0_.swept as swept4_2_1_, means0_.version as version5_2_1_, variable1_.variable_id as variable1_5_2_, variable1_.definition as definiti2_5_2_, variable1_.description as descript3_5_2_, variable1_.name as name4_5_2_, variable1_.project_id as project_6_5_2_, variable1_.version as version5_5_2_ from mean means0_ inner join variable variable1_ on means0_.variable_id=variable1_.variable_id where means0_.belief_id=?
Hibernate: delete from covariance where belief_id=? and col_variable_id=? and row_variable_id=? and version=?
Hibernate: delete from covariance where belief_id=? and col_variable_id=? and row_variable_id=? and version=?
Hibernate: delete from mean where belief_id=? and variable_id=? and version=?
Hibernate: delete from mean where belief_id=? and variable_id=? and version=?
Hibernate: delete from mean where belief_id=? and variable_id=? and version=?
Hibernate: delete from mean where belief_id=? and variable_id=? and version=?
Hibernate: delete from mean where belief_id=? and variable_id=? and version=?
Hibernate: delete from belief where belief_id=? and version=?
n + 1, select, //.
- , ?
!