3

I have two different data sources for which I need two different PersistenceManagerFactory. This I can always get by writing a persistence.xml file. But I want this to be represented programmatically. Though the second data-source remains relatively unchanged, the first data-source may have additions to it via plugins. These plugins can come with one or more JDO annotated classes. A persitance.xml wouldn't be such a good idea here because I want them to be loaded at runtime.

In Hibernate (and with JPA) this would be possible by creating a configuration object and adding all annotated classes to it. Whenever I see a new plugin being loaded, I can always shutdown the SessionFactory and reload it with the extra classes from plugin by looking at @Entity annotation.

Is there a similar way to do it in DataNucleus/JDO?

I tried searching it on Google, but all I end up is at DataNucleus site explaining how to write a persitence.xml file.

Unmanned Player
  • 1,109
  • 9
  • 30

1 Answers1

0

The code below in Scala demonstrates how you can create a PersistenceManager dynamically. You just have to populate a map and pass it to JDOHelper#getPersistenceManagerFactory.

private val pu  = props(db.driver, db.url, db.username, db.password)
private val pmf = JDOHelper.getPersistenceManagerFactory(pu.asJava)
private val pm  = pmf.getPersistenceManager.asInstanceOf[JDOPersistenceManager]

Below you can see an example on how you will probably be willing to populate such map in the case of H2, MongoDB and PostgreSQL:

  def props(driver: String, url: String, username: String, password: String): Map[String, Any] =
    driver match {
      case "org.h2.Driver" =>
        Map[String, Any](
          "javax.jdo.option.Mapping"                 -> "h2",
          "datanucleus.schema.autoCreateAll"         -> "true",
          "javax.jdo.PersistenceManagerFactoryClass" -> "org.datanucleus.api.jdo.JDOPersistenceManagerFactory",
          "javax.jdo.option.ConnectionDriverName"    -> driver,
          "javax.jdo.option.ConnectionURL"           -> url,
          "javax.jdo.option.ConnectionUserName"      -> username,
          "javax.jdo.option.ConnectionPassword"      -> password
        )

      case "org.postgresql.Driver" =>
        Map[String, Any](
          "datanucleus.schema.autoCreateAll"         -> "true",
          "javax.jdo.PersistenceManagerFactoryClass" -> "org.datanucleus.api.jdo.JDOPersistenceManagerFactory",
          "javax.jdo.option.ConnectionDriverName"    -> driver,
          "javax.jdo.option.ConnectionURL"           -> url,
          "javax.jdo.option.ConnectionUserName"      -> username,
          "javax.jdo.option.ConnectionPassword"      -> password,
          "javax.jdo.option.RetainValues"            -> "true",
          "javax.jdo.option.RestoreValues"           -> "true",
          "javax.jdo.option.Optimistic"              -> "true",
          "javax.jdo.option.NontransactionalWrite"   -> "false",
          "javax.jdo.option.NontransactionalRead"    -> "true",
          "javax.jdo.option.Multithreaded"           -> "true",
          "javax.jdo.option.IgnoreCache"             -> "false"
        )

      case "mongodb.jdbc.MongoDriver" =>
        Map[String, Any](
          "javax.jdo.option.Mapping"                 -> "mongo",
          "datanucleus.schema.autoCreateAll"         -> "true",
          "javax.jdo.PersistenceManagerFactoryClass" -> "org.datanucleus.api.jdo.JDOPersistenceManagerFactory",
          "javax.jdo.option.ConnectionDriverName"    -> driver,
          "javax.jdo.option.ConnectionURL"           -> url,
          "javax.jdo.option.ConnectionUserName"      -> username,
          "javax.jdo.option.ConnectionPassword"      -> password
        )

      case _ => throw new IllegalArgumentException(s"unknown driver %s".format(driver))
    }
Richard Gomes
  • 5,675
  • 2
  • 44
  • 50