Skip to content

Commit 849d544

Browse files
committed
Revert "DATACOUCH-550 - Refactored the usage of CouchbasePersistentEntityIndexCreator. (#298)"
This reverts commit 883c931.
1 parent eab0844 commit 849d544

File tree

7 files changed

+141
-54
lines changed

7 files changed

+141
-54
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@
157157
</dependency>
158158

159159
<dependency>
160-
<groupId>com.couchbase.mock</groupId>
160+
<groupId>com.github.Couchbase</groupId>
161161
<artifactId>CouchbaseMock</artifactId>
162-
<version>1.5.25</version>
162+
<version>73e493d259</version>
163163
<scope>test</scope>
164164
</dependency>
165165

src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
3838
import org.springframework.data.couchbase.core.convert.translation.JacksonTranslationService;
3939
import org.springframework.data.couchbase.core.convert.translation.TranslationService;
40-
import org.springframework.data.couchbase.core.index.CouchbasePersistentEntityIndexCreator;
4140
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
4241
import org.springframework.data.couchbase.core.mapping.Document;
4342
import org.springframework.data.couchbase.repository.config.ReactiveRepositoryOperationsMapping;
@@ -282,6 +281,7 @@ public CouchbaseMappingContext couchbaseMappingContext(CustomConversions customC
282281
mappingContext.setInitialEntitySet(getInitialEntitySet());
283282
mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
284283
mappingContext.setFieldNamingStrategy(fieldNamingStrategy());
284+
mappingContext.setAutoIndexCreation(autoIndexCreation());
285285

286286
return mappingContext;
287287
}
@@ -293,18 +293,6 @@ protected boolean autoIndexCreation() {
293293
return false;
294294
}
295295

296-
/**
297-
* Creates a {@link CouchbasePersistentEntityIndexCreator} bean that takes on the responsibility of automatically
298-
* creating indices.
299-
*
300-
* Does nothing if {@link #autoIndexCreation()} returns false.
301-
*/
302-
@Bean
303-
public CouchbasePersistentEntityIndexCreator couchbasePersistentEntityIndexCreator(CouchbaseMappingContext couchbaseMappingContext,
304-
CouchbaseClientFactory clientFactory) {
305-
return new CouchbasePersistentEntityIndexCreator(couchbaseMappingContext, clientFactory, typeKey(), autoIndexCreation());
306-
}
307-
308296
/**
309297
* Register custom Converters in a {@link CustomConversions} object if required. These {@link CustomConversions} will
310298
* be registered with the {@link #mappingCouchbaseConverter(CouchbaseMappingContext, CouchbaseCustomConversions)} )}

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

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,17 @@
1919
import org.springframework.beans.BeansException;
2020
import org.springframework.context.ApplicationContext;
2121
import org.springframework.context.ApplicationContextAware;
22+
import org.springframework.context.ConfigurableApplicationContext;
2223
import org.springframework.data.couchbase.CouchbaseClientFactory;
2324
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
2425
import org.springframework.data.couchbase.core.convert.translation.JacksonTranslationService;
2526
import org.springframework.data.couchbase.core.convert.translation.TranslationService;
27+
import org.springframework.data.couchbase.core.index.CouchbasePersistentEntityIndexCreator;
28+
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
29+
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
30+
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
31+
import org.springframework.data.mapping.context.MappingContext;
32+
import org.springframework.lang.Nullable;
2633

2734
import com.couchbase.client.java.Collection;
2835

@@ -31,7 +38,6 @@
3138
*
3239
* @author Michael Nitschinger
3340
* @author Michael Reiche
34-
* @author Aaron Whiteside
3541
* @author Jorge Rodriguez Martin
3642
* @since 3.0
3743
*/
@@ -40,7 +46,9 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationContex
4046
private final CouchbaseClientFactory clientFactory;
4147
private final CouchbaseConverter converter;
4248
private final CouchbaseTemplateSupport templateSupport;
49+
private final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext;
4350
private final ReactiveCouchbaseTemplate reactiveCouchbaseTemplate;
51+
private @Nullable CouchbasePersistentEntityIndexCreator indexCreator;
4452

4553
public CouchbaseTemplate(final CouchbaseClientFactory clientFactory, final CouchbaseConverter converter) {
4654
this(clientFactory, converter, new JacksonTranslationService());
@@ -52,6 +60,14 @@ public CouchbaseTemplate(final CouchbaseClientFactory clientFactory, final Couch
5260
this.converter = converter;
5361
this.templateSupport = new CouchbaseTemplateSupport(converter, translationService);
5462
this.reactiveCouchbaseTemplate = new ReactiveCouchbaseTemplate(clientFactory, converter, translationService);
63+
64+
this.mappingContext = this.converter.getMappingContext();
65+
if (mappingContext instanceof CouchbaseMappingContext) {
66+
CouchbaseMappingContext cmc = (CouchbaseMappingContext) mappingContext;
67+
if (cmc.isAutoIndexCreation()) {
68+
indexCreator = new CouchbasePersistentEntityIndexCreator(cmc, this);
69+
}
70+
}
5571
}
5672

5773
@Override
@@ -140,7 +156,28 @@ public ReactiveCouchbaseTemplate reactive() {
140156

141157
@Override
142158
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
159+
prepareIndexCreator(applicationContext);
143160
templateSupport.setApplicationContext(applicationContext);
144161
reactiveCouchbaseTemplate.setApplicationContext(applicationContext);
145162
}
163+
164+
private void prepareIndexCreator(final ApplicationContext context) {
165+
String[] indexCreators = context.getBeanNamesForType(CouchbasePersistentEntityIndexCreator.class);
166+
167+
for (String creator : indexCreators) {
168+
CouchbasePersistentEntityIndexCreator creatorBean = context.getBean(creator,
169+
CouchbasePersistentEntityIndexCreator.class);
170+
if (creatorBean.isIndexCreatorFor(mappingContext)) {
171+
return;
172+
}
173+
}
174+
175+
if (context instanceof ConfigurableApplicationContext && indexCreator != null) {
176+
((ConfigurableApplicationContext) context).addApplicationListener(indexCreator);
177+
if (mappingContext instanceof CouchbaseMappingContext) {
178+
CouchbaseMappingContext cmc = (CouchbaseMappingContext) mappingContext;
179+
cmc.setIndexCreator(indexCreator);
180+
}
181+
}
182+
}
146183
}

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

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,56 +20,39 @@
2020

2121
import org.slf4j.Logger;
2222
import org.slf4j.LoggerFactory;
23-
import org.springframework.beans.factory.InitializingBean;
2423
import org.springframework.context.ApplicationListener;
2524
import org.springframework.dao.DataIntegrityViolationException;
26-
import org.springframework.data.couchbase.CouchbaseClientFactory;
25+
import org.springframework.data.couchbase.core.CouchbaseOperations;
2726
import org.springframework.data.couchbase.core.index.CouchbasePersistentEntityIndexResolver.IndexDefinitionHolder;
2827
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
2928
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
3029
import org.springframework.data.couchbase.core.mapping.Document;
30+
import org.springframework.data.mapping.PersistentEntity;
31+
import org.springframework.data.mapping.context.MappingContext;
32+
import org.springframework.data.mapping.context.MappingContextEvent;
3133

3234
import com.couchbase.client.core.error.IndexExistsException;
3335
import com.couchbase.client.java.Cluster;
34-
import org.springframework.data.mapping.PersistentEntity;
35-
import org.springframework.data.mapping.context.MappingContextEvent;
3636

37-
/**
38-
* Encapsulates the logic of creating indices.
39-
*
40-
* @author Michael Nitschinger
41-
* @author Aaron Whiteside
42-
*/
43-
public class CouchbasePersistentEntityIndexCreator implements InitializingBean, ApplicationListener<MappingContextEvent<?, ?>> {
37+
public class CouchbasePersistentEntityIndexCreator implements ApplicationListener<MappingContextEvent<?, ?>> {
4438

4539
private static final Logger LOGGER = LoggerFactory.getLogger(CouchbasePersistentEntityIndexCreator.class);
4640

4741
private final Map<Class<?>, Boolean> classesSeen = new ConcurrentHashMap<>();
4842
private final CouchbaseMappingContext mappingContext;
4943
private final QueryIndexResolver indexResolver;
50-
private final CouchbaseClientFactory clientFactory;
51-
private final boolean enabled;
44+
private final CouchbaseOperations couchbaseOperations;
5245

5346
public CouchbasePersistentEntityIndexCreator(final CouchbaseMappingContext mappingContext,
54-
final CouchbaseClientFactory clientFactory, final String typeKey, final boolean enabled) {
47+
final CouchbaseOperations operations) {
5548
this.mappingContext = mappingContext;
56-
this.clientFactory = clientFactory;
57-
this.enabled = enabled;
58-
this.indexResolver = QueryIndexResolver.create(mappingContext, typeKey);
59-
}
60-
61-
@Override
62-
public void afterPropertiesSet() throws Exception {
63-
if (enabled) {
64-
mappingContext.getPersistentEntities().forEach(this::checkForIndexes);
65-
} else {
66-
LOGGER.debug("Automatic index creation not enabled.");
67-
}
49+
this.couchbaseOperations = operations;
50+
this.indexResolver = QueryIndexResolver.create(mappingContext, operations);
6851
}
6952

7053
@Override
7154
public void onApplicationEvent(final MappingContextEvent<?, ?> event) {
72-
if (!enabled || !event.wasEmittedBy(mappingContext)) {
55+
if (!event.wasEmittedBy(mappingContext)) {
7356
return;
7457
}
7558

@@ -88,7 +71,7 @@ private void checkForIndexes(final CouchbasePersistentEntity<?> entity) {
8871
this.classesSeen.put(type, Boolean.TRUE);
8972

9073
if (LOGGER.isDebugEnabled()) {
91-
LOGGER.debug("Analyzing class {} for index information.", type);
74+
LOGGER.debug("Analyzing class " + type + " for index information.");
9275
}
9376

9477
checkForAndCreateIndexes(entity);
@@ -110,10 +93,10 @@ private void checkForAndCreateIndexes(final CouchbasePersistentEntity<?> entity)
11093
}
11194

11295
private void createIndex(final IndexDefinitionHolder indexToCreate) {
113-
Cluster cluster = clientFactory.getCluster();
96+
Cluster cluster = couchbaseOperations.getCouchbaseClientFactory().getCluster();
11497

11598
StringBuilder statement = new StringBuilder("CREATE INDEX ").append(indexToCreate.getIndexName()).append(" ON `")
116-
.append(clientFactory.getBucket().name()).append("` (")
99+
.append(couchbaseOperations.getBucketName()).append("` (")
117100
.append(String.join(",", indexToCreate.getIndexFields())).append(")");
118101

119102
if (indexToCreate.getIndexPredicate() != null && !indexToCreate.getIndexPredicate().isEmpty()) {
@@ -124,10 +107,21 @@ private void createIndex(final IndexDefinitionHolder indexToCreate) {
124107
cluster.query(statement.toString());
125108
} catch (IndexExistsException ex) {
126109
// ignored on purpose, rest is propagated
127-
LOGGER.debug("Index \"{}\" already exists, ignoring.", indexToCreate.getIndexName());
110+
LOGGER.debug("Index \"" + indexToCreate.getIndexName() + "\" already exists, ignoring.");
128111
} catch (Exception ex) {
129112
throw new DataIntegrityViolationException("Could not auto-create index with statement: " + statement.toString(),
130113
ex);
131114
}
132115
}
116+
117+
/**
118+
* Returns whether the current index creator was registered for the given {@link MappingContext}.
119+
*/
120+
public boolean isIndexCreatorFor(final MappingContext<?, ?> context) {
121+
return this.mappingContext.equals(context);
122+
}
123+
124+
public boolean hasSeen(CouchbasePersistentEntity<?> entity) {
125+
return classesSeen.containsKey(entity.getType());
126+
}
133127
}

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.List;
2121
import java.util.stream.Collectors;
2222

23+
import org.springframework.data.couchbase.core.CouchbaseOperations;
2324
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
2425
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
2526
import org.springframework.data.couchbase.core.mapping.Document;
@@ -34,13 +35,13 @@
3435
public class CouchbasePersistentEntityIndexResolver implements QueryIndexResolver {
3536

3637
private final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext;
37-
private final String typeKey;
38+
private final CouchbaseOperations operations;
3839

3940
public CouchbasePersistentEntityIndexResolver(
4041
final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext,
41-
final String typeKey) {
42+
CouchbaseOperations operations) {
4243
this.mappingContext = mappingContext;
43-
this.typeKey = typeKey;
44+
this.operations = operations;
4445
}
4546

4647
@Override
@@ -134,6 +135,7 @@ protected List<IndexDefinitionHolder> createCompositeQueryIndexDefinitions(final
134135
}
135136

136137
private String getPredicate(final MappingCouchbaseEntityInformation<?, Object> entityInfo) {
138+
String typeKey = operations.getConverter().getTypeKey();
137139
String typeValue = entityInfo.getJavaType().getName();
138140
return "`" + typeKey + "` = \"" + typeValue + "\"";
139141
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.data.couchbase.core.index;
1717

18+
import org.springframework.data.couchbase.core.CouchbaseOperations;
1819
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
1920
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
2021
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
@@ -42,9 +43,9 @@ public interface QueryIndexResolver {
4243
*/
4344
static QueryIndexResolver create(
4445
MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext,
45-
String typeKey) {
46+
CouchbaseOperations operations) {
4647
Assert.notNull(mappingContext, "CouchbaseMappingContext must not be null!");
47-
return new CouchbasePersistentEntityIndexResolver(mappingContext, typeKey);
48+
return new CouchbasePersistentEntityIndexResolver(mappingContext, operations);
4849
}
4950

5051
/**

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

Lines changed: 67 additions & 2 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;
@@ -32,7 +37,6 @@
3237
*
3338
* @author Michael Nitschinger
3439
* @author Michael Reiche
35-
* @author Aaron Whiteside
3640
*/
3741
public class CouchbaseMappingContext
3842
extends AbstractMappingContext<BasicCouchbasePersistentEntity<?>, CouchbasePersistentProperty>
@@ -51,6 +55,10 @@ public class CouchbaseMappingContext
5155
*/
5256
private FieldNamingStrategy fieldNamingStrategy = DEFAULT_NAMING_STRATEGY;
5357

58+
private boolean autoIndexCreation = true;
59+
private ApplicationEventPublisher eventPublisher;
60+
private CouchbasePersistentEntityIndexCreator indexCreator = null;
61+
5462
/**
5563
* Configures the {@link FieldNamingStrategy} to be used to determine the field name if no manual mapping is applied.
5664
* Defaults to a strategy using the plain property name.
@@ -100,8 +108,65 @@ protected CouchbasePersistentProperty createPersistentProperty(Property property
100108
*/
101109
@Override
102110
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
103-
super.setApplicationContext(applicationContext);
104111
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+
}
121+
}
122+
123+
public boolean isAutoIndexCreation() {
124+
return autoIndexCreation;
125+
}
126+
127+
public void setAutoIndexCreation(boolean autoCreateIndexes) {
128+
this.autoIndexCreation = autoCreateIndexes;
129+
}
130+
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;
105161
}
106162

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+
}
107172
}

0 commit comments

Comments
 (0)