How to use datanucleus.CurrentUserProvider?


Andy
 

The "persistence properties" are amply defined in the docs. "datanucleus.CurrentUserProvider" is one of them.
As said, you are using
PersistenceManagerFactory pmf = new JDOPersistenceManagerFactory(globalPumd, null);

and you need to provide any ADDITIONAL persistence properties (such as the one you wanted to specify) via the second argument in that constructor.


1919wang@...
 

I got your point on PersistenceUnitMetaData.
May I ask what is the "persistence properties" if it doesn't mean JDOPersistenceManagerFactory.setPersistenceProperties()? I am new to datanucleus, your guide would be appreciated~

 

You create an INSTANCE of your CurrentUserProvider, and specify that as the value of "datanucleus.CurrentUserProvider" to the persistence properties.


Andy
 

I didnt mention JDOPersistenceManagerFactory.setPersistenceProperties(), no.

PersistenceUnitMetaData is to replicate the file "persistence.xml" content. You cannot specify an Object in a text-based persistence.xml file. Hence PersistenceUnitMetaData doesnt support Object values.


1919wang@...
 
Edited

Thanks Andy. 
I have several more questions:
  • The 1st option you mentioned is `JDOPersistenceManagerFactory.setPersistenceProperties()`, right? The underlying logic of those 2 options seems identical - saving the properties via `Configuration.setPersistenceProperties`, please correct me if I misunderstood.
  • One thing confusing is that PersistenceUnitMetaData only support String value properties, while overrideProps supports Object value; And when constructing PMF, those 2 properties are actually merged into one Map. So one question is - Is it better to make PersistenceUnitMetaData support Object value?
    public JDOPersistenceManagerFactory(PersistenceUnitMetaData pumd, Map overrideProps)
    {
    // Build up map of all properties to apply (from persistence-unit + overridden + defaulted)
    Map props = new HashMap();
    if (pumd != null && pumd.getProperties() != null)
    {
    props.putAll(pumd.getProperties());
    }
    if (overrideProps != null)
    {
    props.putAll(overrideProps);
    }


Andy
 
Edited

You create an INSTANCE of your CurrentUserProvider, and specify that as the value of "datanucleus.CurrentUserProvider" to the persistence properties.
If you insist on creating a PMF in that way you use the second argument to input OVERRIDING PROPERTIES.


1919wang@...
 

According to JDO Mapping Guide, to support auditing @CreateUser, we could define an implementation of the DataNucleus interface CurrentUserProvider, and specify it on PMF creation using the property datanucleus.CurrentUserProvider. 

I have a com.alpha.MyUserProvider implements CurrentUserProvider, and tried to set the property like below:

PersistenceUnitMetaData globalPumd = new PersistenceUnitMetaData(jdoName, transactionType, null);
Map<String, String> jdoProperties =
new HashMap<>();
...
jdoProperties.put("datanucleus.CurrentUserProvider", "com.alpha.MyUserProvider");

for (Map.Entry<String, String> entry: jdoProperties.entrySet()) {
globalPumd.addProperty(entry.getKey()
, entry.getValue()); // Here can only add String property value
}


PersistenceManagerFactory pmf
= new JDOPersistenceManagerFactory(globalPumd, null);
...


The property value can only be set as String; However, in org.datanucleus.PersistenceNucleusContextImpl gets the CurrentUserProvider by calling Configuration.getProperty, which is a String, then got a ClassCastException

(CurrentUserProvider)config.getProperty(PropertyNames.PROPERTY_MAPPING_CURRENT_USER_PROVIDER); 


Seems it requires put an MyUserProvider instance  as property value, but PersistenceUnitMetaData only accept String value.