配置带有自定义基础存储库的Spring @DataJpaTest

huangapple go评论95阅读模式
英文:

Configure Spring @DataJpaTest with custom base repository

问题

假设有一个自定义的基础 JpaRepository 实现如下所示。

public class SimpleCustomJpaRepository<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CustomJpaRepository<T, ID> {

    @Override
    public List<T> findAllCustom() {

        ...
    }
}

使用 @EnableJpaRepositories 注解注册基础存储库。

@EnableJpaRepositories(value = "org.somebody.repository", repositoryBaseClass = SimpleCustomJpaRepository.class)

我应该如何配置一个关于 UserRepository 的集成测试,该存储库扩展了 CustomJpaRepository 接口,因此应该使用自定义的基础实现?

public interface UserRepository extends CustomJpaRepository<User, Long> { ... }

目前使用的集成测试失败,出现 org.springframework.data.mapping.PropertyReferenceException: No property findAllCustom found for type User!。实际上,它未能加载 ApplicationContext,因为我的自定义基础存储库实现在集成测试期间未被注册,因此找不到 findAllCustom 的实现。

@ExtendWith(SpringExtension.class)
@DataJpaTest
class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;
}

我应该如何在 JPA 存储库集成测试中注册自定义的 JpaRepository 实现?

英文:

Let's assume a custom base JpaRepository implementation like the following.

public class SimpleCustomJpaRepository&lt;T, ID extends Serializable&gt; extends SimpleJpaRepository&lt;T, ID&gt; implements CustomJpaRepository&lt;T, ID&gt; {

    @Override
    public List&lt;T&gt; findAllCustom() {

        ...
    }
}

The base repository is registered using the @EnableJpaRepositories annotation.

@EnableJpaRepositories(value = &quot;org.somebody.repository&quot;, repositoryBaseClass = SimpleCustomJpaRepository.class)

How should I configure a integration test for the UserRepository that's extending the CustomJpaRepository interface and should therefor use the custom base implementation?

public interface UserRepository extends CustomJpaRepository&lt;User, Long&gt; { ... }

The currently used integration test fails with org.springframework.data.mapping.PropertyReferenceException: No property findAllCustom found for type User!. Actually it failed to load the ApplicationContext because my custom base repository implementation is not registered during integration test and therefor no implementation for findAllCustom was found.

@ExtendWith(SpringExtension.class)
@DataJpaTest
class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository. 
}

How should I register a custom JpaRepository implementation in combination with a JPA repository integration test?

答案1

得分: 5

我仍然无法解释问题的原因,但是手动配置JPA已经解决了我的问题。

@TestConfiguration
@EnableAutoConfiguration(exclude = {JpaRepositoriesAutoConfiguration.class})
@EnableJpaRepositories(value = "org.somebody.repository", repositoryBaseClass = SimpleCustomJpaRepository.class)
public class JpaTestConfig {

    ...
}

我只是在我的测试中导入了这个额外的配置类,它就像魔法一样起作用。

@ExtendWith(SpringExtension.class)
@DataJpaTest
@Import(JpaTestConfig.class)
class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;
}
英文:

I still can't explain the cause of the problem, but manually configuring the JPA has solved my problem.

@TestConfiguration
@EnableAutoConfiguration(exclude = {JpaRepositoriesAutoConfiguration.class})
@EnableJpaRepositories(value = &quot;org.somebody.repository&quot;, repositoryBaseClass = SimpleCustomJpaRepository.class)
public class JpaTestConfig {

    ...
}

I just imported this additional configuration class in my tests and it works like a charm.

@ExtendWith(SpringExtension.class)
@DataJpaTest
@Import(JpaTestConfig.class)
class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository. 
}

答案2

得分: 0

SimpleCustomJpaRepository的构造函数应如下所示:

public class SimpleCustomJpaRepository<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CustomJpaRepository<T, ID> {
    
    private final EntityManager entityManager;
    
    public SimpleCustomJpaRepository(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityManager = entityManager;
    }
    
    @Override
    public List<T> findAllCustom() {
    
        ...
    }
}

此外,请确保CustomJpaRepository接口被注解如下:

@NoRepositoryBean
public interface CustomJpaRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
    List<T> findAllCustom();
}
英文:

The constructor of SimpleCustomJpaRepository should look like:

public class SimpleCustomJpaRepository&lt;T, ID extends Serializable&gt; extends SimpleJpaRepository&lt;T, ID&gt; implements CustomJpaRepository&lt;T, ID&gt; {

	private final EntityManager entityManager;
	
	public SimpleCustomJpaRepository(JpaEntityInformation entityInformation, EntityManager entityManager) {
		super(entityInformation, entityManager);
		this.entityManager = entityManager;
	}

	@Override
	public List&lt;T&gt; findAllCustom() {

        ...
	}
}

Additionally, make sure that interface CustomJpaRepository is annotated with:

@NoRepositoryBean
public interface CustomJpaRepository&lt;T, ID extends Serializable&gt; extends JpaRepository&lt;T, ID&gt; {
	List&lt;T&gt; findAllCustom();
}

huangapple
  • 本文由 发表于 2020年4月3日 22:23:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/61014009.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定