Skip to content

Commit 8ebb81b

Browse files
authored
Datacouch 550 autoindex not working in spring boot app (#295)
* DATACOUCH-550 Autoindexing only works from SpringJunitConfig Due to the interdependency in bean creation, Autoindexing does not work in a normal spring-boot application. This change overrides the addPersistentEntity and getPersistentEntity of CouchbaseMappingContext to avoid entries cached before the indexCreator was listening from preventing MappingContextEvents from being published after the indexCreator is listening. It also exposes the indexCreators classesSeen map so that MappingEvents for an entity are not re-published after the indexCreator has seen them. * DATACOUCH-550 - Autoindexing does not work spring-boot application. Due to the interdependencies of beans, autoindexing does not work in the startup of a normal spring-boot application. Processing of entities occurs during the initialization of CouchbaseMappinContext, which occurs before initialization of MappingCouchbaseConverter, which occurs before the initialization of CouchbaseTemplate - which creates the indexCreator listener. So when the AbstractMappingContext (CouchbaseMappingContext) is publishing MappingContextEvents - there is not yet any indexCreator. And subsequent processing of entities finds the entities cached, and therefore does not publish MappingContextEvents. This change overrides the addPersistentEntity() and getPersistentEntity() methods of AbstractMappingContext such that caching does not preven the MappingContextEvents from being published. This change also exposes indexCreator classesSeen map to CouchbaseMappingContext so that once an entity has been processed by indexCreator, it is not published again. Autoindexing by SpringJUnitConfig did work prior to this change. Co-authored-by: mikereiche <michael.reiche@couchbase.com>
1 parent f7b6765 commit 8ebb81b

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ private void prepareIndexCreator(final ApplicationContext context) {
166166

167167
if (context instanceof ConfigurableApplicationContext && indexCreator != null) {
168168
((ConfigurableApplicationContext) context).addApplicationListener(indexCreator);
169+
if (mappingContext instanceof CouchbaseMappingContext) {
170+
CouchbaseMappingContext cmc = (CouchbaseMappingContext) mappingContext;
171+
cmc.setIndexCreator(indexCreator);
172+
}
169173
}
170174
}
171175
}

src/main/java/org/springframework/data/couchbase/core/index/CouchbasePersistentEntityIndexCreator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,7 @@ public boolean isIndexCreatorFor(final MappingContext<?, ?> context) {
121121
return this.mappingContext.equals(context);
122122
}
123123

124+
public boolean hasSeen(CouchbasePersistentEntity<?> entity) {
125+
return classesSeen.containsKey(entity.getType());
126+
}
124127
}

src/main/java/org/springframework/data/couchbase/core/mapping/CouchbaseMappingContext.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@
1616

1717
package org.springframework.data.couchbase.core.mapping;
1818

19+
import java.util.Optional;
20+
1921
import org.springframework.beans.BeansException;
2022
import org.springframework.context.ApplicationContext;
2123
import org.springframework.context.ApplicationContextAware;
24+
import org.springframework.context.ApplicationEventPublisher;
25+
import org.springframework.data.couchbase.core.index.CouchbasePersistentEntityIndexCreator;
2226
import org.springframework.data.mapping.context.AbstractMappingContext;
27+
import org.springframework.data.mapping.context.MappingContextEvent;
2328
import org.springframework.data.mapping.model.FieldNamingStrategy;
2429
import org.springframework.data.mapping.model.Property;
2530
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
@@ -31,6 +36,7 @@
3136
* {@link BasicCouchbasePersistentEntity} and {@link BasicCouchbasePersistentProperty} as primary abstractions.
3237
*
3338
* @author Michael Nitschinger
39+
* @author Michael Reiche
3440
*/
3541
public class CouchbaseMappingContext
3642
extends AbstractMappingContext<BasicCouchbasePersistentEntity<?>, CouchbasePersistentProperty>
@@ -50,6 +56,8 @@ public class CouchbaseMappingContext
5056
private FieldNamingStrategy fieldNamingStrategy = DEFAULT_NAMING_STRATEGY;
5157

5258
private boolean autoIndexCreation = true;
59+
private ApplicationEventPublisher eventPublisher;
60+
private CouchbasePersistentEntityIndexCreator indexCreator = null;
5361

5462
/**
5563
* Configures the {@link FieldNamingStrategy} to be used to determine the field name if no manual mapping is applied.
@@ -101,6 +109,15 @@ protected CouchbasePersistentProperty createPersistentProperty(Property property
101109
@Override
102110
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
103111
context = applicationContext;
112+
super.setApplicationContext(applicationContext);
113+
}
114+
115+
@Override
116+
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
117+
eventPublisher = applicationEventPublisher;
118+
if (this.eventPublisher == null) {
119+
this.eventPublisher = context;
120+
}
104121
}
105122

106123
public boolean isAutoIndexCreation() {
@@ -111,4 +128,45 @@ public void setAutoIndexCreation(boolean autoCreateIndexes) {
111128
this.autoIndexCreation = autoCreateIndexes;
112129
}
113130

131+
/**
132+
* override method from AbstractMappingContext as that method will not publishEvent() if it finds the entity has
133+
* already been cached
134+
*
135+
* @param typeInformation - entity type
136+
*/
137+
@Override
138+
protected Optional<BasicCouchbasePersistentEntity<?>> addPersistentEntity(TypeInformation<?> typeInformation) {
139+
Optional<BasicCouchbasePersistentEntity<?>> entity = super.addPersistentEntity(typeInformation);
140+
141+
if (this.eventPublisher != null && entity.isPresent()) {
142+
if (this.indexCreator != null) {
143+
if (!indexCreator.hasSeen(entity.get())) {
144+
this.eventPublisher.publishEvent(new MappingContextEvent(this, entity.get()));
145+
}
146+
}
147+
}
148+
return entity;
149+
}
150+
151+
/**
152+
* override method from AbstractMappingContext as that method will not publishEvent() if it finds the entity has
153+
* already been cached. Instead, user our own addPersistEntity that will.
154+
*
155+
* @param typeInformation - entity type
156+
*/
157+
@Override
158+
public BasicCouchbasePersistentEntity<?> getPersistentEntity(TypeInformation<?> typeInformation) {
159+
Optional<BasicCouchbasePersistentEntity<?>> entity = addPersistentEntity(typeInformation);
160+
return entity.isPresent() ? entity.get() : null;
161+
}
162+
163+
/**
164+
* capture the indexCreator when it has been added as a listener. only publishEvent() if the indexCreator hasn't
165+
* already seen the class.
166+
*
167+
* @param indexCreator
168+
*/
169+
public void setIndexCreator(CouchbasePersistentEntityIndexCreator indexCreator) {
170+
this.indexCreator = indexCreator;
171+
}
114172
}

0 commit comments

Comments
 (0)