EntityManager became NULL after a while (about 10m) - java

in my JavaEE 6 application (JBoss 6.0.0.Final) I have a class hierarchy outlined like this
#Stateful public class UserFacade
{
#Inject #MyRepository
private EntityManager em;
}
#Stateful public class UserBl
{
#EJB private UserFacade fUser;
}
public class MyServlet
{
#EJB private UserBl blUser;
}
The servlet is used during a login process and it works fine. But if the servlet is called from the same browser after an inactivity period of about 10 minutes, the EntityManager em in UserBl became NULL (checked this explicitly before using it).
In a other application (JBoss 5.1.0.GA) I've had a similar issued and solved it by explicitly checking for NULL and looking up the EntitiyManager from the context in that case.
I'm wondering if there is a fundamental design flaw or if I missed something. In this scenario #Stateless Beans are possible, too. But in my understanding this should also work with #Stateful Beans.

As far as I recall, injection of stateful beans has been problematic (at least in JavaEE 5). It might be a passivation-activation issue.
But you don't really need stateful beans here - the EntityManager is per-transaction (by default; you can set it to extended which allows it span multiple requests) and a stateless bean is the proper way to go.

Related

Stateful EJB in business tier used in the conversation scope of the web tier

I have an enterprise application with (at least) a web tier (UI only) and a service tier. In the service layer is all the business logic and the current conversation state implemented as #Stateful #LocalBean EJBs (no CDI).
This is somewhat similar to a #SessionScoped bean in terms of CDI, right?
So, here's the issue:
I have a long running conversation in the web tier (#Named #ConversationScoped) and want to access the Stateful EJB. The EJB should be accessed in different controllers (beans) of this conversation. I can't do it like this: #EJB because it would be a different instance of the particular EJB type. I have to save the reference to the EJB somehow. This is my current solution:
#EJB
private MyEJB _myEJB; // a stateful EJB
#Produces
#Builder // custom quallifier
#ConversationScoped
public MyEJB produceMyEJB() {
return _myEJB;
}
Now I can access the same instance of the stateful EJB in each of the conversation scoped controllers like this #Inject #Builder MyEJB _myEJB.
It works, most of the time. But in some long running tests this reference is null and I don't know why.
I get this stack trace in the server.log of Glassfish:
javax.ejb.NoSuchObjectLocalException: The EJB does not exist. session-key:
907f0200001f-ffffffffc3388fbb-761
and/or
Cannot load from BACKUPSTORE FOR Key: <907f0200001f-ffffffffc3388fbb-761>
Do You have any ideas why this happens? Thanks for help and sorry for my bad English.
Your stateful EJB is probably timing out. Check out javax.ejb.StatefulTimeout: http://docs.oracle.com/javaee/6/api/javax/ejb/StatefulTimeout.html
#Stateful
#StatefulTimeout(unit = TimeUnit.MINUTES, value = 30)
public class MyEJB {

CDI Injection of an EJB leads to NullPointerException

I am new to Java EE 6 and CDI. I have read a couple of tutorials and the weld documentation. However something that should work from my understanding doesn't so I need help.
I have the following situation. I created a Java EE 6 Application with NetBeans 7.0.1 using the maven archetype supplied with the IDE and I deploy to GlassFish 3.1 also supplied by the IDE.
The beans.xml is located in the META-INF directory of my EJB jar.
I have created a class that works soley as a producer class for my EJB Artifacts (and EntityManager)
#Stateless
public class EjbArtifactProducer {
#PersistenceContext(unitName = "trackProfiler-PU")
private EntityManager em;
#EJB
private UserFacadeLocal userFacade;
#EJB
private AuthServiceLocal authService;
#EJB
private NewsEntryFacadeLocal newsEntryFacade;
#EJB
private RoleFacadeLocal roleFacade;
#EJB
private TrackCommentFacade trackCommentFacade;
#EJB
private TrackFacade trackFacade;
#EJB
private TrackTypeFacade trackTypeFacade;
#EJB
private WaypointFacadeLocal waypointFacade;
#Produces
public AuthServiceLocal getAuthService() {
return authService;
}
#Produces
public EntityManager getEm() {
return em;
}
#Produces
public NewsEntryFacadeLocal getNewsEntryFacade() {
return newsEntryFacade;
}
#Produces
public RoleFacadeLocal getRoleFacade() {
return roleFacade;
}
#Produces
public TrackCommentFacade getTrackCommentFacade() {
return trackCommentFacade;
}
#Produces
public TrackFacade getTrackFacade() {
return trackFacade;
}
#Produces
public TrackTypeFacade getTrackTypeFacade() {
return trackTypeFacade;
}
#Produces
public UserFacadeLocal getUserFacade() {
return userFacade;
}
#Produces
public WaypointFacadeLocal getWaypointFacade() {
return waypointFacade;
}
}
I tried to apply the #Produces annotation directly to the fields an on methods as shown above.
However the following does not inject anything in another EJB
#Inject
private NewsEntryFacadeLocal newsEntryFacade;
This is done in a stateless session ejb but when I try to access newsEntryFacade in any of my business methods a NullPointerException is thrown. So clearly no Injection is happening or my producers produce null references.
Am I missing something? Or should this work according to CDI/Weld?
Strangely it seems to work that way when I try to #Inject EJBs into the web application part (however i needed an extra producer class in my .war for this to work, is this as it should be?).
EDIT: The project works with an ant build (generated by NetBeans). Are there issues with the Maven archetype provided by NetBeans? It seems that with the Maven archetype there are some issues with CDI injection between the war and ejb modules. I found that if I had separate producers in the web and ejb module Glassfish generates a deployment error stating that there are two indistinguishable implementations of an interface. But when I remove the producer in the web module Weld complains that the EJB i want to inject into my beans in the web module cannot be resolved. Also with the Ant build EJBs can be #Injected without a producer while the maven build needs producer fields on a class. I can't explain how this could happen. After all the final deployment should be more or less equal, shouldn't it?
If you want to use #Inject then annotate it as #Named #ApplicationScoped, otherwise use #EJB when injecting your singleton.
Jordan Denison is correct. You're trying to #Inject and EJB, but you be using #EJB for EJBs. You're EJB class is probably annotated with #Stateless or something. #Inject should be used on session beans that annotated with #Named and some sort of scope.
Hard to tell whats going wrong but what definitely did not work for us is to use CDI between class loader boundaries. For example if your application is packaged as an ear file you would have your ejbs in an jar file and your webapp in your war file. In this case you can not use CDI to inject your ejbs in your web layer. The problem is that the jar and the war is loaded by different class loaders. Maybe newer CDI implementations behave different but at least JBoss 6 and Glassfish had this problem.
Try to put #Named into EjbArtifactProducer. Also, if the produces is this kind of simple, I think it's better to remove it too (else, you should do one more change).
you are mixing two different concepts... use CDI as backing beans for JSF. (CDI in Web Container) and use EJB and JPA in the Business Layer... the CDI layer can inject a EJB to call the specific business method.
in this case you have a clean separation on concerns.
BTW: you do not need any EJB interfaces at all! use only interfaces if you have a requirements to communicate from remote... (#Remote). with the #LocalBean annotation you can inject directly the EJB itself..
if you have e clean separation of layers each with his own concern i think you better find the reason for this NullPointerException.. and i think your NullPointerException does not exists any more after this...
Layering:
Web Browser --> JSF Facelet --> CDI Backing Bean --> EJB Service(s) --> EntityManager

CDI #TransactionAttribute for bean

I am experimenting with CDI on a test application. I have a DAO which injects a container managed JTA persistence context like this:
public class TestDAO implements Serializable {
#PersistenceContext
private EntityManager entityManager;
public void insertEntity(Test test) {
entityManager.persist(test);
}
}
Now I have a CDI controller bean like this:
#Named
#SessionScoped
public class TestController implements Serializable {
#Inject
private TestDAO testDAO;
public void finishGame() {
testDAO.insertEntity(new Test(1, 2, 3));
}
}
If I run this, I receive an error in the DAO when trying to insert the entity, because there is no active transaction available. So far so good. I can solve this by making the controller bean a stateful EJB which will wrap the finishGame() in a transaction.
But let assume I don't want an EJB. As a test I annotated the finishGame() with the #TransactionAttribute annotation and it worked(the controller bean is NOT an EJB). So my question is: how does it work? Does the CDI define #TransactionAttribute for plain beans? I know that Seam Persistence Module does this, but I am not using it. Actually I added it to the project, but I removed it after, because I received awkward exceptions.
Could anyone clear my confusion? Do really CDI define #TransactionAttribute for plain beans?
P.S. I have another sort of question. I see the tendencies is to port all EJB annotations to plain beans. So will EJBs become obsolete in the future? I mean I saw in JIRA that #TransactionAttribute will be added in the future for plain beans(the task is still not resolved). So isn't this eclipsing EJBs, sort of duplicating functionality?
Best regards,
Petar
You need do define a transaction interceptor. Basically define a #Transactional annotation and intercept all methods annotated with it. In the interceptor just begin, commit or rollback the transaction. It gets more complicated when transaction propagation comes into the picture. So check if Seam doesn't have anything ready-to-use http://seamframework.org/Seam3/PersistenceModule

Spring session-scoped beans (controllers) and references to services, in terms of serialization

a standard case - you have a controller (#Controller) with #Scope("session").
classes put in the session usually are expected to implement Serializable so that they can be stored physically in case the server is restarted, for example
If the controller implements Serializable, this means all services (other spring beans) it is referring will also be serialized. They are often proxies, with references to transaction mangers, entity manager factories, etc.
It is not unlikely that some service, or even controller, hold a reference to the ApplicationContext, by implementing ApplicationContextAware, so this can effectively mean that the whole context is serialized. And given that it holds many connections - i.e. things that are not serializable by idea, it will be restored in corrupt state.
So far I've mostly ignored these issues. Recently I thought of declaring all my spring dependencies transient and getting them back in readResolve() by the static utility classes WebApplicationContextUtils and such that hold the request/ServletContext in a ThreadLocal. This is tedious, but it guarantees that, when the object is deserialized, its dependencies will be "up to date" with the current application context.
Is there any accepted practice for this, or any guidelines for serializing parts of the spring context.
Note that in JSF, managed beans (~controllers) are stateful (unlike action-based web frameworks). So perhaps my question stands more for JSF, than for spring-mvc.
In this presentation (around 1:14) the speaker says that this issue is resolved in spring 3.0 by providing a proxy of non-serializable beans, which obtains an instance from the current application context (on deserialization)
It appears that bounty didn't attract a single answer, so I'll document my limited understanding:
#Configuration
public class SpringConfig {
#Bean
#Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
MyService myService() {
return new MyService();
}
#Bean
#Scope("request")
public IndexBean indexBean() {
return new IndexBean();
}
#Bean
#Scope("request")
public DetailBean detailBean() {
return new DetailBean();
}
}
public class IndexBean implements Serializable {
#Inject MyService myService;
public void doSomething() {
myService.sayHello();
}
}
public class MyService {
public void sayHello() {
System.out.println("Hello World!");
}
}
Spring will then not inject the naked MyService into IndexBean, but a serializable proxy to it. (I tested that, and it worked).
However, the spring documentation writes:
You do not need to use the <aop:scoped-proxy/> in conjunction with beans that are scoped as singletons or prototypes. If you try to create a scoped proxy for a singleton bean, the BeanCreationException is raised.
At least when using java based configuration, the bean and its proxy can be instantiated just fine, i.e. no Exception is thrown. However, it looks like using scoped proxies to achieve serializability is not the intended use of such proxies. As such I fear Spring might fix that "bug" and prevent the creation of scoped proxies through Java based configuration, too.
Also, there is a limitation: The class name of the proxy is different after restart of the web application (because the class name of the proxy is based on the hashcode of the advice used to construct it, which in turn depends on the hashCode of an interceptor's class object. Class.hashCode does not override Object.hashCode, which is not stable across restarts). Therefore the serialized sessions can not be used by other VMs or across restarts.
I would expect to scope controllers as 'singleton', i.e. once per application, rather than in the session.
Session-scoping is typically used more for storing per-user information or per-user features.
Normally I just store the 'user' object in the session, and maybe some beans used for authentication or such. That's it.
Take a look at the spring docs for configuring some user data in session scope, using an aop proxy:
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes-other-injection
Hope that helps
I recently combined JSF with Spring. I use RichFaces and the #KeepAlive feature, which serializes the JSF bean backing the page. There are two ways I have gotten this to work.
1) Use #Component("session") on the JSF backing bean
2) Get the bean from ELContext when ever you need it, something like this:
#SuppressWarnings("unchecked")
public static <T> T getBean(String beanName) {
return (T) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(FacesContext.getCurrentInstance().getELContext(), null, beanName);
}
After trying all the different alternatives suggested all I had to do was add aop:scoped-proxy to my bean definition and it started working.
<bean id="securityService"
class="xxx.customer.engagement.service.impl.SecurityContextServiceImpl">
<aop:scoped-proxy/>
<property name="identityService" ref="identityService" />
</bean>
securityService is injected into my managedbean which is view scoped. This seems to work fine. According to spring documentation this is supposed to throw a BeanCreationException since securityService is a singleton. However this does not seems to happen and it works fine. Not sure whether this is a bug or what the side effects would be.
Serialization of Dynamic-Proxies works well, even between different JVMs, eg. as used for Session-Replication.
#Configuration public class SpringConfig {
#Bean
#Scope(proxyMode = ScopedProxyMode.INTERFACES)
MyService myService() {
return new MyService();
}
.....
You just have to set the id of the ApplicationContext before the context is refreshed (see: org.springframework.beans.factory.support.DefaultListableBeanFactory.setSerializationId(String))
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
// all other initialisation part ...
// before! refresh
ctx.setId("portal-lasg-appCtx-id");
// now refresh ..
ctx.refresh();
ctx.start();
Works fine on Spring-Version: 4.1.2.RELEASE

How is threadsafty guranteed with #PersistenceContext?

According to many examples it is possible to inject an EntityManager into #Stateless or #Singleton EJBs like this:
#Stateless // or #Singleton
public class MyRepository {
#PersistenceContext
private EntityManager em;
...
}
The EJB 3.1 Spec says that dependency injection is only performed at construction time, so that all callers of MyRepository would use the same instance of EntityManager. How does the EJB container ensure that the correct EntityManager instance is used?
My understanding is that a #Stateless bean will never be used by two clients concurrently; the container will simply create more instances of the same bean if it needs to serve multiple clients.
As for #Singleton beans, the spec says that by default they use Container Managed Concurrency, where the container uses method Locks and could reject clients with a timeout exception if the singleton is busy.
Edit: additionally, the #PersistentContext type is transaction-scoped by default (16.11.1.1 in the spec) so all entities managed by EntityManager are detached at the end of each transaction.

Categories

Resources