[英]Generic class Implementation for a SpringData & QueryDSL Service
我有一堆具有扩展JpaRepository和QueryDslPredicateExecutor的存储库的服务类。 服务类中的方法除了它所处理的实体外都是相同的。 我正在尝试创建一个通用服务类,但是却收到“注入资源依赖项失败;嵌套的异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有找到依赖项类型为[pkg.BaseRepository]的合格bean:预期为至少1个符合此依赖项自动装配条件的bean”。
以下是我的课程:
//BaseRepository.java
@NoRepositoryBean
public interface BaseRepository<T> extends JpaRepository<T, Long>, QueryDslPredicateExecutor<T> {}
//RegionRepository.java
@Repository
public interface RegionRepository<Region> extends JpaRepository<Region, Long>, QueryDslPredicateExecutor<Region> {}
//ProvinceRepository.java
@Repository
public interface ProvinceRepository<Province> extends JpaRepository<Province, Long>, QueryDslPredicateExecutor<Province> {}
...以及更多XxxRepository接口
//AbstractBaseService.java
public abstract class AbstractBaseService<T>{
@Autowired
private BaseRepository<T> repository;
public void add(T entity) {
System.out.println("Adding entity " + entity.getClass());
}
public T retrieve(Long id) {
System.out.println("Retrieving region with dbId = " + id);
return repository.findOne(id);
}
public List<T> findAll() {
return repository.findAll();
}
...
//some other methods
}
//RegionService.java
@Service("regService")
public class RegionService extends AbstractBaseService<Region> {}
//ProvinceService.java
@Service("provService")
public class ProvinceService extends AbstractBaseService<Province> {}
@Controller
public class MyController {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("/spring/application-context.xml");
MyController controller = new MyController();
controller.run(context);
}
public void run(ApplicationContext context) {
RegionService regService = (RegionService)context.getBean("regService");
Region reg = regService.retrieve(1L);
}
}
我的persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="generics" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" />
</properties>
</persistence-unit>
</persistence>
application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<context:component-scan base-package="com.dreamcorps.gen" />
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:spring/db.properties" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="${jpa.dbVendor}" />
<property name="databasePlatform" value="${jpa.dialect}" />
<property name="showSql" value="${jpa.showSql}" />
<property name="generateDdl" value="false" />
</bean>
</property>
<property name="persistenceUnitName" value="generics" />
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<!-- access -->
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- pool sizing -->
<property name="initialPoolSize" value="${c3p0.initialPoolSize}"/>
<property name="minPoolSize" value="${c3p0.minPoolSize}"/>
<property name="maxPoolSize" value="${c3p0.maxPoolSize}"/>
<property name="acquireIncrement" value="${c3p0.acquireIncrement}"/>
<property name="maxStatements" value="${c3p0.maxStatements}"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
</bean>
<tx:annotation-driven />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<jpa:repositories base-package="com.dreamcorps.gen" />
</beans>
以下是运行MyController时的错误日志。
Dec 12, 2015 12:49:35 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.0.3.Final}
Dec 12, 2015 12:49:35 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Dec 12, 2015 12:49:35 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Dec 12, 2015 12:49:36 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.0.Final}
Dec 12, 2015 12:49:36 AM org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator initiateService
WARN: HHH000181: No appropriate connection provider encountered, assuming application will be supplying connections
Dec 12, 2015 12:49:36 AM org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator initiateService
WARN: HHH000342: Could not obtain connection to query metadata : The application must supply JDBC connections
Dec 12, 2015 12:49:36 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
Dec 12, 2015 12:49:36 AM org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl makeLobCreatorBuilder
INFO: HHH000422: Disabling contextual LOB creation as connection was null
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'regionServiceImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:311)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:835)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.dreamcorps.sample.controller.MyController.main(MyController.java:18)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1192)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:508)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:486)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:615)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:308)
... 13 more
Caused by: java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object
at org.hibernate.jpa.internal.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:210)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:68)
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:67)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:142)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:89)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:71)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:185)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:251)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:237)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
... 28 more
Is there a way to make the AbstractBaseService work as I envision above so that I don't have to create the one Service class with the same implementation as AbstractBaseService for each of my entities (Region, Province, User, Vehicle.... etc)?
任何帮助将不胜感激。
预先感谢,马里奥
//RegionRepository.java
@Repository
public interface RegionRepository<Region> extends JpaRepository<Region, Long>, QueryDslPredicateExecutor<Region> {}
^^^^^^ Here you are actually making a new Type Variable, which is bounded to Object.
您正在创建新的类型变量,这实际上隐藏了要为其创建存储库的类名。
我终于能够完成我原来的工作。 缺少的是上面编辑的BaseRepository.java接口上的@NoRepositoryBean注释和RegionRepository / ProvinceRepository接口上的@Repository注释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.