Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JDO: Is the PersistenceManager a singleton?

Just the basics: I'm using DataNucleus backed with an embedded DB4O database.

If I do this simple test:

    PersistenceManager pm1 = persistenceManagerFactory.getPersistenceManager();
    PersistenceManager pm2 = persistenceManagerFactory.getPersistenceManager();

    pm1.makePersistent(t1);
    pm2.makePersistent(t2);

I get a file locked exception:

com.db4o.ext.DatabaseFileLockedException: C:\<path>\primary_datastore.data

Which tells me I don't know how the PersistenceManager is supposed to work. I thought I just called PersistenceManagerFactory whenever I needed a PersistenceManager to query or persist data and I would get something thread safe.

  • Do I need to make PersistenceManager a singleton across my entire application?
  • How do multiple threads, performing queries and updates work in JDO/DataNucleus?
like image 887
David Parks Avatar asked Jan 30 '26 06:01

David Parks


2 Answers

Do I need to make PersistenceManager a singleton across my entire application?

It depends on you application. If you developing a desktop-application you probably only need only one persistence manager. This persistence-manager represent the state of the database for you desktop-app. However for other scenarios this isn't the case. For example in web application you want to isolate the requests or sessions from each other. Therefore you use multiple PersistenceManager. For example a PersistenceManager per request. Each PersistenceManager hold the state and transaction for the current request.

So a PersistenceManager-instance represents a unit work / transaction.

like image 70
Gamlor Avatar answered Jan 31 '26 18:01

Gamlor


  • You don't need to create a singleton instance. Instead, DataNucleus recommends using a Persistence Manager Proxy.

So, following the guide, your code should work with this change:

PersistenceManager pm1 = persistenceManagerFactory.getPersistenceManager();
PersistenceManager pm2 = persistenceManagerFactory.getPersistenceManagerProxy();

pm1.makePersistent(t1);
pm2.makePersistent(t2);

The second instance is a Proxy referring the first PersistenceManager instantiated.

  • To make your PersistenceManager thread safe, you have to set the datanucleus.ConnectionFactory (or its alias javax.jdo.option.Multithreaded) property at your PersistenceManagerFactory.

For instance, setting it programatically:

Properties properties = new Properties();
properties.setProperty("javax.jdo.PersistenceManagerFactoryClass",
                "org.datanucleus.jdo.JDOPersistenceManagerFactory");
//configure connection, etc...
properties.setProperty("javax.jdo.option.Multithreaded", "true");
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(properties);
like image 37
Tomas Narros Avatar answered Jan 31 '26 20:01

Tomas Narros