JPA and JDO API’s introduced the concept of an AttributeConverter which can be used to define how a type is persisted into the datastore, converting from the Java (field) type to a datastore (column) type. All such AttributeConverter classes defined by JPA and JDO are effectively stateless. They are constructed using a default constructor, by the JPA/JDO provider (i.e DataNucleus). DataNucleus v5.1 now makes it possible to utilise CDI to inject properties into an AttributeConverter.
Let’s say we have a type SecretData that we want to store encrypted in the datastore, with an AttributeConverter like this
public class SecretDataConverter implements AttributeConverter<SecretData, String>{ public String convertToDatabaseColumn (SecretData attribute) {...} public SecretData convertToEntityAttribute (String dbData) {...} }
Note : we do not recommend encrypting data in this way, it is just an example to demonstrate the injection of state into the converter
This is all well and good but we want to configure our encryption process, using a different encryptor based on certain conditions. With standard JPA and JDO we have no way of getting state into these classes. Well let’s use CDI to inject a field, modifying our converter like this
import javax.inject.Inject; public class SecretDataConverter implements AttributeConverter<SecretData, String> { @Inject Encryptor enycryptor; ... }
The only thing we need to do now is CDI enable our JPA or JDO environment.
With DataNucleus JPA v5.1 you would simply define the persistence property javax.persistence.bean.manager specifying the BeanManager instance for CDI (will be standard in JPA 2.2).
With DataNucleus JDO v5.1 you would simply define the persistence property datanucleus.cdi.bean.manager specifying the BeanManager instance for CDI.
When you run your application the AttributeConverter is instantiated and it will have this field injected by CDI. The same idea also applies to JPA event listener classes (i.e just set the persistence property, and follow general CDI documentation for how to inject properties).