Spring Data JPA Custom Generic Repository Pattern问题

时间:2014-07-05 13:34:09

标签: spring jpa spring-data spring-data-jpa

我在Spring中有以下配置,但由于缺少存储库的Impl类中的init方法,自动装配失败。 Spring不应该尝试通过构造函数初始化bean,但它应该使用Factory ...我错过了一些简单的配置......或者我遇到了一个bug。

我正在尝试实现一个通用存储库,其中所有存储库都可以共享特定于我的映射域类的方法和特定的存储库...

这是我的错误:

Error creating bean with name 'auditRepositoryImpl' defined in file AuditRepositoryImpl.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.domain.biz.dao.impl.AuditRepositoryImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.domain.biz.dao.impl.AuditRepositoryImpl.<init>()

另一方面,看起来我的CustomFactory没有被选中。

2014-07-05 08:16:48,343 DEBUG  org.springframework.data.repository.config.RepositoryComponentProvider Identified candidate component class: file [InventoryRepository.class] 

...

2014-07-05 08:16:48,366 DEBUG  org.springframework.data.repository.config.RepositoryBeanDefinitionBuilder Registering custom repository implementation: auditRepositoryImpl AuditRepositoryImpl 
2014-07-05 08:16:48,367 DEBUG  org.springframework.data.repository.config.RepositoryConfigurationDelegate Registering repository: auditRepository - Interface: AuditRepository - Factory: org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean 







    //Spring Java config
    @Configuration
    @EnableScheduling
    @EnableSpringConfigured
    @Import(EnvConfiguration.class)
    @EnableAspectJAutoProxy
    @EnableJpaRepositories(repositoryFactoryBeanClass = DefaultRepositoryFactoryBean.class, basePackages = { "com.domain.biz.dao" }, repositoryImplementationPostfix = "Impl")
    @EnableCaching
    @EnableTransactionManagement(proxyTargetClass = true)
    @ComponentScan(basePackages = { "com.domain.biz" })
    @Order(2)
    public class AppConfiguration extends CachingConfigurerSupport implements LoadTimeWeavingConfigurer 

    ...

@NoRepositoryBean
public interface GenericRepository<T extends Serializable, I extends Serializable>
        extends JpaRepository<T, I> {

...


@NoRepositoryBean
public abstract class AbstractRepositoryImpl<T extends Serializable, I extends Serializable>
        extends SimpleJpaRepository<T, I> implements GenericRepository<T, I> {

    private static Logger log = LoggerFactory
            .getLogger(AbstractRepositoryImpl.class);

    private Class<T> clazz;

    @Autowired
    EntityManager entityManager;

        @Autowired
        SessionFactory sessionFactory;

        public AbstractRepositoryImpl(Class<T> domainClass, EntityManager em) {
            super(domainClass, em);

        }

        public AbstractRepositoryImpl(JpaEntityInformation<T, ?> entityInformation,
                EntityManager entityManager) {
            super(entityInformation, entityManager);

        }


    ...


        @NoRepositoryBean
        // @Scope( BeanDefinition.SCOPE_PROTOTYPE )
        public class GenericRepositoryImpl<T extends Serializable, I extends Serializable>
                extends AbstractRepositoryImpl<T, I> implements GenericRepository<T, I> {


...

    public interface AuditRepositoryCustom {

        public Audit audit(Audit audit);



    public interface AuditRepository extends GenericRepository<Audit, Long>, AuditRepositoryCustom {




  public class DefaultRepositoryFactoryBean<R extends JpaRepository<T, I>, T extends Serializable, I extends Serializable>
        extends JpaRepositoryFactoryBean<R, T, I> {

    private static class RepositoryFactory<T extends Serializable, I extends Serializable>
            extends JpaRepositoryFactory {

        private EntityManager entityManager;

        public RepositoryFactory(EntityManager entityManager) {
            super(entityManager);

            this.entityManager = entityManager;
        }

        @Override
        protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {

            // The RepositoryMetadata can be safely ignored, it is used by the
            // JpaRepositoryFactory
            // to check for QueryDslJpaRepository's which is out of scope.
            return GenericRepository.class;
        }

        @Override
        protected Object getTargetRepository(RepositoryMetadata metadata) {

            return new GenericRepositoryImpl<T, I>(
                    (Class<T>) metadata.getDomainType(), this.entityManager);
        }
    }

    @Override
    protected RepositoryFactorySupport createRepositoryFactory(
            EntityManager entityManager) {

        return new RepositoryFactory(entityManager);
    }

2 个答案:

答案 0 :(得分:5)

关于根本原因的例外很清楚。您的AuditRepositoryImpl没有no-arg构造函数或使用@Inject / @Autowired注释的构造函数。

答案 1 :(得分:4)

如果有人需要,这是更正后的代码。

@NoRepositoryBean
    public interface GenericRepository<T extends Serializable, I extends Serializable>
            extends JpaRepository<T, I> {

        Result truncate();

...

@NoRepositoryBean
public abstract class AbstractRepositoryImpl<T extends Serializable, I extends Serializable>
        extends SimpleJpaRepository<T, I> implements GenericRepository<T, I> {



    public AbstractRepositoryImpl(Class<T> domainClass, EntityManager em) {
        super(domainClass, em);

    }

    public AbstractRepositoryImpl(JpaEntityInformation<T, ?> entityInformation,
            EntityManager entityManager) {
        super(entityInformation, entityManager);

    }

    @Override
    public Result truncate() {


...


public class GenericRepositoryImpl<T extends Serializable, I extends Serializable>
        extends AbstractRepositoryImpl<T, I> implements GenericRepository<T, I> {

    public GenericRepositoryImpl(Class<T> domainClass, EntityManager em) {
        super(domainClass, em);

    }

    public GenericRepositoryImpl(JpaEntityInformation<T, ?> entityInformation,
            EntityManager entityManager) {
        super(entityInformation, entityManager);

    }


...


public interface AuditRepositoryCustom {

    public Audit audit(Audit audit);

....



public interface AuditRepository extends GenericRepository<Audit, Long>,
AuditRepositoryCustom {


...


@NoRepositoryBean
public class AuditRepositoryImpl extends GenericRepositoryImpl<Audit, Long>
        implements AuditRepositoryCustom {

    private static Logger log = LoggerFactory.getLogger(AuditService.class);

    public AuditRepositoryImpl(Class<Audit> domainClass, EntityManager em) {
        super(domainClass, em);

        log.debug("AuditDAO Created...");
        // TODO Auto-generated constructor stub
    }

    @Autowired
    public AuditRepositoryImpl(EntityManager em) {
        super(Audit.class, em);

    }

    public AuditRepositoryImpl(
            JpaEntityInformation<Audit, ?> entityInformation,
            EntityManager entityManager) {
        super(entityInformation, entityManager);

        log.debug("AuditDAO Created...");
        // TODO Auto-generated constructor stub
    }

    @Override
    public Audit audit(Audit audit) {

        return super.save(audit);

    }