Spring Data JPA: inserción por lotes para entidades anidadas
Tengo un caso de prueba en el que necesito persistir 100.000 instancias de entidad en la base de datos. El código que estoy usando actualmente hace esto, pero toma hasta 40 segundos hasta que todos los datos permanecen en la base de datos. Los datos se leen de un archivo JSON que tiene un tamaño de aproximadamente 15 MB.
Ahora ya había implementado un método de inserción por lotes en un repositorio personalizado antes para otro proyecto. Sin embargo, en ese caso tenía muchas entidades de nivel superior para persistir, con solo unas pocas entidades anidadas.
En mi caso actual tengo 5Job
entidades que contienen una lista de aproximadamente ~ 30JobDetail
entidades. UnoJobDetail
contiene entre 850 y 1100JobEnvelope
entidades.
Al escribir en la base de datos, confirmo la Lista deJob
entidades con el valor predeterminadosave(Iterable<Job> jobs)
método de interfaz Todas las entidades anidadas tienen el CascadeTypePERSIST
. Cada entidad tiene su propia tabla.
La forma habitual de habilitar las inserciones por lotes sería implementar un método personalizado comosaveBatch
que se sonroja de vez en cuando. Pero mi problema en este caso son losJobEnvelope
entidades. No los persisto con unJobEnvelope
repositorio, en cambio dejo el repositorio de laJob
entidad manejarlo. Estoy usando MariaDB como servidor de base de datos.
Entonces mi pregunta se reduce a lo siguiente: ¿Cómo puedo hacer que elJobRepository
insertar sus entidades anidadas en lotes?
Estas son mis 3 entidades en cuestión:
Trabajo@Entity
public class Job {
@Id
@GeneratedValue
private int jobId;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST, mappedBy = "job")
@JsonManagedReference
private Collection<JobDetail> jobDetails;
}
Detalles del trabajo@Entity
public class JobDetail {
@Id
@GeneratedValue
private int jobDetailId;
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinColumn(name = "jobId")
@JsonBackReference
private Job job;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST, mappedBy = "jobDetail")
@JsonManagedReference
private List<JobEnvelope> jobEnvelopes;
}
JobEnvelope@Entity
public class JobEnvelope {
@Id
@GeneratedValue
private int jobEnvelopeId;
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinColumn(name = "jobDetailId")
private JobDetail jobDetail;
private double weight;
}