Hazelcast KeyValueRepository (spring-data-keyvalue) не работает со списком объектов как с сущностью

Недавно мы обновили наше приложение с весенней загрузки 2.1.6.RELEASE до 2.6.14. Параллельно с этим мы также обновилиspring-boot-starter-data-jpaчтобы быть совместимым с Spring-Boot, который приводит к обновлению этих двух библиотек `

  • org.springframework.data:spring-data-keyvalue с 2.1.9 по 2.6.10
  • org.springframework.data:spring-data-commons с 2.1.9 по 2.6.10`

Мы создаем KeyValueRepository в приложении, поддерживаемом объектом hazelcast (мы используем v3.12 для hazelcast).

      //Creating an hazelcast entity with value as List of employees and key as a employeeId
@HazelcastEntity(backingStoreMapStoreClass = EmployeeCacheLoader::class)
interface TraderRepository : KeyValueRepository<List<EmployeeDetails>, String>

//EmployeeCacheLoader implementation
class TraderCacheLoader() : MapStore<String, List<EmployeeDetails>>() {

  override fun load(employeeId: String): List<EmployeeDetails> {
      //implementation to load an employee
   }

   override fun loadAll(requestList: Collection<String>): Map<String, List<EmployeeDetails>> {
      //implementation to load all
   }
}

Раньше это работало правильно, без каких-либо ошибок с пружинным значением ключа v2.1.9, но не работает с v2.6.10 и выдает эту ошибку:

      org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeRepository' defined in com.lab49.ca.salesandtrading.cache.EmployeerRepository defined in @EnableHazelcastRepositories declared on GenericRfqApp: Invocation of init method failed; nested exception is

 java.lang.IllegalArgumentException: Entity must not be 'null'.
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:936)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:745)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:423)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
    at com.lab49.ca.ionapp.spring.ion20.ION20SpringApplicationModule$SpringApplicationService$1.onSuccess(ION20SpringApplicationModule.java:162)
    at com.lab49.ca.ionapp.spring.ion20.ION20SpringApplicationModule$SpringApplicationService$1.onSuccess(ION20SpringApplicationModule.java:127)
    at com.iontrading.isf.commons.async.impl.a$1.run(AsyncResultPromiseImpl.java:131)
    at com.iontrading.isf.executors.impl.monitoring.g.run(MonitoredRunnable.java:18)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.IllegalArgumentException: Entity must not be 'null'.
    at org.springframework.util.Assert.notNull(Assert.java:201)
    at org.springframework.data.hazelcast.repository.support.HazelcastRepositoryFactory.getEntityInformation(HazelcastRepositoryFactory.java:91)
    at org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory.getTargetRepository(KeyValueRepositoryFactory.java:132)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:325)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:323)
    at org.springframework.data.util.Lazy.getNullable(Lazy.java:231)
    at org.springframework.data.util.Lazy.get(Lazy.java:115)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:329)
    at org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean.afterPropertiesSet(KeyValueRepositoryFactoryBean.java:135)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
    ... 19 more

После отладки мы обнаружили, что приведенный ниже код дает нулевое значение, поскольку нет контекста сопоставления, созданного с помощью Spring-data-keyvalue для java.util.List, чего не было раньше.

      //domainClass will be java.util.List
PersistentEntity<T, ?> entity = (PersistentEntity<T, ?>) keyValueOperations.getMappingContext()
      .getPersistentEntity(domainClass)

Есть ли способ исправить это после обновления?

Мы попытались отладить старую и новую реализацию библиотеки Spring-Data-Keyvalue и обнаружили, что реализация по какой-то причине изменилась. Так что либо мы не поддерживаем это сейчас, либо есть способ поддержать это.

НОВАЯ РЕАЛИЗАЦИЯ (v2.6.10)

      File Name: AbstractMappingContext.java

//code
Line 178: if (!this.shouldCreatePersistentEntityFor(type) is returing true and hence the result

//In this function the java.util.list is treated as a simple type which seems wrong to me
protected boolean shouldCreatePersistentEntityFor(TypeInformation<?> type) {
    if (this.simpleTypeHolder.isSimpleType(type.getType())) {
      return false; //it reaches here
    } else if (NullableWrapperConverters.supports(type.getType())) {
      return false;
    } else {
      return !KotlinDetector.isKotlinType(type.getType()) || KotlinReflectionUtils.isSupportedKotlinClass(type.getType());
    }
  }

СТАРАЯ РЕАЛИЗАЦИЯ

      //This function returns true and hence there is a mapping contecxt added for that domain type
protected boolean shouldCreatePersistentEntityFor(TypeInformation<?> type) {
    if (this.simpleTypeHolder.isSimpleType(type.getType())) {
      return false;
    } else {
      return !org.springframework.data.util.ReflectionUtils.isKotlinClass(type.getType()) || org.springframework.data.util.ReflectionUtils.isSupportedKotlinClass(type.getType());
    }
  }

0 ответов

Другие вопросы по тегам