Skip to content

Commit e20ed08

Browse files
committed
Rebase with main.
1 parent edadede commit e20ed08

File tree

58 files changed

+754
-1275
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+754
-1275
lines changed

pom.xml

+6-1
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,6 @@
245245
<scope>compile</scope>
246246
</dependency>
247247

248-
249248
</dependencies>
250249

251250
<repositories>
@@ -263,6 +262,12 @@
263262
<enabled>false</enabled>
264263
</releases>
265264
</repository>
265+
<!--
266+
<repository>
267+
<id>jitpack.io</id>
268+
<url>https://jitpack.io</url>
269+
</repository>
270+
-->
266271
</repositories>
267272

268273
<pluginRepositories>

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

+40-21
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
*/
1616
package org.springframework.data.couchbase.core;
1717

18+
import java.lang.reflect.InaccessibleObjectException;
19+
import java.util.Map;
20+
import java.util.Set;
21+
1822
import org.slf4j.Logger;
1923
import org.slf4j.LoggerFactory;
2024
import org.springframework.context.ApplicationContext;
@@ -26,17 +30,16 @@
2630
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
2731
import org.springframework.data.couchbase.core.mapping.event.AfterSaveEvent;
2832
import org.springframework.data.couchbase.core.mapping.event.CouchbaseMappingEvent;
33+
import org.springframework.data.couchbase.core.support.TemplateUtils;
2934
import org.springframework.data.couchbase.repository.support.MappingCouchbaseEntityInformation;
3035
import org.springframework.data.couchbase.repository.support.TransactionResultHolder;
3136
import org.springframework.data.couchbase.transaction.CouchbaseResourceHolder;
3237
import org.springframework.data.mapping.PersistentPropertyAccessor;
3338
import org.springframework.data.mapping.context.MappingContext;
3439
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
35-
3640
import org.springframework.util.ClassUtils;
3741

38-
import java.util.Map;
39-
import java.util.Set;
42+
import com.couchbase.client.core.error.CouchbaseException;
4043

4144
public abstract class AbstractTemplateSupport {
4245

@@ -47,7 +50,8 @@ public abstract class AbstractTemplateSupport {
4750
ApplicationContext applicationContext;
4851
static final Logger LOG = LoggerFactory.getLogger(AbstractTemplateSupport.class);
4952

50-
public AbstractTemplateSupport(ReactiveCouchbaseTemplate template, CouchbaseConverter converter, TranslationService translationService) {
53+
public AbstractTemplateSupport(ReactiveCouchbaseTemplate template, CouchbaseConverter converter,
54+
TranslationService translationService) {
5155
this.template = template;
5256
this.converter = converter;
5357
this.mappingContext = converter.getMappingContext();
@@ -56,10 +60,8 @@ public AbstractTemplateSupport(ReactiveCouchbaseTemplate template, CouchbaseConv
5660

5761
abstract ReactiveCouchbaseTemplate getReactiveTemplate();
5862

59-
public <T> T decodeEntityBase(String id, String source, long cas, Class<T> entityClass, String scope, String collection,
60-
TransactionResultHolder txResultHolder, CouchbaseResourceHolder holder) {
61-
final CouchbaseDocument converted = new CouchbaseDocument(id);
62-
converted.setId(id);
63+
public <T> T decodeEntityBase(String id, String source, Long cas, Class<T> entityClass, String scope,
64+
String collection, TransactionResultHolder txResultHolder, CouchbaseResourceHolder holder) {
6365

6466
// this is the entity class defined for the repository. It may not be the class of the document that was read
6567
// we will reset it after reading the document
@@ -79,18 +81,32 @@ public <T> T decodeEntityBase(String id, String source, long cas, Class<T> entit
7981
// to unwrap. This results in List<String[]> being unwrapped past String[] to String, so this may also be a
8082
// Collection (or Array) of entityClass. We have no way of knowing - so just assume it is what we are told.
8183
// if this is a Collection or array, only the first element will be returned.
84+
final CouchbaseDocument converted = new CouchbaseDocument(id);
8285
Set<Map.Entry<String, Object>> set = ((CouchbaseDocument) translationService.decode(source, converted))
8386
.getContent().entrySet();
8487
return (T) set.iterator().next().getValue();
8588
}
8689

90+
if (id == null) {
91+
throw new CouchbaseException(TemplateUtils.SELECT_ID + " was null. Either use #{#n1ql.selectEntity} or project "
92+
+ TemplateUtils.SELECT_ID);
93+
}
94+
95+
final CouchbaseDocument converted = new CouchbaseDocument(id);
96+
8797
// if possible, set the version property in the source so that if the constructor has a long version argument,
88-
// it will have a value an not fail (as null is not a valid argument for a long argument). This possible failure
98+
// it will have a value and not fail (as null is not a valid argument for a long argument). This possible failure
8999
// can be avoid by defining the argument as Long instead of long.
90100
// persistentEntity is still the (possibly abstract) class specified in the repository definition
91101
// it's possible that the abstract class does not have a version property, and this won't be able to set the version
92-
if (cas != 0 && persistentEntity.getVersionProperty() != null) {
93-
converted.put(persistentEntity.getVersionProperty().getName(), cas);
102+
if (persistentEntity.getVersionProperty() != null) {
103+
if (cas == null) {
104+
throw new CouchbaseException("version/cas in the entity but " + TemplateUtils.SELECT_CAS
105+
+ " was not in result. Either use #{#n1ql.selectEntity} or project " + TemplateUtils.SELECT_CAS);
106+
}
107+
if (cas != 0) {
108+
converted.put(persistentEntity.getVersionProperty().getName(), cas);
109+
}
94110
}
95111

96112
// if the constructor has an argument that is long version, then construction will fail if the 'version'
@@ -101,13 +117,13 @@ public <T> T decodeEntityBase(String id, String source, long cas, Class<T> entit
101117

102118
persistentEntity = couldBePersistentEntity(readEntity.getClass());
103119

104-
if (cas != 0 && persistentEntity.getVersionProperty() != null) {
120+
if (cas != null && cas != 0 && persistentEntity.getVersionProperty() != null) {
105121
accessor.setProperty(persistentEntity.getVersionProperty(), cas);
106122
}
107123
N1qlJoinResolver.handleProperties(persistentEntity, accessor, getReactiveTemplate(), id, scope, collection);
108124

109-
if(holder != null){
110-
holder.transactionResultHolder(txResultHolder, (T)accessor.getBean());
125+
if (holder != null) {
126+
holder.transactionResultHolder(txResultHolder, (T) accessor.getBean());
111127
}
112128

113129
return accessor.getBean();
@@ -117,13 +133,16 @@ CouchbasePersistentEntity couldBePersistentEntity(Class<?> entityClass) {
117133
if (ClassUtils.isPrimitiveOrWrapper(entityClass) || entityClass == String.class) {
118134
return null;
119135
}
120-
return mappingContext.getPersistentEntity(entityClass);
121-
}
122-
136+
try {
137+
return mappingContext.getPersistentEntity(entityClass);
138+
} catch (InaccessibleObjectException t) {
123139

140+
}
141+
return null;
142+
}
124143

125144
public <T> T applyResultBase(T entity, CouchbaseDocument converted, Object id, long cas,
126-
TransactionResultHolder txResultHolder, CouchbaseResourceHolder holder) {
145+
TransactionResultHolder txResultHolder, CouchbaseResourceHolder holder) {
127146
ConvertingPropertyAccessor<Object> accessor = getPropertyAccessor(entity);
128147

129148
final CouchbasePersistentEntity<?> persistentEntity = converter.getMappingContext()
@@ -139,8 +158,8 @@ public <T> T applyResultBase(T entity, CouchbaseDocument converted, Object id, l
139158
accessor.setProperty(versionProperty, cas);
140159
}
141160

142-
if(holder != null){
143-
holder.transactionResultHolder(txResultHolder, (T)accessor.getBean());
161+
if (holder != null) {
162+
holder.transactionResultHolder(txResultHolder, (T) accessor.getBean());
144163
}
145164
maybeEmitEvent(new AfterSaveEvent(accessor.getBean(), converted));
146165
return (T) accessor.getBean();
@@ -202,7 +221,7 @@ private boolean canPublishEvent() {
202221
return this.applicationContext != null;
203222
}
204223

205-
public TranslationService getTranslationService(){
224+
public TranslationService getTranslationService() {
206225
return translationService;
207226
}
208227
}

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

+8-84
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import org.springframework.data.couchbase.core.mapping.event.CouchbaseMappingEvent;
3636
import org.springframework.data.couchbase.core.support.TemplateUtils;
3737
import org.springframework.data.couchbase.repository.support.MappingCouchbaseEntityInformation;
38+
import org.springframework.data.couchbase.repository.support.TransactionResultHolder;
39+
import org.springframework.data.couchbase.transaction.CouchbaseResourceHolder;
3840
import org.springframework.data.mapping.PersistentPropertyAccessor;
3941
import org.springframework.data.mapping.callback.EntityCallbacks;
4042
import org.springframework.util.Assert;
@@ -73,95 +75,13 @@ public CouchbaseDocument encodeEntity(final Object entityToEncode) {
7375
}
7476

7577
@Override
76-
public <T> T decodeEntity(String id, String source, Long cas, Class<T> entityClass, String scope, String collection) {
77-
78-
// this is the entity class defined for the repository. It may not be the class of the document that was read
79-
// we will reset it after reading the document
80-
//
81-
// This will fail for the case where:
82-
// 1) The version is defined in the concrete class, but not in the abstract class; and
83-
// 2) The constructor takes a "long version" argument resulting in an exception would be thrown if version in
84-
// the source is null.
85-
// We could expose from the MappingCouchbaseConverter determining the persistent entity from the source,
86-
// but that is a lot of work to do every time just for this very rare and avoidable case.
87-
// TypeInformation<? extends R> typeToUse = typeMapper.readType(source, type);
88-
89-
CouchbasePersistentEntity persistentEntity = couldBePersistentEntity(entityClass);
90-
91-
if (persistentEntity == null) { // method could return a Long, Boolean, String etc.
92-
// QueryExecutionConverters.unwrapWrapperTypes will recursively unwrap until there is nothing left
93-
// to unwrap. This results in List<String[]> being unwrapped past String[] to String, so this may also be a
94-
// Collection (or Array) of entityClass. We have no way of knowing - so just assume it is what we are told.
95-
// if this is a Collection or array, only the first element will be returned.
96-
final CouchbaseDocument converted = new CouchbaseDocument(id);
97-
Set<Map.Entry<String, Object>> set = ((CouchbaseDocument) translationService.decode(source, converted))
98-
.getContent().entrySet();
99-
return (T) set.iterator().next().getValue();
100-
}
101-
102-
if (id == null) {
103-
throw new CouchbaseException(TemplateUtils.SELECT_ID + " was null. Either use #{#n1ql.selectEntity} or project "
104-
+ TemplateUtils.SELECT_ID);
105-
}
106-
107-
final CouchbaseDocument converted = new CouchbaseDocument(id);
108-
109-
// if possible, set the version property in the source so that if the constructor has a long version argument,
110-
// it will have a value and not fail (as null is not a valid argument for a long argument). This possible failure
111-
// can be avoid by defining the argument as Long instead of long.
112-
// persistentEntity is still the (possibly abstract) class specified in the repository definition
113-
// it's possible that the abstract class does not have a version property, and this won't be able to set the version
114-
if (persistentEntity.getVersionProperty() != null) {
115-
if (cas == null) {
116-
throw new CouchbaseException("version/cas in the entity but " + TemplateUtils.SELECT_CAS
117-
+ " was not in result. Either use #{#n1ql.selectEntity} or project " + TemplateUtils.SELECT_CAS);
118-
}
119-
if (cas != 0) {
120-
converted.put(persistentEntity.getVersionProperty().getName(), cas);
121-
}
122-
}
123-
124-
// if the constructor has an argument that is long version, then construction will fail if the 'version'
125-
// is not available as 'null' is not a legal value for a long. Changing the arg to "Long version" would solve this.
126-
// (Version doesn't come from 'source', it comes from the cas argument to decodeEntity)
127-
T readEntity = converter.read(entityClass, (CouchbaseDocument) translationService.decode(source, converted));
128-
final ConvertingPropertyAccessor<T> accessor = getPropertyAccessor(readEntity);
129-
130-
persistentEntity = couldBePersistentEntity(readEntity.getClass());
131-
132-
if (cas != null && cas != 0 && persistentEntity.getVersionProperty() != null) {
133-
accessor.setProperty(persistentEntity.getVersionProperty(), cas);
134-
}
135-
N1qlJoinResolver.handleProperties(persistentEntity, accessor, template.reactive(), id, scope, collection);
136-
return accessor.getBean();
137-
}
138-
CouchbasePersistentEntity couldBePersistentEntity(Class<?> entityClass) {
139-
if (ClassUtils.isPrimitiveOrWrapper(entityClass) || entityClass == String.class) {
140-
return null;
141-
}
142-
return mappingContext.getPersistentEntity(entityClass);
143-
}
144-
145-
CouchbasePersistentEntity couldBePersistentEntity(Class<?> entityClass) {
146-
if (ClassUtils.isPrimitiveOrWrapper(entityClass) || entityClass == String.class) {
147-
return null;
148-
}
149-
try {
150-
return mappingContext.getPersistentEntity(entityClass);
151-
} catch (InaccessibleObjectException t) {
152-
153-
}
154-
return null;
155-
}
156-
157-
@Override
158-
public <T> T decodeEntity(String id, String source, long cas, Class<T> entityClass, String scope, String collection,
78+
public <T> T decodeEntity(String id, String source, Long cas, Class<T> entityClass, String scope, String collection,
15979
TransactionResultHolder txHolder) {
16080
return decodeEntity(id, source, cas, entityClass, scope, collection, txHolder);
16181
}
16282

16383
@Override
164-
public <T> T decodeEntity(String id, String source, long cas, Class<T> entityClass, String scope, String collection,
84+
public <T> T decodeEntity(String id, String source, Long cas, Class<T> entityClass, String scope, String collection,
16585
TransactionResultHolder txHolder, CouchbaseResourceHolder holder) {
16686
return decodeEntityBase(id, source, cas, entityClass, scope, collection, txHolder, holder);
16787
}
@@ -225,4 +145,8 @@ protected <T> T maybeCallAfterConvert(T object, CouchbaseDocument document, Stri
225145
return object;
226146
}
227147

148+
@Override
149+
ReactiveCouchbaseTemplate getReactiveTemplate() {
150+
return template.reactive();
151+
}
228152
}

0 commit comments

Comments
 (0)