Multi-thread access to single EM's entities

#1

If my entity classes have synchronized getters and setters, is it reliable for multiple threads to access a single EM's managed entities, as long as only the thread that created the EM interacts directly with it?  I've tested this and it seems to work... but I know better than to depend on the observable behavior of multithreaded code.

When I run this example and examine the database, the entity contains the value set by the second thread, as expected.

 

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;


public class ODBMultiThread {

    public static void main(String[] args) throws InterruptedException {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory(
            "objectdb:/home/kevin/threads-test.odb");
        EntityManager em = emf.createEntityManager();
 
        final PointlessEntity pointless = new PointlessEntity(69);
        em.getTransaction().begin();
        em.persist(pointless);
        em.getTransaction().commit();
        em.getTransaction().begin();
 
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                pointless.setValue(42);   
            }
        });
        t.start();
        t.join();
 
        em.getTransaction().commit(); // commit t's changes
        em.close();
        emf.close();
    }


    @Entity
    static class PointlessEntity {

        private int value;
 
        public PointlessEntity(int value) {
            this.value = value;
        }
 
        synchronized public int getValue() {
            return value;
        }
 
        synchronized public void setValue(int value) {
            this.value = value;
        }
    }
}
#2

This is an interesting question.

Apparently it should work fine if you access persistent fields only from the synchronized get/set methods (and the constructors), including in the entity classes themselves.

Notice that enhancement of your classes will replace every access of a persistent field (outside the constructor) with invocation of a method that ObjectDB adds to the classes during enhancement and these methods are not synchronized. But if these methods are invoked only from your synchronized get/set methods it seems to be safe.

All the methods in ObjectDB's EntityManager and associated classes are synchronized, so even if you do use the same EntityManager in more than one thread it should still work.

ObjectDB Support
#3

Thanks for the reply.

I'm using ObjectDB in a rather unconventional application: a client that parses and stores data from the ancient text-based game TradeWars 2002.

Reply