Can I create an EntityManager from EntityManagerFactory outside a bean. If so, how would I do it?
In a non-managed environment (this is what you mean by outside a bean, right?), then you typically use:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MyPu");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin()
...
em.getTransaction().commit();
emf.close();
Check the other factory method allowing to pass properties as parameter (they will override any values that may have been configured elsewhere): Persistence.createEntityManagerFactory(String, Map).
See also
Using the Java Persistence API in Desktop Applications
An Introduction to Java Persistence for Client-Side Developers
Related
I'm working with JBoss Wildfly as an application server on my JPA layer.
For technical requirements i need to get my entity persistence manager using the JavaSE/application managed approach. I. e.:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("idelivery", properties);
EntityManager em = emf.createEntityManager();
MyEntity exUser= new MyEntity();
try{
Context context = new InitialContext();
UserTransaction userTransaction = (UserTransaction)context.lookup("java:comp/UserTransaction");
userTransaction.begin();
em.persist(exUser);
userTransaction.commit();
where in properties i set:
properties.put ("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
properties.put("javax.persistence.provider", "org.hibernate.jpa.HibernatePersistenceProvider");
properties.put("javax.persistence.transactionType", "JTA");
properties.put("javax.persistence.jtaDataSource", dataSourcePath);
The problem, of course, is with the code lines above I cannot bind the entitymanager to the container JTA transaction manager.
So my question is: is there some example or some way I can make the entity manager to join a complicated JTA transaction? I don't know... maybe with a CDI producer the way i can put the entitymanager inside the container context?
In Java EE environment, you may inject EntityManagerFactory and use it to create EntityManager with custom properties. Therefore, instead of
EntityManagerFactory emf = Persistence.createEntityManagerFactory("idelivery", properties);
EntityManager em = emf.createEntityManager();
you should do something like:
// inject emf from container
#PersistenceUnit("idelivery")
private EntityManagerFactory emf;
// and in your method create em with your properties...
EntityManager em = emf.createEntityManager(properties);
Can #PersistenceUnit be used with JTA in JPA? If so, how is it possible?
Per http://tomee.apache.org/jpa-concepts.html:
With <persistence-unit transaction-type="RESOURCE_LOCAL"> [...]
You must use the EntityManagerFactory to get an EntityManager
[...]
An EntityManagerFactory can be injected via the #PersistenceUnit annotation only (not #PersistenceContext)
With <persistence-unit transaction-type="JTA"> [...]
An EntityManager can be injected via the #PersistenceContext annotation only (not #PersistenceUnit)
I have a similar code which uses JTA and #PersistenceUnit at the same time. But sometimes I am having NullPointerException when accesing transaction (defined as #Resource).
Using JTA means that you delegate the work to the container. You can override it by using a UserTransaction. Your quotation contains all the answers you want to know. Using PersistenceUnit to get an EntityManager won't work.
If you are using RESOURCE_LOCAL you are responsible for the transaction itself, by using EntityManager.getTransaction(). An entity manager is created by an EntityManagerFactory. To obtain that factory, you can use PersistenceUnit.
So the simple answer is no, if you rely on container managed entity managers.
As example see http://docs.oracle.com/javaee/6/tutorial/doc/bnbqw.html
Application Managed Entity Managers = RESOURCE_LOCAL can use UserTransaction (which are part of JTA).
What does entity manager means???
If i am a naive programmer i could simply interpret something which manages entity & Indeed it means the same.
An Entity Manager is been instantiated with the help of an Entity Manager Factory. A connection to a database is managed by the entity manager i.e. it provides functionality for performing operations on a database. Therefore we could say if an application needs multiple database connections, an EntityManagerFactory will be constructed for a specific database which provides an efficient way to construct multiple EntityManager instances(if required, even single instance of entity manager can the job depending upon the requirement you may opt for multiple instances) for that database required for every HTTP request. We shall understand this with the help of an example. Suppose we have a
Database : A , having a relational tables B and C.
So for A, an instance of entity manager factory will be instantiated. Now we if ever want to perform any update to table B & lets say delete operation for table C, either two different entity manager could be instantiated or same the entity manager instance can be utilized for both.
The instantiation of Entity Manager Factory itself is considered to be less efficient but since it's a one time activity therefore it's manageable task because Entity Manager Factory once instantiated, it will serve the entire application
The entity manager instantiated is associated with a persistence context.
#PersistenceUnit(unitName = "MyDatabase")
EntityManagerFactory emf;
EntityManager entityManager = emf.createEntityManager();
or
#PersistenceContext(unitName = "MyDatabase")
private EntityManager entityManager;
PersistenceUnit injects an EntityManagerFactory, and PersistenceContext injects an EntityManager. It's generally better to use PersistenceContext unless you really need to manage the EntityManager lifecycle manually.
EntityManagerFactory defines another method for instantiation of EntityManager that, like the factory, takes a map of properties as an argument. This form is useful when a user name and a password other than the EntityManagerFactory's default user name and password have to specified:
Map properties = new HashMap();
properties.put("javax.persistence.jdbc.user", "kashyap");
properties.put("javax.persistence.jdbc.password","kashyap");
EntityManager em = emf.createEntityManager(properties);
Within the persistence context, the entity instances and their lifecycle are managed. By Entity instance, we mean instance of an entity & each entity designates relational table in the database. Entity Manager is actually an interface which provides methods to create and remove persistent entity instances, to find entities by their primary key, and to query over entities so together these functionalities are grouped under operations we perform. Operations that modify the content of a database require active transactions. Transactions are managed by an Entity Transaction instance obtained from the EntityManager.
Precise Definition :-
An Entity Manager is defined by a persistence unit. A persistence unit defines the set of all classes that are related or grouped by the application, and which must be colocated in their mapping to a single database.
Below i'm writing a code snippet for better understanding :-
try {
em.getTransaction().begin();
// Operations that modify the database should come here.
em.getTransaction
/**
*getTransaction() EntityManager's method Return the resource-level EntityTransaction object. See JavaDoc Reference Page
*/
em.getTransaction().commit();
}
finally {
if (em.getTransaction().isActive())
em.getTransaction().rollback();
}
Lets proceed as per JPA Specification :-
1) Extended vs Transactional - Scoped :
By Default the Transactional Persistence Context is in used which means all changes are flushed and all managed entities become detahced when the current transaction commits.
The Extended scope is available only for Stateful EJBs & it even makes a perfect sense since stateful beans can save the state therefore one can say end of
one business method doesn't necessary means the end of the transaction.
With the Stateless beans, it has a different aspect - We have business method that must end when the business method finishes.
===> One Method = One Transaction;
Only Transactional-Scoped Entity Manager is allowed for Stateless Beans
You can control if the EntityManager is extended or transactional during the EntityManager Injection :-
#PersistenceContext (type = javax.persistence.PersistenceContextType.EXTENDED)
EntityManager emng;
By Default it's javax.persistence.PersistenceContextType.TRANSACTION
Extended and Transaction Scoped PersistenceContext are allowed only in case of container-managed EntityManagers.
Time to step up a bit with: Container-managed vs Application-managed
2) Container-managed vs Application-managed :
#PersistenceContext
EntityManager emng;
Above statement authorises Container to inject the entity manager for you, hence Container-Managed.
Alternatively, you can create an EntityManager by yourself using EntityManagerFactory But this time the injection will be bit different -
#PersistenceUnit
EntityManagerFactory emf;
Now to get the EntityManager you need to invoke
emf.createEntityManager();
And here it is - you're using the application managed Persistence Context. Now you're responsible for creation and removal of EntityManagers.
Focus before you read the next para because that's what the tangled context , i'm trying to resolve-
You might use createEntityManager if you want to have control over created EM - e.g. if you need to move the created EntityManager across multiple beans involved in the trasaction - the container won't do it for you and every time you invoke createEntityManager(), you're creating an EntityManager that is connected to the new PersistenceContext. You might use the CDI for EntityManager's sharing.
Stay tuned for Entity Transaction - JPA and Resource-local, will be posting a detailed discussion on it.
Hope it gives a brief idea about the context. & Feel free to post queries.
Read the second part from here
I have many persistence units in my persistence.xml, one by postgreSQL schema.
I instantiate my EntityManager whenever I need by creating EntityManagerFactory dynamically :
EntityManagerFactory emf = Persistence.createEntityManagerFactory(schemaToChoose);
EntityManager em = emf.createEntityManager();
and it works fine. But thus, I don't use container injection.
Now, I wonder if it doesn't cost too much resources by this way ?
I don't probably understand well JPA cache but I believe that entities are stored inside em cache and inside emf cache, there are 2 levels. So when I instantiate em and emf each time I probably loose JPA cache and thus, I recreate it each time too.
I have 2 questions : could instantiate each time emf and em impact perfomances ? Should I inject as many em that I have schemas instead to keep cache ?
Thank you
An EntityManagerFactory is a heavyweight, long-to-create object. It should be created only once, and then reused. Indeed, every time it's created, it parses the persistence.xml file, computes the mapping metadata of every entity, etc.
If you're running inside a Java EE container, then you should definitely let the container instantiate it for you, and inject the entity managers inside your EJBs.
I find it strange that a single application uses several database shemas. Why is it so?
Regarding the caches: there is a first-level cache associated with the entity manager (which is a short-lived cache, typically having the same life-time as a transaction. It's also possible to have a second-level cache, associated with the entity manager factory, but this is off by default, and, if enabled, must only be used for some entities and configured with care.
You basically have a multi-tenant pattern. EJB injection doesn't handle this very well.
An EntityManagerFactory is not something you want to create more than once, and does contain the shared cache. (the share cache default is not specified by JPA, it is on by default in EclipseLink, but configurable through JPA cache-mode and #Cacheable and #Cache).
I would recommend some sort of registry for your factories. Perhaps this would even be an application object, such as your Universe.
public class Universe {
static Map<String, Universe> universes;
EntityManagerFactory emf;
public static Universe getUniverse(String schema) {
... hopefully you get the idea ...
}
public EntityManagerFactory getEntityManagerFactory() {
return emf;
}
}
Also, I would recommend you look into EclipseLink's multi-tenant support,
http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_multitenant.htm#BABEGBIJ
In a Java EE application I am using #PersistenceContext on an EJB3.0 SessionBean to let an EntityManager be autowired.
As I am using multiple Datasources, I want to programmatically determine the autowired PersistenceUnit name of the EntityManager. Any chance?
You can retrieve more than one entity manager in this way:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("name your PU")
EntityManager em = emf.createEntityManager();
...
em.close();
emf.close();
But I do not know if a good solution. Annotation #PersistenceContext allows retrieve only one entity manager. But you may try create one class/stateless bean which will keep more than one PU, and take from him PU which you need. Maybe this little better than use EntityManagerFactory.
I am new to Hibernate and I'm not sure whether to use a Hibernate SessionFactory or a JPA EntityManagerFactory to create a Hibernate Session.
What is the difference between these two? What are the pros & cons of using each of those?
Prefer EntityManagerFactory and EntityManager. They are defined by the JPA standard.
SessionFactory and Session are hibernate-specific. The EntityManager invokes the hibernate session under the hood. And if you need some specific features that are not available in the EntityManager, you can obtain the session by calling:
Session session = entityManager.unwrap(Session.class);
SessionFactory vs. EntityManagerFactory
As I explained in the Hibernate User Guide, the Hibernate SessionFactory extends the JPA EntityManagerFactory, as illustrated by the following diagram:
So, the SessionFactory is also a JPA EntityManagerFactory.
Both the SessionFactory and the EntityManagerFactory contain the entity mapping metadata and allow you to create a Hibernate Session or a EntityManager.
Session vs. EntityManager
Just like the SessionFactory and EntityManagerFactory, the Hibernate Session extends the JPA EntityManager. So, all methods defined by the EntityManager are available in the Hibernate Session.
The Session and the `EntityManager translate entity state transitions into SQL statements, like SELECT, INSERT, UPDATE, and DELETE.
Hibernate vs. JPA bootstrap
When bootstrapping a JPA or Hibernate application, you have two choices:
You can bootstrap via the Hibernate native mechanism, and create a SessionFactory via the BootstrapServiceRegistryBuilder. If you're using Spring, the Hibernate bootstrap is done via the LocalSessionFactoryBean, as illustrated by this GitHub example.
Or, you can create a JPA EntityManagerFactory via the Persistence class or the EntityManagerFactoryBuilder. If you're using Spring, the JPA bootstrap is done via the LocalContainerEntityManagerFactoryBean, as illustrated by this GitHub example.
Bootstrapping via JPA is to be preferred. That's because the JPA FlushModeType.AUTO is a much better choice than the legacy FlushMode.AUTO, which breaks read-your-writes consistency for native SQL queries.
Unwrapping JPA to Hibernate
Also, if you bootstrap via JPA, and you have injected the EntityManagerFactory via the #PersistenceUnit annotation:
#PersistenceUnit
private EntityManagerFactory entityManagerFactory;
You can easily get access to the underlying Sessionfactory using the unwrap method:
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
The same can be done with the JPA EntityManager. If you inject the EntityManager via the #PersistenceContext annotation:
#PersistenceContext
private EntityManager entityManager;
You can easily get access to the underlying Session using the unwrap method:
Session session = entityManager.unwrap(Session.class);
Conclusion
So, you should bootstrap via JPA, use the EntityManagerFactory and EntityManager, and only unwrap those to their associated Hibernate interfaces when you want to get access to some Hibernate-specific methods that are not available in JPA, like fetching the entity via its natural identifier.
I want to add on this that you can also get Hibernate's session by calling getDelegate() method from EntityManager.
ex:
Session session = (Session) entityManager.getDelegate();
I prefer the JPA2 EntityManager API over SessionFactory, because it feels more modern. One simple example:
JPA:
#PersistenceContext
EntityManager entityManager;
public List<MyEntity> findSomeApples() {
return entityManager
.createQuery("from MyEntity where apples=7", MyEntity.class)
.getResultList();
}
SessionFactory:
#Autowired
SessionFactory sessionFactory;
public List<MyEntity> findSomeApples() {
Session session = sessionFactory.getCurrentSession();
List<?> result = session.createQuery("from MyEntity where apples=7")
.list();
#SuppressWarnings("unchecked")
List<MyEntity> resultCasted = (List<MyEntity>) result;
return resultCasted;
}
I think it's clear that the first one looks cleaner and is also easier to test because EntityManager can be easily mocked.
Using EntityManagerFactory approach allows us to use callback method annotations like #PrePersist, #PostPersist,#PreUpdate with no extra configuration.
Using similar callbacks while using SessionFactory will require extra efforts.
Related Hibernate docs can be found here and here.
Related SOF Question and Spring Forum discussion
By using EntityManager, code is no longer tightly coupled with hibernate. But for this, in usage we should use :
javax.persistence.EntityManager
instead of
org.hibernate.ejb.HibernateEntityManager
Similarly, for EntityManagerFactory, use javax interface. That way, the code is loosely coupled. If there is a better JPA 2 implementation than hibernate, switching would be easy. In extreme case, we could type cast to HibernateEntityManager.
EntityManagerFactory is the standard implementation, it is the same across all the implementations. If you migrate your ORM for any other provider like EclipseLink, there will not be any change in the approach for handling the transaction. In contrast, if you use hibernate’s session factory, it is tied to hibernate APIs and cannot migrate to new vendor.
EntityManager interface is similar to sessionFactory in hibernate.
EntityManager under javax.persistance package but session and sessionFactory under org.hibernate.Session/sessionFactory package.
Entity manager is JPA specific and session/sessionFactory are hibernate specific.