英文:
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<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CustomJpaRepository<T, ID> {
@Override
public List<T> findAllCustom() {
...
}
}
The base repository is registered using the @EnableJpaRepositories
annotation.
@EnableJpaRepositories(value = "org.somebody.repository", 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<User, Long> { ... }
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 = "org.somebody.repository", 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<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CustomJpaRepository<T, ID> {
private final EntityManager entityManager;
public SimpleCustomJpaRepository(JpaEntityInformation entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
}
@Override
public List<T> findAllCustom() {
...
}
}
Additionally, make sure that interface CustomJpaRepository is annotated with:
@NoRepositoryBean
public interface CustomJpaRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
List<T> findAllCustom();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论