java - 未注入(inject)带有 JPA2 的 Apache Ignite 2.7 IgniteRepository

标签 java spring-boot spring-data-jpa ignite

使用在 Web 上创建的 guildes,我使用 Spring Data JPA 2 应用程序制作了简单的 Spring Boot 2。仅在 2.7 版本中才向 Apache Ignite 添加了 Spring Boot JPA 2 支持(现在只能通过夜间构建使用 - Apache Ignite 2.7 release date )。 有代码片段: 配置:

@Configuration
@EnableIgniteRepositories
public class SpringDataConfig {

    @Bean
    public Ignite igniteInstance() {
        IgniteConfiguration config = new IgniteConfiguration();

        config.setIgniteInstanceName("ignite-1");
        config.setPeerClassLoadingEnabled(true);

        CacheConfiguration cache = new CacheConfiguration("usersCache");
        cache.setIndexedTypes(Integer.class, UserEntity.class);

        config.setCacheConfiguration(cache);
        Ignite ignite = Ignition.start(config);
        ignite.cluster().active(true);
        return ignite;
    }}

存储库:

@RepositoryConfig(cacheName = "usersCache")
public interface UsersRepository extends IgniteRepository<UserEntity, Integer> {
    UserEntity getByUsername(String username);
}

服务:

@Service
public class UserServiceImpl implements UserService {
    @Autowired
//    UsersRepository repository;
    ApplicationContext context;

    @Override
    public UserEntity getByUsername(String username) {
        return context.getBean(UsersRepository.class).getByUsername(username);
    }}

运行时出现以下异常:

[09:59:18] Ignite node started OK (id=8497f64c, instance name=ignite-1)
[09:59:18] Topology snapshot [ver=1, locNode=8497f64c, servers=1, clients=0, state=ACTIVE, CPUs=4, offheap=1.5GB, heap=1.7GB]
..

Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.lang.Iterable org.apache.ignite.springdata20.repository.IgniteRepository.save(java.util.Map)! No property save found for type UserEntity!
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:82)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:103)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:208)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:79)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lookupQuery(RepositoryFactorySupport.java:565)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(RepositoryFactorySupport.java:558)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Iterator.forEachRemaining(Iterator.java:116)
    at java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Collections.java:1049)
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.mapMethodsToQuery(RepositoryFactorySupport.java:560)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$new$0(RepositoryFactorySupport.java:550)
    at java.util.Optional.map(Optional.java:215)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:550)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:323)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$4(RepositoryFactoryBeanSupport.java:290)
    at org.springframework.data.util.Lazy.getNullable(Lazy.java:141)
    at org.springframework.data.util.Lazy.get(Lazy.java:63)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:293)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:102)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1758)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1695)
    ... 67 more
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property save found for type UserEntity!
    at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:94)
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:358)
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:334)
    at org.springframework.data.mapping.PropertyPath.lambda$from$0(PropertyPath.java:287)
    at java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:324)
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:269)
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:252)
    at org.springframework.data.repository.query.parser.Part.<init>(Part.java:81)
    at org.springframework.data.repository.query.parser.PartTree$OrPart.lambda$new$0(PartTree.java:250)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:251)
    at org.springframework.data.repository.query.parser.PartTree$Predicate.lambda$new$0(PartTree.java:380)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:381)
    at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:93)
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:76)
    ... 93 more

我的存储库中没有 save* 函数声明。仅 getByUsername()。

  1. 如何修复该错误?
  2. 如何连接几个 ignite 节点 并像单个数据库一样使用它们?
  3. 我有现有的 PostgreSQL 数据库。我可以将它们与 Ignite 一起使用吗? (我正在查看 ignite JDBC 驱动程序,发现不存在 PostgreSQL 驱动程序,仅支持 MySQL、SQL Server、H2 等。但是有普通的 JDBC 驱动程序 其中)。

此处描述的问题上下文:Which distributed database I need to choose for medium data project

最佳答案

  1. How can I fix that error?

我也遇到了同样的问题。当我们尝试一起使用 JPA 存储库和 Ignite 存储库时,Spring 将 Ignite Repository 视为 JPA 存储库,因为它也是从 Repository 接口(interface)扩展的。它尝试将我们的 IgniteRepository 实现为 JpaRepository,但这会失败,因为使用的实体不是 Jpa 实体。

因此我们需要从 JpaRepository 配置中排除 IgniteRepository 接口(interface)。为此,您可以在@SpringBootApplication注释下面添加注释。

@EnableJpaRepositories(excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = RepositoryConfig.class)})

现在所有 IgniteRepository 接口(interface)(用 @RepositoryConfig 注释的)都将从 Jpa 配置中排除。

  1. How can I connect few ignite nodes and works with them like a single Database?

很简单,你需要组建一个Ignite Cluster。 Ignite 实例有两种,一种在实例中单独运行,另一种在另一个应用程序(如 Spring Boot 应用程序)中运行。在您的例子中,您正在尝试在 Spring Boot 应用程序中创建一个 ignite 实例。要回答您的问题,您需要配置DiscoverySpi和CommunicationSpi。

这意味着您必须配置要运行 Ignite 实例的节点的 IP 和通信端口。只需浏览文档即可。

但我会解释一下我们使用它的场景。我们开发了一个在 4 个实例上运行的应用程序。因此,我们为 Ignite 配置了 4 个实例 IP 和端口号以进行通信。现在假设一个实例启动了,它将在其中创建一个 ignite 节点,当另一个实例启动时,将在其中创建另一个 ignite 节点。现在两个节点将在您指定的端口上相互通信。您可以将此集群用作分布式缓存。

  1. I have existing PostgreSQL database. Can I use them with Ignite? (I'm looking at ignite JDBC drivers and found that no PostgreSQL driver exists, onlyMySQL, SQL Server, H2 etc supported. But there is plain JDBC Driver among them).

有一个名为CacheStoreAdapter的抽象类。您只需创建一个扩展该适配器的类并提供您自己的实现。 它充当持久存储。您可以使用任何技术。

您将数据存储在 ignite 缓存中。点燃然后将它们存储在数据库中。实际上它会调用CacheStoreAdapter的方法,就是这样。无论您提供什么实现,都将被执行。它有一个写入方法。如果您只是让它将数据打印到控制台,那么它就会在控制台上打印。如果你使用JPA将其存储在数据库中,它就会存储。你可以给出任何实现。它不依赖于驱动程序或任何东西,只依赖于您的 CacheStoreAdapter 实现

这里的问题是,您创建的适配器不是 spring 托管 bean,因此您将无法直接注入(inject) Jpa Repo 或任何 spring bean,但您可以间接执行(Google it)。

希望对你有帮助!

关于java - 未注入(inject)带有 JPA2 的 Apache Ignite 2.7 IgniteRepository,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53534260/

相关文章:

java - 数据最小原则、软件架构

java - 语言环境 Caldroid

java - 在Java中更改Import的名称,或者导入两个同名的类

spring - @CreatedBy 和 @LastModifiedDate 不再与 ZonedDateTime 一起使用?

java - Android JNI 无法使用 dlopen 成功加载库 - 但它曾经

java - 如何修复 "Direct notifications and query notifications cannot be requested together"

java - 使用 DB 对 Hibernate 进行单元测试,测试返回 nullpointerException

java - Spring Controller LoggingAspect不拦截方法

java - 从数据库加载数据时发生StackOverflowError

java - Spring boot @Autowired 无法初始化类