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

java.lang.IllegalStateException is thrown by invoking findBy method #3294

Open
quaff opened this issue Jan 3, 2024 · 4 comments
Open

java.lang.IllegalStateException is thrown by invoking findBy method #3294

quaff opened this issue Jan 3, 2024 · 4 comments
Assignees
Labels
status: pending-design-work Needs design work before any code can be developed type: enhancement A general enhancement

Comments

@quaff
Copy link
Contributor

quaff commented Jan 3, 2024

java.lang.IllegalStateException: No MethodInvocation found: Check that an AOP invocation is in progress, and that the CrudMethodMetadataPopulatingMethodInterceptor is upfront in the interceptor chain.
	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.currentInvocation(CrudMethodMetadataPostProcessor.java:123)
	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$ThreadBoundTargetSource.getTarget(CrudMethodMetadataPostProcessor.java:294)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:229)
	at jdk.proxy2/jdk.proxy2.$Proxy100.getLockModeType(Unknown Source)
	at org.springframework.data.jpa.repository.support.SimpleJpaRepository.applyRepositoryMethodMetadata(SimpleJpaRepository.java:845)
	at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:756)
	at org.springframework.data.jpa.repository.support.SimpleJpaRepository.lambda$doFindBy$2(SimpleJpaRepository.java:521)
	at org.springframework.data.jpa.repository.support.FetchableFluentQueryBySpecification.createSortedAndProjectedQuery(FetchableFluentQueryBySpecification.java:183)
	at org.springframework.data.jpa.repository.support.FetchableFluentQueryBySpecification.stream(FetchableFluentQueryBySpecification.java:166)
	at findby.FindByTests.findBy(FindByTests.java:30)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Here is test case:

package findby;

import java.util.function.Function;
import java.util.stream.Stream;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.data.jpa.domain.AbstractPersistable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.test.context.ContextConfiguration;

import jakarta.persistence.Entity;

@DataJpaTest
@EnableJpaRepositories(basePackageClasses = FindByTests.TestEntityRepository.class, considerNestedRepositories = true)
@EntityScan(basePackageClasses = FindByTests.TestEntity.class)
@ContextConfiguration(classes = FindByTests.class)
class FindByTests {

	@Autowired
	TestEntityRepository repository;

	@Test
	void findBy() {
		// will throw java.lang.IllegalStateException: No MethodInvocation found
		repository.findBy((root, query, cb) -> null, Function.identity()).stream();
	}

	@Test
	void findByInDefaultMethod() {
		// works fine
		repository.findByInDefaultMethod();
	}

	interface TestEntityRepository extends JpaRepository<TestEntity, Long>, JpaSpecificationExecutor<TestEntity> {

		default Stream<TestEntity> findByInDefaultMethod() {
			return findBy((root, query, cb) -> null, Function.identity()).stream();
		}

	}

	@Entity
	static class TestEntity extends AbstractPersistable<Long> {

	}

}

with

plugins {
	id 'java'
	id 'org.springframework.boot' version '3.2.1'
	id 'io.spring.dependency-management' version 'latest.release'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testRuntimeOnly 'com.h2database:h2'
}

tasks.named('test') {
	useJUnitPlatform()
}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jan 3, 2024
@pbeltechi
Copy link

I also ecountered this using "org.springframework.boot:spring-boot-starter-data-mongodb"

@christophstrobl
Copy link
Member

Thank you @quaff for reporting and adding the test snippet. The current behaviour, though unintuitive, is the expected one. The findBy method in this case exposes the FetchableFluentQuery outside the repository. So when the stream invocation happens the context is already gone.

We're considering to enhance the current flow so that we capture method metadata early and can provide it later on in this scenario.

Meanwhile you can try it this way repository.findBy((root, query, cb) -> null, FetchableFluentQuery::stream).

@christophstrobl christophstrobl added status: pending-design-work Needs design work before any code can be developed type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Jan 9, 2024
@christophstrobl christophstrobl self-assigned this Jan 9, 2024
@quaff
Copy link
Contributor Author

quaff commented Jan 10, 2024

Meanwhile you can try it this way repository.findBy((root, query, cb) -> null, FetchableFluentQuery::stream).

Thanks, it works, does the document mention such limitation?

@christophstrobl
Copy link
Member

Unfortunately not, all samples are using one of the terminating (one, first, all,...) methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: pending-design-work Needs design work before any code can be developed type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants