Skip to content
This repository was archived by the owner on Feb 23, 2023. It is now read-only.

Fix data repository type resolution. #1442

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

package org.springframework.data;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.aot.context.bootstrap.generator.bean.BeanRegistrationWriter;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
Expand All @@ -34,6 +38,7 @@
* repository with the resolved generics of the repository.
*
* @author Stephane Nicoll
* @author Christoph Strobl
*/
class RepositoryFactoryBeanPostProcessor implements BeanDefinitionPostProcessor, BeanFactoryAware {

Expand Down Expand Up @@ -61,10 +66,10 @@ private void resolveRepositoryFactoryBeanTypeIfNecessary(RootBeanDefinition bean
Class<?> repositoryType = loadRepositoryType(valueHolder);
if (repositoryType != null) {
ResolvableType resolvableType = ResolvableType.forClass(repositoryType).as(Repository.class);
ResolvableType entityType = resolvableType.getGenerics()[0];
ResolvableType idType = resolvableType.getGenerics()[1];
List<ResolvableType> typeArgs = new ArrayList<>(Arrays.asList(resolvableType.getGenerics()));
typeArgs.add(0, ResolvableType.forClass(repositoryType));
ResolvableType resolvedRepositoryType = ResolvableType.forClassWithGenerics(
beanDefinition.getBeanClass(), ResolvableType.forClass(repositoryType), entityType, idType);
beanDefinition.getBeanClass(), typeArgs.toArray(new ResolvableType[0]));
beanDefinition.setTargetType(resolvedRepositoryType);
beanDefinition.setAttribute(BeanRegistrationWriter.PRESERVE_TARGET_TYPE, true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ void resolveRepositoryTypeWithTypeAsString() {
assertThat(beanDefinition.getAttribute(BeanRegistrationWriter.PRESERVE_TARGET_TYPE)).isEqualTo(true);
}

@Test
void resolveRepositoryTypeIfNotDirectSubOfRepository() {
RootBeanDefinition beanDefinition = (RootBeanDefinition) BeanDefinitionBuilder.rootBeanDefinition(JpaRepositoryFactoryBean.class)
.addConstructorArgValue("org.springframework.data.RepositoryFactoryBeanPostProcessorTests.RockstarRepository").getBeanDefinition();
assertThat(beanDefinition.getResolvableType().hasUnresolvableGenerics()).isTrue();
postProcess(beanDefinition);
assertFactoryBeanForRockstarRepository(beanDefinition.getResolvableType());
assertThat(beanDefinition.getAttribute(BeanRegistrationWriter.PRESERVE_TARGET_TYPE)).isEqualTo(true);
}

@Test
void resolveRepositoryTypeWithTypeAsStringThatDoesNotExist() {
RootBeanDefinition beanDefinition = (RootBeanDefinition) BeanDefinitionBuilder.rootBeanDefinition(JpaRepositoryFactoryBean.class)
Expand Down Expand Up @@ -109,6 +119,13 @@ private void assertFactoryBeanForSpeakerRepository(ResolvableType resolvedType)
assertThat(resolvedType.getGenerics()[2].resolve()).isEqualTo(Integer.class);
}

private void assertFactoryBeanForRockstarRepository(ResolvableType resolvedType) {
assertThat(resolvedType.hasUnresolvableGenerics()).isFalse();
assertThat(resolvedType.getGenerics()[0].resolve()).isEqualTo(RockstarRepository.class);
assertThat(resolvedType.getGenerics()[1].resolve()).isEqualTo(Speaker.class);
assertThat(resolvedType.getGenerics()[2].resolve()).isEqualTo(Integer.class);
}

private void postProcess(RootBeanDefinition beanDefinition) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
RepositoryFactoryBeanPostProcessor processor = new RepositoryFactoryBeanPostProcessor();
Expand All @@ -120,6 +137,10 @@ interface SpeakerRepository extends CrudRepository<Speaker, Integer> {

}

interface RockstarRepository extends SpeakerRepository {

}

static class Speaker {

}
Expand Down