2013-05-17 2 views
2

Я пытаюсь реализовать пользовательский java Spring JPA-репозиторий, как описано в Spring documentation. кажется, что моя весна конфигурация настаивает на создание хранилищ стандартным образом, вместо того, чтобы использовать данную MyRepositoryFactoryBean, давая мнеSpring JPA 2.0 Repository/Factory не работает

Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.myapp.repository.impl.DocumentRepositoryImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.myapp.repository.impl.DocumentRepositoryImpl.<init>() 
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:83) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1006) 
... 43 more 
Caused by: java.lang.NoSuchMethodException: com.myapp.repository.impl.DocumentRepositoryImpl.<init>() 
at java.lang.Class.getConstructor0(Class.java:2730) 
at java.lang.Class.getDeclaredConstructor(Class.java:2004) 
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:78) 

Я использую Spring 3.2.2-RELEASE и пружинные данные-jpa- 1.3.2-RELEASE, который является последним, если я прав. Вот моя весна конфигурации:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd 
     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
     http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd 
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> 

<import resource="spring-repository-config.xml"/> 
<import resource="spring-security-config.xml"/> 

<context:component-scan base-package="com.myapp.web.controller"/> 
<context:component-scan base-package="com.myapp.webservice.controller"/> 

И вот весна-хранилище-config.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans:beans xmlns="http://www.springframework.org/schema/data/jpa" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:beans="http://www.springframework.org/schema/beans" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
     http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd"> 

<repositories base-package="com.myapp.repository" 
    factory-class="com.myapp.repository.impl.MyRepositoryFactoryBean"/> 
<!-- entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" --> 

If've добавил отладочные точки останова во всех способах ком. myapp.repository.impl.MyRepositoryFactoryBean, но они не вызывались.

Базовый интерфейс, так же, как в примере

package com.myapp.repository.impl; 

@NoRepositoryBean 
public interface MyRepository<T, ID extends Serializable> extends JpaRepository<T, ID> { 

Базовая реализация:

package com.myapp.repository.impl; 

@NoRepositoryBean 
public class MyRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements MyRepository<T, ID> { 

private EntityManager entityManager; 

public MyRepositoryImpl(Class<T> domainClass, EntityManager entityManager) { 
    super(domainClass, entityManager); 

    // This is the recommended method for accessing inherited class dependencies. 
    this.entityManager = entityManager; 
} 

public void sharedCustomMethod(ID id) { 
    // implementation goes here 
} 
} 

И завод:

package com.myapp.repository.impl; 

import java.io.Serializable; 

import javax.persistence.EntityManager; 

import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory; 
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; 
import org.springframework.data.repository.core.RepositoryMetadata; 
import org.springframework.data.repository.core.support.RepositoryFactorySupport; 

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

protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) { 
    return new MyRepositoryFactory(entityManager); 
} 

private static class MyRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory { 
    private EntityManager entityManager; 

    public MyRepositoryFactory(EntityManager entityManager) { 
     super(entityManager); 
     this.entityManager = entityManager; 
    } 

    protected Object getTargetRepository(RepositoryMetadata metadata) { 
     return new MyRepositoryImpl<T, I>((Class<T>) metadata.getDomainType(), entityManager); 
    } 

    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 MyRepositoryImpl.class; 
    } 
} 
} 

Мои репозиториев интерфейсы определяет как:

package com.myapp.repository; 

public interface DocumentRepository { // extends MyRepository<Document, Long> 

public Document findByDocumentHash(String hashCode); 

public Document findById(long id); 

} 

И реализация

package com.myapp.repository.impl; 

import java.io.Serializable; 

import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 

public class DocumentRepositoryImpl<Document, ID extends Serializable> extends MyRepositoryImpl<Document, Serializable> { 

    private static final long serialVersionUID = 1L; 

     public DocumentRepositoryImpl(Class<Document> domainClass, EntityManager entityManager) { 
     super(domainClass, entityManager); 
    } 

И я использую эти репозиториев autowired в моих ссылке, контроллеры:

package com.myapp.web.controller; 

@Controller 
@RequestMapping(value = "/documents") 
public class DocumentController { 

@Autowired 
private DocumentRepository documentRepository; 

@RequestMapping(method = RequestMethod.GET) 
public ModelAndView list(HttpServletRequest request) { 
    this.documentRepository. ... 
} 

Я посмотрел на различные ресурсы в Интернете, как this one, но я могу Не могу сказать разницу с моим кодом. Любые намеки более чем приветствуются!

+0

когда-нибудь решают это? –

ответ

0

Вы должны по умолчанию конструктор для com.myapp.repository.impl.DocumentRepositoryImpl

public DocumentRepositoryImpl(){} 

Spring первый экземпляр бобы, которые вы объявляете в контексте приложения (в вашем случае), вызвав конструктор по умолчанию (без параметров), а затем использует сеттеры вводить другие фасоль.

+0

Thx для быстрого ответа. Но родительский класс SimpleJpaRepository имеет 2 конструктора, каждый из которых должен содержать 2 аргумента. [Утверждение не выполнено] - этот аргумент требуется; он не должен быть нулевым org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata (JpaEntityInformationSupport.java:58) at org.springframework.data.jpa.repository.support.SimpleJpaRepository. (SimpleJpaRepository.java:91) at com.myapp.repository.impl.MyRepositoryImpl. (MyRepositoryImpl.java:18) at com.myapp.repository.impl.DocumentRepositoryImpl. Ronald

+1

И класс PersonRepoImpl здесь (http://hvanhove.blogspot.nl/2013/03/generic-repo-for-all-repositories.html) не имеет конструктора по умолчанию. – Ronald