11

I am not using Spring so I am creating an instance of EntityManager within a class.

I used Hibernate-Eclipse reverse engineering to auto-generate the classes. These classes all has an instance of EntityManager.

I am not 100% sure how Hibernate works with the EntityManager so I am wondering if it is okay that so many instances of this class (EntityManager) are made, for example, will there be problems with transactions?

Should I just make a separate class that distributes a static instance of an EntityManager for all my other classes? or does it not matter?

EDIT: I see there's something called @PersistenceContext, it doesn't seem to load my persistence.xml as a bean in to the instance variable, does this feature require spring? (I get null pointer exception, because it was never injected)

snip of code from where I attempt to use @persistencecontext

@PersistenceContext(unitName = "manager1")
private EntityManager entityManager;

my persistence.xml

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
   <persistence-unit name="manager1" transaction-type="RESOURCE_LOCAL">
         <provider>org.hibernate.ejb.HibernatePersistence</provider>

      <properties>

         <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
         <property name="javax.persistence.jdbc.user" value="root"/>
         <property name="javax.persistence.jdbc.password" value="mypassword"/>
         <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/ptbrowserdb"/>
         <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
      </properties>
   </persistence-unit>
</persistence>

2 Answers2

15

See this Article: JPA Architecture it explain it very well.

In General you need a single Entity Manager per transaction. And this Entity Manager must not be used in two transactions at the same time.

Clairification: I mean, do not use a single Entity Manager for different unit of works. Typical one transaction in one unit of work, if you have different transactions of one unit of work, then you can use the same Entity Manager

If you use Spring then Spring do this handling for you if you use the @PersistenceContext annotation to inject the EntityManager. Per default Spring "bind" the the injected EntityManager (via a proxy) to the current transaction. (And the transaction is "bound" to the thread.)

@See Spring Reference 13.5.2 Implementing DAOs based on plain JPA - it contains a interesting paragagraph after the code examples.

Ralph
  • 118,862
  • 56
  • 287
  • 383
  • 1
    lol you don't need a single entity manager per transaction. One entity manager represents one opened session (connection) to the database, its very costly just to use it for one transaction. 1 session-per-operation is considered an antipattern! https://developer.jboss.org/wiki/Sessionsandtransactions – Maurice May 20 '17 at 17:06
  • 1
    @Maurice: This is an interesting article, but it is about Hibernate's "old" Session/SessionFactory model, but this question is about JPA. As fare as I know this in one of the rare topics where JPA and Hibernate-Session differs. Have a look at chapter "5.1. Entity manager and transaction scopes" in https://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/transactions.html - it claims: "An EntityManager is an inexpensive, non-threadsafe object that should be used once, for a single business process, a single unit of work, and then discarded." – Ralph May 22 '17 at 07:55
  • and a single business process can consist of multiple transactions right? Or do you disagree. Don't they say in my link that one I supposed to put more then one transaction in a session otherwise it would be an antipattern? – Maurice May 23 '17 at 18:41
  • 1
    @Maurice: The point is: do not use one EntityManager instance for more than one business process. – Ralph May 24 '17 at 20:39
0

You need a dependency injection framework like Spring or Google Guice to inject objects into your class otherwise it may not be injected automatically for you.

Basically this is an annotation provided by JPA which will work with in tandem with hibernate or any other ORM framework per say but you need a DI framework to inject the objects.

Regarding the single instance of entity manager i don't think you need that if you go by Spring since it takes care of managing the instances and the transactions for you by tying your entity manager with the jpa transaction.

raddykrish
  • 1,866
  • 13
  • 15
  • 1
    In J2EE you don't need any external dependency injection framework. The injections are handled by the container. – Santosh Feb 21 '12 at 10:20
  • You do not need a Dependency Injection framework: you can do it by your own: in a web application for example with a tread local holding the entity manager and a EntityManagerPerRequestPatternFilter – Ralph Feb 21 '12 at 10:31
  • @Ralph - Yes i agree we can do the injection by ourselves but to avoid the overhead we have proven frameworks for DI..spring or guice will seamlessly do that for us..provided these should be part of the application stack.. – raddykrish Feb 21 '12 at 17:45
  • @Radhakrishnan Subbiah: Do you and Rodrigo Salazar work at the same project? – Ralph Feb 21 '12 at 18:35