如何通过Xml配置连接JpaRepository的a(子类/子接口)?
所以我有一个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);
}
问题出在应用程序上下文.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
interface MyDepartmentJpaRepo extends JpaRepository<Department, Long>
因此,当您尝试用xml定义IoC/DI时,您会得到“interface not allowed for non-abtractbean”。
这看起来像是第二十二条军规......:(
神奇的问题:
如何将xml-config用于IoC/DI...................利用一个子接口的JpaRepository????
追加:
如果我添加“jpa:存储库”,那么我没有“管理器”的构造函数参数。
http://www . spring framework . org/schema/beans/spring-beans . xsd http://www.springframework.org/schema/data/jpa https://www . spring framework . 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}
另一个答案远比这个答案简单,也更好。(来自“R.G .”的回答)。然而,我确实为未来的读者找到了一个丑陋的变通方法。
不要喜欢这个答案,而不是来自R. G.的答案!
import org.springframework.stereotype.Component;
import javax.inject.Inject;
@Component
public class DepartmentJpaRepositoryFactory {
@Inject
private MyDepartmentJpaRepo autoinjectedDepartmentJpaRepositoryWorkaround;
/* this is a workaround for using explicit xml IOC with spring-data.
* because it is "interface MyDepartmentJpaRepo" (not a class), you cannot do traditional xml IoC definitions :(
* this is a workaround. this factory should NEVER be used by the code base, only by spring-di */
public MyDepartmentJpaRepo getInstanceDepartmentJpaRepository() {
return this.autoinjectedDepartmentJpaRepositoryWorkaround;
}
}
然后是应用程序上下文.xml
<jpa:repositories base-package="com.blah.blah.blah.jpa.repositories" />
<bean id="DepartmentManagerBean" class="com.blah.blah.blah.managers.DepartmentManager">
<constructor-arg ref="DepartmentJpaRepositoryViaFactoryMethodBean"/>
</bean>
<bean id="DepartmentJpaRepositoryServiceLocatorBean" class="com.blah.blah.blah.jpa.factories.DepartmentJpaRepositoryFactory">
<!-- inject any dependencies required by this locator bean -->
</bean>
<bean id="DepartmentJpaRepositoryViaFactoryMethodBean"
factory-bean="DepartmentJpaRepositoryServiceLocatorBean"
factory-method="getInstanceDepartmentJpaRepository"/>
以上是一个丑陋和令人讨厌的解决方法,使用
https://docs . spring . io/spring/docs/current/spring-framework-reference/core . html # beans-factory-class-instance-factory-method
"使用实例工厂方法进行实例化"
基于参考文档:XML 配置
以下配置工作基于以下理解:
每个bean都注册在派生自接口名称的bean名称下,因此UserRepository的接口将注册在userRepository下。
所以接口的豆名
public interface MyDepartmentJpaRepo extends JpaRepository<Department, Long> {
..
}
将如下所示: 我的部门Jpa回复
<?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:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
https://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<jpa:repositories base-package="com.mycompany.organizationdemo.businesslayer.repository"/>
<bean id="IDepartmentManagerBean" class="com.mycompany.organizationdemo.businesslayer.managers.DepartmentManager">
<constructor-arg ref="myDepartmentJpaRepo"/>
</bean>
</beans>
为了验证,我自动装配并使用了DepartmentManager实例,如下所示
@Autowired
IDepartmentManager manager;
Spring开机版本:2.2.6
文档还提到了以下内容
一种方法是使用每个支持存储库机制的Spring Data模块随附的Spring命名空间,尽管我们通常建议使用Java配置。
注意:程序包名称已修改以匹配问题,请根据需要进行修改。
希望这能有所帮助。
我想要的是,在不编写setup()方法的情况下,如何连接(或引用)两个xml(parent-xml和child-xml)? 在setup()方法中,有一些使context.xml child-xml connect(连接context.xml和child-xml)的逻辑(cording)。但我认为还有另一种方法可以把它们联系起来。Alredy我试着写了 在contextsub.xml中,但它不起作
我对配置SJMS2组件的最佳方法感到困惑。我正在一个简单的测试应用程序中使用,并尝试使用SJMS2camel组件从编写到ActiveMQ Artemis。组件文档说它处理连接缓存之类的事情,我通常会在ConnectionFactory bean中配置这些事情,所以我感觉到在配置中应该比不使用Camel时定义的更少。 在使用Camel Spring时,文档似乎缺少如何配置jsms2路由及其Conne
问题内容: 我有以下代码: 并且在编译时给出错误: 我如何使用它来执行查询并检索其值。 谢谢 PS:与数据库的连接正在工作..(如果我取消注释该行,它将打印“ connected”)。 问题答案: 这是非常糟糕的代码-书面上没有用。您有很多工作要做。 我建议您研究一下并丢弃代码:
我目前正在着手一个将spring数据与JPA/Hibernate结合使用的项目。现在,我正在使用@Autowired注释在相关属性上注入JpaRepositories,例如: ...在这里,我员工道是一个扩展JpaRepository的接口,注释为@Repository: 使用这种方法一切都很好——然而,我相当习惯于用XML完成我的大部分Spring配置工作,因为我个人喜欢所有相关配置都在同一个地
由于安全原因,一个测试人员不应该在采样器中看到另一个测试人员的jdbc配置详细信息,因为有可能误用用户名、密码和其他详细信息,所以我们有通用的测试机。 1、有没有办法为MySQL、DB2和Microsoft SQL等多个数据库的不同jdbc连接配置设置系统变量。例如:应用程序X使用Microsoft SQL,其中应用程序Y使用DB2,应用程序Z使用MySQL。Y和Z是集成层。数据库URL、JDBC
使用mapr沙箱如果我尝试通过beeline连接到配置单元,使用以下命令: 它连接无问题 如果我尝试使用实际地址连接: 错误:无法使用JDBC URI:JDBC:hive2://192.168.48.138:10000:null(状态=08S01,代码=0)0:JDBC:hive2://192.168.48.138:10000(关闭)>打开客户端传输 我可以通过cli看到hiveserver2正在