com.github.hammelion.mappedjpa.MappedRepository Maven / Gradle / Ivy
package com.github.hammelion.mappedjpa;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import io.vavr.control.Try;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* A repository which actually creates an abstraction layer between domain objects and persistence layer entity objects.
*
* @param Wrapped JpaRepository
* @param Entity object
* @param Domain object (DTO)
* @param Id of an entity
*/
@SuppressWarnings({"unchecked", "OptionalUsedAsFieldOrParameterType", "unused"})
public class MappedRepository, D, E, ID> implements JpaRepository {
protected final J repository;
protected final DtoMapper mapper;
public MappedRepository(
J repository,
DtoMapper mapper
) {
this.repository = repository;
this.mapper = mapper;
}
private static RuntimeException runtimeException(Throwable t) {
if (t instanceof RuntimeException) {
return (RuntimeException) t;
}
return new RuntimeException(t);
}
@Override
public Optional findById(ID id) {
return callOpt(() -> repository.findById(id));
}
@Override
public boolean existsById(ID id) {
return repository.existsById(id);
}
@Override
public List findAll() {
return callList(repository::findAll);
}
@Override
public List findAll(Sort sort) {
return callList(() -> repository.findAll(sort));
}
@Override
public Page findAll(Pageable pageable) {
return callPage(() -> repository.findAll(pageable));
}
@Override
public List findAllById(Iterable ids) {
return callList(() -> repository.findAllById(ids));
}
@Override
public long count() {
return repository.count();
}
@Override
public void deleteById(ID id) {
repository.deleteById(id);
}
@Override
public void delete(D entity) {
repository.delete(fromDto(entity));
}
@Override
public void deleteAll(Iterable extends D> entities) {
repository.deleteAll(fromDtoList(entities));
}
@Override
public void deleteAll() {
repository.deleteAll();
}
@Override
public S save(S entity) {
return call(() -> repository.save(fromDto(entity)));
}
@Override
public List saveAll(Iterable entities) {
return callList(() -> repository.saveAll(fromDtoList(entities)));
}
@Override
public void flush() {
repository.flush();
}
@Override
public S saveAndFlush(S entity) {
return call(() -> repository.saveAndFlush(fromDto(entity)));
}
@Override
public void deleteInBatch(Iterable entities) {
repository.deleteInBatch(fromDtoList(entities));
}
@Override
public void deleteAllInBatch() {
repository.deleteAllInBatch();
}
@Override
public D getOne(ID id) {
return call(() -> repository.getOne(id));
}
@Override
public Optional findOne(Example example) {
return callOpt(() -> repository.findOne(fromDto(example)));
}
@Override
public List findAll(Example example) {
return this.callList(() -> repository.findAll(fromDto(example)));
}
@Override
public List findAll(
Example example,
Sort sort
) {
return this.callList(() -> repository.findAll(fromDto(example), sort));
}
@Override
public Page findAll(
Example example,
Pageable pageable
) {
return callPage(() -> repository.findAll(fromDto(example), pageable));
}
@Override
public long count(Example example) {
return repository.count(fromDto(example));
}
@Override
public boolean exists(Example example) {
return repository.exists(fromDto(example));
}
private List callList(
Callable> f
) {
return Try.of(() -> f.call().stream().map(e -> (S) mapper.toDto(e)).collect(Collectors.toList()))
.getOrElseThrow(MappedRepository::runtimeException);
}
private Optional callOpt(
Callable> f
) {
return Try.of(f::call)
.map(o -> o.map(e -> (S) mapper.toDto(e)))
.getOrElseThrow(MappedRepository::runtimeException);
}
private S call(Callable f) {
return Try.of(f::call)
.map(e -> (S) mapper.toDto(e))
.getOrElseThrow(MappedRepository::runtimeException);
}
private Page callPage(Callable> f) {
return Try.of(f::call)
.map(p -> p.map(e -> (S) mapper.toDto(e)))
.getOrElseThrow(MappedRepository::runtimeException);
}
public Optional toDto(Optional o) {
return o.map(mapper::toDto);
}
public List toDto(Iterable entities) {
return StreamSupport.stream(entities.spliterator(), false)
.map(mapper::toDto)
.collect(Collectors.toList());
}
public List fromDtoList(Iterable extends D> dtos) {
return StreamSupport.stream(dtos.spliterator(), false)
.map(this::fromDto)
.collect(Collectors.toList());
}
public E fromDto(D dto) {
return mapper.fromDto(dto);
}
public Example fromDto(Example example) {
return Example.of(fromDto(example.getProbe()));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy