如何通过Xml配置连接JpaRepository(的子类/子接口?)>

问题描述 投票:0回答:2

如何通过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;导入...

spring-boot java-8 spring-data-jpa java-11
2个回答
1
投票

基于参考文档:XML Configuration

以下配置基于对以下内容的理解:>

每个bean都以从接口名称,因此将注册UserRepository的接口在userRepository下。


0
投票

另一个答案比这个答案简单得多,也更好。 (来自“ R.G.”的答复)。但是,我确实为以后的读者找到了一个丑陋的解决方法。

[请勿将此答案优先于R.G. !

© www.soinside.com 2019 - 2024. All rights reserved.