As I wrote in this topic I need to invoke some action when user close or change page. I thought I could use #PreDestroy in my view scoped bean, but it is never called (even when session expires). Is this a bug? I use Glassfish 3.1.2.
Any other suggestions how can I call bean method when user leave page? Is javascript window.onunload good idea?
Even if the bean is view scoped, it's the container's responsibility to decide when to collect and destroy unused resources.
The annotations used for defining a scope indicate how long a managed bean has to survive, but you are not guaranteed about when they'll be destroyed.
As you have suggested, JavaScript can be a solution for your problem. See also this answer: How to detect unsaved data in form when user leaves the page?
Related
I need a specific scope in my spring-managed (w/ spring-security) web application. But this scope must have a narrower scope than session and wider than request. Corresponding beans should be initialized and destructed on certain cases, within current session. But for sure only destructed for the user who requested such.
I successfully implement a custom-scope but it is not user-aware and when I try to finalize it, all created beans on that scope are finalized.
Is there any way to initialize beans with e.g logged user name?
In a nutshell, I need to initialize some of the variables on such beans on certain cases, that's why I want to destroy and re-initialize them.
Any suggestion will be well accepted,
Thanks all.
Edit: As #Stefan suggested to use webflow, even that'll probably solve our issues i think it doesn't seem an acceptable method because our bunch of pages are dependent to fields defined in spring beans. Now we have to bind them to viewscope/flowscope.
I still need a quicker way to handle this issue,
Thanks.
You might have a look at Spring Webflow. It works with JSF and has a 'flow scope' that is between request and session scope.
If the stateful session bean is going to passivate, its state is written to harddisk and then the bean instance will be freed to serve other request (at least this is my understanding). When the same client is active again, bean instance will read the state from hard disk to regain the state. But how the bean instance knows that for which client which file it has to read to maintain the state?
I am very new to J2EE, so please pardon me if I am asking a very naive doubt. If I need to know any other topic to understand this, please point me in the right direction.
It's best to visualize a Stateful Session Bean (SfSB) as very close to an instance of a normal Java class. You look up (or inject) an instance of a SfSB, and the container will create one for you and return the instance. You then work with that instance like you would any other Java instance.
That means that you can store the instance in to a Session, serialize it to disk, etc.
The detail is that the instance you are working with is actually a proxy to the actual, underlying SfSB instance. It's not the actual SfSB itself.
When you make a call on your local proxy to the bean, it is the containers job to manifest that bean in to memory for you. The passivation and activation of the bean is done behind the scenes for you (though you can tap in to the process through the beans lifecycle).
Any information that the container needs to find the passivated SfSB is stored in the proxy that you're working with, but this is opaque to you. You needn't worry about it.
So, in a typical web based scenario, the life cycle would be that you get your bean instance, store it in a web session, and then simply use it like normal. If the container decides it needs to passivate your bean to make room or whatever, it will passivate it automatically for you. When your user returns, your app pulls the instance from the web session, and makes its calls. At that time, if the bean is passivated, the container will activate the bean for you, again automatically. This entire mechanism is dependent on the container, yet transparent to you. The important thing for you to recall is that you must hang on to SfSB that you get from the container, like you would any java object.
The final caveat is that if you allow a SfSB to be passivated for too long, the container will automatically delete it for you.
Im really new to java, jsf, jsp, and I need to learn how it works quickly. So the website Im using to practise has some terms etc that I dont know what they mean and Im hoping somebody can explain what they mean and how/what they are used for:)
Requestscoped
Applicationscoped
Sessionscoped
EntityManager
and could someone walk me through what these lines do?
#RequestScoped
public class Dao {
#DataRepository
#Inject
private EntityManager entityManager;
First of all, in Java (5 and higher), "things" starting with a # (e.g. #Deprecated) are called annotations.
Annotations provide data about a
program that is not part of the
program itself. They have no direct
effect on the operation of the code
they annotate.
Your JavaBeans needs to be configured to a scope if you want to use it in JSF (Definitions can be found here).
#RequestScoped: Objects with this scope are visible from the start of the request until the end
of the request. Request scope starts at the beginning of a request and ends when the
response has been sent to the client. If the request is forwarded, the objects are visible
in the forwarded page, because that page is still part of the same request/response
cycle. Objects with request scope can use other objects with none, request, session,
or application scope. If you have to think it in terms of servlet, the managed bean is stored in the HttpServletRequest until the end of the request (when the response is sent to the client). After that, the bean no longer exists in the request.
#SessionScoped: An object with session scope is visible for any request/response cycle that
belongs to a session. Objects with this scope have their state persisted between
requests and last until the object or the session is invalidated. Objects with session
scope can use other objects with none, session, or application scope. Basically, these objects are stored in a HttpSession (refer to Servlets again). Each session has a session ID (known as JSESSIONID) that the bean is associated with.
ApplicationScoped: An object with application scope is visible in all request/response cycles
for all clients using the application, for as long as the application is active. In terms of Servlet, this could be, managed bean stored in a ServletConfig.
#NoneScoped: Objects with this scope are not visible in any JSF page. When used in the configuration file, they indicate managed beans that are used by other managed beans in the application. Objects with none scope can use other objects with none scope.
For EntityManager, this is associated with persistence context. It is used to create and remove persistent entity instances, to find entities by their primary key identity, and to query over all entities. For more, refer to the JPA (Java Persistence API) Specification, or Hibernate.
#Inject, means that the instance is injectable. They follow the infamous crase word of Depency Injection or Inversion of Control (IOC). What this basically mean, is that when the resource (in your case EntityManager entityManager is needed, the JEE container instantiates the resource for you (without you needed to instantiate it directly through e.g. a constructor, etc.).
I have no clue what #DataRepository means. Never seen it before.
I hope this helps you.
These terms are usually associated with a dependency injection framework like guice and not with java in particular.
http://code.google.com/p/google-guice/wiki/Scopes describes the various scopes that are built into guice.
By default, Guice returns a new instance each time it supplies a value. This behaviour is configurable via scopes. Scopes allow you to reuse instances: for the lifetime of an application (#Singleton), a session (#SessionScoped), or a request (#RequestScoped). Guice includes a servlet extension that defines scopes for web apps. Custom scopes can be written for other types of applications.
Can get work the attribute "destroy-method".
First, even if I type non-existing method name into "destroy-method" attribute,
Spring initialization completes fine (already strange!).
Next, when a bean has a "prototype" scope, then I suppose it must be destroyed before the application
is closed. That not happens, it is simply never called in my case.
Though, after extracting this bean I can call this method explicitly and it does its job.
Could you explain why this method is never called in my Spring 2.5 case?
p.s. The method exists, it is public and has no arguments.
It seems to be a more difficult task then I thought.
The problem is that this destroy method is called whenever the context is closed, and
this is a rare case.
My question is this:
I have a web app. I have a "prototype"-scoped bean.
What I need is when the current session is closed, this destroy method was automatically called by Spring.
I can do it by hand, but is there any solution how to make Spring do this job? It destroys the bean after the session is destroyed, it might be possible for Spring to call a method on that bean before destroying it?
p.s. Spring does not manage the lifecycle of prototype beans, so Spring does not destroy them :)
The Spring container doesn't manage prototype beans.
A snippet from the reference documentation:
Thus, although initialization
lifecycle callback methods are called
on all objects regardless of scope, in
the case of prototypes, configured
destruction lifecycle callbacks are
not called.
If possible, try the request or session scope.
When the HTTP Session is eventually
discarded, the bean that is scoped to
that particular HTTP Session is also
discarded.
Btw: The session and request scope only works if you're using a web-aware ApplicationContext such as XmlWebApplicationContext
First off, I think I'm trying to use Spring incorrectly, but confirmation would be appreciated.
I am trying to reset a single bean in mid-application. My initial configuration works just fine.
My scenario
1 Insurance Claim bean (session
scope)
1 Claim details bean which is a
multiactionController
(getClaim&setClaim enabled, prototype
scope)
1 Claimant details bean which is a
multiactionController
(getClaim&setClaim enabled, prototype
scope)
1 Submit claim bean which is a
multiactionController
(getClaim&setClaim enabled, prototype
scope).
My application is more complex than this, but for the sake of providing a clear example I wont describe the whole thing.
The first two controllers are used to set various properties of the claim, validate etc.
The third writes a claim to the database. THEN I want it to reset the bean. However I can't just say claim=new Claim() in SubmitClaimController.OnSubmit() as the ApplicationContext keeps its reference to the old Claim.
I could just create a method Claim.clear(), but that feels like the wrong approach. However, I can't see anything like ApplicationContext.destroyBean(beanname) or ApplicationContext.createBean().
I do not want to refresh the entire ApplicationContext as I will have other beans I want to keep alive throughout the session.
Thanks in advance.
I don't think the Claim object should be Spring-managed. It's really not injected; sounds like it should be bound from the request sent into the controller and passed to the service for processing. If you put a Claim into session scope, you need to invalidate the session when the transaction is done or if the session times out.
By the way, I see you mention three controllers, but no service. You should have a service layer, and controllers should not deal with DAOs or persistence.
You can change the scope of a bean. Default is singleton which is sometimes not appropriate in web contexts. You can change it to be session scoped by adding for example
the attribute scope="session"
and the child <aop:scoped-proxy proxy-target-class="false"/>
to the bean definition.
I am working with 3.0M4, btw, but I would expect it to be in earlier versions, as well, as it's a very important functionality. Have a look at:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ch03s05.html
Cheers!