Blazebit / blaze-persistence

Rich Criteria API for JPA providers
https://persistence.blazebit.com
Apache License 2.0
728 stars 85 forks source link

Spring-Data generic repository #1081

Open beikov opened 4 years ago

beikov commented 4 years ago

It would be great if we could create a generic injectable repository that gives easy access to most features of Blaze-Persistence. @EugenMayer mentioned that having to inject the CriteriaBuilderFactory, EntityViewManager and EntityManager to be able to write some queries feels clunky and I understand the pain. I saw quite a few versions of generic abstractions that try to encapsulate some of the boilerplate parts.

We could also create something similar for CDI/DeltaSpike

EugenMayer commented 4 years ago

I do no think the generic repository have to be over complicated or do a really lot, just offer the usual bit's and pieces

We have such an implementation while using BP and it works fairly well for us - so we at least see a value for us here, but also a a general one.

EugenMayer commented 4 years ago

we used the following signature with hopefully obvious implementation

// E is the Entity, ID is the type of the PK
public class RegularEntityViewRepository<E, ID> {
  public <V> Optional<V> findOne(EntityViewSetting<V, CriteriaBuilder<V>> setting, ID id) {}

  public <V> Optional<V> findOne(EntityViewSetting<V, CriteriaBuilder<V>> setting, Class<E> entityClass) {}

  public <V> Optional<V> findOne(
    Class<E> entityClass,
    Class<V> entityViewClass,
    UnaryOperator<CriteriaBuilder<E>> function
  )
  {
    var setting = EntityViewSetting.create(entityViewClass);
    var criteriaBuilder = createCriteriaBuilder(entityClass);
    return findOne(setting, function.apply(criteriaBuilder));
  }

  public <V> Optional<V> findOne(
    EntityViewSetting<V, CriteriaBuilder<V>> setting,
    CriteriaBuilder<E> entityCriteriaBuilder
  ){}

  public <V> Set<V> findAll(EntityViewSetting<V, CriteriaBuilder<V>> setting, Class<E> entityClass){}

  public <V> Set<V> findAll(EntityViewSetting<V, CriteriaBuilder<V>> setting, CriteriaBuilder<E> entityCriteriaBuilder){}

  public <V> Set<V> findAll(Class<V> entityViewClass, CriteriaBuilder<E> entityCriteriaBuilder)

  public <V> Set<V> findAll(
    Class<E> entityClass,
    Class<V> entityViewClass,
    UnaryOperator<CriteriaBuilder<E>> function
  ){
    var setting = EntityViewSetting.create(entityViewClass);
    var criteriaBuilder = createCriteriaBuilder(entityClass);
    return findAll(setting, function.apply(criteriaBuilder));
  }

  public <CV> CV create(CV createView){}

  public <UV> void update(UV updateView){}

  public <UV> void updateFull(UV updateView){}

  public <ID, V> void delete(ID id, Class<V> idViewClass){}

  public DeleteCriteriaBuilder<E> delete(Class<E> entityClass){}

  public boolean exists(CriteriaBuilder<E> criteriaBuilder)
  {
    return !criteriaBuilder.setMaxResults(1).getResultList().isEmpty(); // Expression is negated!!!
  }

  public boolean exists(Class<E> entityClass, UnaryOperator<CriteriaBuilder<E>> function)
  {
    return exists(function.apply(createCriteriaBuilder(entityClass).select("1")));
  }

  public boolean exists(Class<E> entityClass, String alias, UnaryOperator<CriteriaBuilder<E>> function)
  {
    return exists(function.apply(createCriteriaBuilder(entityClass, alias).select("1")));
  }
}