InMemoryJpaRepository.java
package com.reallifedeveloper.tools.test.database.inmemory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import org.springframework.data.domain.Example;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;
/**
* An implementation of the Spring Data JPA {@code JpaRepository} interface that holds entities in a map. Useful for testing.
*
* @param <T> the type of the entities handled by this repository
* @param <ID> the type of the entities' primary keys
*
* @author RealLifeDeveloper
*/
public class InMemoryJpaRepository<T, ID extends Comparable<ID>> extends AbstractInMemoryCrudRepository<T, ID>
implements JpaRepository<T, ID> {
/**
* Creates a new {@code InMemoryJpaRepository} with no primary key generator. If an entity with a {@code null} primary key is saved, an
* exception is thrown.
*/
public InMemoryJpaRepository() {
super();
}
/**
* Creates a new {@code InMemoryJpaRepository} with the provided primary key generator. If an entity with a {@code null} primary key is
* saved, the generator is used to create a new primary key that is stored in the entity before saving.
*
* @param primaryKeyGenerator the primary key generator to use
*/
public InMemoryJpaRepository(PrimaryKeyGenerator<ID> primaryKeyGenerator) {
super(primaryKeyGenerator);
}
/**
* {@inheritDoc}
*/
@Override
public void deleteAllInBatch() {
deleteAll();
}
/**
* {@inheritDoc}
*/
@Override
public void deleteAllInBatch(Iterable<T> entities) {
deleteAll(entities);
}
/**
* {@inheritDoc}
*/
@Override
public void deleteAllByIdInBatch(Iterable<ID> ids) {
deleteAllById(ids);
}
/**
* {@inheritDoc}
*/
@Override
public void flush() {
// Do nothing.
}
/**
* {@inheritDoc}
*/
@Override
public <S extends T> S saveAndFlush(S entity) {
S savedEntity = save(entity);
flush();
return savedEntity;
}
/**
* {@inheritDoc}
*/
@Override
public <S extends T> List<S> saveAllAndFlush(Iterable<S> entities) {
List<S> savedEntities = saveAll(entities);
flush();
return savedEntities;
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings("deprecation")
public T getById(ID id) {
Optional<T> optionalElement = findById(id);
return optionalElement.orElseThrow(() -> new EntityNotFoundException("Entity with ID " + id + " not found"));
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings("deprecation")
public T getOne(ID id) {
return getById(id);
}
@Override
protected boolean isIdField(Field field) {
return field.getAnnotation(Id.class) != null || field.getAnnotation(EmbeddedId.class) != null;
}
@Override
protected boolean isIdMethod(Method method) {
return method.getAnnotation(Id.class) != null || method.getAnnotation(EmbeddedId.class) != null;
}
@Override
@SuppressWarnings("unchecked")
protected Optional<Class<ID>> getIdClass(Object entity) {
IdClass idClass = entity.getClass().getAnnotation(IdClass.class);
if (idClass == null) {
return Optional.empty();
} else {
return Optional.ofNullable((Class<ID>) idClass.value());
}
}
@Override
public <S extends T, R> R findBy(Example<S> example, Function<FetchableFluentQuery<S>, R> queryFunction) {
throw new UnsupportedOperationException("Unimplemented method 'findBy'");
}
@Override
public T getReferenceById(ID id) {
throw new UnsupportedOperationException("Unimplemented method 'getReferenceById'");
}
}