Reputation: 1622
I would like to know what I need to do in order to make the access to DB thread-safe.
This is my Entity class:
@Entity
@Table(name = "students")
@NamedQuery(name = "Student.getAll", query = "SELECT s FROM Student s")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(length = 32, name = "name")
private String name;
// ... constructor, getters and setters, toString ...
}
This is the DbService class:
public class DbService {
public EntityManager em = Persistence
.createEntityManagerFactory("MyPersistenceUnit")
.createEntityManager();
public Student add(Student student) {
EntityTransaction tx = em.getTransaction();
tx.begin();
Student studentFromDb = em.merge(student);
tx.commit();
return studentFromDb;
}
public void delete(long id) {
EntityTransaction tx = em.getTransaction();
tx.begin();
em.remove(get(id));
tx.commit();
}
public Student get(long id) {
return em.find(Student.class, id);
}
public void update(Student student) {
EntityTransaction tx = em.getTransaction();
tx.begin();
em.merge(student);
tx.commit();
}
public List<Student> getAll() {
TypedQuery<Student> namedQuery =
em.createNamedQuery("Student.getAll", Student.class);
return namedQuery.getResultList();
}
}
And here is a class that work with DbService:
public class SomeDbWorker implements Runnable {
@Override
public void run() {
DbService service = new DbService();
// do something ...
service.add( ... );
service.delete( ... );
service.getAll();
// ...
}
}
Upvotes: 1
Views: 4269
Reputation: 8323
No need to synchronize anything,
the entityManager is not threadSafe and designed to be instantiated for each unit of work and destroyed just after.
The factory on the contrary is costly to create and should be reused
See http://docs.oracle.com/javaee/6/tutorial/doc/bnbqw.html "Application-Managed Entity Managers" and https://stackoverflow.com/a/22773758/2087640
Upvotes: 6
Reputation: 40500
You don't need to make those methods synchronized, they are thread safe as it is. Yeah, it probably makes sense to make DbService
a singleton. Alternatively, you could just make em
static. Singleton would be my preference. You also don't want em
be public. Make it private while you are at it.
Upvotes: -2