Spring 集成 JPA:有没有办法在 IntegrationFlows Jpa.inboundAdapter 中传递 JpaRepository 而不是 EntityManagerFactory?
Spring Integration JPA : Is there a way to pass a JpaRepository instead of an EntityManagerFactory in the IntegrationFlows Jpa.inboundAdapter?
我有一个已经在工作的 Jpa 存储库公开了一个本机查询方法
myPrimary.datasource.jdbc-url=jdbc:sqlserver://host:1433;databaseName=dbName
myPrimary.datasource.username=user
myPrimary.datasource.password=pwd
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "myPrimaryEntityManagerFactory",
transactionManagerRef = "myPrimaryTransactionManager",
basePackages = {"myPrimaryPackage"}
)
@EnableTransactionManagement
public class PrimaryDaoConfig {
@Primary
@Bean(name = "myPrimaryDataSource")
@ConfigurationProperties(prefix = "myPrimary.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "myPrimaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("myPrimaryDataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("myPrimaryPackage").persistenceUnit("myPrimary").build();
}
@Primary
@Bean(name = "myPrimaryTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("myPrimaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
@Repository
public interface MyPrimaryRepository<T extends MyPrimaryEntity, ID extends MyPrimaryId> extends org.springframework.data.repository.Repository<T, ID> {
String MY_CUSTOM_NATIVE_QUERY = "...";
@Query(
value = MY_CUSTOM_NATIVE_QUERY,
nativeQuery = true
)
List<MyPrimaryEntity> findAll();
}
@RunWith(SpringRunner.class)
@ActiveProfiles("dev")
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class RepositoryTest {
@Autowired
private MyPrimaryRepository myPrimaryRepository;
@Test
public void findAll() {
assertNotNull(myPrimaryRepository);
List<MyPrimaryEntity> entities = myPrimaryRepository.findAll();
assertEquals(332, entities.size());
}
}
我想在 Spring IntegrationFlows 中使用它。
根据我找到的文档,有一种方法可以像这样传递 EntityManagerFactory
@Bean
public IntegrationFlow dbInboundFlow() throws Exception {
return IntegrationFlows
.from(Jpa
.inboundAdapter(myPrimaryEntityManagerFactory)
.nativeQuery(MyPrimaryRepository.MY_CUSTOM_NATIVE_QUERY)
.entityClass(MyPrimaryEntity.class),
e -> e.poller(Pollers.fixedDelay(10000))
)
.handle(jobLaunchingMessageHandler())
.channel("nullChannel")
.get();
}
我的单元测试成功了,但是当试图通过 IntegrationFlows 中的 entityMangerFactory 时,我得到了
Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
错误。
我试着添加
spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
但也不走运。
那么有没有办法传递存储库而不是 entityManagerFactory?
目前我只能回答,如果您已经有一个 JPA 存储库,您应该使用通用方法调用 MessageSource
而不是那个 Jpa.inboundChannelAdapter()
。最后一个在技术上为我们做了任何存储库所做的事情,但更多的是以消息传递的方式。
我不清楚方言的问题:看起来你使用的是一样的。如果未明确设置方言,则派生自 JpaVendorAdapter
。 HibernateJpaConfiguration
应该为我们解决这个问题。不清楚 @DataJpaTest
是否为我们做了我们需要的一切。
尽管与 Spring 集成无关。我想看看你的一些简单的项目,让我在本地玩。
我有一个已经在工作的 Jpa 存储库公开了一个本机查询方法
myPrimary.datasource.jdbc-url=jdbc:sqlserver://host:1433;databaseName=dbName
myPrimary.datasource.username=user
myPrimary.datasource.password=pwd
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "myPrimaryEntityManagerFactory",
transactionManagerRef = "myPrimaryTransactionManager",
basePackages = {"myPrimaryPackage"}
)
@EnableTransactionManagement
public class PrimaryDaoConfig {
@Primary
@Bean(name = "myPrimaryDataSource")
@ConfigurationProperties(prefix = "myPrimary.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "myPrimaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("myPrimaryDataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("myPrimaryPackage").persistenceUnit("myPrimary").build();
}
@Primary
@Bean(name = "myPrimaryTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("myPrimaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
@Repository
public interface MyPrimaryRepository<T extends MyPrimaryEntity, ID extends MyPrimaryId> extends org.springframework.data.repository.Repository<T, ID> {
String MY_CUSTOM_NATIVE_QUERY = "...";
@Query(
value = MY_CUSTOM_NATIVE_QUERY,
nativeQuery = true
)
List<MyPrimaryEntity> findAll();
}
@RunWith(SpringRunner.class)
@ActiveProfiles("dev")
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class RepositoryTest {
@Autowired
private MyPrimaryRepository myPrimaryRepository;
@Test
public void findAll() {
assertNotNull(myPrimaryRepository);
List<MyPrimaryEntity> entities = myPrimaryRepository.findAll();
assertEquals(332, entities.size());
}
}
我想在 Spring IntegrationFlows 中使用它。
根据我找到的文档,有一种方法可以像这样传递 EntityManagerFactory
@Bean
public IntegrationFlow dbInboundFlow() throws Exception {
return IntegrationFlows
.from(Jpa
.inboundAdapter(myPrimaryEntityManagerFactory)
.nativeQuery(MyPrimaryRepository.MY_CUSTOM_NATIVE_QUERY)
.entityClass(MyPrimaryEntity.class),
e -> e.poller(Pollers.fixedDelay(10000))
)
.handle(jobLaunchingMessageHandler())
.channel("nullChannel")
.get();
}
我的单元测试成功了,但是当试图通过 IntegrationFlows 中的 entityMangerFactory 时,我得到了
Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
错误。 我试着添加
spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
但也不走运。
那么有没有办法传递存储库而不是 entityManagerFactory?
目前我只能回答,如果您已经有一个 JPA 存储库,您应该使用通用方法调用 MessageSource
而不是那个 Jpa.inboundChannelAdapter()
。最后一个在技术上为我们做了任何存储库所做的事情,但更多的是以消息传递的方式。
我不清楚方言的问题:看起来你使用的是一样的。如果未明确设置方言,则派生自 JpaVendorAdapter
。 HibernateJpaConfiguration
应该为我们解决这个问题。不清楚 @DataJpaTest
是否为我们做了我们需要的一切。
尽管与 Spring 集成无关。我想看看你的一些简单的项目,让我在本地玩。