Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@PreDestroy not called on View Scope? #1355

Closed
ren-zhijun-oracle opened this issue Oct 3, 2009 · 13 comments
Closed

@PreDestroy not called on View Scope? #1355

ren-zhijun-oracle opened this issue Oct 3, 2009 · 13 comments
Assignees

Comments

@ren-zhijun-oracle
Copy link
Contributor

Possible unconfirmed error reported on the forums:

I have a managed bean that needs to remove its data listener from an
ApplicationScoped data model, and I would like to put the managed bean in View
scope. So I need to know when its lifespan is up.

I naively thought that ViewScoped managed beans expire when I change to a
different page in the browser, but I see that it's not so simple. If I then use
the browser's back (or forward) button the view is still there, maintaining its
state. I was also a little surprised to see that the ViewScoped bean survives
destroying the session.

Anyway, I put a method with a @PreDestroy annotation on the ViewScoped bean, and
also registered a ComponentSystemEventListener on the view root for
PreDestroyViewMap events.

In the server logs, I see it create new instances of my bean when I reload the
page or follow a link to it, but I have never seen either the PreDestroy method
or the listener called. (The PostConstruct method DOES get called).

Am I confused, is there a bug, or do they just live forever? Or is there another
way to find out when they expire? Is it possible to have more than one
UIViewRoot on the same page concurrently in one session? What triggers their
expiration? I haven't found much detail on this, so if anyone knows of any doc,
please let me know.

Here's my code for registering the listener. I tried calling it in the bean's
constructor and in the PostConstruct method, which does get called.

private void registerViewListener() {

FacesContext context = FacesContext.getCurrentInstance();
UIViewRoot viewRoot = context.getViewRoot();
viewRoot.subscribeToEvent(PreDestroyViewMapEvent.class, new ViewMapExitHandler());
}

public class ViewMapExitHandler
implements ComponentSystemEventListener, Serializable {

public ViewMapExitHandler() {}

public void processEvent (ComponentSystemEvent event) {

System.out.println("ViewMapExitHandler");
diagram.setDataModel(null);
event.getComponent().unsubscribeFromEvent(PreDestroyViewMapEvent.class, this);
}
}

Thanks for any help.

Environment

Operating System: All
Platform: All

Affected Versions

[2.0.0-RC1]

@ren-zhijun-oracle
Copy link
Contributor Author

@javaserverfaces Commented
Reported by driscoll

@ren-zhijun-oracle
Copy link
Contributor Author

@javaserverfaces Commented
Was assigned to driscoll

@ren-zhijun-oracle
Copy link
Contributor Author

@javaserverfaces Commented
driscoll said:
Forum thread:

http://forums.java.net/jive/thread.jspa?threadID=67603&tstart=0

@ren-zhijun-oracle
Copy link
Contributor Author

@javaserverfaces Commented
@rlubke said:
Assigned.

@ren-zhijun-oracle
Copy link
Contributor Author

@javaserverfaces Commented
driscoll said:
Created an attachment (id=1030)
Zip of working Netbeans project

@ren-zhijun-oracle
Copy link
Contributor Author

@javaserverfaces Commented
File: ViewPreDestroy.zip
Attached By: driscoll

@ren-zhijun-oracle
Copy link
Contributor Author

@javaserverfaces Commented
judys said:
Thx for the project code, I see now what's happening.

If you exit the page with an <h:command link, it calls the bean's PreDestroy
method. If you exit any other way, like <a href= or reload the page or type
something into the browser's location bar and load that, then it doesn't call
the PreDestroy method. I haven't tried killing the session yet.

I think in my case I would run the risk of accumulating dead diagrams which
can't be displayed and can't be garbage collected because the data model still
has refs to their listeners, and that would be a problem.

@ren-zhijun-oracle
Copy link
Contributor Author

@javaserverfaces Commented
driscoll said:
I talked with Ryan and Ed about this, and here's what they said, paraphrased.

Essentially, this is expected behavior.

Imagine a case where you have multiple tabs open, or press the back button - in
both cases, under the case where you're doing a GET, you'd expect the state to
be there - otherwise, you'll get a ViewExpiredException.

This means that if you also do <h:link> this will also be the behavior.

The views will all be reaped when the session expires, of course, which is often
set to 30 or 60 minutes.

There's also a configurable limit to the number of views - 15 is the default,
and it's a LRU (Least Recently Used) queue.

Ed Burns had said when I asked this that he'd also like to think about this
further. I'll leave this open for today awaiting his input. However, I'm
changing the milestone to TBD, while the bug is open.

Sorry it took so many iterations for you to get your answer, but I'm afraid that
this is going to be closed as not a bug. If you have specific questions about
other ways to reduce memory consumption, we should probably discuss them on the
forum.

@ren-zhijun-oracle
Copy link
Contributor Author

@javaserverfaces Commented
driscoll said:
Closing, as per previous comments.

@ren-zhijun-oracle
Copy link
Contributor Author

@javaserverfaces Commented
Marked as incomplete on Thursday, July 1st 2010, 3:09:26 am

@ren-zhijun-oracle
Copy link
Contributor Author

@javaserverfaces Commented
@manfredriem said:
Closing resolved issue out

@ren-zhijun-oracle
Copy link
Contributor Author

@javaserverfaces Commented
This issue was imported from java.net JIRA JAVASERVERFACES-1351

@ren-zhijun-oracle
Copy link
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants