Spring App - StackOverflowError on Serialization - Need our ObjectMapper


#1

I have a Spring/JPA (Hibernate) App that we are trying to be bring Couchbase into for some caching and other functionality. Some of this functionality requires us to pull objects from MySQL and serialize them into Couchbase (JSON). We have some @OneToMany type of scenarios that create circular references for JSON serializers. We already have this problem solved with our own Jackson ObjectMapper for our REST API.

My question is - how do I use our own Jackson ObjectMapper to perform all the serialization/deserialization for for Couchbase. We ARE using extension of CrudRepository, which is making it difficult. I know how to do it if I simply wanted to do key/value or direct N1QL queries, it’s the Repo stuff that is challenging to figure out what is happening under the hood.

We are using a CouchbaseConfig that extends AbstractCouchbaseConfig in our spring app. When the circular reference causes the StackOverflowError, we are seeing the following (repeated):

org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.access$000(MappingCouchbaseConverter.java:65)
org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter$3.doWithPersistentProperty(MappingCouchbaseConverter.java:442)
org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter$3.doWithPersistentProperty(MappingCouchbaseConverter.java:432)
org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:310)
org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.writeInternal(MappingCouchbaseConverter.java:432)
org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.writeInternal(MappingCouchbaseConverter.java:387)
org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.writeCollectionInternal(MappingCouchbaseConverter.java:590)
org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.createCollection(MappingCouchbaseConverter.java:566)
org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.writePropertyInternal(MappingCouchbaseConverter.java:483

I don’t see any indication of Couchbase using Jackson.

Thanks for any help.
Geoff


#2

JacksonTranslationService is the object that does the serialization. You should be able to override the bean creation method in the configuration, call the super implementation and set your Object mapper using the setObjectMapper method…


#3

Thanks. I had tried that. I even tried writing a custom TranslationService implementation and returning that in the bean creation. I still was not able to step into my code nor was Jackson showing up in the stack that was overflowing.

Does the stack that I posted indicate that I am bombing out inside the JacksonTranslationService? It doesn’t appear to - yet I know this is a serialization issue since I have known circular references that require observance of @JsonIgnore annotations.

I will give it another shot.

Thanks.


#4

@simonbasle - I have dug a little deeper into this issue and the problem doesn’t appear to be on the JSON serialization. We are blowing the stack in the:

this.converter.write(objectToPersist, converted);

Any suggestions on either Annotation based solutions or modifications to the MappingCouchbaseConverter to properly handle circular references? The property is currently annotated with @JsonIgnore, for Jackson, but that doesn’t seem to hae any impact on the mapper.

Any help is appreciated.

Thanks,
Geoff


#5

I have a working solution, but it required me to basically copy/paste the entire code for MappingCouchbaseConverter since many of the methods required were “private” scoped.

The method:

protected void writeInternal(final Object source, final CouchbaseDocument target,
final CouchbasePersistentEntity<?> entity) {

requires a check to see if the CouchbasePersistentProperty is actually annotated with @Field before writing the object.

if(prop.isAnnotationPresent(Field.class)){
//do writePropertyInternal or writeSimpleInternal
}

I haven’t see anywhere in the code where the @Field annotation is actually used, not sure what the intention of that was, but I think this is the “edge” case that the user docs were referring to. I would be willing to submit a patch to add functionality to “enableStrictFieldChecking”.