Skip to content

Commit 26c7d89

Browse files
committed
To support jdk 16, add converters and module-info.
Closes #1057.
1 parent 7cde6b9 commit 26c7d89

20 files changed

+233
-41
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
</parent>
1919

2020
<properties>
21-
<couchbase>3.1.6</couchbase>
22-
<couchbase.osgi>3.1.6</couchbase.osgi>
21+
<couchbase>3.2.0</couchbase>
22+
<couchbase.osgi>3.2.0</couchbase.osgi>
2323
<springdata.commons>2.6.0-SNAPSHOT</springdata.commons>
2424
<java-module-name>spring.data.couchbase</java-module-name>
2525
</properties>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public long getCas(final Object entity) {
133133

134134
long cas = 0;
135135
if (versionProperty != null) {
136-
Object casObject = (Number) accessor.getProperty(versionProperty);
136+
Object casObject = accessor.getProperty(versionProperty);
137137
if (casObject instanceof Number) {
138138
cas = ((Number) casObject).longValue();
139139
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public Long getCas(final Object entity) {
140140

141141
long cas = 0;
142142
if (versionProperty != null) {
143-
Object casObject = (Number) accessor.getProperty(versionProperty);
143+
Object casObject = accessor.getProperty(versionProperty);
144144
if (casObject instanceof Number) {
145145
cas = ((Number) casObject).longValue();
146146
}

src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseCustomConversions.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017-2020 the original author or authors.
2+
* Copyright 2017-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -50,6 +50,7 @@ public class CouchbaseCustomConversions extends org.springframework.data.convert
5050

5151
converters.addAll(DateConverters.getConvertersToRegister());
5252
converters.addAll(CouchbaseJsr310Converters.getConvertersToRegister());
53+
converters.addAll(OtherConverters.getConvertersToRegister());
5354

5455
STORE_CONVERTERS = Collections.unmodifiableList(converters);
5556
STORE_CONVERSIONS = StoreConversions.of(SimpleTypeHolder.DEFAULT, STORE_CONVERTERS);

src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors
2+
* Copyright 2012-2021 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@
3535
import org.springframework.core.convert.ConversionService;
3636
import org.springframework.core.convert.support.DefaultConversionService;
3737
import org.springframework.data.annotation.Transient;
38+
import org.springframework.data.convert.CustomConversions;
3839
import org.springframework.data.convert.EntityInstantiator;
3940
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
4041
import org.springframework.data.couchbase.core.mapping.CouchbaseList;
@@ -117,11 +118,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
117118
private @Nullable EntityCallbacks entityCallbacks;
118119

119120
public MappingCouchbaseConverter() {
120-
super(new DefaultConversionService());
121-
122-
this.typeMapper = new DefaultCouchbaseTypeMapper(TYPEKEY_DEFAULT);
123-
this.mappingContext = new CouchbaseMappingContext();
124-
this.spELContext = new SpELContext(CouchbaseDocumentPropertyAccessor.INSTANCE);
121+
this(new CouchbaseMappingContext(), null);
125122
}
126123

127124
/**
@@ -131,7 +128,7 @@ public MappingCouchbaseConverter() {
131128
*/
132129
public MappingCouchbaseConverter(
133130
final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext) {
134-
this(mappingContext, TYPEKEY_DEFAULT);
131+
this(mappingContext, null);
135132
}
136133

137134
/**
@@ -145,8 +142,14 @@ public MappingCouchbaseConverter(
145142
final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext,
146143
final String typeKey) {
147144
super(new DefaultConversionService());
148-
149145
this.mappingContext = mappingContext;
146+
// this is how the MappingCouchbaseConverter gets the custom conversions.
147+
// the conversions Service gets them in afterPropertiesSet()
148+
CustomConversions customConversions = new CouchbaseCustomConversions(Collections.emptyList());
149+
this.setCustomConversions(customConversions);
150+
// if the mappingContext does not have the SimpleTypes, it will not know that they have converters, then it will
151+
// try to access the fields of the type and (maybe) fail with InaccessibleObjectException
152+
((CouchbaseMappingContext) mappingContext).setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
150153
typeMapper = new DefaultCouchbaseTypeMapper(typeKey != null ? typeKey : TYPEKEY_DEFAULT);
151154
spELContext = new SpELContext(CouchbaseDocumentPropertyAccessor.INSTANCE);
152155
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2021 the original author or authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.data.couchbase.core.convert;
18+
19+
import java.math.BigInteger;
20+
import java.util.ArrayList;
21+
import java.util.Collection;
22+
import java.util.List;
23+
import java.util.UUID;
24+
25+
import org.springframework.core.convert.converter.Converter;
26+
import org.springframework.data.convert.ReadingConverter;
27+
import org.springframework.data.convert.WritingConverter;
28+
29+
/**
30+
* Out of the box conversions for java dates and calendars.
31+
*
32+
* @author Michael Reiche
33+
*/
34+
public final class OtherConverters {
35+
36+
private OtherConverters() {}
37+
38+
/**
39+
* Returns all converters by this class that can be registered.
40+
*
41+
* @return the list of converters to register.
42+
*/
43+
public static Collection<Converter<?, ?>> getConvertersToRegister() {
44+
List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
45+
46+
converters.add(UuidToString.INSTANCE);
47+
converters.add(StringToUuid.INSTANCE);
48+
converters.add(BigIntegerToString.INSTANCE);
49+
converters.add(StringToBigInteger.INSTANCE);
50+
51+
return converters;
52+
}
53+
54+
@WritingConverter public enum UuidToString implements Converter<UUID,String>
55+
{
56+
INSTANCE;
57+
58+
@Override
59+
public String convert(UUID source) {
60+
return source == null ? null : source.toString();
61+
}}
62+
63+
@ReadingConverter public enum StringToUuid implements Converter<String,UUID>{INSTANCE;
64+
65+
@Override
66+
public UUID convert(String source) {
67+
return source == null ? null : UUID.fromString(source);
68+
}}
69+
70+
@WritingConverter public enum BigIntegerToString implements Converter<BigInteger,String>{INSTANCE;
71+
72+
@Override
73+
public String convert(BigInteger source) {
74+
return source == null ? null : source.toString();
75+
}}
76+
77+
@ReadingConverter public enum StringToBigInteger implements Converter<String,BigInteger>{INSTANCE;
78+
79+
@Override
80+
public BigInteger convert(String source) {
81+
return source == null ? null : new BigInteger(source);
82+
}
83+
}}

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors
2+
* Copyright 2012-2021 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,6 +34,10 @@
3434
import com.couchbase.client.core.error.IndexExistsException;
3535
import com.couchbase.client.java.Cluster;
3636

37+
/**
38+
* @author Michael Nitschinger
39+
* @author Michael Reiche
40+
*/
3741
public class CouchbasePersistentEntityIndexCreator implements ApplicationListener<MappingContextEvent<?, ?>> {
3842

3943
private static final Logger LOGGER = LoggerFactory.getLogger(CouchbasePersistentEntityIndexCreator.class);
@@ -95,7 +99,8 @@ private void checkForAndCreateIndexes(final CouchbasePersistentEntity<?> entity)
9599
private void createIndex(final IndexDefinitionHolder indexToCreate) {
96100
Cluster cluster = couchbaseOperations.getCouchbaseClientFactory().getCluster();
97101

98-
StringBuilder statement = new StringBuilder("CREATE INDEX ").append(indexToCreate.getIndexName()).append(" ON `")
102+
StringBuilder statement = new StringBuilder("CREATE INDEX `")
103+
.append(indexToCreate.getIndexName()).append("` ON `")
99104
.append(couchbaseOperations.getBucketName()).append("` (")
100105
.append(String.join(",", indexToCreate.getIndexFields())).append(")");
101106

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors
2+
* Copyright 2012-2021 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,6 +32,10 @@
3232
import org.springframework.util.Assert;
3333
import org.springframework.util.StringUtils;
3434

35+
/**
36+
* @author Michael Nitschinger
37+
* @author Michael Reiche
38+
*/
3539
public class CouchbasePersistentEntityIndexResolver implements QueryIndexResolver {
3640

3741
private final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext;
@@ -103,7 +107,8 @@ protected IndexDefinitionHolder createFieldQueryIndexDefinition(final CouchbaseP
103107
String fieldName = index.name().isEmpty() ? property.getFieldName() : index.name();
104108
fields.add(fieldName + (index.direction() == QueryIndexDirection.DESCENDING ? " DESC" : ""));
105109

106-
String indexName = "idx_" + StringUtils.uncapitalize(entity.getType().getSimpleName()) + "_" + fieldName;
110+
String indexName = "idx_" + StringUtils.uncapitalize(entity.getType().getSimpleName()) + "_"
111+
+ fieldName.replace(".", "_");
107112

108113
return new IndexDefinitionHolder(fields, indexName, getPredicate(entityInfo));
109114
}
@@ -126,8 +131,8 @@ protected List<IndexDefinitionHolder> createCompositeQueryIndexDefinitions(final
126131

127132
return indexAnnotations.stream().map(ann -> {
128133
List<String> fields = Arrays.asList(ann.fields());
129-
String fieldsIndexName = String.join("_", fields).toLowerCase().replace(" ", "").replace("asc", "")
130-
.replace("desc", "");
134+
String fieldsIndexName = String.join("_", fields).toLowerCase().replace(".", "_").replace(" ", "")
135+
.replace("asc", "").replace("desc", "");
131136

132137
String indexName = "idx_" + StringUtils.uncapitalize(entity.getType().getSimpleName()) + "_" + fieldsIndexName;
133138
return new IndexDefinitionHolder(fields, indexName, predicate);

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors
2+
* Copyright 2012-2021 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,13 +16,15 @@
1616

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

19+
import java.lang.reflect.InaccessibleObjectException;
1920
import java.util.Optional;
2021

2122
import org.springframework.beans.BeansException;
2223
import org.springframework.context.ApplicationContext;
2324
import org.springframework.context.ApplicationContextAware;
2425
import org.springframework.context.ApplicationEventPublisher;
2526
import org.springframework.data.couchbase.core.index.CouchbasePersistentEntityIndexCreator;
27+
import org.springframework.data.mapping.MappingException;
2628
import org.springframework.data.mapping.context.AbstractMappingContext;
2729
import org.springframework.data.mapping.context.MappingContextEvent;
2830
import org.springframework.data.mapping.model.FieldNamingStrategy;
@@ -131,12 +133,17 @@ public void setAutoIndexCreation(boolean autoCreateIndexes) {
131133
/**
132134
* override method from AbstractMappingContext as that method will not publishEvent() if it finds the entity has
133135
* already been cached
134-
*
136+
*
135137
* @param typeInformation - entity type
136138
*/
137139
@Override
138140
protected Optional<BasicCouchbasePersistentEntity<?>> addPersistentEntity(TypeInformation<?> typeInformation) {
139-
Optional<BasicCouchbasePersistentEntity<?>> entity = super.addPersistentEntity(typeInformation);
141+
Optional<BasicCouchbasePersistentEntity<?>> entity = null;
142+
try {
143+
entity = super.addPersistentEntity(typeInformation);
144+
} catch (InaccessibleObjectException ioe) {
145+
throw new MappingException("due to InaccessibleObjectException", ioe);
146+
}
140147

141148
if (this.eventPublisher != null && entity.isPresent()) {
142149
if (this.indexCreator != null) {

src/main/java/org/springframework/data/couchbase/repository/support/CrudMethodMetadataPostProcessor.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ public Object invoke(MethodInvocation invocation) throws Throwable {
145145
currentInvocation.set(invocation);
146146

147147
try {
148-
149148
CrudMethodMetadata metadata = (CrudMethodMetadata) TransactionSynchronizationManager.getResource(method);
150149

151150
if (metadata != null) {
@@ -156,7 +155,7 @@ public Object invoke(MethodInvocation invocation) throws Throwable {
156155

157156
if (methodMetadata == null) {
158157

159-
methodMetadata = new DefaultCrudMethodMetadata(method, repositoryInformation);
158+
methodMetadata = new DefaultCrudMethodMetadata(method);
160159
CrudMethodMetadata tmp = metadataCache.putIfAbsent(method, methodMetadata);
161160

162161
if (tmp != null) {
@@ -187,7 +186,6 @@ private static class DefaultCrudMethodMetadata implements CrudMethodMetadata {
187186

188187
private final Method method;
189188
private final ScanConsistency scanConsistency;
190-
private final RepositoryInformation repositoryInformation;
191189
private final String scope;
192190
private final String collection;
193191

@@ -198,10 +196,9 @@ private static class DefaultCrudMethodMetadata implements CrudMethodMetadata {
198196
*
199197
* @param method must not be {@literal null}.
200198
*/
201-
DefaultCrudMethodMetadata(Method method, RepositoryInformation repositoryInformation) {
199+
DefaultCrudMethodMetadata(Method method) {
202200
Assert.notNull(method, "Method must not be null!");
203201
this.method = method;
204-
this.repositoryInformation = repositoryInformation;
205202
String n = method.getName();
206203
// internal methods
207204
if (n.equals("getEntityInformation") || n.equals("getOperations") || n.equals("withOptions")
@@ -212,8 +209,7 @@ private static class DefaultCrudMethodMetadata implements CrudMethodMetadata {
212209
return;
213210
}
214211

215-
AnnotatedElement[] annotated = new AnnotatedElement[] { method, method.getDeclaringClass(),
216-
repositoryInformation.getRepositoryInterface(), repositoryInformation.getDomainType() };
212+
AnnotatedElement[] annotated = new AnnotatedElement[] { method, method.getDeclaringClass()};
217213
this.scanConsistency = OptionsBuilder.annotation(ScanConsistency.class, "query", QueryScanConsistency.NOT_BOUNDED,
218214
annotated);
219215
this.scope = OptionsBuilder.annotationString(Scope.class, CollectionIdentifier.DEFAULT_SCOPE, annotated);

src/main/resources/notice.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Spring Data Couchbase 4.3 M1 (2021.1.0)
1+
Spring Data Couchbase 4.3 M2 (2021.1.0)
22
Copyright (c) [2013-2019] Couchbase / Pivotal Software, Inc.
33

44
This product is licensed to you under the Apache License, Version 2.0 (the "License").
@@ -27,4 +27,5 @@ conditions of the subcomponent's license, as noted in the LICENSE file.
2727

2828

2929

30+
3031

src/test/java/org/springframework/data/couchbase/core/mapping/MappingCouchbaseConverterTests.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.core.convert.converter.Converter;
3030
import org.springframework.data.annotation.Id;
3131
import org.springframework.data.annotation.TypeAlias;
32+
import org.springframework.data.convert.CustomConversions;
3233
import org.springframework.data.convert.ReadingConverter;
3334
import org.springframework.data.convert.WritingConverter;
3435
import org.springframework.data.couchbase.core.convert.CouchbaseCustomConversions;
@@ -421,8 +422,10 @@ void writesAndReadsCustomConvertedClass() {
421422
List<Object> converters = new ArrayList<>();
422423
converters.add(BigDecimalToStringConverter.INSTANCE);
423424
converters.add(StringToBigDecimalConverter.INSTANCE);
424-
converter.setCustomConversions(new CouchbaseCustomConversions(converters));
425+
CustomConversions customConversions = new CouchbaseCustomConversions(converters);
426+
converter.setCustomConversions(customConversions);
425427
converter.afterPropertiesSet();
428+
((CouchbaseMappingContext) converter.getMappingContext()).setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
426429

427430
CouchbaseDocument converted = new CouchbaseDocument();
428431

@@ -469,8 +472,11 @@ void writesAndReadsCustomFieldsConvertedClass() {
469472
List<Object> converters = new ArrayList<>();
470473
converters.add(BigDecimalToStringConverter.INSTANCE);
471474
converters.add(StringToBigDecimalConverter.INSTANCE);
472-
converter.setCustomConversions(new CouchbaseCustomConversions(converters));
475+
CustomConversions customConversions = new CouchbaseCustomConversions(converters);
476+
converter.setCustomConversions(customConversions);
473477
converter.afterPropertiesSet();
478+
((CouchbaseMappingContext) converter.getMappingContext()).setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
479+
474480

475481
CouchbaseDocument converted = new CouchbaseDocument();
476482

@@ -517,8 +523,10 @@ void writesAndReadsClassContainingCustomConvertedObjects() {
517523
List<Object> converters = new ArrayList<>();
518524
converters.add(BigDecimalToStringConverter.INSTANCE);
519525
converters.add(StringToBigDecimalConverter.INSTANCE);
520-
converter.setCustomConversions(new CouchbaseCustomConversions(converters));
526+
CustomConversions customConversions = new CouchbaseCustomConversions(converters);
527+
converter.setCustomConversions(customConversions);
521528
converter.afterPropertiesSet();
529+
((CouchbaseMappingContext) converter.getMappingContext()).setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
522530

523531
CouchbaseDocument converted = new CouchbaseDocument();
524532

0 commit comments

Comments
 (0)