io.hypersistence.utils.spring.repository.BaseJpaRepositoryImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hypersistence-utils-hibernate-52 Show documentation
Show all versions of hypersistence-utils-hibernate-52 Show documentation
Utilities for Spring and Hibernate ORM 5.2 to 5.4
package io.hypersistence.utils.spring.repository;
import io.hypersistence.utils.hibernate.util.ReflectionUtils;
import org.hibernate.Session;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.AbstractSharedSessionContract;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
/**
* @author Vlad Mihalcea
*/
public class BaseJpaRepositoryImpl extends SimpleJpaRepository
implements BaseJpaRepository {
private static final String ID_MUST_NOT_BE_NULL = ReflectionUtils.getFieldValueOrNull(SimpleJpaRepository.class, "ID_MUST_NOT_BE_NULL");
private final EntityManager entityManager;
private final JpaEntityInformation entityInformation;
public BaseJpaRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityInformation = entityInformation;
this.entityManager = entityManager;
}
@Transactional
public S persist(S entity) {
entityManager.persist(entity);
return entity;
}
@Transactional
public S persistAndFlush(S entity) {
persist(entity);
entityManager.flush();
return entity;
}
@Transactional
public List persistAll(Iterable entities) {
List result = new ArrayList<>();
for(S entity : entities) {
result.add(persist(entity));
}
return result;
}
@Transactional
public List persistAllAndFlush(Iterable entities) {
return executeBatch(() -> {
List result = new ArrayList<>();
for(S entity : entities) {
result.add(persist(entity));
}
entityManager.flush();
return result;
});
}
@Transactional
public S merge(S entity) {
return entityManager.merge(entity);
}
@Transactional
public S mergeAndFlush(S entity) {
S result = merge(entity);
entityManager.flush();
return result;
}
@Transactional
public List mergeAll(Iterable entities) {
List result = new ArrayList<>();
for(S entity : entities) {
result.add(merge(entity));
}
return result;
}
@Transactional
public List mergeAllAndFlush(Iterable entities) {
return executeBatch(() -> {
List result = new ArrayList<>();
for(S entity : entities) {
result.add(merge(entity));
}
entityManager.flush();
return result;
});
}
@Transactional
public S update(S entity) {
session().update(entity);
return entity;
}
@Transactional
public S updateAndFlush(S entity) {
update(entity);
entityManager.flush();
return entity;
}
@Transactional
public List updateAll(Iterable entities) {
List result = new ArrayList<>();
for(S entity : entities) {
result.add(update(entity));
}
return result;
}
@Transactional
public List updateAllAndFlush(Iterable entities) {
return executeBatch(() -> {
List result = new ArrayList<>();
for(S entity : entities) {
result.add(update(entity));
}
entityManager.flush();
return result;
});
}
@Override
public T getReferenceById(ID id) {
Assert.notNull(id, ID_MUST_NOT_BE_NULL);
return entityManager.getReference(getDomainClass(), id);
}
@Override
public T lockById(ID id, LockModeType lockMode) {
return (T) entityManager.find(entityInformation.getJavaType(), id, lockMode);
}
protected Integer getBatchSize(Session session) {
SessionFactoryImplementor sessionFactory = session.getSessionFactory().unwrap(SessionFactoryImplementor.class);
final JdbcServices jdbcServices = sessionFactory.getServiceRegistry().getService(JdbcServices.class);
if(!jdbcServices.getExtractedMetaDataSupport().supportsBatchUpdates()) {
return Integer.MIN_VALUE;
}
return session.unwrap(AbstractSharedSessionContract.class).getConfiguredJdbcBatchSize();
}
protected R executeBatch(Supplier callback) {
Session session = session();
Integer jdbcBatchSize = getBatchSize(session);
Integer originalSessionBatchSize = session.getJdbcBatchSize();
try {
if (jdbcBatchSize == null) {
session.setJdbcBatchSize(10);
}
return callback.get();
} finally {
session.setJdbcBatchSize(originalSessionBatchSize);
}
}
protected Session session() {
return entityManager.unwrap(Session.class);
}
}