diff --git a/commons-business-impl/src/main/java/com/appjars/saturn/service/ConversionQueryServiceMixin.java b/commons-business-impl/src/main/java/com/appjars/saturn/service/ConversionQueryServiceMixin.java index 57547d9..d2cddf5 100644 --- a/commons-business-impl/src/main/java/com/appjars/saturn/service/ConversionQueryServiceMixin.java +++ b/commons-business-impl/src/main/java/com/appjars/saturn/service/ConversionQueryServiceMixin.java @@ -61,6 +61,12 @@ default List filter(QuerySpec filter) { return getQueryDao().filter(filter).stream().map(this::convertToBusiness).collect(Collectors.toList()); } + @Transactional(value = TxType.REQUIRED, rollbackOn = Exception.class) + @Override + default Optional filterWithSingleResult(QuerySpec filter) { + return getQueryDao().filterWithSingleResult(filter).map(this::convertToBusiness); + } + @Transactional(value = TxType.REQUIRED, rollbackOn = Exception.class) @Override default long count(QuerySpec filter) { diff --git a/commons-business/src/main/java/com/appjars/saturn/service/QueryService.java b/commons-business/src/main/java/com/appjars/saturn/service/QueryService.java index 40d4b0a..334b158 100644 --- a/commons-business/src/main/java/com/appjars/saturn/service/QueryService.java +++ b/commons-business/src/main/java/com/appjars/saturn/service/QueryService.java @@ -65,4 +65,14 @@ public interface QueryService { */ long count(QuerySpec filter); + /** + * Apply filtering to entities in the system based on a certain query specification and retrieve a + * single result. + * + * @param filter the query specification used for filtering + * @return an {@code Optional} instance containing a single entity matching the query + * specification if it exists; otherwise empty + */ + Optional filterWithSingleResult(QuerySpec filter); + } diff --git a/commons-data-impl/src/main/java/com/appjars/saturn/dao/jpa/ConversionJpaDaoSupport.java b/commons-data-impl/src/main/java/com/appjars/saturn/dao/jpa/ConversionJpaDaoSupport.java index 201ebf7..61b8ef2 100644 --- a/commons-data-impl/src/main/java/com/appjars/saturn/dao/jpa/ConversionJpaDaoSupport.java +++ b/commons-data-impl/src/main/java/com/appjars/saturn/dao/jpa/ConversionJpaDaoSupport.java @@ -110,6 +110,16 @@ default List filter(QuerySpec filter) { return FilterProcesor.of(getEntityManager(), getPersistentClass()).filter(filter).stream() .map(this::convertFrom).collect(Collectors.toList()); } + + @Override + default Optional filterWithSingleResult(QuerySpec filter) { + List filtered = FilterProcesor.of(getEntityManager(), getPersistentClass()).filter(filter); + if (filtered.size()>1) { + throw new IllegalStateException("Current filter returned more than one result"); + } + return filtered.stream() + .map(this::convertFrom).findAny(); + } static class FilterProcesor, K extends Serializable> { diff --git a/commons-data-impl/src/test/java/com/appjars/saturn/dao/jpa/JpaDaoSupportTest.java b/commons-data-impl/src/test/java/com/appjars/saturn/dao/jpa/JpaDaoSupportTest.java index d154b79..5af5052 100644 --- a/commons-data-impl/src/test/java/com/appjars/saturn/dao/jpa/JpaDaoSupportTest.java +++ b/commons-data-impl/src/test/java/com/appjars/saturn/dao/jpa/JpaDaoSupportTest.java @@ -110,6 +110,18 @@ void testFilter() { assertEquals(10, allMinusFirst); } + @Test + void testFilterWithSingleResult() { + PersonFilter pf = new PersonFilter(); + pf.addConstraint(ConstraintBuilder.in("id", Arrays.asList(new Integer[] { persistedPerson.getId() }))); + boolean isPresent = dao.filterWithSingleResult(pf).isPresent(); + assertEquals(true, isPresent); + pf = new PersonFilter(); + pf.addConstraint(ConstraintBuilder.in("id", Arrays.asList(new Integer[] { -1 }))); + isPresent = dao.filterWithSingleResult(pf).isPresent(); + assertEquals(false, isPresent); + } + @Test void testCount() { PersonFilter pf = new PersonFilter(); diff --git a/commons-data/src/main/java/com/appjars/saturn/dao/QueryDao.java b/commons-data/src/main/java/com/appjars/saturn/dao/QueryDao.java index 433f39a..8520b45 100644 --- a/commons-data/src/main/java/com/appjars/saturn/dao/QueryDao.java +++ b/commons-data/src/main/java/com/appjars/saturn/dao/QueryDao.java @@ -32,6 +32,8 @@ public interface QueryDao { List filter(QuerySpec filter); + Optional filterWithSingleResult(QuerySpec filter); + long count(QuerySpec filter); }