Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data JPA Custom Generic Repository Pattern issue

I have the following configuration in Spring but Autowiring fails due to lack of an init method in the Impl class of the repository. Spring shouldn't be attempting to init the bean by a constructor, but it should be using the Factory ... I've missed some simple configuration... or I have ran into a bug.

I am trying to achieve a single generic repository where all repositories can share methods and specific ones that are particular to my mapped domain classes...

Here is my error:

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

On another side note, it looks like my CustomFactory isn't being picked up.

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);
    }
like image 882
chrislhardin Avatar asked Jan 27 '26 17:01

chrislhardin


2 Answers

The exception is pretty clear about the root cause. Your AuditRepositoryImpl does not have either a no-arg constructor or a constructor annotated with @Inject/@Autowired.

like image 124
Oliver Drotbohm Avatar answered Jan 30 '26 19:01

Oliver Drotbohm


Here is the corrected code in case anyone needs it.

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

    }
like image 43
chrislhardin Avatar answered Jan 30 '26 17:01

chrislhardin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!