-
Notifications
You must be signed in to change notification settings - Fork 38.2k
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
Generic interface on FactoryBean
class not autowired in case of targetType
mismatch
#32489
Comments
Could you indicate more specifically between which versions you see this regression: from 5.3.x to 6.1.4, I suppose? To be on the safe side, you can also try against 6.1.5 even though I do not expect a difference there. The current behavior is present since 6.0 already and has not changed recently. |
I just tried this also with Spring Framework 6.1.5 but behavior stayed the same. And the regression seems to have appeared between versions 6.0.17 and 6.1.1 |
I confirm it works with Spring Boot 3.1.9/Spring Framework 6.0.17 but failed with Spring Boot 3.2.3/Spring Framework 6.1.4. import java.util.List;
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.config.EnableJpaRepositories;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.core.support.RepositoryFactoryInformation;
import org.springframework.test.context.ContextConfiguration;
import jakarta.persistence.Entity;
@DataJpaTest
@EnableJpaRepositories(basePackageClasses = InjectTests.TestEntityRepository.class, considerNestedRepositories = true)
@EntityScan(basePackageClasses = InjectTests.TestEntity.class)
@ContextConfiguration(classes = InjectTests.class)
class InjectTests {
@Autowired
private List<RepositoryFactoryInformation<?, ?>> repositoryFactoryInformations;
@Autowired
private List<JpaRepositoryFactoryBean<?, ?, ?>> jpaRepositoryFactoryBeans;
@Test
void test() {
assertThat(repositoryFactoryInformations).isEqualTo(jpaRepositoryFactoryBeans);
}
interface TestEntityRepository extends JpaRepository<TestEntity, Long> {
}
@Entity
static class TestEntity extends AbstractPersistable<Long> {
}
} plugins {
id 'java'
id 'org.springframework.boot' version '3.2.3'
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()
}
|
Created another reproducer using spring-context and replicating the behavior of spring-data-commons. The issue is present in spring-beans 6.0.0 until latest (6.1.5) and works fine in spring-beans 5.x versions e.g. 5.3.33 This issue started happening because spring-data-commons is generating bean definitions for FactoryBeans with beanDefinition.setTargetType(getRepositoryInterface(configuration)); The reproducer: @Configuration
public class Main {
public interface GenericIntf<T> {}
// Default bean definition doesn't have targetType set so won't reproduce
// @Component
public static class MyFactoryBean<T extends CharSequence> implements FactoryBean<T>, GenericIntf<T> {
@Override
public T getObject() { return (T) "bean"; }
@Override
public Class<?> getObjectType() { return String.class; }
}
@Component
public record FactoryHolder(List<GenericIntf<?>> factoryBeans) { // Inject site is not FactoryBean
public FactoryHolder {
System.out.println(factoryBeans);
}
}
@Component // Uncomment and use @Component on MyFactoryBean to see expected behavior
public static class BFPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
RootBeanDefinition rbd = new RootBeanDefinition();
rbd.setBeanClass(MyFactoryBean.class);
// Important: Replicate org.springframework.data.repository.config.RepositoryConfigurationDelegate#registerRepositoriesIn
// behavior of setting targetType, required to hit other branch in org.springframework.beans.factory.support.GenericTypeAwareAutowireCandidateResolver.checkGenericTypeMatch
rbd.setTargetType(ResolvableType.forClassWithGenerics(MyFactoryBean.class, String.class));
((BeanDefinitionRegistry) beanFactory).registerBeanDefinition("myBean", rbd);
System.out.println("Registered FactoryBean def: " + rbd);
}
}
public static void main(String[] args) {
new AnnotationConfigApplicationContext(Main.class).start();
}
} The issue seems to happen due to the change 0e9eab5#diff-bc3adc4d2ff654e867247e2887b0f6e738b2d07bc55f6ff45328d406be53c74f if (resolvedClass != null && FactoryBean.class.isAssignableFrom(resolvedClass)) {
Class<?> typeToBeMatched = dependencyType.resolve();
if (typeToBeMatched != null && !FactoryBean.class.isAssignableFrom(typeToBeMatched)) {
targetType = targetType.getGeneric(); The bean candidate |
@murkaje I haven't tried it yet (it would be better to share something we can clone or download rather than having to copy paste code in text from a comment), but what the OP shared is working with Spring Framework |
I can see that there is a change in Spring Data between Spring Boot |
FactoryBean
class not autowired in case of targetType
mismatch
Affects: \6.1.4
We have encountered an issue where RepositoryFactoryInformation is no longer autowired correctly.
E.g.
@Service public class MyService { private final List<RepositoryFactoryInformation<?, ?>> repositoryFactoryInformations; private final List<JpaRepositoryFactoryBean<?, ?, ?>> jpaRepositoryFactoryBeans;
JpaRepositoryFactoryBean is found, but RepositoryFactoryInformation is not, although JpaRepositoryFactoryBean also implements RepositoryFactoryInformation.
A small project with a more complete description and reproduction is available here: https://github.com/Pinusar/RepositoryFactoryInformationBug
The issue might be related to this commit: 0e9eab5#diff-bc3adc4d2ff654e867247e2887b0f6e738b2d07bc55f6ff45328d406be53c74f
The text was updated successfully, but these errors were encountered: