简体   繁体   中英

Builder pattern when retrieving entity from DB w/ spring boot reactor & mongo

I have the following bean that describes a mongo document, and that uses lombok:

@JsonDeserialize(builder = MyClass.MyClassBuilder.class)
@Builder(toBuilder = true)
@Value
public class MyClass {

    private final String id;

    @Default
    private final String field = "defaultValue";

    @JsonPOJOBuilder(withPrefix = "")
    public static class MyClassBuilder {}
}

When deserializing {"id": "document"} with jackson, I end-up with a bean containing both id=document and field=defaultValue because it used the builder that provide a default value for the field.

Now what I want to do, is to have the defaultValue set for documents coming out of the database (coming from ReactiveMongoTemplate ). But it seems to use the all args constructor even if I set it private (or some reflect black magic)

So the main question is: is it possible to tell spring to use the builder to build the bean when coming out of the database?

  • You are not going to be able to use your custom serialiser because when I go through the source code of MappingMongoConverter in spring mongodb (debugged it with a sample app), I see only the following steps.

  • Once the value from db is available as org.bson.Document , MappingMongoConverter.java is looking to create your entity object.

  • First, it checks if you have any custom converters registered and if you have it, then use it. So one option is to use a custom converter registered.

  • If there is no custom converters registered, it goes and find the PersistenceConstructor and use it. I had an object with 3 constructors (no param, one param, and all param) and it chose my no param constructor.

  • However, if I annotate a constructor with @PersistenceConstructor , it is choosing that constructor. So could follow this approach but then you have to keep String field un-initialised and getting initialised differently in each constructor

  • MappingMongoConverter.java

The correct way of using Builder with Lombok is to use the following annotations:

@NoArgsConstructor
@AllArgsConstructor
@Builder

In order to make the Jackson deserializer use this Builder, you need to add two annotations to the code.

  1. Marking the class with @JsonDeserialize annotation, passing a builder parameter with a fully qualified domain name of a builder class - which you have done
  2. Annotate the builder class itself as @JsonPOJOBuilder

For Exmaple:

 @JsonPOJOBuilder(buildMethodName = "create", withPrefix = "set")
 public class Builder {
    ...
 }

Using JsonPOJOBuilder

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM