Add support for PropertyValueConverters.
Closes: #3596 Original pull request: #3982.
This commit is contained in:
committed by
Mark Paluch
parent
15cac49f9c
commit
29fb085d8b
@@ -5,6 +5,7 @@
|
||||
== What's New in Spring Data MongoDB 3.4
|
||||
|
||||
* Find and update ``Document``s via <<mongodb.repositories.queries.update,Repository method>>.
|
||||
* Property specific <<mongo.property-converters, value converters>>.
|
||||
|
||||
[[new-features.3.3]]
|
||||
== What's New in Spring Data MongoDB 3.3
|
||||
|
||||
@@ -900,3 +900,4 @@ Declaring these beans in your Spring ApplicationContext causes them to be invoke
|
||||
include::unwrapping-entities.adoc[]
|
||||
|
||||
include::mongo-custom-conversions.adoc[]
|
||||
include::mongo-property-converters.adoc[]
|
||||
|
||||
108
src/main/asciidoc/reference/mongo-property-converters.adoc
Normal file
108
src/main/asciidoc/reference/mongo-property-converters.adoc
Normal file
@@ -0,0 +1,108 @@
|
||||
[[mongo.property-converters]]
|
||||
== Property Converters - Mapping specific fields
|
||||
|
||||
Although to the <<mongo.custom-converters, type based conversion>> already offers means to influence the representation of certain types within the target store it has its limitations when not all potential values of that type should be considered as a conversion targets.
|
||||
Property based converters allow to specify conversion instructions on a per property basis either declarative, via `@ValueConverter`, or programmatic by registering a `PropertyValueConverter` for a specific field.
|
||||
|
||||
A `PropertyValueConverter` is responsible of transforming a given value into its store representation (write) and back (read) as shown in the snippet below.
|
||||
Please mind the presence of the `ValueConversionContext` providing additional information, such as mapping metadata.
|
||||
|
||||
.PropertyValueConverter
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
class ReversingValueConverter implements PropertyValueConverter<String, String, ValueConversionContext> {
|
||||
|
||||
@Override
|
||||
public String read(String value, ValueConversionContext context) {
|
||||
return reverse(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String write(String value, ValueConversionContext context) {
|
||||
return reverse(value);
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
`PropertyValueConverter` instances can be obtained via `CustomConversions#getPropertyValueConverter(...)` delegating to `PropertyValueConversions` typically using a `PropertyValueConverterFactory` to provide the actual converter.
|
||||
Depending on the applications needs multiple instances of `PropertyValueConverterFactory` can be chained or decorated (eg. for caching).
|
||||
By default a caching implementation is used that is capable of serving types with a default constructor or enum values.
|
||||
A set of predefined factories is available via `PropertyValueConverterFactory`.
|
||||
To obtain a `PropertyValueConverter` from an `ApplicationContext` make sure to use the `PropertyValueConverterFactory.beanFactoryAware(...)` factory.
|
||||
|
||||
Changing the default behavior can be done via the `ConverterConfiguration`.
|
||||
|
||||
=== Declarative Value Converter
|
||||
|
||||
The most straight forward usage of a `PropertyValueConverter` is via the `@ValueConverter` annotation referring to the target converter type.
|
||||
|
||||
.Declarative PropertyValueConverter
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
public class Person {
|
||||
// ...
|
||||
@ValueConverter(ReversingValueConverter.class)
|
||||
String ssn;
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
=== Programmatic Value Converter
|
||||
|
||||
Following the programmatic approach does not require to put additional annotations on the domain model but registers `PropertyValueConverter` instances for certain paths in a `PropertyValueConverterRegistrar` as shown below.
|
||||
|
||||
.Programmatic PropertyValueConverter
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
PropertyValueConverterRegistrar registrar = new PropertyValueConverterRegistrar();
|
||||
|
||||
registrar.registerConverter(Address.class, "street", new PropertyValueConverter() { ... }); <1>
|
||||
|
||||
// type safe registration
|
||||
registrar.registerConverter(Person.class, Person::getSsn()) <2>
|
||||
.writing(value -> encrypt(value))
|
||||
.reading(value -> decrypt(value));
|
||||
----
|
||||
<1> Register a converter for the field identified by its name.
|
||||
<2> Type safe variant that allows to register a converter and its conversion functions.
|
||||
====
|
||||
|
||||
[WARNING]
|
||||
====
|
||||
Dot notation (eg. `registerConverter(Person.class, "address.street", ...)`) is *not* supported when registering converters.
|
||||
====
|
||||
|
||||
=== MongoDB property value conversions
|
||||
|
||||
The above sections outlined the purpose an overall structure of `PropertyValueConverters`.
|
||||
This section will focus on MongoDB specific aspects.
|
||||
|
||||
==== MongoValueConverter & MongoConversionContext
|
||||
|
||||
The `MongoValueConverter` offers a pre typed `PropertyValueConverter` interface leveraging the `MongoConversionContext`.
|
||||
|
||||
==== MongoCustomConversions configuration
|
||||
|
||||
`MongoCustomConversions` are by default capable of dealing with declarative value converters depending on the configured `PropertyValueConverterFactory`.
|
||||
The `MongoConverterConfigurationAdapter` is there to help set up programmatic value conversions or define the `PropertyValueConverterFactory` to be used.
|
||||
|
||||
.Configuration Sample
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
MongoCustomConversions.create(configurationAdapter -> {
|
||||
|
||||
SimplePropertyValueConversions valueConversions = new SimplePropertyValueConversions();
|
||||
valueConversions.setConverterFactory(...);
|
||||
valueConversions.setValueConverterRegistry(new PropertyValueConverterRegistrar()
|
||||
.registerConverter(...)
|
||||
.buildRegistry());
|
||||
|
||||
configurationAdapter.setPropertyValueConversions(valueConversions);
|
||||
});
|
||||
----
|
||||
====
|
||||
Reference in New Issue
Block a user