Spring Data JPA自定义通用仓库模式问题

3

我在Spring中有以下配置,但Autowiring失败,因为存储库的Impl类缺少一个init方法。Spring不应该尝试通过构造函数初始化bean,而应该使用Factory...我可能错过了一些简单的配置...或者遇到了一个错误。

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

这是我的错误:

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个回答

5
异常信息非常清晰明了,原因是您的 AuditRepositoryImpl 没有无参构造函数或带有 @Inject/@Autowired 注解的构造函数。

是的,我承认这一点。Spring Data Jpa存储库示例中没有默认构造函数。我正在寻求来自曾经完成此操作或具有Spring Data权威经验的人的回应。 - chrislhardin
2
我认为我至少在这个主题上有一些经验,因为我写了这个东西:)。在你的情况下,问题并不真正与Spring Data有关。自定义实现首先是一个普通的Spring bean。如果您添加一个空构造函数或注释构造函数以进行自动装配,您将看到它起作用。 - Oliver Drotbohm
最终情况比那还要复杂一些...接口的继承出现了问题。我会发布正确的代码。不过,感谢你指出了问题的部分。 - chrislhardin

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);

    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接