没有 Spring 引导,泛型会失败?
Generics fails without Spring Boot?
我有这个配置class:
@Configuration
@Import(PersistenceConfiguration.class)
public class DAOConfiguration {
@PersistenceContext
private EntityManager entityManager;
@Bean
public ClientDAO clientDAO() {
SimpleJpaRepository<Client, String> support = this.getSimpleJpaRepository(Client.class);
return new MySQLClientDAO(support);
}
@Bean
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Description("Hibernate repository helper")
protected <T> SimpleJpaRepository<T, String> getSimpleJpaRepository(Class<T> domainClass) {
return new SimpleJpaRepository<T, String>(domainClass, this.entityManager);
}
}
如果我 运行 它与 Spring 引导,一切正常。但如果我不这样做,我会得到这个例外:
Caused by: java.lang.ClassCastException: com.sun.proxy.$Proxy36 cannot be cast to org.springframework.data.jpa.repository.support.SimpleJpaRepository
at com.example.movies.domain.config.DAOConfiguration$$EnhancerBySpringCGLIB$8dfcc5.getSimpleJpaRepository(<generated>) ~[spring-core-4.1.6.RELEASE.jar:na]
at com.example.movies.domain.config.DAOConfiguration.clientDAO(DAOConfiguration.java:27) ~[classes/:na]
at com.example.movies.domain.config.DAOConfiguration$$EnhancerBySpringCGLIB$8dfcc5.CGLIB$clientDAO[=12=](<generated>) ~[spring-core-4.1.6.RELEASE.jar:na]
at com.example.movies.domain.config.DAOConfiguration$$EnhancerBySpringCGLIB$8dfcc5$$FastClassBySpringCGLIB$fcb656.invoke(<generated>) ~[spring-core-4.1.6.RELEASE.jar:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at com.example.movies.domain.config.DAOConfiguration$$EnhancerBySpringCGLIB$8dfcc5.clientDAO(<generated>) ~[spring-core-4.1.6.RELEASE.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_75]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_75]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_75]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_75]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
... 43 common frames omitted
16:31:50.506 [main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test class: context [DefaultTestContext@4ff04845 testClass = ClientDAOTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@75c57e85 testClass = ClientDAOTest, locations = '{}', classes = '{class com.example.movies.domain.config.DAOConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], dirtiesContext [false].
你知道这是怎么回事吗?我很困惑...提前致谢
编辑
这是失败的行:
return new SimpleJpaRepository<T, String>(domainClass, this.entityManager);
我会说你的做法是错误的,你不应该乱搞 SimpleJapRepository
。您应该使用 @EnableJpaRepositories
并让它完成工作。
您应该做的是创建一个扩展 Spring 数据存储库接口之一的接口并添加 @EnableJpaRepository
,基本上就是这样。不 MySQLClientDAO
只是一个接口,您将在运行时为其提供一个实现。
public interface ClientDAO<Client, String> extends JpaRepository {... }
然后在你的配置中
@Configuration
@Import(PersistenceConfiguration.class)
@EnableJpaRepositories(basePackages={"package.containing.repository.interfaces"}
public class DAOConfiguration { }
这基本上就是您所需要的。
如果您有另一个存储库,您唯一需要做的就是添加另一个接口。
public interface MovieDAO<Movie, String> extends CrudRepository { ... }
我有这个配置class:
@Configuration
@Import(PersistenceConfiguration.class)
public class DAOConfiguration {
@PersistenceContext
private EntityManager entityManager;
@Bean
public ClientDAO clientDAO() {
SimpleJpaRepository<Client, String> support = this.getSimpleJpaRepository(Client.class);
return new MySQLClientDAO(support);
}
@Bean
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Description("Hibernate repository helper")
protected <T> SimpleJpaRepository<T, String> getSimpleJpaRepository(Class<T> domainClass) {
return new SimpleJpaRepository<T, String>(domainClass, this.entityManager);
}
}
如果我 运行 它与 Spring 引导,一切正常。但如果我不这样做,我会得到这个例外:
Caused by: java.lang.ClassCastException: com.sun.proxy.$Proxy36 cannot be cast to org.springframework.data.jpa.repository.support.SimpleJpaRepository
at com.example.movies.domain.config.DAOConfiguration$$EnhancerBySpringCGLIB$8dfcc5.getSimpleJpaRepository(<generated>) ~[spring-core-4.1.6.RELEASE.jar:na]
at com.example.movies.domain.config.DAOConfiguration.clientDAO(DAOConfiguration.java:27) ~[classes/:na]
at com.example.movies.domain.config.DAOConfiguration$$EnhancerBySpringCGLIB$8dfcc5.CGLIB$clientDAO[=12=](<generated>) ~[spring-core-4.1.6.RELEASE.jar:na]
at com.example.movies.domain.config.DAOConfiguration$$EnhancerBySpringCGLIB$8dfcc5$$FastClassBySpringCGLIB$fcb656.invoke(<generated>) ~[spring-core-4.1.6.RELEASE.jar:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at com.example.movies.domain.config.DAOConfiguration$$EnhancerBySpringCGLIB$8dfcc5.clientDAO(<generated>) ~[spring-core-4.1.6.RELEASE.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_75]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_75]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_75]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_75]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
... 43 common frames omitted
16:31:50.506 [main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test class: context [DefaultTestContext@4ff04845 testClass = ClientDAOTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@75c57e85 testClass = ClientDAOTest, locations = '{}', classes = '{class com.example.movies.domain.config.DAOConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], dirtiesContext [false].
你知道这是怎么回事吗?我很困惑...提前致谢
编辑
这是失败的行:
return new SimpleJpaRepository<T, String>(domainClass, this.entityManager);
我会说你的做法是错误的,你不应该乱搞 SimpleJapRepository
。您应该使用 @EnableJpaRepositories
并让它完成工作。
您应该做的是创建一个扩展 Spring 数据存储库接口之一的接口并添加 @EnableJpaRepository
,基本上就是这样。不 MySQLClientDAO
只是一个接口,您将在运行时为其提供一个实现。
public interface ClientDAO<Client, String> extends JpaRepository {... }
然后在你的配置中
@Configuration
@Import(PersistenceConfiguration.class)
@EnableJpaRepositories(basePackages={"package.containing.repository.interfaces"}
public class DAOConfiguration { }
这基本上就是您所需要的。
如果您有另一个存储库,您唯一需要做的就是添加另一个接口。
public interface MovieDAO<Movie, String> extends CrudRepository { ... }