Hibernate domain objects - how to load before parameter application

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Hibernate domain objects - how to load before parameter application

Javier Molina
Hello all,

this is my first Tapestry application. I have used Hibernate before in a
standalone (GUI) application. I will try to explain the situation as
clearly as possible, so this message might get a bit long.

I have been looking at Tapestry and find it great that it works in an
object oriented fashion rather than worrying about urls, parameters,
etc. I have used <property-declaration> and ognl bindings in forms, so
far so good.

I have not found an easy way to have Tapestry update hibernate domain
objects. I can load the object, let's say, a NewsItem, use
setNewsItem(item) and display it in a form for editing. I want the edit
page to be stateless because it's easy to find users opening several
edit windows at the same time, so it must be self contained. To this
effect, I'm encoding the primary key in a Hidden field.

Here comes the problem: the only way I have found that will work is to
have <property-declaration>s for each field in the form, load the object
from the database in the submit listener and copy the properties from
the page to the domain object. I would rather have the ognl bindings
point directly to the object instead of having to do some mechanical
coding like domainObject.setWhatever(getWhatever()); but for this to
work, I'd have to be able to load the object before rewinding, so the
bindings could be applied.

I am experimenting with a custom DataSqueezer which encodes the class
and primary key of the object so I can pass it around. However, if I
wanted to load the object from the database in unsqueeze, I'd need
access to the hibernate session, which could mean opening the session at
the beginning of unsqueeze and closing it at the end, which would not be
acceptable. I'd like to open the session before the processing of the
form starts and close it when it's done so all the work could be done in
one session.

Am I missing something obvious? the mechanical
domainObject.setWhatever(getWhatever()); seems to go against the spirit
of Tapestry. How could I work as explained above?

Thanks in advance.


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: Hibernate domain objects - how to load before parameter application

Patrick Casey

        Encode the primary key in a hidden field at the *top* of your form.

        Write an explicit setKey() function in your page class. In that
setKey() class load your object e.g.

        Public void setKey(String key) {

        fObject = HibHelper.getSession().get(MyClass.class, key);
        }

        If you want to take explicit control of when persistence happens
e.g. you want to validate it and have it happen during an edit listener
instead of whenever hibernate decides to flush the session, you'll also want
to evict the object e.g.

        Public void setKey(String key) {

        fObject = HibHelper.getSession().get(MyClass.class, key);
        HibHelper.getSession.evict(fObject);
        }
       

> -----Original Message-----
> From: news [mailto:[hidden email]] On Behalf Of Javier Molina
> Sent: Tuesday, May 17, 2005 8:27 AM
> To: [hidden email]
> Subject: Hibernate domain objects - how to load before parameter
> application
>
> Hello all,
>
> this is my first Tapestry application. I have used Hibernate before in a
> standalone (GUI) application. I will try to explain the situation as
> clearly as possible, so this message might get a bit long.
>
> I have been looking at Tapestry and find it great that it works in an
> object oriented fashion rather than worrying about urls, parameters,
> etc. I have used <property-declaration> and ognl bindings in forms, so
> far so good.
>
> I have not found an easy way to have Tapestry update hibernate domain
> objects. I can load the object, let's say, a NewsItem, use
> setNewsItem(item) and display it in a form for editing. I want the edit
> page to be stateless because it's easy to find users opening several
> edit windows at the same time, so it must be self contained. To this
> effect, I'm encoding the primary key in a Hidden field.
>
> Here comes the problem: the only way I have found that will work is to
> have <property-declaration>s for each field in the form, load the object
> from the database in the submit listener and copy the properties from
> the page to the domain object. I would rather have the ognl bindings
> point directly to the object instead of having to do some mechanical
> coding like domainObject.setWhatever(getWhatever()); but for this to
> work, I'd have to be able to load the object before rewinding, so the
> bindings could be applied.
>
> I am experimenting with a custom DataSqueezer which encodes the class
> and primary key of the object so I can pass it around. However, if I
> wanted to load the object from the database in unsqueeze, I'd need
> access to the hibernate session, which could mean opening the session at
> the beginning of unsqueeze and closing it at the end, which would not be
> acceptable. I'd like to open the session before the processing of the
> form starts and close it when it's done so all the work could be done in
> one session.
>
> Am I missing something obvious? the mechanical
> domainObject.setWhatever(getWhatever()); seems to go against the spirit
> of Tapestry. How could I work as explained above?
>
> Thanks in advance.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Hibernate domain objects - how to load before parameter application

Pablo Ruggia
In reply to this post by Javier Molina
I think you can set the user property in your pageBeginRender()
method, implementing PageRenderListener interface. It will be called
both before the page starts rendering and rewinding.

On 5/17/05, Javier Molina <[hidden email]> wrote:

> Hello all,
>
> this is my first Tapestry application. I have used Hibernate before in a
> standalone (GUI) application. I will try to explain the situation as
> clearly as possible, so this message might get a bit long.
>
> I have been looking at Tapestry and find it great that it works in an
> object oriented fashion rather than worrying about urls, parameters,
> etc. I have used <property-declaration> and ognl bindings in forms, so
> far so good.
>
> I have not found an easy way to have Tapestry update hibernate domain
> objects. I can load the object, let's say, a NewsItem, use
> setNewsItem(item) and display it in a form for editing. I want the edit
> page to be stateless because it's easy to find users opening several
> edit windows at the same time, so it must be self contained. To this
> effect, I'm encoding the primary key in a Hidden field.
>
> Here comes the problem: the only way I have found that will work is to
> have <property-declaration>s for each field in the form, load the object
> from the database in the submit listener and copy the properties from
> the page to the domain object. I would rather have the ognl bindings
> point directly to the object instead of having to do some mechanical
> coding like domainObject.setWhatever(getWhatever()); but for this to
> work, I'd have to be able to load the object before rewinding, so the
> bindings could be applied.
>
> I am experimenting with a custom DataSqueezer which encodes the class
> and primary key of the object so I can pass it around. However, if I
> wanted to load the object from the database in unsqueeze, I'd need
> access to the hibernate session, which could mean opening the session at
> the beginning of unsqueeze and closing it at the end, which would not be
> acceptable. I'd like to open the session before the processing of the
> form starts and close it when it's done so all the work could be done in
> one session.
>
> Am I missing something obvious? the mechanical
> domainObject.setWhatever(getWhatever()); seems to go against the spirit
> of Tapestry. How could I work as explained above?
>
> Thanks in advance.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: Hibernate domain objects - how to load before parameter application

Geoffc
In reply to this post by Javier Molina
Hi,

I hope I have understood your question.  You can have page properties that are
beans and edit the property directly (validation can require another property).
The only possibly tricky bit is checking where you are at in the editing process
which I take care of in the pageBeginRender.

I have a page that is called EditPlace.  It may be editing a new or existing
place. Place and placeAddress are beans with a 1..0 between them.  There is a
little hidden logic in that Place and PlaceAddress are edited on separate tabs
and we don't let them add a PlaceAddress until there is a Place (hence the
conditional on the hidden field getPlaceId() only). I'll include just the
snippets that sound relevant to me, let me know if you want all the code.

As an aside we're using Hibernate + Spring + Tapestry which is working really
well and gives a very natural divide point for working with the other developer.
Spring was very fast to get up to speed with.

Cheers,
Geoff

// From EditPlace.page

<property-specification name="place" type="nz.org.geonet.delta.domain.Place"/>
<property-specification name="placeAddress"
type="nz.org.geonet.delta.domain.PlaceAddress"/>
...

// From EditPlace.java
....
  public void pageBeginRender(
                        PageEvent event
                        )
  {
    if (getPlace() == null) {
      Place place = new Place();
      PlaceAddress placeAddress = new PlaceAddress();
      setPlace(place);
      setPlaceAddress(placeAddress);
    }

    if (getPlaceId() != null) {
      loadPlace();
    }
  }

 private void loadPlace()
  {
    Long placeId = getPlaceId();
    placeUtil = getPlaceUtil();
    Place place = placeUtil.findPlaceById(placeId);
    setPlace(place);

    // At any point we could be editing a new PlaceAddress for an
    // existing Place, dealing with validation errors, or editing an
    // existing PlaceAddress.
    PlaceAddress placeAddress = getPlaceAddress();

    if (place.getPlaceAddress() == null && placeAddress == null) {
      placeAddress = new PlaceAddress();
    } else if (place.getPlaceAddress() != null) {
      placeAddress = place.getPlaceAddress();
    }

    setPlaceAddress(placeAddress);

    // Load the Set of maps and convert it to a List.
    List maps = new ArrayList();
    Set currMaps = place.getNzms260Sheets();
    for (Iterator iter = currMaps.iterator(); iter.hasNext() ; ) {
      Nzms260Sheet sheet = (Nzms260Sheet) iter.next();
      maps.add(sheet);
    }
    setSelectedNzms260Sheets(maps);
  }

  // Persists to DB
  public void addPlace(IRequestCycle cycle) {
    IValidationDelegate delegate = getValidationDelegate();

    if (delegate.getHasErrors()) {
      return;
    }

    Place place = getPlace();

      // Check that the notes field is not >500 in length
    if (place.getNotes().length() > 500) {

            setErrorField("inputTextArea", getMessage("textarea-length"));
            return;
      }

    placeUtil = getPlaceUtil();
    placeUtil.storePlace(place);

    setPlaceId(place.getPlaceId());
    cycle.activate(this);

    return;
  }

...

// From EditPlace.html
...
<input type="text" jwcid="@TextField" value="ognl:placeAddress.addressLine3"
size="50" maxlength="50" />

...



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]