Skip to content

Commit

Permalink
Streamable support (#49)
Browse files Browse the repository at this point in the history
* added stream support to jdbc and jpa module

* compilation fixes

* added README.md section for jdbc streamable

* updated README.md

* updated README.md

* bumped minor

* updated README.md

* updated CHANGELOG.md
  • Loading branch information
lpandzic committed Dec 17, 2021
1 parent 707f8b7 commit ead317f
Show file tree
Hide file tree
Showing 20 changed files with 152 additions and 34 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,7 @@
### 6.2.0

* added `streamAll` to JDBC and JPA modules

### 6.1.2
* fixed sorting issue [#39](/../../issues/39)

Expand Down
29 changes: 29 additions & 0 deletions README.md
Expand Up @@ -22,6 +22,7 @@ Infobip Spring Data Querydsl provides new functionality that enables the user to
* [Delete](#JDBCDelete)
* [Transactional support](#JDBCTransactionalSupport)
* [Embedded support](#JDBCEmbeddedSupport)
* [Streaming](#JDBCStreaming)
* [Extension](#JDBCExtension)
1. [R2DBC module:](#R2DBC)
* [Requirements](#R2DBCRequirements)
Expand All @@ -46,6 +47,7 @@ Infobip Spring Data Querydsl provides new functionality that enables the user to
* [List instead of Iterable return type](#JPAListInsteadOfIterableReturnType)
* [Transactional support](#JPATransactionalSupport)
* [Stored procedure builder](#JPAStoredProcedureBuilder)
* [Streaming](#JPAStreaming)
* [Extension](#JPAExtension)
1. [Annotation processor](#AnnotationProcessor)
1. [Further reading](#FurtherReading)
Expand Down Expand Up @@ -205,6 +207,7 @@ public class PersonWithEmbeddedFirstAndLastName {
}
```


```java
@Value
public class FirstAndLastName {
Expand All @@ -220,6 +223,19 @@ Query (note the missing .personWithEmbeddedFirstAndLastName field in Q instance)
repository.findAll(personWithEmbeddedFirstAndLastName.firstName.in("John", "Johny"));
```

#### <a name="JDBCStreaming"></a> Streaming

`streamAll` is a new method added to repository for more convenient use.

```
@Transactional
public void transactionalAnnotatedMethodRequiredForConsumingStream() {
try (Stream<Person> stream = repository.streamAll()) {
// use stream
}
}
```

### <a name="JDBCExtension"></a> Extension:

To create a custom base repository interface you'll need to create:
Expand Down Expand Up @@ -514,6 +530,19 @@ public List<Person> delete(Person personToDelete) {
}
```

#### <a name="JPAStreaming"></a> Streaming

`streamAll` is a new method added to repository for more convenient use.

```
@Transactional
public void transactionalAnnotatedMethodRequiredForConsumingStream() {
try (Stream<Person> stream = repository.streamAll()) {
// use stream
}
}
```

### <a name="JPAExtension"></a> Extension:

To create a custom base repository interface you'll need to create:
Expand Down
2 changes: 1 addition & 1 deletion infobip-spring-data-common/pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.infobip</groupId>
<artifactId>infobip-spring-data-querydsl</artifactId>
<version>6.1.4-SNAPSHOT</version>
<version>6.2.0-SNAPSHOT</version>
</parent>

<artifactId>infobip-spring-data-common</artifactId>
Expand Down
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.infobip</groupId>
<artifactId>infobip-spring-data-querydsl</artifactId>
<version>6.1.4-SNAPSHOT</version>
<version>6.2.0-SNAPSHOT</version>
</parent>

<artifactId>infobip-spring-data-jdbc-annotation-processor-common</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion infobip-spring-data-jdbc-annotation-processor/pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.infobip</groupId>
<artifactId>infobip-spring-data-querydsl</artifactId>
<version>6.1.4-SNAPSHOT</version>
<version>6.2.0-SNAPSHOT</version>
</parent>

<artifactId>infobip-spring-data-jdbc-annotation-processor</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion infobip-spring-data-jdbc-querydsl-boot-starter/pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.infobip</groupId>
<artifactId>infobip-spring-data-querydsl</artifactId>
<version>6.1.4-SNAPSHOT</version>
<version>6.2.0-SNAPSHOT</version>
</parent>

<artifactId>infobip-spring-data-jdbc-querydsl-boot-starter</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion infobip-spring-data-jdbc-querydsl/pom.xml
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>com.infobip</groupId>
<artifactId>infobip-spring-data-querydsl</artifactId>
<version>6.1.4-SNAPSHOT</version>
<version>6.2.0-SNAPSHOT</version>
</parent>

<artifactId>infobip-spring-data-jdbc-querydsl</artifactId>
Expand Down
Expand Up @@ -14,6 +14,7 @@
import org.springframework.data.querydsl.QSort;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.repository.query.FluentQuery;
import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.jdbc.core.RowMapper;
Expand All @@ -26,6 +27,7 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.function.Function;

public class QuerydslJdbcPredicateExecutor<T> implements QuerydslPredicateExecutor<T> {

Expand Down Expand Up @@ -115,6 +117,11 @@ public boolean exists(Predicate predicate) {
return createQuery(predicate).fetchCount() > 0;
}

@Override
public <S extends T, R> R findBy(Predicate predicate, Function<FluentQuery.FetchableFluentQuery<S>, R> queryFunction) {
throw new UnsupportedOperationException();
}

protected SQLQuery<?> createQuery(Predicate... predicate) {

Assert.notNull(predicate, "Predicate must not be null!");
Expand Down
@@ -1,15 +1,18 @@
package com.infobip.spring.data.jdbc;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import org.springframework.data.domain.Sort;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

@Transactional(readOnly = true)
@NoRepositoryBean
public interface QuerydslJdbcRepository<T, ID>
extends PagingAndSortingRepository<T, ID>, QuerydslPredicateExecutor<T>, QuerydslJdbcFragment<T> {
Expand All @@ -21,6 +24,16 @@ default List<T> save(T... entities) {
@Override
<S extends T> List<S> saveAll(Iterable<S> entities);

default Stream<T> streamAll() {
return streamAllBy();
}

/**
* @deprecated use {@link QuerydslJdbcRepository#streamAll} instead
*/
@Deprecated
Stream<T> streamAllBy();

@Override
List<T> findAll();

Expand Down
Expand Up @@ -74,14 +74,14 @@ protected RepositoryFactorySupport doCreateRepositoryFactory() {
}

@Autowired
protected void setMappingContext(RelationalMappingContext mappingContext) {
public void setMappingContext(RelationalMappingContext mappingContext) {

super.setMappingContext(mappingContext);
this.mappingContext = mappingContext;
}

@Autowired
protected void setDialect(Dialect dialect) {
public void setDialect(Dialect dialect) {
this.dialect = dialect;
}

Expand Down
Expand Up @@ -6,9 +6,12 @@
import lombok.AllArgsConstructor;
import lombok.Value;
import org.junit.jupiter.api.*;
import org.springframework.transaction.annotation.Transactional;

import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.infobip.spring.data.jdbc.QPerson.person;
import static com.infobip.spring.data.jdbc.QPersonSettings.personSettings;
Expand All @@ -34,6 +37,24 @@ void cleanUpTimeZone() {
TimeZone.setDefault(oldTimeZone);
}

@Transactional
@Test
void shouldStreamAll() {

// given
Person johnDoe = givenSavedPerson("John", "Doe");
Person johnyRoe = givenSavedPerson("Johny", "Roe");
Person janeDoe = givenSavedPerson("Jane", "Doe");
List<Person> actual = null;

// when
try (Stream<Person> stream = repository.streamAll()) {
actual = stream.collect(Collectors.toList());
}

then(actual).usingRecursiveFieldByFieldElementComparator().containsExactlyInAnyOrder(johnDoe, johnyRoe, janeDoe);
}

@Test
void shouldFindAll() {

Expand Down
2 changes: 1 addition & 1 deletion infobip-spring-data-jpa-querydsl-boot-starter/pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.infobip</groupId>
<artifactId>infobip-spring-data-querydsl</artifactId>
<version>6.1.4-SNAPSHOT</version>
<version>6.2.0-SNAPSHOT</version>
</parent>

<artifactId>infobip-spring-data-jpa-querydsl-boot-starter</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion infobip-spring-data-jpa-querydsl/pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.infobip</groupId>
<artifactId>infobip-spring-data-querydsl</artifactId>
<version>6.1.4-SNAPSHOT</version>
<version>6.2.0-SNAPSHOT</version>
</parent>

<artifactId>infobip-spring-data-jpa-querydsl</artifactId>
Expand Down
@@ -1,15 +1,23 @@
package com.infobip.spring.data.jpa;

import static org.hibernate.jpa.QueryHints.HINT_FETCH_SIZE;

import javax.persistence.QueryHint;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

@Transactional(readOnly = true)
@NoRepositoryBean
public interface ExtendedQuerydslJpaRepository<T, ID>
extends JpaRepository<T, ID>, QuerydslPredicateExecutor<T>, QuerydslJpaFragment<T> {
Expand All @@ -18,6 +26,10 @@ default List<T> save(T... entities) {
return this.saveAll(Arrays.asList(entities));
}

@QueryHints(@QueryHint(name = HINT_FETCH_SIZE, value = "1000"))
@Query("select e from #{#entityName} e")
Stream<T> streamAll();

@Override
List<T> findAll(Predicate predicate);

Expand Down
Expand Up @@ -4,8 +4,11 @@
import lombok.AllArgsConstructor;
import lombok.Value;
import org.junit.jupiter.api.Test;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.infobip.spring.data.jpa.QPerson.person;
import static com.infobip.spring.data.jpa.QPersonSettings.personSettings;
Expand All @@ -17,6 +20,24 @@ public class ExtendedQuerydslJpaRepositoryTest extends TestBase {
private final PersonRepository repository;
private final PersonSettingsRepository settingsRepository;

@Transactional
@Test
void shouldStreamAll() {

// given
Person johnDoe = givenSavedPerson("John", "Doe");
Person johnyRoe = givenSavedPerson("Johny", "Roe");
Person janeDoe = givenSavedPerson("Jane", "Doe");
List<Person> actual = null;

// when
try (Stream<Person> stream = repository.streamAll()) {
actual = stream.collect(Collectors.toList());
}

then(actual).usingRecursiveFieldByFieldElementComparator().containsExactlyInAnyOrder(johnDoe, johnyRoe, janeDoe);
}

@Test
void shouldFindAllWithPredicate() {

Expand All @@ -28,7 +49,7 @@ void shouldFindAllWithPredicate() {
// when
List<Person> actual = repository.findAll(person.firstName.in("John", "Johny"));

then(actual).usingFieldByFieldElementComparator().containsOnly(johnDoe, johnyRoe);
then(actual).usingRecursiveFieldByFieldElementComparator().containsOnly(johnDoe, johnyRoe);
}

@Test
Expand All @@ -51,7 +72,7 @@ void shouldQuery() {
.offset(1)
.fetch());

then(actual).usingFieldByFieldElementComparator().containsOnly(johnDoe);
then(actual).usingRecursiveFieldByFieldElementComparator().containsOnly(johnDoe);
}

@Test
Expand Down Expand Up @@ -103,7 +124,7 @@ void shouldDelete() {
// when
long numberOfAffectedRows = repository.deleteWhere(person.firstName.like("John%"));

then(repository.findAll()).usingFieldByFieldElementComparator().containsExactly(janeDoe);
then(repository.findAll()).usingRecursiveFieldByFieldElementComparator().containsExactly(janeDoe);
then(numberOfAffectedRows).isEqualTo(3L);
}

Expand Down Expand Up @@ -133,7 +154,7 @@ void shouldJpaSqlQuery() {
.fetch()
);

then(actual).usingFieldByFieldElementComparator().containsExactly(janeDoe, janieDoe, johnDoe, johnRoe);
then(actual).usingRecursiveFieldByFieldElementComparator().containsExactly(janeDoe, janieDoe, johnDoe, johnRoe);
}

@Test
Expand Down Expand Up @@ -173,7 +194,7 @@ void shouldExecuteStoredProcedure() {

// then
then(actual).containsExactlyInAnyOrder(johnyRoe.getFirstName(), johnRoe.getFirstName());
then(repository.findAll()).usingFieldByFieldElementComparator()
then(repository.findAll()).usingRecursiveFieldByFieldElementComparator()
.containsExactlyInAnyOrder(johnDoe, janeDoe, janieDoe);
}

Expand All @@ -196,8 +217,8 @@ void shouldExecuteStoredProcedureWithResultClasses() {
.getResultList());

// then
then(actual).usingFieldByFieldElementComparator().containsExactlyInAnyOrder(johnyRoe);
then(repository.findAll()).usingFieldByFieldElementComparator()
then(actual).usingRecursiveFieldByFieldElementComparator().containsExactlyInAnyOrder(johnyRoe);
then(repository.findAll()).usingRecursiveFieldByFieldElementComparator()
.containsExactlyInAnyOrder(johnDoe, janeDoe, johnRoe, janieDoe);
}

Expand Down
2 changes: 1 addition & 1 deletion infobip-spring-data-r2dbc-querydsl-boot-starter/pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.infobip</groupId>
<artifactId>infobip-spring-data-querydsl</artifactId>
<version>6.1.4-SNAPSHOT</version>
<version>6.2.0-SNAPSHOT</version>
</parent>

<artifactId>infobip-spring-data-r2dbc-querydsl-boot-starter</artifactId>
Expand Down

0 comments on commit ead317f

Please sign in to comment.