[JAVA-2872] Provide an extension point for injecting a custom PropertySerialization implementation Created: 29/May/18 Updated: 10/Mar/23 |
|
| Status: | Backlog |
| Project: | Java Driver |
| Component/s: | POJO |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | New Feature | Priority: | Major - P3 |
| Reporter: | Chris Birchall | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Epic Link: | Investigate our POJO implementation |
| Quarter: | FY23Q4, FY24Q2 |
| Case: | (copied to CRM) |
| Description |
|
I have fields of type java.util.Optional in my POJOs, and I would like to avoid serialising the field if the value is an empty Optional. It looks like I can do this using a custom implementation of PropertySerialization, but as far as I can tell there is no easy way to inject my custom implementation when using the PojoCodecProvider. The only way I have found to do this is with some nasty reflection hackery, abusing a Convention to overwrite the propertySerialization field in all the PropertyModel s of the ClassModelBuilder:
I then register this convention when building the codec registry:
This works, i.e. the property is not written to the Mongo document if it is empty, and it is passed to the POJO constructor as null when reading back from Mongo. But I have trouble sleeping at night knowing this code is running in production |
| Comments |
| Comment by Chris Birchall [ 08/Jun/18 ] | |||||
You're right! Sorry, don't know how I missed that method. I'll get rid of my reflection code and just use that.
If you mean I could use the Optional codec given in the example in the doc, but just remove the writer.writeNull() line, unfortunately that doesn't work. Because the Bson writer has already started writing the field (I think it writes the field name first, IIRC?) before it calls the Codec. So if you don't write any value, you end up with invalid Bson.
Yes, this is a problem. For now I've just added null checks in my POJO's constructors:
Not pretty, but not the end of the world. | |||||
| Comment by Ross Lawley [ 08/Jun/18 ] | |||||
|
Hi Chris, You don't have to write anything to Bson via the Codec if its null, you can ignore it. Its more how to handle the hydration of the Option when loading Bson data, to ensure it has a value. That cannot be handled by Codecs and would require the Java bean to have a default value. Ross | |||||
| Comment by Chris Birchall [ 08/Jun/18 ] | |||||
|
Hi Ross, Thanks for the reply. I had a look at the Optional codec example that you mentioned. As you say, with a codec there is no way to say "skip the field completely" - you have to write a null value. Unfortunately that doesn't work in my case, because I have a unique index on that field. I guess I could make a partial index to only enforce uniqueness on non-null values, but I'd rather not have to fiddle with the indexes just for the sake of the Java driver. | |||||
| Comment by Ross Lawley [ 04/Jun/18 ] | |||||
|
Hi cb372, Thanks for the ticket, you should be able to set custom property serialization instances without the need for any reflection. Using the PropertyModelBuilder#propertySerialization method. A Convention is the correct level for manipulating the ClassModel and PropertyModel builders. So you should be able to achieve your aim with the current API. However, there may be an alternative approach, in the generics support section of the documentation there is an example of creating a OptionalPropertyCodecProvider and a OptionalCodec implementation that could be adapted. However, a default value for the Optional is required with the codec approach. I hope that helps, Ross |