Skip to content

Commit a806631

Browse files
authored
Expose ObjectMapper used by JsonSerializer (#1132)
Closes #1130. Co-authored-by: mikereiche <[email protected]>
1 parent 36de313 commit a806631

File tree

3 files changed

+56
-10
lines changed

3 files changed

+56
-10
lines changed

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

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616

1717
package org.springframework.data.couchbase.config;
1818

19-
import static com.couchbase.client.java.ClusterOptions.*;
19+
import static com.couchbase.client.java.ClusterOptions.clusterOptions;
2020

2121
import java.util.Collections;
2222
import java.util.HashSet;
2323
import java.util.Set;
2424

25+
import org.springframework.beans.factory.annotation.Autowired;
2526
import org.springframework.beans.factory.config.BeanDefinition;
2627
import org.springframework.context.annotation.Bean;
2728
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
@@ -48,11 +49,19 @@
4849
import org.springframework.util.StringUtils;
4950

5051
import com.couchbase.client.core.deps.com.fasterxml.jackson.databind.DeserializationFeature;
52+
import com.couchbase.client.core.deps.com.fasterxml.jackson.databind.Module;
53+
import com.couchbase.client.core.encryption.CryptoManager;
5154
import com.couchbase.client.core.env.Authenticator;
5255
import com.couchbase.client.core.env.PasswordAuthenticator;
56+
import com.couchbase.client.core.error.CouchbaseException;
5357
import com.couchbase.client.java.Cluster;
58+
import com.couchbase.client.java.codec.JacksonJsonSerializer;
59+
import com.couchbase.client.java.encryption.databind.jackson.EncryptionModule;
5460
import com.couchbase.client.java.env.ClusterEnvironment;
5561
import com.couchbase.client.java.json.JacksonTransformers;
62+
import com.couchbase.client.java.json.JsonValueModule;
63+
import com.couchbase.client.java.json.RepackagedJsonValueModule;
64+
import com.fasterxml.jackson.databind.ObjectMapper;
5665

5766
/**
5867
* Base class for Spring Data Couchbase configuration using JavaConfig.
@@ -65,12 +74,13 @@
6574
@Configuration
6675
public abstract class AbstractCouchbaseConfiguration {
6776

77+
@Autowired ObjectMapper couchbaseObjectMapper;
78+
6879
/**
6980
* The connection string which allows the SDK to connect to the cluster.
7081
* <p>
71-
* Note that the connection string can take many forms, in its simplest it is just a single hostname
72-
* like "127.0.0.1". Please refer to the couchbase Java SDK documentation for all the different
73-
* possibilities and options.
82+
* Note that the connection string can take many forms, in its simplest it is just a single hostname like "127.0.0.1".
83+
* Please refer to the couchbase Java SDK documentation for all the different possibilities and options.
7484
*/
7585
public abstract String getConnectionString();
7686

@@ -130,6 +140,10 @@ public Cluster couchbaseCluster(ClusterEnvironment couchbaseClusterEnvironment)
130140
@Bean(destroyMethod = "shutdown")
131141
public ClusterEnvironment couchbaseClusterEnvironment() {
132142
ClusterEnvironment.Builder builder = ClusterEnvironment.builder();
143+
if (!nonShadowedJacksonPresent()) {
144+
throw new CouchbaseException("non-shadowed Jackson not present");
145+
}
146+
builder.jsonSerializer(JacksonJsonSerializer.create(couchbaseObjectMapper));
133147
configureEnvironment(builder);
134148
return builder.build();
135149
}
@@ -273,6 +287,25 @@ public CouchbaseMappingContext couchbaseMappingContext(CustomConversions customC
273287
return mappingContext;
274288
}
275289

290+
/**
291+
* Creates a {@link ObjectMapper} for the jsonSerializer of the ClusterEnvironment
292+
*
293+
* @throws Exception on Bean construction failure.
294+
* @return ObjectMapper
295+
*/
296+
297+
@Bean
298+
public ObjectMapper couchbaseObjectMapper() {
299+
ObjectMapper mapper = new ObjectMapper();
300+
mapper.configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
301+
mapper.registerModule(new JsonValueModule());
302+
CryptoManager cryptoManager = null;
303+
if (cryptoManager != null) {
304+
mapper.registerModule(new EncryptionModule(cryptoManager));
305+
}
306+
return mapper;
307+
}
308+
276309
/**
277310
* Configure whether to automatically create indices for domain types by deriving the from the entity or not.
278311
*/
@@ -327,4 +360,14 @@ protected FieldNamingStrategy fieldNamingStrategy() {
327360
return abbreviateFieldNames() ? new CamelCaseAbbreviatingFieldNamingStrategy()
328361
: PropertyNameFieldNamingStrategy.INSTANCE;
329362
}
363+
364+
private boolean nonShadowedJacksonPresent() {
365+
try {
366+
JacksonJsonSerializer.preflightCheck();
367+
return true;
368+
} catch (Throwable t) {
369+
return false;
370+
}
371+
}
372+
330373
}

src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ void findByTypeAlias() {
184184
vie = new Airport("airports::vie", "vie", "loww");
185185
vie = airportRepository.save(vie);
186186
List<Airport> airports = couchbaseTemplate.findByQuery(Airport.class)
187+
.withConsistency(QueryScanConsistency.REQUEST_PLUS)
187188
.matching(new Query(QueryCriteria.where(N1QLExpression.x("_class")).is("airport"))).all();
188189
assertFalse(airports.isEmpty(), "should have found aiport");
189190
} finally {

src/test/java/org/springframework/data/couchbase/repository/ReactiveCouchbaseRepositoryKeyValueIntegrationTests.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616

1717
package org.springframework.data.couchbase.repository;
1818

19-
import static org.junit.jupiter.api.Assertions.*;
19+
import static org.junit.jupiter.api.Assertions.assertEquals;
20+
import static org.junit.jupiter.api.Assertions.assertFalse;
21+
import static org.junit.jupiter.api.Assertions.assertTrue;
2022

21-
import java.util.List;
2223
import java.util.Optional;
2324
import java.util.UUID;
25+
2426
import org.junit.jupiter.api.Test;
2527
import org.springframework.beans.factory.annotation.Autowired;
2628
import org.springframework.context.annotation.Bean;
@@ -64,13 +66,13 @@ void saveAndFindById() {
6466
}
6567

6668
@Test
67-
void findBySimplePropertyAudited() {
69+
void findByIdAudited() {
6870
Airport vie = null;
6971
try {
7072
vie = new Airport("airports::vie", "vie", "low2");
7173
Airport saved = airportRepository.save(vie).block();
72-
List<Airport> airports1 = airportRepository.findAllByIata("vie").collectList().block();
73-
assertEquals(saved, airports1.get(0));
74+
Airport airport1 = airportRepository.findById(saved.getId()).block();
75+
assertEquals(airport1, saved);
7476
assertEquals(saved.getCreatedBy(), "auditor"); // NaiveAuditorAware will provide this
7577
} finally {
7678
airportRepository.delete(vie).block();
@@ -79,7 +81,7 @@ void findBySimplePropertyAudited() {
7981

8082
@Configuration
8183
@EnableReactiveCouchbaseRepositories("org.springframework.data.couchbase")
82-
@EnableReactiveCouchbaseAuditing
84+
@EnableReactiveCouchbaseAuditing
8385
static class Config extends AbstractCouchbaseConfiguration {
8486

8587
@Override

0 commit comments

Comments
 (0)