Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Illegal reuse of criteria for count()-operator #352

Closed
julgus opened this issue Jun 30, 2023 · 1 comment
Closed

Illegal reuse of criteria for count()-operator #352

julgus opened this issue Jun 30, 2023 · 1 comment
Assignees
Labels
bug Something isn't working
Milestone

Comments

@julgus
Copy link
Member

julgus commented Jun 30, 2023

Describe the bug
When performing repeated .count() queries, an exception is thrown. This seems to be related to differences between Hibernate 5 and 6, and how JPAStreamer reuses certain Criteria objects when creating the queries.

Expected behavior
The query should execute without exceptions.

Actual behavior
The query yields an exception, see below.

How To Reproduce
Performing the following test reveals the exception:

    @Test
    void countTest() {
        final List<Film> collect = jpaStreamer.stream(Film.class).collect(Collectors.toList());
        
        final long expected = collect.stream()
                .filter(f -> f.getTitle().startsWith("A"))
                .count(); 
        
        final long actual = jpaStreamer.stream(Film.class)
                .filter(Film$.title.startsWith("A"))
                .count(); 
        
        assertEquals(expected, actual);
    }

Exception:

java.lang.IllegalArgumentException: Already registered a copy: SqmBasicValuedSimplePath(com.speedment.jpastreamer.integration.test.model.Film(1295155256344291).title)

	at org.hibernate.query.sqm.tree.SqmCopyContext$1.registerCopy(SqmCopyContext.java:33)
	at org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath.copy(SqmBasicValuedSimplePath.java:53)
	at org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath.copy(SqmBasicValuedSimplePath.java:26)
	at org.hibernate.query.sqm.tree.predicate.SqmLikePredicate.copy(SqmLikePredicate.java:90)
	at org.hibernate.query.sqm.tree.predicate.SqmLikePredicate.copy(SqmLikePredicate.java:19)
	at org.hibernate.query.sqm.tree.predicate.SqmWhereClause.copy(SqmWhereClause.java:33)
	at org.hibernate.query.sqm.tree.select.SqmQuerySpec.copy(SqmQuerySpec.java:104)
...

Build tool
e.g. Maven 3.9.0

JPAStreamer version
e.g. JPAStreamer 3.0.2

JPA Provider
e.g. Hibernate 6.0.2.Final

Java Version
e.g. Java 11.0.17

Additional context
The thread that potentially explains the issue: https://hibernate.atlassian.net/browse/HHH-15951?jql=project%20%3D%20HHH%20AND%20component%20%3D%20hibernate-entitymanager%20AND%20resolution%20%3D%20Unresolved%20AND%20fixVersion%20is%20EMPTY%20ORDER%20BY%20priority%20DESC.

@julgus julgus added the bug Something isn't working label Jun 30, 2023
@julgus julgus self-assigned this Jun 30, 2023
@julgus julgus added this to the 3.0.3 milestone Jun 30, 2023
@julgus
Copy link
Member Author

julgus commented Jun 30, 2023

The issue is how we copy restrictions from the original Criteria when building the count Criteria. These restrictions are associated with a certain Path element that cannot be reused from one Criteria to another.

if (criteriaQuery.getRestriction() != null) {
            countQuery.where(criteriaQuery.getRestriction());
}

I fixed it by recreating the predicate from the internal pipeline. This adds a bit of redundant work but seems like the simplest solution at this point.

if (!filters.isEmpty()) {
    // There can only be one JPAStreamer filter after the filter merge (see FilterCriteriaModifier). 
    IntermediateOperation<?, ?> filter = filters.stream().findFirst().get();
    this.<T>getPredicate(filter).ifPresent(speedmentPredicate -> {
        final Predicate predicate = predicateFactory.createPredicate(countCriteria, speedmentPredicate);
        countQuery.where(predicate);
    });
}

@julgus julgus closed this as completed in 9523193 Jul 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant