I am a newbie in Hibernate. In order to get the transaction by the EntityManager, I need to use EntityManager Factory. When I put this code block on my file:
EntityManagerFactory entityManagerFactory = Persistence
.createEntityManagerFactory("Comment");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
entityManager.persist(obj);
transaction.commit();
I got this Exception:
javax.persistence.PersistenceException: No Persistence provider for EntityManager named Comment
Then I realized that I need to add a persistence.xml file:
<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_1_0.xsd" version="1.0">
<persistence-unit name="QuestionsComments" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>Comment</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="root"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/sogdb"/>
<property name="hibernate.max_fetch_depth" value="3"/>
</properties>
</persistence-unit>
</persistence>
Actually, The app I am using is not a Java on Server app (I have a Client app). Which means that there is no META-INF folder that will contain the persistence.xml file.
My Questions are:
1- Where I need to put the persistence.xml file?
2- Is the code below OK? Knowing that my table in the database is QuestionsComments and my class that will be related to it using Hibernate is Comment.
If you are using Eclipse, adding the JPA facet to your project allows Eclipse to take care of setting these things up for you. It will create the META-INF folder, and can generate a stub persistence.xml file in it. You don't have to be running the code on a server to have a META-INF folder in your jar file.
When you are creating the EntityManagerFactory the string argument should be the name of the persistence unit. I'd recommend using annotations in your entity class for specifying table name, id column, etc.
Edit: fixed link.
Answered clearly in this section of the Hibernate JPA Quick Start Guide. It goes in META-INF.
Check out the same guide just linked.
Personally I prefer the Hibernate-specific configuration hibernate.cfg.xml with annotations for mappings and Hibernate's SessionFactory for transaction access; I find it easier to wrap my head around -- although that's probably because I originally learned how to use Hibernate without knowing how to use JPA.
Related
I need to migrate a project that uses hibernate from Jboss to weblogic. Currently I'm using this configuration:
persistence.xml
<persistence-unit name="pagosHibernate" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>...</class>
<properties>
<property name="hibernate.ejb.cfgfile" value="META-INF/hibernate.cfg.xml"/>
</properties>
</persistence-unit>
hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<property name="connection.datasource">MyDS</property>
<property name="jndi.class">weblogic.jndi.WLInitialContextFactory</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WeblogicTransactionManagerLookup</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
</session-factory>
</hibernate-configuration>
And the code is:
EntityManager em = this.factory.createEntityManager();
EntityTransaction entityTransaction = em.getTransaction();
entityTransaction.begin();
...
em.persist(device);
entityTransaction.commit();
But I'm getting:
java.sql.SQLException: Cannot call commit when using distributed transactions
Thanks
The DataSource "MyDS" used in Hibernate configuration looks like a XA DataSource.
In your case, Non-XA DataSource should be used. While configuring DataSource in Weblogic, you have to choose appropriate thin driver. Hope this helps.
The problem was caused by the XA datasource as R Sawant said. Nevertheless the solution was creating a non-XA datasource and disabling global transactions (keeping global transactions activated persisted the problem).
I would like to know how to configure this project to work on XA databases but that would be another question.
I'm using Eclipse Juno IDE
In phpMyAdmin I created my own database and my Table.
Now with the JDBC I entered some recoreds.
Next I tried to implement some queries with the JPA, I created an Entity
with the same columns and the persistence.xml connected to my database.
but when I was running the program it's delete the all the recoreds and created
a new empty table (with the same name) in my database.
So my question is : how can i connect to existed table in the database but not create
a new one.
another question is: i didn't give to my table a primary key because my table it's
about drivers travels, so each driver can travel many times... so if I use the primary
key it will not add the new data about the driver. with the JDBC it works fine.
but with the JPA the entity needs some field to be a Primary Key.. so how can I add
a new data about the same driver in JPA?
the persistence file:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit transaction-type="RESOURCE_LOCAL" name="MyJPA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>pack.bl.Travels</class>
<properties> <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/drivers"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
</properties>
</persistence-unit>
Code:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MyJPA");
EntityManager em = emf.createEntityManager();
List<Travels> allTravels = em.createQuery("SELECT t FROM travels t",Travels.class).getResultList();
for (Travels s : allTravels)
System.out.println(s.toString());
em.close();
Add an id autoincrement field to your table. It will be the primary key.
About auto-creation of tables, look here(I assume you are using Hibernate as JPA implementation):
Hibernate hbm2ddl.auto possible values and what they do?
in your hibernate configuration, make sure hibernate.hbm2ddl.auto isnt set to create-drop (because thats what it sounds like).
try setting it to validate
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html
follow the link for jpa configuration
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html
add code in your configuration xml file
<property name="hibernate.hbm2ddl.auto" value="validate"/>
I am doing a small project using JPA. I need to insert the employee object.
For that when I use the annotated entity manager I got the NullPointer exception.
But when I use the Normal EntityManager without using the annotation it is working fine.
Do I need to configure somewhere else other than persistence.xml to work this examle fine?
Please see the code below.
public class EmployeeDao implements IEmployeeDao{
#PersistenceContext(unitName = "timesheet")
private EntityManager entityManager ;
#Override
public boolean createEmployee(IEmployee employee) {
this.entityManager.persist(employee);
return true;
}
}
persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>
<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" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="timesheet" transaction-type="RESOURCE_LOCAL">
<class>com.timesheet.model.Employee</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/timesheet" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode"
value="database" />
</properties>
</persistence-unit>
</persistence>
Injection of resources (in your case via use of #PersistenceContext) works only in container managed classes (like EJBs and Servlets). This explained with more details for example in Java EE specification v6, EE5.2.5.
What you can do:
Modify your class so that it is managed class
move injection of resources to managed class and pass it to
EmployeeDao,
use JNDI lookup as before
Use the annotation javax.ejb.Stateless for your EmployeeDao and IEmployeeDao classes. Entitymanager is a no-interface an Enterprise Java Bean injected in your client.
The client must be either a web component or another enterpise bean. See here for further details about how to use EJBs.
In other words, using the Stateless annotation, the web container will take care of the lifecycle of your EmployeeDao class.
Use transaction type of JTA instead of RESOURCE_LOCAL. You can acquire the EntityManager instance if and only if the program is running in app server and transaction type is JTA.
So above all answers lead to summarise that :
Injection of resources through annotation will work on container managed classes (e.g EJB, Servlet).
Injection of resources can be done except annotation (e.g #PersistenceContext) on a simple JPA project ( a project which hasn't container managed classes ). Following code snippet give you lucid view :
private EntityManagerFactory factory;
factory = Persistence.createEntityManagerFactory("PERSISTENCE_UNIT_NAME");
EntityManager em = factory.createEntityManager();
Thanks to all for sharing knowledge.
I want to use the #PersistenceUnit annotation in my app to create an application managed EntityManager
#PersistenceUnit(unitName="primary")
private static EntityManagerFactory entityManagerFactory;
EntityManager entityManager = entityManagerFactory.createEntityManager();
This doesn't seem to be working. I run my code through a debugger and discover that entityManagerFactory is null. My guess is that the injection of Persistence context with the #PersistenceUnit annotation is not working.
My app is a CDI app. It was not previously a CDI application - I converted it to CDI by creating a beans.xml file in WEB-INF, I needed to in order to do something like this.
Is there anything I need to configure within CDI to get the annotation to work? Thanks.
I have a JPA application running with only Java SE. I don't have a WEB-INF/beans.xml, but I do have a META-INF/persistence.xml configuration file:
<?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="JPAPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>jpa.Container</class>
<class>jpa.Item</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:derby:D:\NetBeansProjects\JPA\jpaTestDB;create=true"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="javax.persistence.jdbc.user" value=""/>
<property name="eclipselink.ddl-generation" value="create-tables"/>
</properties>
</persistence-unit>
</persistence>
Container and Item are the two persistence classes in my jpa package.
This was generated automatically by Netbeans. There is also some information about using JPA without Java EE in the official (Sun/Oracle) Java EE tutorial in the persistence chapter.
I have a DAO that uses JPA with a non-JTA data source and RESOURCE_LOCAL transactions. All of my unit tests that exercise the DAO work perfectly (data is inserted and retrieved from the database).
When I deploy my EJB to my Weblogic 10.3.3 server, however, I get the following exception:
Caused by: java.lang.IllegalArgumentException: Unknown entity bean class: class com.foo.bar.CatalogEntity, please verify that this class has been marked with the #Entity annotation.
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.find(EntityManagerImpl.java:576)
My persistence.xml (in WEB-INF/classes/META-INF):
<?xml version="1.0" ?>
<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_1_0.xsd"
version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="cmf-awe-service" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<non-jta-data-source>MyDataSource</non-jta-data-source>
<class>com.foo.bar.CatalogEntity</class>
<properties>
<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.query-results-cache" value="false"/>
<property name="eclipselink.target-server" value="WebLogic_10" />
<property name="eclipselink.logging.level" value="FINEST" />
</properties>
</persistence-unit>
</persistence>
I have confirmed that the CatalogEntity class is in the WEB-INF/classes directory. Any ideas about why this works in unit tests but not when deployed to the application server?
Brian, I had the same issue here... and I solved by adding a PreDestroy method on my bean that closes EntityManagerFactory:
#PreDestroy
public void close()
{
emf.close();
}
I hope this can help you! Please vote if it works...