0

I'm trying to migrate spring boot application from mssql to CosmosDb.

We have the below repository implementation using org.springframework.data.jpa.domain.Specification; which can fetch data based on any (one or more) columns requested by the user.

static Specification<User> isMatching(final Map<String, String> parameters) {
    return new Specification<User>() {
        private static final long serialVersionUID = 1L;

        public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
            List<Predicate> predicates = new ArrayList<>();
            parameters.entrySet().forEach(e -> {
                
                predicates.add(builder.and(builder.equal(root.get(e.getKey()), e.getValue())));
            });
            return builder.and(predicates.toArray(new Predicate[predicates.size()]));
        }
    };
}

and then we are calling this as below:

repo.findAll(UserRepo.isMatching(parameters));

I had to remove spring-boot-starter-data-jpa from classpath as it will not support CosmosDb. I'm using the below spring and spring data cosmos references in classpath as that is the only combination working for me.

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath />
    </parent>
<dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-spring-data-cosmos</artifactId>
            <version>3.0.0</version>
        </dependency>

I couldn't really figure out how I can implement the above Specification logic for CosmosDb. I would really appreciate any guidance regarding this. Thanks in advance!

user3407500
  • 35
  • 1
  • 6

1 Answers1

1

Currently azure-spring-data-cosmos doesn't provide support for Specification / QueryDSL in azure-spring-data-cosmos SDK. The closest option I can think of is using Criteria API with SqlQuerySpec. Using SqlQuerySpec you can generate CosmosQuery type, which can then be executed using CosmosTemplate or ReactiveCosmosTemplate based on your repository style (sync vs async).

Regarding versioning, I would recommend using the latest version of spring-boot-starter-parent - 2.6.2 and azure-spring-data-cosmos 3.17.0, so that you get the latest features of query annotation as well.

If the SqlQuerySpec doesn't work either, alternative would be to get CosmosClient bean through applicationContext in your spring application, and running the queries directly against azure-cosmos Java v4 SDK, which is used under the hood of our azure-spring-data-cosmos SDK.

Please follow this github issue for any updates on your question - https://github.com/Azure/azure-sdk-for-java/issues/25629

  • thank you for your response. I actually tried to implement it using SqlQuerySpec and CosmosAsyncClient as below. return this.cosmosAsyncClient .getDatabase("user-db") .getContainer("User") .queryItems(new SqlQuerySpec(query, sqlParameters), User.class); But I couldn't return the Paginated results using the above approach for below method. Page findAll(Map parameters, Pageable pageable); – user3407500 Feb 09 '22 at 16:56
  • 1. Will CosmosQuery support pagination with Pageable parameter? Can you suggest about how to generate CosmosQuery using SqlQuerySpec? 2. Is it possible to return Page using CosmosAsyncClient? Thanks in advance! – user3407500 Feb 09 '22 at 16:56