Я пытаюсь использовать Spring Data Mongo с транзакциями. Сначала я столкнулся с проблемой, из-за которой мои вставки не работали из-за того, что Spring пытался создать коллекцию и / или индексы во время первой вставки документа. С тех пор я решил эту проблему, создав все свои коллекции и индексы при запуске до начала какой-либо транзакции. Однако я все еще использую аннотации Spring Data для определения индексов (т. Е. @Indexed
, @CompoundIndexes
и т. Д.). Однако, хотя я уже создал все индексы, Spring все еще пытается обеспечить / создать индексы во время обработки монго.
В моей ситуации я использую наследование с моими типами данных. Т.е., BasicUnit
какой другой блок распространяется. Если я иду, чтобы сохранить определенный тип модуля, и я впервые пытаюсь сохранить этот тип объекта во время текущего запуска приложения, Spring не распознает его и создает для него новый PersistentEntity
. В рамках создания нового PersistentEntity
Spring отправляет событие, которое MongoPersistentEntityIndexCreator
перехватывает, которое, в свою очередь, пытается обеспечить создание всех индексов, и, таким образом, генерируется исключение.
Вот исключение:
Caused by: com.mongodb.MongoCommandException: Command failed with error 263 (OperationNotSupportedInTransaction): 'It is illegal to run command createIndexes in a multi-document transaction.' on server 127.0.0.1:27017. The full response is { "operationTime" : { "$timestamp" : { "t" : 1560198052, "i" : 1 } }, "ok" : 0.0, "errmsg" : "It is illegal to run command createIndexes in a multi-document transaction.", "code" : 263, "codeName" : "OperationNotSupportedInTransaction", "$clusterTime" : { "clusterTime" : { "$timestamp" : { "t" : 1560198052, "i" : 1 } }, "signature" : { "hash" : { "$binary" : "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "$type" : "00" }, "keyId" : { "$numberLong" : "0" } } } }
at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:179)
at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:293)
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:255)
at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:99)
at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:444)
at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:72)
at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:200)
at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:269)
at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:131)
at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:123)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:242)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:233)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:170)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:163)
at com.mongodb.operation.CreateIndexesOperation$1.call(CreateIndexesOperation.java:174)
at com.mongodb.operation.CreateIndexesOperation$1.call(CreateIndexesOperation.java:169)
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:453)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:415)
at com.mongodb.operation.CreateIndexesOperation.execute(CreateIndexesOperation.java:169)
at com.mongodb.operation.CreateIndexesOperation.execute(CreateIndexesOperation.java:70)
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:193)
at com.mongodb.client.internal.MongoCollectionImpl.executeCreateIndexes(MongoCollectionImpl.java:805)
at com.mongodb.client.internal.MongoCollectionImpl.createIndexes(MongoCollectionImpl.java:800)
at com.mongodb.client.internal.MongoCollectionImpl.createIndexes(MongoCollectionImpl.java:793)
at com.mongodb.client.internal.MongoCollectionImpl.createIndex(MongoCollectionImpl.java:778)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:246)
at org.springframework.data.mongodb.SessionAwareMethodInterceptor.invoke(SessionAwareMethodInterceptor.java:123)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy202.createIndex(Unknown Source)
at org.springframework.data.mongodb.core.DefaultIndexOperations.lambda$ensureIndex$0(DefaultIndexOperations.java:135)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:545)
Вот стек вызовов, привязанный к вызову для обеспечения индексирования:
DefaultIndexOperations.lambda$ensureIndex$0(IndexDefinition, MongoCollection) line: 135
1894975953.doInCollection(MongoCollection) line: not available
MongoTemplate.execute(String, CollectionCallback<T>) line: 545
DefaultIndexOperations.execute(CollectionCallback<T>) line: 218
DefaultIndexOperations.ensureIndex(IndexDefinition) line: 121
MongoPersistentEntityIndexCreator.createIndex(MongoPersistentEntityIndexResolver$IndexDefinitionHolder) line: 145
MongoPersistentEntityIndexCreator.checkForAndCreateIndexes(MongoPersistentEntity<?>) line: 135
MongoPersistentEntityIndexCreator.checkForIndexes(MongoPersistentEntity<?>) line: 127
MongoPersistentEntityIndexCreator.onApplicationEvent(MappingContextEvent<?,?>) line: 111
MongoPersistentEntityIndexCreator.onApplicationEvent(ApplicationEvent) line: 54
SimpleApplicationEventMulticaster.doInvokeListener(ApplicationListener, ApplicationEvent) line: 172
SimpleApplicationEventMulticaster.invokeListener(ApplicationListener<?>, ApplicationEvent) line: 165
SimpleApplicationEventMulticaster.multicastEvent(ApplicationEvent, ResolvableType) line: 139
AnnotationConfigWebApplicationContext(AbstractApplicationContext).publishEvent(Object, ResolvableType) line: 398
AnnotationConfigWebApplicationContext(AbstractApplicationContext).publishEvent(ApplicationEvent) line: 355
MongoMappingContext(AbstractMappingContext<E,P>).addPersistentEntity(TypeInformation<?>) line: 405
MongoMappingContext(AbstractMappingContext<E,P>).getPersistentEntity(TypeInformation<?>) line: 248
MongoMappingContext(AbstractMappingContext<E,P>).getPersistentEntity(Class<?>) line: 191
MongoMappingContext(AbstractMappingContext<E,P>).getPersistentEntity(Class) line: 85
MongoMappingContext(MappingContext<E,P>).getRequiredPersistentEntity(Class<?>) line: 73
EntityOperations$AdaptibleMappedEntity<T>.of(T, MappingContext<MongoPersistentEntity<?>,MongoPersistentProperty>, ConversionService) line: 600
EntityOperations$AdaptibleMappedEntity<T>.access$100(Object, MappingContext, ConversionService) line: 580
EntityOperations.forEntity(T, ConversionService) line: 105
MongoTemplate.doInsert(String, T, MongoWriter<T>) line: 1237
Вы можете увидеть, где Spring пытается получить постоянную сущность, затем, наконец, решает добавить , а затем инициирует событие, а затем событие обрабатывается путем попытки создания индексы.
Мне нужно знать, как предотвратить попытки Spring создать эти индексы во время транзакции.
Вещи, которые я рассмотрел
- Попробуй выяснить, как предварительно зарегистрировать все мои постоянные сущности,
но я не уверен, как это сделать, кроме ручного ведения списка, или
написание кода для сканирования пути к классам, чтобы найти все классы, которые
аннотируется @Document или расширяет такой класс.
- Полностью отказаться от индексных аннотаций Spring и использовать только явные вызовы
sureIndex для каждого нужного мне индекса.
Ни одно из этих решений не очень привлекательно для меня.
Мне трудно поверить, что никто другой не сталкивался с подобными проблемами индексации, используя Spring Data Mongo с транзакциями, поэтому любой из вас знает решение этой проблемы, я хотел бы услышать это.
Спасибо.