annotated entity manager null pointed exception - java

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.

Related

Are there any drawbacks to using dynamic JPA endpoints in Camel?

CONTEXT
I've been trying to create a generic persistence layer for my application using Camel (v2.23.0) and Hibernate(v5.3.7). I'm also using HikariCP as the connection pool. To implement this generic persistence layer, I'm using the Camel JPA component to construct the core persistence routes as follows:
from("direct:getEntityById")
.toD("jpa:${header.entityClassName}?persistenceUnit=" + projectStage.toString() +
"&namedQuery=${header.entityClassSimpleName}.${header.queryName}");
from("direct:upsertEntity")
.toD("jpa:${header.entityClassName}?usePersist=false&persistenceUnit=" + projectStage.toString());
In the DAO, I'm using a dynamic JPA endpoint, so that I can reuse the route for any JPA entity.
I'm calling these routes through a plain Java DAO class, as follows:
...
public <T> Optional<T> getEntityById(Object id, String queryName, Class<T> clazz) throws GenericDAOException {
try {
Map<String, Object> queryParams = new HashMap<>();
queryParams.put("id", id);
List<T> entities = (List<T>) fluentProducerTemplate
.withHeader("id", id)
.withHeader("entityClassName", clazz.getName())
.withHeader("entityClassSimpleName", clazz.getSimpleName())
.withHeader("queryName", queryName)
.withHeader("CamelJpaParameters", queryParams)
.to("direct:getEntityById")
.request(List.class);
...
}
...
}
#Override
public <T> void upsertEntity(T entityObject) throws GenericDAOException {
try {
fluentProducerTemplate
.withBody(entityObject)
.withHeader("entityClassName", entityObject.getClass().getName())
.to("direct:upsertEntity")
.request();
}
...
}
This is the configuration for my persistence unit:
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="Production" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>...</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.url"
value="jdbc:postgresql://..."/>
<property name="javax.persistence.jdbc.user" value="..."/>
<property name="javax.persistence.jdbc.password" value="..."/>
<property name="hibernate.dialect" value="<custom dialect>"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.hikari.minimumIdle" value="25"/>
<property name="hibernate.hikari.maximumPoolSize" value="70"/>
<property name="hibernate.hikari.idleTimeout" value="300000"/>
<property name="hibernate.hikari.maxLifetime" value="600000"/>
<property name="hibernate.connection.provider_class"
value="org.hibernate.hikaricp.internal.HikariCPConnectionProvider"/>
</properties>
</persistence-unit>
</persistence>
Also, my JPA component is being created using a specific EntityManagerFactory (so I'm assuming all JPA endpoints will be sharing the same factory). (Using CDI for dependency injections)
#Produces
#ApplicationScoped
#Named("jpa")
public JpaComponent getComponent(PlatformTransactionManager transactionManager, EntityManager entityManager) {
JpaComponent component = new JpaComponent();
component.setTransactionManager(transactionManager);
component.setEntityManagerFactory(entityManager.getEntityManagerFactory());
component.setCamelContext(camelContext);
return component;
}
QUESTIONS:
As per the following doc: https://camel.apache.org/components/latest/eips/toD-eip.html, we should avoid creating endless dynamic endpoints, due to the excessive resource consumption. Since I'm working with the JPA component, I am especially concerned about the number of DB connections created, which could lead to application failures if not within a certain threshold.
To get around these potential issues, I'm using a connection pool. Since all JPA endpoints would use the same EntityManagerFactory, I presume that the connection pool would also be shared between these endpoints.
So I have the following questions:
When exactly would the JPA route release the DB connection? (as in, are they released immediately after the JPA route has completed processing a message, or are the connections tied to the lifecycle of the JPA endpoints?)
Would a new dynamic JPA endpoint be created for each unique URI?
What are the other potential issues that I would need to be wary of, when using dynamic JPA endpoints? (I suppose memory consumption would be one).

Location of the persistence.xml in a Java Client App

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.

Configuration to be able to #Inject EntityManager in Seam 3

In my project I use Seam 3 and I am having issues injecting the EntityManager with the #Inject annotation. I am pretty sure there is some kind of configuration to make sure the EnityManager knows which PersistenceUnit to use. For example with EJB you can type:
#PersistenceContext(unitName="MY_PERSISTENCE_UNIT_NAME")
private EntityManager eManager;
which persistence unit is configured in the persistence.xml file. Here is my pseudo configuration:
<?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="MY_PERSISTENCE_UNIT_NAME" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/TimeReportDS</jta-data-source>
<mapping-file>META-INF/orm.xml</mapping-file>
<class>....</class>
<class>....</class>
<class>....</class>
<properties>
<property name="jboss.entity.manager.factory.jndi.name"
value="java:/modelEntityManagerFactory" />
<!-- PostgreSQL Configuration File -->
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.connection.password" value="password" />
<property name="hibernate.connection.url" value="jdbc:postgresql://192.168.2.125:5432/t_report" />
<property name="hibernate.connection.username" value="username" />
<!-- Specifying DB Driver, providing hibernate cfg lookup
and providing transaction manager configuration -->
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup" />
<property name="hibernate.archive.autodetection" value="class" />
<!-- Useful configuration during development - developer can see structured SQL queries -->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="false" />
</properties>
</persistence-unit>
</persistence>
I have read some articles about Seam 2 but there the configuration is made in components.xml file by adding the:
<persistence:managed-persistence-context
name="entityManager" auto-create="true" persistence-unit-jndi-name="java:/modelEntityManagerFactory" />
inside the <components> tag. The next step in Seam 2 is to add the:
<property name="jboss.entity.manager.factory.jndi.name"
value="java:/modelEntityManagerFactory" />
in the persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence ...>
<persistence-unit name="MY_PERSISTENCE_UNIT_NAME" ...>
...
<properties>
...
<property name="jboss.entity.manager.factory.jndi.name"
value="java:/modelEntityManagerFactory" />
</properties>
</persistence-unit>
</persistence>
but it seam that in Seam 3 there is no file components.xml. Also there is no attribute unitName in #Inject annotation to specify the persistence unit.
So please help me to configure my project so I can use the #Inject with EntityManager as shown in many examples on the net.
I use Postgres database and JBoss AS 7.
EDIT: Adding an example. I don't use the EntityManager in an Entity class.
#Named("validateReportAction")
#SessionScoped
public class ValidateReportAction extends ReportAction implements Serializable {
private static final long serialVersionUID = -2456544897212149335L;
#Inject
private EntityManager em;
...
}
Here in this #Inject I get warning from Eclipse "No bean is eligible for injection to the injection point [JSR-299 ยง5.2.1]"
If I use the #Inject on some beans that are marked as Entity the #Inject works fine.
You can use #PersistenceContext on a CDI bean. It doesn't have to be an EJB.
If for some reason you want to use #Inject, you have to do more work. #Inject doesn't know about the EntityManager; it can only inject other managed beans. Happily, there is a simple workaround - use a producer method that acts as a simple trampoline.
#ApplicationScoped
public class EntityManagerProducer {
#PersistenceContext
private EntityManager entityManager;
#Produces
#RequestScoped
public EntityManager getEntityManager {
return entityManager;
}
public void closeEntityManager(#Disposes EntityManager em) {
if (em != null && em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (em != null && em.isOpen()) {
em.close();
}
}
}
You can now use #Inject to inject the EntityManager. The injected EntityManager will be RequestScoped, while the EntityManagerProducer is ApplicationScoped. Furthermore, the entityManager must be closed.

#PersistenceUnit annotation not working

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.

JPA Entity found in unit tests, not in EJB

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...

Categories