I'm writing method to update batch using entity manager (Eclipselink as a provider).
One approach I found here: Batch updates in JPA (Toplink) and here: JPA - Batch/Bulk Update - What is the better approach?.
But I'm not using spring Data JPA. If I use JPQL then the entity will not be added to cache (is it right). I'm using the following approach. But it is slower. Is there any other approach I can use?
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public <T> void updatetBatch(List<T> list) {
if (list == null || list.isEmpty())
throw new NullPointerException();
EntityManager entityManager = entityManagerFactory.createEntityManager();
final int BATCHLIMIT = 50;
try {
int size = list.size();
for (int i = 0; i < size; i++) {
//Using find as it will make entity managed.
Object found=entityManager.find(list.get(i).getClass(), this.getPrimaryKey(list.get(i)));
if(found!=null)
entityManager.merge(list.get(i));
if (i % BATCHLIMIT == 0) {
entityManager.flush();
entityManager.clear();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
entityManager.close();
}
}
private Object getPrimaryKey(Object object) {
return entityManagerFactory.getPersistenceUnitUtil().getIdentifier(object);
}
Here is your modified code,
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public <T> void updatetBatch(List<T> list) {
if (list == null || list.isEmpty())
throw new NullPointerException();
EntityManager entityManager = entityManagerFactory.createEntityManager();
final int BATCHLIMIT = 50;
try {
int size = list.size();
for (int i = 0; i < size; i++) {
Object primaryKeyObj = this.getPrimaryKey(list.get(i));
//Using find as it will make entity managed.
T entityObject = list.get(i);
Object found = entityManager.find(entityObject.getClass(), primaryKeyObj);
if(found!=null) {
entityManager.merge(entityObject);
} else{
entityManager.persist(entityObject);
}
if (i % BATCHLIMIT == 0) {
entityManager.flush();
entityManager.clear();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
entityManager.close();
}
}
private Object getPrimaryKey(Object object) {
return entityManagerFactory.getPersistenceUnitUtil().getIdentifier(object);
}