Skip to content

Deprecated Specification cannot be replaced by QuerySpecification #3791

@ds-usova

Description

@ds-usova

Expected Behavior

Deprecated classes are replacable with non-deprecated classes (https://micronaut-projects.github.io/micronaut-data/latest/api/deprecated-list.html):

  1. io.micronaut.data.hibernate.reactive.repository.jpa.ReactorJpaSpecificationExecutor (deprecated)
    io.micronaut.data.repository.jpa.reactive.ReactorJpaSpecificationExecutor

  2. io.micronaut.data.jpa.repository.criteria.Specification (deprecated)
    io.micronaut.data.repository.jpa.criteria.QuerySpecification

Actual Behaviour

findAll in a repository implementing ReactorJpaSpecificationExecutor throws an exception:

org.hibernate.HibernateException: java.lang.ClassCastException: class io.micronaut.data.runtime.criteria.RuntimePersistentEntityCriteriaQuery cannot be cast to class org.hibernate.query.sqm.tree.select.SqmSelectStatement (io.micronaut.data.runtime.criteria.RuntimePersistentEntityCriteriaQuery and org.hibernate.query.sqm.tree.select.SqmSelectStatement are in unnamed module of loader 'app')

at org.hibernate.reactive.session.impl.ReactiveExceptionConverter.convert(ReactiveExceptionConverter.java:27)
at org.hibernate.reactive.session.impl.ReactiveSessionImpl.createReactiveQuery(ReactiveSessionImpl.java:348)
at org.hibernate.reactive.stage.impl.StageSessionImpl.createQuery(StageSessionImpl.java:526)
at io.micronaut.data.hibernate.reactive.operations.DefaultHibernateReactiveRepositoryOperations.lambda$findAll$31(DefaultHibernateReactiveRepositoryOperations.java:450)
...

Steps To Reproduce

  1. Verify working setup (deprecated)

Repository

import io.micronaut.data.hibernate.reactive.repository.jpa.ReactorJpaSpecificationExecutor;
import io.micronaut.data.repository.reactive.ReactorPageableRepository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Repository
public interface BookLegacyRepository extends ReactorPageableRepository<Book, Long>, ReactorJpaSpecificationExecutor<Book> {

    Flux<Book> findByAuthor(String author);

}

Test (passes)

@Test
    void legacy_findAllBySpecificationFiltersCorrectly() {
        Specification<Book> authorSpec = (root, query, criteriaBuilder) ->
                criteriaBuilder.equal(root.get("author"), "J.K. Rowling");

        List<Book> books = bookLegacyRepository.findAll(authorSpec).collectList().block();

        assertNotNull(books);
        assertFalse(books.isEmpty());
        assertEquals(2, books.size());
        assertTrue(books.stream().allMatch(book -> "J.K. Rowling".equals(book.getAuthor())));
    }
  1. Replace the deprecated classes with QuerySpecification and ReactorJpaSpecificationExecutor and run the query on the same data set.

Repository

import io.micronaut.data.annotation.Repository;
import io.micronaut.data.repository.jpa.reactive.ReactorJpaSpecificationExecutor;

@Repository
public interface BookRepository extends ReactorJpaSpecificationExecutor<Book> {

}

Test (fails)

    @Test
    void findAllBySpecificationFiltersCorrectly() {
        QuerySpecification<Book> authorSpec = (root, query, criteriaBuilder) ->
                criteriaBuilder.equal(root.get("author"), "J.K. Rowling");

        List<Book> books = bookRepository.findAll(authorSpec).collectList().block();

        assertNotNull(books);
        assertFalse(books.isEmpty());
        assertEquals(2, books.size());
        assertTrue(books.stream().allMatch(book -> "J.K. Rowling".equals(book.getAuthor())));
    }

Environment Information

No response

Example Application

https://github.com/ds-usova/micronaut-data-bug

Version

4.10.10

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions