You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Bruno Aranda <br...@gmail.com> on 2005/06/28 13:11:49 UTC

Re: SelectItem and Hibernate

Hi Lorenzo. Regarding your questions:

> 1)I need translate Hibernate List get from session.find in []SelectItem?

Yes, you have to create a List of SelectItem objects with the objects
obtained using the query.

> 2) When I use Hibernate with jsf what it is the better session strategy
(ex. close, open). In my getRoles method I must close hibernate session?
I don't know too much about this, but several approximations have been
posted in this list. I hope that anybody with more knowledge than me
will help you on that. Currenty, I am using EJB3 and the strategy to
data access is different,

Regards,

Bruno

2005/6/28, Lorenzo Sicilia <ar...@kemen.it>:
> Hi to all,
> 
> I do some tests with myfaces and hibernate.
> I got some problems about this snippet:
> 
>         <x:selectOneMenu id="menu_roles" >
>                 <f:selectItems value="#{userForm.roles}" />
>         </x:selectOneMenu>
> 
> my userForm.roles get his data from an Hibernate session.
> 
> ...
> public List getRoles() {
>         List roles = null;
>         System.out.println("userForm.getRoles");
>         try {
>                 Session session = HibernateSessionFactory.currentSession();
>                 roles = session.find("from Role");
>         } catch (HibernateException e) {
>                 e.printStackTrace();
>         }
>         return roles;
> }
> ...
> 
> I get this exception
> 
> javax.faces.FacesException: Collection referenced by UISelectItems with
> binding '#{userForm.roles}' and Component-Path : {Component-Path :
> [Class: javax.faces.component.UIViewRoot,ViewId: /role.jsp][Class:
> org.apache.myfaces.component.html.ext.HtmlSelectOneMenu,Id:
> menu_roles][Class: javax.faces.component.UISelectItems,Id: _id0]} does
> not contain Objects of type SelectItem
> 
> 1)I need translate Hibernate List get from session.find in []SelectItem?
> 
> 2) When I use Hibernate with jsf what it is the better session strategy
> (ex. close, open). In my getRoles method I must close hibernate session?
> 
> Many Thanks in advance.
> 
> regards Lorenzo
> 
>

Re: SelectItem and Hibernate

Posted by Jonathan Eric Miller <je...@uchicago.edu>.
Check this document out. It describes the Open Session in View pattern which 
IMHO works great. I think this is largely what Steve was talking about 
except, what he said about Filter.destroy() being called after every request 
is not correct. It's only called when the filter is taken out of service. 
The session should be closed in the Filter.doFilter() method.

http://hibernate.org/43.html

Jon

----- Original Message ----- 
From: "steve rock" <st...@gmail.com>
To: "MyFaces Discussion" <us...@myfaces.apache.org>; "Bruno Aranda" 
<br...@gmail.com>
Sent: Tuesday, June 28, 2005 7:03 AM
Subject: Re: SelectItem and Hibernate


> What I have done is to create a RequestContextFilter that implements
>
> init(), doFilter(), and destroy() on the javax.servlet.Filter interface.
>
> The destroy() method gets called after every reqeust to my app. Here I
> close the db connections. So I keep the connection open for the whole
> request. This makes it so I don't have to close the connection in any
> other part of my code. We have this running in production and works
> real well.
>
> This is configured as a <filter> in my web-app.xml and the
> <filter-mapping> is also defined.
>
> We tried keeping the connection open for a whole jsp session but this
> didn't work well. We had problems deleting PB because we kept getting
> errors like "Cannot delete, an object with this id already exists in
> this session".
>
> The only "problem" to closing db connections for every request is that
> if you have a persistant bean that you use across several pages and
> several requests is that any fields in your PB that are lazy loaded,
> i.e. object references to other peristant beans, you will get
> LazyInstantiationExcpetion. This is because after the first request
> your PB becomes a detached persistance object. You need to know the
> hibernate lifecycle of persistant beans to understand this. Read
> "Hibernate In Action" or look at the web site documentation.
>
>
> There are 2 ways to solve this.
>
> 1. specify eager fetching in your HQL. Return all the fields you need
> in the first request. Once the object becomes detached from the db in
> the second request, it will not execute any sql to fetch any
> non-loaded fields due to lazy loading.
>
> 2. If you still want to use the lazy loading features and not do an
> eager fetch in the first request, reattach your detached persistant
> bean to the database in the second request. This simply means in you
> code call
>
> session.lock( yourPersistantBean, LockMode.NONE) (there are other lock
> modes). Then you can access the fields that are lazy loaded and not
> throw the exception..
>
> Cheers,
> Steve
>
>
>
>
>
>
>
>
> On 6/28/05, Bruno Aranda <br...@gmail.com> wrote:
>> Hi Lorenzo. Regarding your questions:
>>
>> > 1)I need translate Hibernate List get from session.find in 
>> > []SelectItem?
>>
>> Yes, you have to create a List of SelectItem objects with the objects
>> obtained using the query.
>>
>> > 2) When I use Hibernate with jsf what it is the better session strategy
>> (ex. close, open). In my getRoles method I must close hibernate session?
>> I don't know too much about this, but several approximations have been
>> posted in this list. I hope that anybody with more knowledge than me
>> will help you on that. Currenty, I am using EJB3 and the strategy to
>> data access is different,
>>
>> Regards,
>>
>> Bruno
>>
>> 2005/6/28, Lorenzo Sicilia <ar...@kemen.it>:
>> > Hi to all,
>> >
>> > I do some tests with myfaces and hibernate.
>> > I got some problems about this snippet:
>> >
>> >         <x:selectOneMenu id="menu_roles" >
>> >                 <f:selectItems value="#{userForm.roles}" />
>> >         </x:selectOneMenu>
>> >
>> > my userForm.roles get his data from an Hibernate session.
>> >
>> > ...
>> > public List getRoles() {
>> >         List roles = null;
>> >         System.out.println("userForm.getRoles");
>> >         try {
>> >                 Session session = 
>> > HibernateSessionFactory.currentSession();
>> >                 roles = session.find("from Role");
>> >         } catch (HibernateException e) {
>> >                 e.printStackTrace();
>> >         }
>> >         return roles;
>> > }
>> > ...
>> >
>> > I get this exception
>> >
>> > javax.faces.FacesException: Collection referenced by UISelectItems with
>> > binding '#{userForm.roles}' and Component-Path : {Component-Path :
>> > [Class: javax.faces.component.UIViewRoot,ViewId: /role.jsp][Class:
>> > org.apache.myfaces.component.html.ext.HtmlSelectOneMenu,Id:
>> > menu_roles][Class: javax.faces.component.UISelectItems,Id: _id0]} does
>> > not contain Objects of type SelectItem
>> >
>> > 1)I need translate Hibernate List get from session.find in 
>> > []SelectItem?
>> >
>> > 2) When I use Hibernate with jsf what it is the better session strategy
>> > (ex. close, open). In my getRoles method I must close hibernate 
>> > session?
>> >
>> > Many Thanks in advance.
>> >
>> > regards Lorenzo
>> >
>> >
>>
> 


Re: SelectItem and Hibernate

Posted by Werner Punz <we...@gmx.at>.
Yupp dump it into sourceforge, two days ago I opened a backend dir
with one datamodel already in place (that one uses page prefetching 
instead of servlet/page filter callbacks)
Might be a good place for the others to dump their solutions.
Because the data model, demarakation point, how to bind hibernate 
question pretty much comes up every month.


Werner



Enrique Medina wrote:
> Lorenzo,
> 
> 
>>I will try a similar attempt ...
>>anyway, many thanks for the answer now I have a way ;)
> 
> Would you mind sharing with us your final solution to the problem?
> 
> Thanks.
> 
> 2005/6/29, Lorenzo Sicilia <ar...@kemen.it>:
> 
>>steve rock wrote:
>>
>>>There are 2 ways to solve this.
>>>
>>>1. specify eager fetching in your HQL. Return all the fields you need
>>>in the first request. Once the object becomes detached from the db in
>>>the second request, it will not execute any sql to fetch any
>>>non-loaded fields due to lazy loading.
>>
>>mmmm... if a change occured in my db I can get some problems.
>>
>>
>>>2. If you still want to use the lazy loading features and not do an
>>>eager fetch in the first request, reattach your detached persistant
>>>bean to the database in the second request. This simply means in you
>>>code call
>>>
>>>session.lock( yourPersistantBean, LockMode.NONE) (there are other lock
>>>modes). Then you can access the fields that are lazy loaded and not
>>>throw the exception..
>>
>>I will try a similar attempt ...
>>anyway, many thanks for the answer now I have a way ;)
>>
>>regards Lorenzo
>>
> 
> 


Re: SelectItem and Hibernate

Posted by Enrique Medina <e....@gmail.com>.
Lorenzo,

> I will try a similar attempt ...
> anyway, many thanks for the answer now I have a way ;)
Would you mind sharing with us your final solution to the problem?

Thanks.

2005/6/29, Lorenzo Sicilia <ar...@kemen.it>:
> steve rock wrote:
> > There are 2 ways to solve this.
> >
> > 1. specify eager fetching in your HQL. Return all the fields you need
> > in the first request. Once the object becomes detached from the db in
> > the second request, it will not execute any sql to fetch any
> > non-loaded fields due to lazy loading.
> mmmm... if a change occured in my db I can get some problems.
> 
> > 2. If you still want to use the lazy loading features and not do an
> > eager fetch in the first request, reattach your detached persistant
> > bean to the database in the second request. This simply means in you
> > code call
> >
> > session.lock( yourPersistantBean, LockMode.NONE) (there are other lock
> > modes). Then you can access the fields that are lazy loaded and not
> > throw the exception..
> I will try a similar attempt ...
> anyway, many thanks for the answer now I have a way ;)
> 
> regards Lorenzo
>

Re: SelectItem and Hibernate

Posted by Lorenzo Sicilia <ar...@kemen.it>.
steve rock wrote:
> There are 2 ways to solve this.
> 
> 1. specify eager fetching in your HQL. Return all the fields you need
> in the first request. Once the object becomes detached from the db in
> the second request, it will not execute any sql to fetch any
> non-loaded fields due to lazy loading.
mmmm... if a change occured in my db I can get some problems.

> 2. If you still want to use the lazy loading features and not do an
> eager fetch in the first request, reattach your detached persistant
> bean to the database in the second request. This simply means in you
> code call
> 
> session.lock( yourPersistantBean, LockMode.NONE) (there are other lock
> modes). Then you can access the fields that are lazy loaded and not
> throw the exception..
I will try a similar attempt ...
anyway, many thanks for the answer now I have a way ;)

regards Lorenzo

Re: SelectItem and Hibernate

Posted by Werner Punz <we...@gmx.at>.
steve rock wrote:
 > What I have done is to create a RequestContextFilter that implements
 >
 > init(), doFilter(), and destroy() on the javax.servlet.Filter interface.
 >
 > The destroy() method gets called after every reqeust to my app. Here I
 > close the db connections. So I keep the connection open for the whole
 > request. This makes it so I don't have to close the connection in any
 > other part of my code. We have this running in production and works
 > real well.
 >
 > This is configured as a <filter> in my web-app.xml and the
 > <filter-mapping> is also defined.
 >
 > We tried keeping the connection open for a whole jsp session but this
 > didn't work well. We had problems deleting PB because we kept getting
 > errors like "Cannot delete, an object with this id already exists in
 > this session".
 >
session.clean solves that problem, the best approach however is that
you should not care for session handling yourself, but have that covered
with a proven session handler class.
Spring has something in their framework, Hibernate3 finally has
that on Hibernate level as well.


 > The only "problem" to closing db connections for every request is that
 > if you have a persistant bean that you use across several pages and
 > several requests is that any fields in your PB that are lazy loaded,
 > i.e. object references to other peristant beans, you will get
 > LazyInstantiationExcpetion. This is because after the first request
 > your PB becomes a detached persistance object. You need to know the
 > hibernate lifecycle of persistant beans to understand this. Read
 > "Hibernate In Action" or look at the web site documentation.
 >
The other problem of constant closing is that you might run into 
performance problems because closing a session means basically that you 
constantly close the connections instead of keeping a connection pool
and share/recycle them.
I really can recommend to check out spring for that one, or move to 
Hibernate3 (or backport the class for Hibernate2)

As for the servlet filter approach, this one has a nasty sideffect many 
people stumble upon with a wrong session handling algorithm.
The approach basically is the correct way to do it, but you have to be 
aware of following:

a) You allocate the resources on the servlet init stage
b) you deallocate the resources on the servlet destroy stage

But at a) usually a session is opened
You do your db stuff, your objects stay in the session
at a later stage within the same request you recycle the session without 
noticing and pump in an object from outside
you have a high chance, to get an hibernate error which tells you that
the object already is bound to the session

You also have a high chance if you do a session.clear in between that 
you get unwanted sideeffects at a later stage

There are two ways to work around this if you use request demarkation 
(which is the best way to do)

Either you know your algorithmic flow and you recycle the session and be 
careful about cleans and your objects

Or open new sessions to the main session (which you also can do) if needed.

 >
 > There are 2 ways to solve this.
 >
 > 1. specify eager fetching in your HQL. Return all the fields you need
 > in the first request. Once the object becomes detached from the db in
 > the second request, it will not execute any sql to fetch any
 > non-loaded fields due to lazy loading.
 >
 > 2. If you still want to use the lazy loading features and not do an
 > eager fetch in the first request, reattach your detached persistant
 > bean to the database in the second request. This simply means in you
 > code call
 >
 > session.lock( yourPersistantBean, LockMode.NONE) (there are other lock
 > modes). Then you can access the fields that are lazy loaded and not
 > throw the exception..
 >
session.lock only is suitable for reading, for writing do not lock, 
otherwise
hibernate throws you an error or simply does nothing, despite what the 
doc says (at least hibernate 2).
A session.<fill in your op here> does the trick in this case,
that means session.update on a non bound db object should update
the object into the db correctly.

However if the object is bound by session.lock before it happened to
me in Hibernate2 that the hibernate subsystem basically went through the 
update without an error but did nothing.
Somehow the lock must also lock out an update within the same session on 
the same object (no matter which lockmode you use) and does not throw an 
access error.


For pure write access, do not lock the object use the internal 
versioning system instead for avoiding version/soft update conflicts.

If you work with entire object trees I can recommend to use cascade as 
much as possible, at least for 1:1 1:n relations an automatic update on 
a cascaded tree works very well, for pure m:n relations over binding 
tables which are mapped directly to pure m:n object relations, at least 
hibernate 2 had its share of problems the last time I used that, I had 
to revert to manual updating, which itself over so many objects and some 
session.flushes and clears in between caused conflicts with the 
automatic versioning.


Sorry for becoming that long, but there are details which are neither 
covered by the Hibernate docs nor by other documentation to full detail.
I just wanted to add all this info so that others do not have to fight 
with those kind of things like I had.



Re: SelectItem and Hibernate

Posted by steve rock <st...@gmail.com>.
What I have done is to create a RequestContextFilter that implements

init(), doFilter(), and destroy() on the javax.servlet.Filter interface. 

The destroy() method gets called after every reqeust to my app. Here I
close the db connections. So I keep the connection open for the whole
request. This makes it so I don't have to close the connection in any
other part of my code. We have this running in production and works
real well.

This is configured as a <filter> in my web-app.xml and the
<filter-mapping> is also defined.

We tried keeping the connection open for a whole jsp session but this
didn't work well. We had problems deleting PB because we kept getting
errors like "Cannot delete, an object with this id already exists in
this session".

The only "problem" to closing db connections for every request is that
if you have a persistant bean that you use across several pages and
several requests is that any fields in your PB that are lazy loaded,
i.e. object references to other peristant beans, you will get
LazyInstantiationExcpetion. This is because after the first request
your PB becomes a detached persistance object. You need to know the
hibernate lifecycle of persistant beans to understand this. Read
"Hibernate In Action" or look at the web site documentation.


There are 2 ways to solve this.

1. specify eager fetching in your HQL. Return all the fields you need
in the first request. Once the object becomes detached from the db in
the second request, it will not execute any sql to fetch any
non-loaded fields due to lazy loading.

2. If you still want to use the lazy loading features and not do an
eager fetch in the first request, reattach your detached persistant
bean to the database in the second request. This simply means in you
code call

session.lock( yourPersistantBean, LockMode.NONE) (there are other lock
modes). Then you can access the fields that are lazy loaded and not
throw the exception..

Cheers,
Steve

 






On 6/28/05, Bruno Aranda <br...@gmail.com> wrote:
> Hi Lorenzo. Regarding your questions:
> 
> > 1)I need translate Hibernate List get from session.find in []SelectItem?
> 
> Yes, you have to create a List of SelectItem objects with the objects
> obtained using the query.
> 
> > 2) When I use Hibernate with jsf what it is the better session strategy
> (ex. close, open). In my getRoles method I must close hibernate session?
> I don't know too much about this, but several approximations have been
> posted in this list. I hope that anybody with more knowledge than me
> will help you on that. Currenty, I am using EJB3 and the strategy to
> data access is different,
> 
> Regards,
> 
> Bruno
> 
> 2005/6/28, Lorenzo Sicilia <ar...@kemen.it>:
> > Hi to all,
> >
> > I do some tests with myfaces and hibernate.
> > I got some problems about this snippet:
> >
> >         <x:selectOneMenu id="menu_roles" >
> >                 <f:selectItems value="#{userForm.roles}" />
> >         </x:selectOneMenu>
> >
> > my userForm.roles get his data from an Hibernate session.
> >
> > ...
> > public List getRoles() {
> >         List roles = null;
> >         System.out.println("userForm.getRoles");
> >         try {
> >                 Session session = HibernateSessionFactory.currentSession();
> >                 roles = session.find("from Role");
> >         } catch (HibernateException e) {
> >                 e.printStackTrace();
> >         }
> >         return roles;
> > }
> > ...
> >
> > I get this exception
> >
> > javax.faces.FacesException: Collection referenced by UISelectItems with
> > binding '#{userForm.roles}' and Component-Path : {Component-Path :
> > [Class: javax.faces.component.UIViewRoot,ViewId: /role.jsp][Class:
> > org.apache.myfaces.component.html.ext.HtmlSelectOneMenu,Id:
> > menu_roles][Class: javax.faces.component.UISelectItems,Id: _id0]} does
> > not contain Objects of type SelectItem
> >
> > 1)I need translate Hibernate List get from session.find in []SelectItem?
> >
> > 2) When I use Hibernate with jsf what it is the better session strategy
> > (ex. close, open). In my getRoles method I must close hibernate session?
> >
> > Many Thanks in advance.
> >
> > regards Lorenzo
> >
> >
>