如何通过Xml配置连接JpaRepository的(子类/子接口)?
所以我有一个JpaRepository的“实现”
import org.springframework.data.jpa.repository.JpaRepository; import java.time.OffsetDateTime; import java.util.Collection; import java.util.Optional; public interface MyDepartmentJpaRepo extends JpaRepository<Department, Long> { /* "lookup strategy". see https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods */ Optional<Department> findDepartmentByDepartmentNameEquals(String departmentName); Collection<Department> findByCreateOffsetDateTimeBefore(OffsetDateTime zdt); }
和实体
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import java.time.OffsetDateTime; @Entity @Table(name = "DepartmentTable") public class Department { @Id @Column(name = "DepartmentKey", unique = true) @GeneratedValue(strategy = GenerationType.AUTO) private long departmentKey; @Column(name = "DepartmentName", unique = true) private String departmentName; @Column(name = "CreateOffsetDateTime", columnDefinition = "TIMESTAMP WITH TIME ZONE" ) private OffsetDateTime createOffsetDateTime; public long getDepartmentKey() { return departmentKey; } public void setDepartmentKey(long departmentKey) { this.departmentKey = departmentKey; } public String getDepartmentName() { return departmentName; } public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } public OffsetDateTime getCreateOffsetDateTime() { return createOffsetDateTime; } public void setCreateOffsetDateTime(OffsetDateTime createOffsetDateTime) { this.createOffsetDateTime = createOffsetDateTime; } }
和我需要注入MyDepartmentJpaRepo的类
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; import java.time.OffsetDateTime; import java.util.Collection; import java.util.List; import java.util.Optional; public class DepartmentManager implements IDepartmentManager { private final Logger logger; private final MyDepartmentJpaRepo deptRepo; /* The Inject annotation marks which constructor to use for IoC when there are multiple constructors */ @Inject public DepartmentManager(MyDepartmentJpaRepo deptRepo) { this(LoggerFactory.getLogger(DepartmentManager.class), deptRepo); } public DepartmentManager(Logger lgr, MyDepartmentJpaRepo deptRepo) { if (null == lgr) { throw new IllegalArgumentException("Logger is null"); } if (null == deptRepo) { throw new IllegalArgumentException("IDepartmentDomainData is null"); } this.logger = lgr; this.deptRepo = deptRepo; } @Override public Collection<Department> getAll() { List<Department> returnItems = this.deptRepo.findAll(); return returnItems; } @Override public Optional<Department> getSingle(long key) { Optional<Department> returnItem = this.deptRepo.findById(key); return returnItem; } @Override public Optional<Department> getSingleByName(String deptName) { Optional<Department> returnItem = this.deptRepo.findDepartmentByDepartmentNameEquals(deptName); return returnItem; } public Collection<Department> getDepartmentsOlderThanDate(OffsetDateTime zdt) { Collection<Department> returnItems = this.deptRepo.findByCreateOffsetDateTimeBefore(zdt); return returnItems; } @Override public Department save(Department item) { Department returnItem = this.deptRepo.save(item); return returnItem; } }
和“管理器”的接口以确保完整性。
import java.time.OffsetDateTime; import java.util.Collection; import java.util.Optional; public interface IDepartmentManager { Collection<Department> getAll(); Optional<Department> getSingle(long key); Optional<Department> getSingleByName(String deptName); Department save(Department item); Collection<Department> getDepartmentsOlderThanDate(OffsetDateTime zdt); }
问题出在applicationcontext.xml中。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <import resource="jpaSetup.di.xml"/> <bean id="MyDepartmentJpaRepoBean" class="com.mycompany.blah.blah.blah.MyDepartmentJpaRepo"> </bean> <bean id="IDepartmentManagerBean" class="com.mycompany.blah.blah.blah.DepartmentManager"> <constructor-arg ref="MyDepartmentJpaRepoBean"/> </bean> </beans>
所以..spring-boot-data使一个(子接口的JpaRepository)定义为一个接口
”。interface MyDepartmentJpaRepo extends JpaRepository<Department, Long>
因此,当您尝试对IoC / DI进行xml定义时,您会收到“ 非抽象bean不允许的接口
这看起来像个catch-22 ......:(
魔术问题:
[如何将xml-config用于IoC / DI .........并利用子接口的JpaRepository ????
] >APPEND:
如果添加“ jpa:repositories”,那么我就没有“ manager”的构造方法参数。
http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/data/jpahttps://www.springframework.org/schema/data/jpa/spring-jpa.xsd“>
<import resource="jpaSetup.di.xml"/> <jpa:repositories base-package="com.mycompany.blah.blah.blah" />
->->
<bean id="IDepartmentManagerBean" class="com.mycompany.organizationdemo.businesslayer.managers.DepartmentManager"> <constructor-arg ref="NotDoesNotExistMyDepartmentJpaRepoBean"/> <!-- DOES NOT WORK --> </bean>
..................
为了完整起见,下面还有其他文件。
jpaSetup.di.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <beans> <bean id="myLocalContainerEntityManagerFactoryBeanBean" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="packagesToScan" value="com.blah.blah.blah.entities"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="showSql" value="${spring.jpa.show-sql}"/> <property name="generateDdl" value="${spring.jpa.generate-ddl}"/> </bean> </property> <!-- See https://stackoverflow.com/questions/16088112/how-to-auto-detect-entities-in-jpa-2-0/16088340#16088340 --> <property name="jpaProperties"> <props> <prop key="hibernate.hbm2ddl.auto">${spring.jpa.hibernate.ddl-auto}</prop> <prop key="hibernate.dialect">${spring.jpa.properties.hibernate.dialect}</prop> </props> </property> </bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="url" value="${SPRING_DATASOURCE_URL}"/> <property name="username" value="${SPRING_DATASOURCE_USERNAME}"/> <property name="password" value="${SPRING_DATASOURCE_PASSWORD}"/> <property name="driverClassName" value="${SPRING_DATASOURCE_DRIVER-CLASS-NAME}"/> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="myLocalContainerEntityManagerFactoryBeanBean"/> </bean> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/> <bean id="persistenceExceptionTranslationPostProcessor" class= "org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/> </beans> </beans>
和application.yml
spring: jpa: generate-ddl: true show-sql: true hibernate: ddl-auto: update naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy properties: hibernate: dialect: org.hibernate.dialect.H2Dialect datasource: url: ${SPRING_DATASOURCE_URL} username: ${SPRING_DATASOURCE_USERNAME} password: ${SPRING_DATASOURCE_PASSWORD} driverClassName: ${SPRING_DATASOURCE_DRIVER-CLASS-NAME}
如何通过Xml配置连接JpaRepository的(子类/子接口)?所以我有一个JpaRepository的“实现” import org.springframework.data.jpa.repository.JpaRepository;导入...
另一个答案比这个答案简单得多,也更好。 (来自“ R.G.”的答复)。但是,我确实为以后的读者找到了一个丑陋的解决方法。
[请勿将此答案优先于R.G. !