Aside from application scoped beans every scope above @RequestScoped
will have to be stored in the Session, because there is no other place to store data for JSF. A custom scope cannot change that.
So when your Session is destroyed after 30 minutes, everything is lost. The best solution is to set your Session timeout to a higher value by setting it in the web.xml (in minutes):
<web-app ...>
<session-config>
<session-timeout>120</session-timeout>
</session-config>
</web-app>
Or programmatically (in seconds):
HttpSession session = request.getSession();
session.setMaxInactiveInterval(120*60);
If you setup @SessionScoped
only for those beans which need to be available for 2 hours, and use @RequestScoped
or @ViewScoped
for everything else, then your Session will keep only the data which you want to keep for 2 hours and everything else will be deleted much earlier.