I came aboard a new project with a new company and we are trying to use JPA to do some DB work. So we have an Ear with an EJB, a webservice, and then there is a app client in the ear that really does all the work. The Webservice, calls the EJB, and the EJB calls the client to do the DB work. So within the appclient I want to load an EntityManager via annotations, but it does not seem to work (em is always null):
#Entity
public class Whatever...{
#PersistenceContext(unitName="pu")
EntityManager em;
}
So I was thinking that I need to load the EntityManager at the EJB, but that didn't work either, because it seems that JPA didn't see the Entity classes since they are in the appclient and not the EJB. Can anyone give me some guidance?
This is a misuse of an app client. All your db processing should occur in the EJB. There doesn't seem to be any apparent reason for the app clients' existence.
This link is to an old article, but gives examples as to what an app client is used for (Applications not backend services).
Application Client
Related
I am using JPA in a web application running in Tomcat 8. I am relatively new to JPA, and am having a hard time figuring out how to properly design my web app to use EntityManager. I have read "Java Persistence with Hibernate" and "Pro JPA 2", as well as a few posts about Entity Managers, but I am still unclear as to how to properly design my web app.
Should I create a singleton EntityManager that is used by the web app to service all requests, such as to CRUD (create, read, update, delete) entities?
Or should I ask the EntityManagerFactory to create a new EntityManager for each user request that comes in and close the EntityManager when I'm done processing the request?
I'm currently doing development on my local machine, where I am the only user.
What are the pros/cons of each approach?
Do both scale to hundreds of users?
I don't have the real world experience to answer these questions, so I'm looking for some answers/guidance from people who've used JPA in enterprise business apps.
Thanks
I have created ScopedEntityManager wrapper to ease JPA use in a servlet webapp. It creates an auto managed EM for the http request using a threadlocal variable.
It makes sure EM is rollbacked+closed after a servlet request. Same EM is returned in a getter method for the same request thread. You just need to commit() if all is good. Throwing an exception is not a problem because the request listener take care of the rollback().
See this how to instantiate a EM wrapper and life cycle manager.
https://github.com/Murmur/ScopedEntityManager/blob/master/src/es/claro/persistence/ScopedContextListener.java
https://github.com/Murmur/ScopedEntityManager
https://github.com/Murmur/ScopedEntityManager/blob/master/example_webapp/webapp/jpa1.jsp
So yes create a new EntityManager for each http request.
Spring has a class called LocalEntityManagerFactoryBean. Why is this class called "Local"? In what meaning is it local? Is there some RemoteEntityManagerFactoryBean class in Spring as well?
I dont have an authoritative source, however I'm pretty sure that it is "Local" in that it is local to the spring application context used by the application.
Spring doesn't provide a Remote EMF, however other components such as application servers will. For instance JBoss AS (an open source J2EE app server) can manage JPA EMF's and will make it available to your application at runtime, eg over JNDI, refer to the JBoss docs
Trying to get my head around Java EE (ORM/Entities/Annotations/EJB/Servlets etc.). So I've created a very simple webpage where you can enter user information and send it to the server. I'm using Apache Tomcat 8.0 as webbserver application and here is all the relevant parts of the application files and content that is needed to persist an entity:
http://pastebin.com/fwfbnYpU
The application gives me the error on line 99 saying:
08-Apr-2014 16:18:10.329 SEVERE [http-nio-8084-exec-93] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [indexServlet] in context with path [/JavaEENackademin] threw exception
java.lang.NullPointerException
What am I doing wrong? The database exist with the correct named table and columnnames. But then again that is not the problem here maybe it will become a problem after I fix this problem :)
One issue with your code is that you should not inject EntityManagers into servlets. Servlets are usually singletons, so all servlets would use the same EntityManager. You should inject an EntityManagerFactory instead and get your EntityManagers from it. You also have to take care of transactions. Not sure if this has caused your issues, but something that should be fixed.
I'm surprised you are able to deploy the code in your pastebin. Especially:
#WebServlet(name = "indexServlet", urlPatterns = {"/indexServlet"})
public class indexServlet extends HttpServlet {
#Inject
LoginValidation validation;
#PersistenceContext(unitName = "JavaEENackademinPU")
private EntityManager em;
//... offending line 99 calls: em.persist()
}
Neither PersistenceContext nor Inject are part of the servlet spec, so you probably added additional jars to your installation.
But you configured your persistence.xml to use JTA transactions which are barely supported in a servlet environment, probably resulting in tomcat ignoring the #PersistenceContext annotation altogether and leaving em == null (the default value).
I've found this link describing an integration but it looks complicated, requires editing internal xml files and then goes on to use Spring. Likely every part of that is overkill for a beginner.
I suggest you start fresh with a copy of TomEE which already does all the wiring to get you a fully fledged application server that supports CDI (#Inject) and JPA (#PersistenceContext) out of the box.
I have a spring mvc application that I am using Hibernate with.
I am using the sessionFactory.getCurrentSession in my Dao methods (not hibernate support).
What I want to know is, what do I have to do to be able to use my hibernate database layer
in a non-web application?
I have a stand-alone java application (that runs via main) where I load spring's application context
programatically and then get my service layer (which depends on my hibernate db layer).
Do I need to do anything special in my spring.xml file to setup hibernate's session?
In my spring mvc web app, I did annotate my Dao methods with the #Transactional annotation.
(I want the transaction on a per call basis, not for a group of db calls).
P.S In my web app, how are sessions created/destroyed, is it per request?
You can get hold of the spring ApplicationContext from main method. it will behave exactly the same as the one in web.
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
YourDAO yDao = (YourDAO)context.getBean("yourDAO");
yDao.callYourSpecialMethod();
So, from this point there is no dependancy for hibernate, it should work automatically. here just the view gets changed, no logical or structural changes. So the transactions and other things should work as usual.
I'm trying to add rest services to a struts application using jersey.For this i need to segregate the java code in such a way that it can be commonly accessed by both the struts and rest api.This is done so that the code is shared between both rest and struts,and any change will reflect in both the services.I would like to know , how much of this idea is feasible and weather this is how usually people design rest services .
While our presentation layer isn't Struts based (usually it's either Spring Web MVC or JSF), we use Spring 3.0 + Java EE 6, specifically, EJB 3.0 and JPA 2.0 for such situations.
EJB 3.0 stateless session beans work great—they can have declarative (annotation-based) dependency injection and transaction demarcation, or they can manage their transactions, dependencies and resources themselves using whatever traditional mechanism. They seamless integrate with JPA 2.0 and are easy enough to unit test. The main advantage over pure Spring beans is that they can be deployed independently of the Web application (as an EJB JAR).
On the front-facing Web services, we also use Jersey/JAX-RS. Because Jersey/JAX-RS dependency injection is broken (it doesn't use Weld/CDI like the rest of Java EE), we've had to resort to Spring DI to 'wire' up the front-facing REST resource classes with the 'back-end' EJBs. The good thing is this works well enough to inject the EJBs into our MVC controllers and can also be used with JSF managed beans. Alternatively, you can write your REST-ful resources using Spring alone (either way has its own pros/cons, but in general both do the job well).
I know I glossed over the whole thing but I'd be glad to share more details upon request.
EDIT: Some more details, as per request.
You're first stop for learning Jersey/JAX-RS would have to be the Jersey User Guide. There are also several tutorials/examples you can easily find across the 'Net.
While you should be able to package Jersey/JAX-RS resources into the same WAR as your Struts pages, we went with the simpler alternative of deploying them separately.
Now, when deploying to Glassfish 3.1, we hit this bug, also documented here. The bottom line is that #EJB injection didn't work for us as expected.
So, instead, we fell back on to Spring using the jersey-spring contrib module, following this example.
Anyway, the rest of it is standard Java EE 6 / EJB 3.0. We identify and place all common functionality into a 'service' layer which are largely implemented as #Stateless EJBs.
Persistence is handled through JPA #Entitys accessed through a JPA inject EntityManager. Transactions are declaratively demarcated using #TransactionAttribute.
Here's a quick illustration of a typical EJB + JPA service bean:
#Stateless
public class WidgetServiceBean implements WidgetService {
#PersistenceContext
private EntityManager em;
#Override
public List<Widget> findWidgetByName(String name) {
return em.createNamedQuery("Widget.findByName", Widget.class)
.setParam("name", name).getResultList();
}
#Override
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public void removeWidgetById(int id) {
em.find(Widget.class, id).remove();
}
}
(Obviously not production quality but just shows how 'lean' they can be.)
The service layer and entities are packaged as an EJB JAR which can be deployed separately, and made available to all other modules via global JNDI lookup. Or, they can be deployed within the Struts or JAX-RS WAR and as of Java EE 6 (Glassfish 3.x) they will be found, deployed as part of the module and made available to other components within the same WAR.
Some might argue that it's simpler to just use Spring beans if you're using the Spring container anyway. I would say, probably, but then you also have to use Spring's persistence framework, and Spring's transaction framework. (Spring also provides declarative transactions and persistence.) If you're already heavily invested into Spring then that might be an easier path.
OTOH, EJB 3.0, JPA 2.0 and JTA have also been radically simplified from their predecessors and are part of the Java EE standard so it's an architectural decision with a lot of dimensions.