com.xlrit.gears.base.choice.JpaChoices Maven / Gradle / Ivy
package com.xlrit.gears.base.choice;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Tuple;
import jakarta.persistence.TypedQuery;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public abstract class JpaChoices implements Choices {
public static final String PARAM_FILTER = "filter";
protected final EntityManager entityManager;
protected final Function toChoice;
@Override
public Kind kind() {
return Kind.DYNAMIC;
}
@Override
public int count() {
TypedQuery query = createCountQuery();
Long count = query.getSingleResult();
return count == null ? 0 : count.intValue();
}
@Override
public Optional find(String id) {
TypedQuery query = createItemQuery(id);
List resultList = query.getResultList();
if (resultList.isEmpty()) return Optional.empty();
if (resultList.size() > 1) throw new RuntimeException("Item query must return 0 or 1 result, but got " + resultList.size() + ": " + getQueryString(query));
return Optional.of(toChoice.apply(resultList.get(0)));
}
@Override
public Stream items(String filter, int start, int count) {
TypedQuery query = createItemsQuery(filter);
return query
.setFirstResult(start)
.setMaxResults(count)
.getResultStream()
.map(toChoice);
}
protected abstract TypedQuery createCountQuery();
protected abstract TypedQuery createItemsQuery(String filter);
protected abstract TypedQuery createItemQuery(String id);
@SuppressWarnings("rawtypes")
private static String getQueryString(TypedQuery typedQuery) {
if (typedQuery instanceof org.hibernate.query.Query query)
return query.getQueryString();
return "(query unknown)";
}
}