I have a use-case where I think I need two entity managers, that access the same persistence unit. So essentially I want two persistence contexts on the same database. Is this possible via #PersistenceContext annotations?
I want to write something like the following, but don't know how to tell JPA to inject two different manager instances.
#PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager entityManager;
#PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager otherEntityManager;
I think I could switch to application-managed transactions, then I could just create another one using a factory. But I don't want to manage the transactions by myself, if it's not absolutely necessary.
There is some ambiguity in your statement. Are you constrained by using only one 'Persistent Unit'? It is not same as Constrained by using Single Datasource.
You can create multiple persistent units for a single datasource. So, if you are not constrained by the number of persistent units you can create, You can in persistence.xml declare 2 persistent units for the same datasource like below
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
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">
<persistence-unit name="PU1"
transaction-type="JTA">
<jta-data-source>jdbc/myDS</jta-data-source>
<!-- Other properties -->
</persistence-unit>
<persistence-unit name="PU2"
transaction-type="JTA">
<jta-data-source>jdbc/myDS</jta-data-source>
<!-- Other properties -->
</persistence-unit>
</persistence>
Then, you can create 2 entitymanagers like below
#PersistenceContext(unitName="PU1", type = PersistenceContextType.EXTENDED)
private EntityManager entityManager;
#PersistenceContext(unitName="PU2", type = PersistenceContextType.EXTENDED)
private EntityManager otherEntityManager;
Hope this helps.
Related
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>
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.
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.
I've been trying to mess around with MongoDB and Hibernate in Java. I'm having some troubles with the configuration file for it.
I've already used Hibernate in the past with SQL DB, but it seems that the config file has to be quite different for MongoDB.
According to this documentation, it should looks something like this:
<?xml version="1.0" encoding="UTF-8"?>
<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="eshop" transaction-type="JTA">
<provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
<class>org.hsnr.rest.domain.entities.Address</class>
<class>org.hsnr.rest.domain.entities.Order</class>
<class>org.hsnr.rest.domain.entities.Person</class>
<class>org.hsnr.rest.domain.entities.Product</class>
<class>org.hsnr.rest.domain.entities.User</class>
<properties>
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform" />
<property name="hibernate.ogm.datastore.provider"
value="mongodb" />
</properties>
</persistence-unit>
</persistence>
However, when I try to create a session with
new Configuration().configure().buildSessionFactory();
I get a following error:
org.hibernate.internal.util.config.ConfigurationException: Unable to perform unmarshalling at line number 5 and column 28 in RESOURCE hibernate.cfg.xml. Message: cvc-elt.1: Cannot find the declaration of element 'persistence'.
Is my aproach wrong or is there something I overlooked?
You can try basic test set up like below for your config.
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory( "eshop" );
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
// perform operations here
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
From the javadoc of configure():
Use the mappings and properties specified in an application resource
named hibernate.cfg.xml.
You are setting the persistence.xml instead. Using using javax.persistence.Persistence should work:
EntityManagerFactory emf = Persistence.createEntityManagerFactory( "eshop" );
If for some reason you need the session factory instead, but you are working with JPA, you can obtain it using the unwrap() method
SessionFactory sf = emf.unwrap( SessionFactory.class );
UPDATE:
You can also create the factory programmatically, there is a class OgmConfiguration (that extends Configuraiton):
OgmConfiguration configuration = new OgmConfiguration();
// This is optional, if you want to set some options using
// a fluent API
configuration.configureOptionsFor( MongoDB.class )
.writeConcern( WriteConcernType.UNACKNOWLEDGED );
SessionFactory sf = configuration
.addAnnotatedClass( org.hsnr.rest.domain.entities.Address.class )
// ... Other annotated classes
.setProperty( OgmProperties.DATABASE, "mongodb_database" )
.setProperty( OgmProperties.DATASTORE_PROVIDER, DatastoreProviderType.MONGODB.name() )
// All this properties are optional, appropriate default will be used if missing
.setProperty( OgmProperties.CREATE_DATABASE, "false" )
.setProperty( OgmProperties.USERNAME, "username" )
.setProperty( OgmProperties.PASSWORD, "password" )
.setProperty( OgmProperties.HOST, "localhost:12897" )
// Check MongoDBProperties for MongoDB specific options
.setProperty( MongoDBProperties.AUTHENTICATION_MECHANISM, AuthenticationMechanismType.BEST.name() )
.buildSessionFactory();
In this example I've added several options to give an overview but if you are using defaults and you don't need the authentication, only the database name and the datastore provider are needed
use bellow code :
<hibernate-configuration
xmlns="http://www.hibernate.org/xsd/hibernate-configuration"
xsi:schemaLocation="http://www.hibernate.org/xsd/hibernate-configuration hibernate-configuration-4.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
I am trying to create a Java application that will migrate an old schema to a new schema. I've chosen Java for the following reasons:
I need to perform data sanitation.
Business logic needs to be done to default previously null/bad data.
We are using JPA for our server code anyway. Using this in a migration will ensure our data migration has the correct integrity constraints.
My problem is; that when I increase the number of JPA Entity classes it takes a very long time to instantiate the EntityManager. Is there anything I can do to speed this up?
persistence.xml
<?xml version="1.0" encoding="UTF-
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="puMigration" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.myCompany.MyEntity</class>
. . .
<exclude-unlisted-classes>false</exclude-unlisted-classes>
</persistence-unit>
</persistence>
Java Code
Map<String, String> properties = new HashMap<>();
properties.put("javax.persistence.jdbc.driver", "com.mysql.jdbc.Driver");
properties.put("javax.persistence.jdbc.url", url);
properties.put("javax.persistence.jdbc.user", username);
properties.put("javax.persistence.jdbc.password", password);
// TODO Refactor, this call takes 2 minutes. Why?
EntityManagerFactory emf = Persistence.createEntityManagerFactory("puMigration", properties);
entityManager = emf.createEntityManager();
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>
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.
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.
I am using jboss5.1.x EJB3.0
I am trying my first time with JPA, and I get this exception when I run the server:
java.lang.IllegalArgumentException: Can't find a persistence unit named 'java:/mracDS'
..
this is my "DAO" entity which is responsible on all the JPA entities:
#Stateless
public class ECMSEntityManagerDao implements ECMSEntityManagerDaoLocal, ECMSEntityManagerDaoRemote
{
#PersistenceContext(unitName = "java:/mracDS")
EntityManager em;
public ArrayList<T01CounterCalls> getClocksDetailsFromVantive() throws SQLException
{
return (ArrayList<T01CounterCalls>) em.createQuery ("from T01CounterCalls as data").getResultList ();
}
}
I looked a bit in the net:
I never declared persistence.xml
and if I do, what should be declared inside?
thanks,
ray.
From the look of it my guess is that you are confusing a persistence unit with a data source.
These two may feel similar, but they aren't. Very simply said a persistence unit is a set of classes plus an associated data source. In the most basic form, a persistence unit merely couples to a data source:
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"
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_1_0.xsd"
>
<persistence-unit name="mracPU">
<jta-data-source>java:/mracDS</jta-data-source>
</<persistence-unit>
</persistence>
Then use the persistence unit name with the injection annotations:
#Stateless
public class ECMSEntityManagerDao implements ECMSEntityManagerDaoLocal, ECMSEntityManagerDaoRemote {
#PersistenceContext(unitName = "mracPU")
EntityManager em;
}