我在应用程序上使用带有基于注释的/ JavaConfig配置的 Spring Boot(1.3.3)。 我有以下存储库接口:
@RepositoryRestResource(collectionResourceRel = "something", path = "something")
public interface SomethingRepository
extends CrudRepository<SomethingRepository, Long> {
}
我想要做的是覆盖生成的存储库代理中某些方法的行为。我发现这样做的唯一方法是基于文档建议添加新的自定义方法(参见:Adding custom behavior to single repositories),所以我定义了以下接口:
public interface SomethingRepositoryCustom {
Something findOne(Long id);
}
...我添加了相应的实现:
public SomethingRepositoryImpl extends SimpleJpaRepository<Something, Long>
implements SomethingRepositoryCustom {
public SomethingRepositoryImpl(<Something> domainClass, EntityManager em) {
super(domainClass, em);
this.entityManager = em;
}
@Override
public Something findOne(Long id) {
System.out.println("custom find one");
// do whatever I want and then fetch the object
return null;
}
}
现在,如果我启动应用程序,我会收到以下错误:
... org.springframework.beans.BeanInstantiationException:失败 实例化[com.dummy.repositories.SomethingRepositoryImpl]:不 找到默认构造函数;嵌套异常是 java.lang.NoSuchMethodException: com.dummy.repositories.SomethingRepositoryImpl。()...
问题: 我该如何解决BeanInstantiationException?我假设我需要声明一个存储库工厂bean,但我不知道如何覆盖Spring Boot配置。
答案 0 :(得分:7)
确实,您必须在@EnableJpaRepositories
注释中声明一个新的FactoryBean:
@Configuration
@EnableJpaRepositories(value = "your_package",
repositoryFactoryBeanClass = CustomFactoryBean.class)
public class ConfigurationClass{}
CustomFactoryBean.java:
public class CustomFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> extends JpaRepositoryFactoryBean<R, T, I>{
@Override
protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
return new SimpleJpaExecutorFactory(entityManager);
}
/**
* Simple jpa executor factory
* @param <T>
* @param <I>
*/
private static class SimpleJpaExecutorFactory<T, I extends Serializable> extends JpaRepositoryFactory{
private EntityManager entityManager;
/**
* Simple jpa executor factory constructor
* @param entityManager entity manager
*/
public SimpleJpaExecutorFactory(EntityManager entityManager) {
super(entityManager);
this.entityManager = entityManager;
}
@Override
protected Object getTargetRepository(RepositoryMetadata metadata) {
JpaEntityInformation entityInformation =
getEntityInformation(metadata.getDomainType());
return new SomethingRepositoryImpl<T,I>(entityInformation, entityManager);
}
@Override
protected Class getRepositoryBaseClass(RepositoryMetadata metadata) {
return SomethingRepositoryImpl.class;
}
}
}
然后它将是您的SimpleJpaRepository
实例:SimpleJpaRepositoryImpl
将被使用
答案 1 :(得分:1)
从 1.9 版开始,您不再需要创建新的 FactoryBean 类,而是可以直接设置基础存储库。来自Baeldung:
@Configuration
@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao",
repositoryBaseClass = ExtendedRepositoryImpl.class)
public class StudentJPAH2Config {
// additional JPA Configuration
}
public class ExtendedRepositoryImpl<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID> implements ExtendedRepository<T, ID> {
private EntityManager entityManager;
public ExtendedRepositoryImpl(JpaEntityInformation<T, ?>
entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
}
// ...
}