Version 7: How to ignore POJO fields for arangodb but serialize for outgoing as JSON with jackson
lorling88 opened this issue · comments
Hi there, im running on the latest version 7 and ran into this issue.
Before version 7, I had been using "com.arangodb.velocypack.annotations.Expose" to ignore fields being used by arangodb driver,
for example:
public class AAA {
private boolean memberKey;
Expose(serialize=false,deserialize=false) private boolean isStatusActive;
}
for this instance, when I insert, select, replace, etc, the field memberKey will be used and field "isStatusActive" will be ignored by arangodb and I can serialize both "memberKey" and "isStatusActive" for JSON text.
But now after version7, if I put in "@JsonIgnore private boolean isStatusActive" by Jackson "com.fasterxml.jackson.annotation.JsonIgnore", it will be ignore by both arangodb and jackson serialization.
I had just began to learn about jackson so maybe I had missed out some features which can bypass my issue here.
Please kindly advise.
Hi @lorling88,
to work around it you can either:
-
use different classes in different layers of your application: you can use the entity class
PersistentAAAin the persistence layer andWebAAAin the web layer. This would allow for customizing serialization and deserialization in different layers without interfereing with each other. Nonetheless this comes with an additional cost: you need to maintain 2 classes and convert between them. -
you can customize the ArangoDB driver JacksonSerde with custom annotations, e.g. in the following snippet you can see how to create a
@ArangoIgnoreannotation that is equivalent to Jackson@JsonIgnore, but it will only be considered by the ArangoDB serde and not by other Jackson instances in your application:
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface ArangoAnnotationsInside {
}
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@ArangoAnnotationsInside
@JsonIgnore
@interface ArangoIgnore {
}
class AAA {
public boolean memberKey;
@ArangoIgnore
public boolean isStatusActive;
}
// ...
//
JacksonSerde serde = JacksonSerde.of(ContentType.JSON)
.configure((mapper) -> mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
public boolean isAnnotationBundle(Annotation ann) {
return ann.annotationType().getAnnotation(ArangoAnnotationsInside.class) != null;
}
}));
ArangoDB adb = new ArangoDB.Builder()
.serde(serde)
// ...
.build();In my opinion, (1) is a better choice for big projects, while (2) could be suitable for smaller ones.
Hi @rashtao,
Thanks for your helpful reply and I had learnt something new about jackson lib.
I went for your method (2) and its working!
Cheers!
You are welcome @lorling88 !
Please note that I made a small mistake in my snippet, the correct serde configuration should be:
JacksonSerde serde = JacksonSerde.of(ContentType.JSON)
.configure((mapper) -> mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
public boolean isAnnotationBundle(Annotation ann) {
return ann.annotationType().getAnnotation(ArangoAnnotationsInside.class) != null || super.isAnnotationBundle(ann);
}
}));I added here the invocation to super.isAnnotationBundle(ann), to handle also @JacksonAnnotationsInside annotations, which is required to make properly work document annotations like @Key, @Rev and others in com.arangodb.serde.jackson package.