SPIs (hooks)

This page lists (some of) the hooks available to interact with the JDO persistence mechanism itself.

JdoEntityDiscoveryListener

The JdoEntityDiscoveryListener interface is called during bootstrapping after the PersistenceManagerFactory has been created. It can be used to perform additional bootstrapping tasks.

For example, to eagerly register all named queries, you could use:

NamedQueryEagerRegistrar.java
@Component
public class NamedQueryEagerRegistrar implements JdoEntityDiscoveryListener {

    @Override
    public void onEntitiesDiscovered(
            final @NonNull PersistenceManagerFactory persistenceManagerFactory,
            final @NonNull Set<Class<?>> entityTypes,
            final @NonNull Map<String, Object> properties) {

        val pmf = (JDOPersistenceManagerFactory) persistenceManagerFactory;
        val nucleusContext = pmf.getNucleusContext();

        val clr = nucleusContext.getClassLoaderResolver(_Context.getDefaultClassLoader());
        val metaDataManager = nucleusContext.getMetaDataManager();

        metaDataManager
            .getClassesWithMetaData()
            .forEach(className->{
                val meta = metaDataManager.getMetaDataForClass(className, clr);
                _NullSafe.stream(meta.getQueries())
                .forEach(metaDataManager::registerNamedQuery);
            });
    }
}

You could also use an implementation to eagerly create the database tables in the database:

DatabaseCreator.java
@Component
public class DatabaseCreator implements JdoEntityDiscoveryListener {

    @Override
    public void onEntitiesDiscovered(
            final @NonNull PersistenceManagerFactory persistenceManagerFactory,
            final @NonNull Set<Class<?>> entityTypes,
            final @NonNull Map<String, Object> properties) {

        val pmf = (JDOPersistenceManagerFactory) persistenceManagerFactory;
        val nucleusContext = pmf.getNucleusContext();
        val schemaAwareStoreManager = (SchemaAwareStoreManager)nucleusContext.getStoreManager();

        val classNames = entityTypes
                .stream()
                .map(Class::getName)
                .collect(Collectors.toSet());

        schemaAwareStoreManager.createSchemaForClasses(classNames, properties);
    }
}

However, for this second use case it’s easier to simply set the datanucleus.schema.generate-database.mode configuration property.