FAQ
Hi,

Maybe this is not the most adequate forum to post this question, but I
know many of you are using MyFaces together with Spring & Hibernate,
so it would be great it you give me some comments.

The problem I have comes with Lazy collections in my objects. Assuming
you know how to use Hibernate & Spring, the problem comes when I try
to paginate my DataTable using the DataScroller, because the
OpenSessionInViewFilter pattern establishes the session Hibernate in
the initial query (the one that shows the first page of the
DataTable). So, when the following page is needed, as MyFaces executes
a new request, the session binded by the OpenSessionInViewFilter for
this new request, is not obviously the same as the session previously
established at the first request.

Finally, I always get a Lazy initialization exception from Hibernate,
as you surely have imagined...

So my question is very simple:

How do you manage objects with lazy collections being shown in
different request with respect to the OpenSessionInViewFilter pattern?

Thanks in advance. I'm looking forward to hearing your comments.

Enrique Medina.

Search Discussions

  • Werner Punz at Jun 20, 2005 at 8:15 am

    Enrique Medina wrote:
    Hi,

    Maybe this is not the most adequate forum to post this question, but I
    know many of you are using MyFaces together with Spring & Hibernate,
    so it would be great it you give me some comments.

    The problem I have comes with Lazy collections in my objects. Assuming
    you know how to use Hibernate & Spring, the problem comes when I try
    to paginate my DataTable using the DataScroller, because the
    OpenSessionInViewFilter pattern establishes the session Hibernate in
    the initial query (the one that shows the first page of the
    DataTable). So, when the following page is needed, as MyFaces executes
    a new request, the session binded by the OpenSessionInViewFilter for
    this new request, is not obviously the same as the session previously
    established at the first request.

    Finally, I always get a Lazy initialization exception from Hibernate,
    as you surely have imagined...

    So my question is very simple:

    How do you manage objects with lazy collections being shown in
    different request with respect to the OpenSessionInViewFilter pattern?
    Simple answer, to a relatively deep question. You cannot. To be more
    precise, there is a huge flaw in the access pattern of the Datamodel,
    which is somewhat fixed in shale (Clanahan, the core maintainer of Shale
    pointed me towards it), and that is the way you can get access
    boundaries in the Datamodel, which is somewhat non existent.

    But back to your problem which has more to do with Hibernate than with
    the half broken Datamodel.
    The easiest way to deal with your problem is relatively simple, avoid
    the lazy loading for the parts you want to display in the data table
    and only use it for the parts you dont want to display, to avoid
    excessive data loading.
    You can do that either by tinkering with the Hibernate config params, or
    by accessing the lazily loaded parts during session time once.
    Depending on your data structures one approach or the other might
    be more efficient.
  • Enrique Medina at Jun 20, 2005 at 8:20 am
    Hi Werner,

    I see. Regarding to your comments about Shale, do you mean that Shale
    will allow me to have a reference to every object that is prsented in
    the DataModel, so for example I will be able to reattach it to the new
    Hibernate session using Hibernate.lock(object, LockMode.NONE)?

    Thanks for your comments.

    2005/6/20, Werner Punz <werpu@gmx.at>:
    Enrique Medina wrote:
    Hi,

    Maybe this is not the most adequate forum to post this question, but I
    know many of you are using MyFaces together with Spring & Hibernate,
    so it would be great it you give me some comments.

    The problem I have comes with Lazy collections in my objects. Assuming
    you know how to use Hibernate & Spring, the problem comes when I try
    to paginate my DataTable using the DataScroller, because the
    OpenSessionInViewFilter pattern establishes the session Hibernate in
    the initial query (the one that shows the first page of the
    DataTable). So, when the following page is needed, as MyFaces executes
    a new request, the session binded by the OpenSessionInViewFilter for
    this new request, is not obviously the same as the session previously
    established at the first request.

    Finally, I always get a Lazy initialization exception from Hibernate,
    as you surely have imagined...

    So my question is very simple:

    How do you manage objects with lazy collections being shown in
    different request with respect to the OpenSessionInViewFilter pattern?
    Simple answer, to a relatively deep question. You cannot. To be more
    precise, there is a huge flaw in the access pattern of the Datamodel,
    which is somewhat fixed in shale (Clanahan, the core maintainer of Shale
    pointed me towards it), and that is the way you can get access
    boundaries in the Datamodel, which is somewhat non existent.

    But back to your problem which has more to do with Hibernate than with
    the half broken Datamodel.
    The easiest way to deal with your problem is relatively simple, avoid
    the lazy loading for the parts you want to display in the data table
    and only use it for the parts you dont want to display, to avoid
    excessive data loading.
    You can do that either by tinkering with the Hibernate config params, or
    by accessing the lazily loaded parts during session time once.
    Depending on your data structures one approach or the other might
    be more efficient.
  • Werner Punz at Jun 20, 2005 at 8:33 am

    Enrique Medina wrote:
    Hi Werner,

    I see. Regarding to your comments about Shale, do you mean that Shale
    will allow me to have a reference to every object that is prsented in
    the DataModel, so for example I will be able to reattach it to the new
    Hibernate session using Hibernate.lock(object, LockMode.NONE)?
    No... from what I could gather from Clanahans comments you will
    finally get clear demarkation boundaries on when you can aquire
    resources before rendering and when you can drop it after the rendering
    is done.
    Shale finally has a mechanism which you can bend towards following states.

    1) I am before rendering aquire the resources you need
    2) Rendering is done release the resources.

    That means you finally know when the rendering starts and can aquire the
    session, and then finally you also know when the rendering is done and
    you can drop the session.
    In your case this helps for the data table that you can open the session
    at the beginning of the rendering stage, you can use lazy loading to
    load the data just needed for the data table, and once the rendering is
    done you can drop the session.

    The current state of affairs is, you have to preload the data and serve
    it row by row (object by object) and thus you cannot keep the session,
    open during rendering, or you have to keep the session open until a
    stage you cannot control anymore. Therefore you automatically if you
    follow the first approach, you run into lazy loading problems, you have
    to resolve manually.

    Here is the original comment of Clanahan on which mechanism you can use
    to resolve the whole issue:

    -----

    Solving these sorts of problems is exactly what the Shale framework
    (part of the Struts project) is designed to address. Current starting
    point for info is on the wiki (i'm working up the docs for the
    website).

    http://wiki.apache.org/struts/StrutsShale

    You'll be interested particularly in the ViewController interface, and
    the fact that it gives you event callbacks at the beginning and end of
    a view (init and destroy) and well as other events dependent upon
    whether you are processing a form submit or not (preprocess and
    prerender). Shale presumes that JSF exists, and leverages its front
    controller framework rather than treating JSF just as a mechanism for
    constructing the view.
  • Enrique Medina at Jun 20, 2005 at 2:11 pm
    Umm, I see.

    But shouldn't it be interesting for this specific problem to just have
    some kind of callback mechanism in the DataModel, so you could 'do
    something' everytime a row is rendered?

    I mean, you could get a reference to the current object in order to
    reattach it to the new session...

    What do you think? Maybe it's as simpler as reimplementing the actual
    DataModel with callback mechanisms...

    2005/6/20, Werner Punz <werpu@gmx.at>:
    Enrique Medina wrote:
    Hi Werner,

    I see. Regarding to your comments about Shale, do you mean that Shale
    will allow me to have a reference to every object that is prsented in
    the DataModel, so for example I will be able to reattach it to the new
    Hibernate session using Hibernate.lock(object, LockMode.NONE)?
    No... from what I could gather from Clanahans comments you will
    finally get clear demarkation boundaries on when you can aquire
    resources before rendering and when you can drop it after the rendering
    is done.
    Shale finally has a mechanism which you can bend towards following states.

    1) I am before rendering aquire the resources you need
    2) Rendering is done release the resources.

    That means you finally know when the rendering starts and can aquire the
    session, and then finally you also know when the rendering is done and
    you can drop the session.
    In your case this helps for the data table that you can open the session
    at the beginning of the rendering stage, you can use lazy loading to
    load the data just needed for the data table, and once the rendering is
    done you can drop the session.

    The current state of affairs is, you have to preload the data and serve
    it row by row (object by object) and thus you cannot keep the session,
    open during rendering, or you have to keep the session open until a
    stage you cannot control anymore. Therefore you automatically if you
    follow the first approach, you run into lazy loading problems, you have
    to resolve manually.

    Here is the original comment of Clanahan on which mechanism you can use
    to resolve the whole issue:

    -----

    Solving these sorts of problems is exactly what the Shale framework
    (part of the Struts project) is designed to address. Current starting
    point for info is on the wiki (i'm working up the docs for the
    website).

    http://wiki.apache.org/struts/StrutsShale

    You'll be interested particularly in the ViewController interface, and
    the fact that it gives you event callbacks at the beginning and end of
    a view (init and destroy) and well as other events dependent upon
    whether you are processing a form submit or not (preprocess and
    prerender). Shale presumes that JSF exists, and leverages its front
    controller framework rather than treating JSF just as a mechanism for
    constructing the view.
  • Werner Punz at Jun 20, 2005 at 3:25 pm

    Enrique Medina wrote:
    Umm, I see.

    But shouldn't it be interesting for this specific problem to just have
    some kind of callback mechanism in the DataModel, so you could 'do
    something' everytime a row is rendered?
    Actually the current datamodel interface has such a method, getRowData
    is called every time a row is rendered and then the row counter is
    increased.
    Sure you theoretically could open a session every time a row is
    rendered and then drop it, that might work for small prototypes, but
    you basically push the performance down the garbage (sorry for the pun)
    if you do that, because in the best case sessions get recycled
    and transactions are opened and closed constantly, in the worst case
    the sessions also are opened and dropped every time you
    have a row fetched.

    I think you get the picture on where the basic flaw in the current
    datamodel mechanism is. The current datamodel mechanism is basically
    only suited to situations where you can keep the connections open (and
    also the transactions if possible), because of the missing callback
    points which notify the model on when it can aquire resources and drop
    them again.
    You might get around that problem to a certain extent by using JTA, but
    I am not too familiar with it.
    (The studio creator uses it to bypass the problem)

    I mean, you could get a reference to the current object in order to
    reattach it to the new session...
    Well you cannot keep the sessions open forever, I am not sure on what
    you want to do, but if you have more than a handful of users, you should
    drop the session after the entire page is rendered, after all you dont
    know what the user is going to do.
    Once you write the object back you have to reattach the object anyway to
    the next opened session, which is responsible for the write back.

    What do you think? Maybe it's as simpler as reimplementing the actual
    DataModel with callback mechanisms...
    Well to my knowledge you cannot avoid having to implement the entire
    datamodel mechanism and then you run into the scope problems, which are
    also connected to your lazy loading problems.

    So you have several options left to get rid of your lazy loading problem.

    Use shale and write your own shaled datamodel with clear callbacks which
    notify the datamodel on when to aquire and drop the session and be done
    with it.

    Use JTA and hope that it works as you need it (which I cannot really
    assure you since I dont know jta really).

    Preload everything you want to display either by tweaking the hibernate
    configuration files or doing a manual load of the parts you want to
    display within the session scope (which is what I did because I did not
    know the shale solution at that time).

    Hope, that somebody solves the problem for you in a convenient way,
    before the next deadline. Which is very unlikely to happen.

    My personal opinion is, that shale might be the best approach for your
    problem in the long term. The manual preloading, messing around with the
    config files, might be to messy and too error prone in the long run.
  • Enrique Medina at Jun 20, 2005 at 4:41 pm
    Hi Werner,

    What I would try to achieve with the callback mechanism would be
    simply to get the reference to the current object, and reattach it to
    the current session. Please take into account that I'm currently using
    the OpenSessionInViewFilter pattern from Spring, so the session would
    be automatically opened and closed in a transparent way.

    So the only hit in performance would be the call to
    Hibernate.lock(object, LockMode.NONE) for each object in each row in
    the DataModel. If there are many of them, maybe it's worth the effort
    instead of having to preload everything into memory, without lazy
    loading it.

    What do you think? I've been looking at ListDataModel implementation
    of the DataModel interface, and it could be easily extended with a
    callback mechanism every time the getRowData is invoked...

    2005/6/20, Werner Punz <werpu@gmx.at>:
    Enrique Medina wrote:
    Umm, I see.

    But shouldn't it be interesting for this specific problem to just have
    some kind of callback mechanism in the DataModel, so you could 'do
    something' everytime a row is rendered?
    Actually the current datamodel interface has such a method, getRowData
    is called every time a row is rendered and then the row counter is
    increased.
    Sure you theoretically could open a session every time a row is
    rendered and then drop it, that might work for small prototypes, but
    you basically push the performance down the garbage (sorry for the pun)
    if you do that, because in the best case sessions get recycled
    and transactions are opened and closed constantly, in the worst case
    the sessions also are opened and dropped every time you
    have a row fetched.

    I think you get the picture on where the basic flaw in the current
    datamodel mechanism is. The current datamodel mechanism is basically
    only suited to situations where you can keep the connections open (and
    also the transactions if possible), because of the missing callback
    points which notify the model on when it can aquire resources and drop
    them again.
    You might get around that problem to a certain extent by using JTA, but
    I am not too familiar with it.
    (The studio creator uses it to bypass the problem)

    I mean, you could get a reference to the current object in order to
    reattach it to the new session...
    Well you cannot keep the sessions open forever, I am not sure on what
    you want to do, but if you have more than a handful of users, you should
    drop the session after the entire page is rendered, after all you dont
    know what the user is going to do.
    Once you write the object back you have to reattach the object anyway to
    the next opened session, which is responsible for the write back.

    What do you think? Maybe it's as simpler as reimplementing the actual
    DataModel with callback mechanisms...
    Well to my knowledge you cannot avoid having to implement the entire
    datamodel mechanism and then you run into the scope problems, which are
    also connected to your lazy loading problems.

    So you have several options left to get rid of your lazy loading problem.

    Use shale and write your own shaled datamodel with clear callbacks which
    notify the datamodel on when to aquire and drop the session and be done
    with it.

    Use JTA and hope that it works as you need it (which I cannot really
    assure you since I dont know jta really).

    Preload everything you want to display either by tweaking the hibernate
    configuration files or doing a manual load of the parts you want to
    display within the session scope (which is what I did because I did not
    know the shale solution at that time).

    Hope, that somebody solves the problem for you in a convenient way,
    before the next deadline. Which is very unlikely to happen.

    My personal opinion is, that shale might be the best approach for your
    problem in the long term. The manual preloading, messing around with the
    config files, might be to messy and too error prone in the long run.
  • Werner Punz at Jun 20, 2005 at 5:43 pm

    Enrique Medina wrote:
    Hi Werner,

    What I would try to achieve with the callback mechanism would be
    simply to get the reference to the current object, and reattach it to
    the current session. Please take into account that I'm currently using
    the OpenSessionInViewFilter pattern from Spring, so the session would
    be automatically opened and closed in a transparent way.
    Ok I am not familiar with that one, I have to look that up
    (I have to admit I use Spring also, but for other stuff)
    if this one works well then you are set, but it seems rather that it
    does not really do the stuff you want to achieve.

    So the only hit in performance would be the call to
    Hibernate.lock(object, LockMode.NONE) for each object in each row in
    the DataModel. If there are many of them, maybe it's worth the effort
    instead of having to preload everything into memory, without lazy
    loading it.
    well as I said I have to read that Spring pattern up, but the datamodel
    is pure read only, so no lock is required.
    I will try to explain the flow from the datatable control to the
    datamodel...
    First the datamodel is initialized, then a request is started for the
    number of rows, then row by row the model is asked to deliver the data
    and the row counter is increased.
    Once the rendering is finished the rows basically are not requested
    anymore but nothing is sent to the datamodel to free the resources
    (shale fixes that).

    Now to your lazy loading, for some strange kind of reason you seem to
    loose the session along the way.
    Since you do pagination, and that is the huge leak I see in my
    understanding of things, since I do not know exactly what the
    OpenSessionInViewFilter does, is that the session probably is not
    reopened or closed to early. (It is probably closed after the first
    loading and never triggered again or closed to early)
    Thus you run into the lazy loading problem.
    There seems to be a problem between the way the datamodel is handled
    internally and the OpensessionInViewFilter is triggered.

    My guess is that the pagination basically has to store some data in the
    session or server and thus, the pagination basically Interferes with the
    OpenSessionInViewFilter.

    What do you think? I've been looking at ListDataModel implementation
    of the DataModel interface, and it could be easily extended with a
    callback mechanism every time the getRowData is invoked...
    exactly that is the way to do it, as I said, the shale datamodel
    approach might be the best to solve your problem, since you have full
    control over the session/transaction scope that way.
    (I have something with a prefetch caching window sort of working-without
    shale, but I am not happy with that, because that one also has the lazy
    loading problem, you describe)
  • Werner Punz at Jun 20, 2005 at 6:10 pm

    Enrique Medina wrote:
    Hi,

    Maybe this is not the most adequate forum to post this question, but I
    know many of you are using MyFaces together with Spring & Hibernate,
    so it would be great it you give me some comments.

    The problem I have comes with Lazy collections in my objects. Assuming
    you know how to use Hibernate & Spring, the problem comes when I try
    to paginate my DataTable using the DataScroller, because the
    OpenSessionInViewFilter pattern establishes the session Hibernate in
    the initial query (the one that shows the first page of the
    DataTable). So, when the following page is needed, as MyFaces executes
    a new request, the session binded by the OpenSessionInViewFilter for
    this new request, is not obviously the same as the session previously
    established at the first request.

    Finally, I always get a Lazy initialization exception from Hibernate,
    as you surely have imagined...
    Ok sorry for the wild guessing in the last mails, I just read up
    the spring docs, and I now have a clearer picture of things. I think I
    can point you towards a definitive solution now.

    The lazy loading and the old objects BINDING approach you follow is
    rather unnecessary if you use a datamodel instead of feeding old objects
    into the session (probably via a collection you have stored somewhere in
    the session scope).
    So my question is very simple:

    How do you manage objects with lazy collections being shown in
    different request with respect to the OpenSessionInViewFilter pattern?

    Thanks in advance. I'm looking forward to hearing your comments.

    Enrique Medina.
    O think I know where your problems is, you try to recycle the old
    objects in a new session which is opened automatically.
    The objects are probably stored in a session scoped collection
    and then fed back into the model after the request (which is caused
    by the paging), theoretically you could use bind to lock them to the new
    session, but that is problematic and not really necessary.

    The best way to solve your problem if you dont want to go the shale
    route (which basically does the same as the Spring class in a safer way)
    is, just to implement a pure datamodel,
    you get the session from spring anyway, and feed the data from the
    methods you have to implement from the model, just as you guessed.

    The call apprach probably will go like that
    Constructor of the model... request the session from spring, which is
    already opened
    The next callbacks are for delivering the number of rows etc...
    then load the object row by row as the outer system requests it from the
    model and you are set...

    For performance increase you probably can
    set an iterator on the give me the number of rows methods
    and then recycle that one for each subsequent, give me the next row
    request. That way it should work.


    Sorry for the guessing from my side in the last mails. I overlooked the
    Spring part.

    Either way, you probably will have to implement a specialized datamodel.
  • Enrique Medina at Jun 20, 2005 at 7:06 pm
    Hi again,

    I finally solved my problem ;-)

    As I told you, I have extended the ListDataModel class to provide it
    with a callback mechanism to be able to reattach any object to the
    current Hibernate session.

    Let me show you the code:

    // Provide the callback within the constructor.
    public LazyListDataModel(List list, DataModelCallback dataModelCallback)
    {
    super(list);

    this.dataModelCallback = dataModelCallback;
    }

    // Overwritten method to call the provided callback method.
    public Object getRowData()
    {
    // Get the object...
    Object object = super.getRowData();

    // ...and call the callback method before returning the object.
    if (this.dataModelCallback != null)
    {
    this.dataModelCallback.execute(object);
    }

    return object ;
    }

    Then, the DataModelCallback is a simple interface:

    public interface DataModelCallback
    {
    public abstract void execute(Object object);
    }

    And finally, I simply use this special lazy implementation of the
    DataModel in my JSF bean:

    this.workingDataModel = new LazyListDataModel(this.searchData(), new
    DataModelCallback()
    {
    public void execute()
    {
    // Call Hibernate's lock stuff...
    }
    }

    It works like a charm :-)

    2005/6/20, Werner Punz <werpu@gmx.at>:
    Enrique Medina wrote:
    Hi,

    Maybe this is not the most adequate forum to post this question, but I
    know many of you are using MyFaces together with Spring & Hibernate,
    so it would be great it you give me some comments.

    The problem I have comes with Lazy collections in my objects. Assuming
    you know how to use Hibernate & Spring, the problem comes when I try
    to paginate my DataTable using the DataScroller, because the
    OpenSessionInViewFilter pattern establishes the session Hibernate in
    the initial query (the one that shows the first page of the
    DataTable). So, when the following page is needed, as MyFaces executes
    a new request, the session binded by the OpenSessionInViewFilter for
    this new request, is not obviously the same as the session previously
    established at the first request.

    Finally, I always get a Lazy initialization exception from Hibernate,
    as you surely have imagined...
    Ok sorry for the wild guessing in the last mails, I just read up
    the spring docs, and I now have a clearer picture of things. I think I
    can point you towards a definitive solution now.

    The lazy loading and the old objects BINDING approach you follow is
    rather unnecessary if you use a datamodel instead of feeding old objects
    into the session (probably via a collection you have stored somewhere in
    the session scope).
    So my question is very simple:

    How do you manage objects with lazy collections being shown in
    different request with respect to the OpenSessionInViewFilter pattern?

    Thanks in advance. I'm looking forward to hearing your comments.

    Enrique Medina.
    O think I know where your problems is, you try to recycle the old
    objects in a new session which is opened automatically.
    The objects are probably stored in a session scoped collection
    and then fed back into the model after the request (which is caused
    by the paging), theoretically you could use bind to lock them to the new
    session, but that is problematic and not really necessary.

    The best way to solve your problem if you dont want to go the shale
    route (which basically does the same as the Spring class in a safer way)
    is, just to implement a pure datamodel,
    you get the session from spring anyway, and feed the data from the
    methods you have to implement from the model, just as you guessed.

    The call apprach probably will go like that
    Constructor of the model... request the session from spring, which is
    already opened
    The next callbacks are for delivering the number of rows etc...
    then load the object row by row as the outer system requests it from the
    model and you are set...

    For performance increase you probably can
    set an iterator on the give me the number of rows methods
    and then recycle that one for each subsequent, give me the next row
    request. That way it should work.

    Sorry for the guessing from my side in the last mails. I overlooked the
    Spring part.

    Either way, you probably will have to implement a specialized datamodel.
  • Werner Punz at Jun 21, 2005 at 7:38 am
    Interesting approach, I would have implemented a full model to do it,
    like I recommended.
    But yours looks much more compact.
    I never thought of applying a delegate to an existing model.

    Just a minor question, do you have callbacks into the setRowIndex method
    as well, because I just wonder if you load the entire collection at once
    or the objects only by demand.

    The reason why I am asking this is, that you might bet a much better
    mem footprint if you apply the rowIndex callbacks as well and use an
    iterator, because to my knowledge only the page data is requested
    normally, not the entire collection, if you enable the datatable paging.


    Werner


    Enrique Medina wrote:
    Hi again,

    I finally solved my problem ;-)

    As I told you, I have extended the ListDataModel class to provide it
    with a callback mechanism to be able to reattach any object to the
    current Hibernate session.

    Let me show you the code:

    // Provide the callback within the constructor.
    public LazyListDataModel(List list, DataModelCallback dataModelCallback)
    {
    super(list);

    this.dataModelCallback = dataModelCallback;
    }

    // Overwritten method to call the provided callback method.
    public Object getRowData()
    {
    // Get the object...
    Object object = super.getRowData();

    // ...and call the callback method before returning the object.
    if (this.dataModelCallback != null)
    {
    this.dataModelCallback.execute(object);
    }

    return object ;
    }

    Then, the DataModelCallback is a simple interface:

    public interface DataModelCallback
    {
    public abstract void execute(Object object);
    }

    And finally, I simply use this special lazy implementation of the
    DataModel in my JSF bean:

    this.workingDataModel = new LazyListDataModel(this.searchData(), new
    DataModelCallback()
    {
    public void execute()
    {
    // Call Hibernate's lock stuff...
    }
    }
  • Enrique Medina at Jun 21, 2005 at 7:49 am
    Hi Werner,

    As we've been discussing, I'm only interested in getting a reference
    to the object being processed by each row in the DataTable, so IMHO
    the perfect point to get it is in the getRowData method.

    Currently, I'm loading the entire collection at once. This is an
    interesting area of discussion about pagination. After some
    investigation and comments from other developers, I ended up by just
    retrieving an exact number of records, e.g. the first 1000, because it
    does makes not make so much sense to implement such a complicated
    DataModel, and it would be as simple as asking the users to refine
    their searching criteria. So I simply use the Criteria API with
    setMaxResults(int max) to limit the number of results.

    2005/6/21, Werner Punz <werpu@gmx.at>:
    Interesting approach, I would have implemented a full model to do it,
    like I recommended.
    But yours looks much more compact.
    I never thought of applying a delegate to an existing model.

    Just a minor question, do you have callbacks into the setRowIndex method
    as well, because I just wonder if you load the entire collection at once
    or the objects only by demand.

    The reason why I am asking this is, that you might bet a much better
    mem footprint if you apply the rowIndex callbacks as well and use an
    iterator, because to my knowledge only the page data is requested
    normally, not the entire collection, if you enable the datatable paging.


    Werner


    Enrique Medina wrote:
    Hi again,

    I finally solved my problem ;-)

    As I told you, I have extended the ListDataModel class to provide it
    with a callback mechanism to be able to reattach any object to the
    current Hibernate session.

    Let me show you the code:

    // Provide the callback within the constructor.
    public LazyListDataModel(List list, DataModelCallback dataModelCallback)
    {
    super(list);

    this.dataModelCallback = dataModelCallback;
    }

    // Overwritten method to call the provided callback method.
    public Object getRowData()
    {
    // Get the object...
    Object object = super.getRowData();

    // ...and call the callback method before returning the object.
    if (this.dataModelCallback != null)
    {
    this.dataModelCallback.execute(object);
    }

    return object ;
    }

    Then, the DataModelCallback is a simple interface:

    public interface DataModelCallback
    {
    public abstract void execute(Object object);
    }

    And finally, I simply use this special lazy implementation of the
    DataModel in my JSF bean:

    this.workingDataModel = new LazyListDataModel(this.searchData(), new
    DataModelCallback()
    {
    public void execute()
    {
    // Call Hibernate's lock stuff...
    }
    }
  • Werner Punz at Jun 22, 2005 at 1:29 am

    Enrique Medina wrote:
    Hi Werner,

    As we've been discussing, I'm only interested in getting a reference
    to the object being processed by each row in the DataTable, so IMHO
    the perfect point to get it is in the getRowData method.

    Currently, I'm loading the entire collection at once. This is an
    interesting area of discussion about pagination. After some
    investigation and comments from other developers, I ended up by just
    retrieving an exact number of records, e.g. the first 1000, because it
    does makes not make so much sense to implement such a complicated
    DataModel, and it would be as simple as asking the users to refine
    their searching criteria. So I simply use the Criteria API with
    set

    Ok thanks for the clarification, btw. thanks for pointing me towards
    that spring interceptor class, this one might solve a huge problem for
    me in the near future (I always shied away of adding shale,
    because I did not want to introduce a framework which is under
    fluctuation into my core codebase)
  • Jonathan Eric Miller at Jun 20, 2005 at 8:56 pm
    I don't know if you already know this and there's a reason why you aren't
    doing it this way or not, but, in HQL, you can use "fetch" to tell it to do
    an immediate load of collections even if the mapping files specify them as
    lazy.

    Jon

    ----- Original Message -----
    From: "Enrique Medina" <e.medina.m@gmail.com>
    To: "MyFaces Discussion" <users@myfaces.apache.org>
    Sent: Saturday, June 18, 2005 1:16 PM
    Subject: DataScroller & Lazy loading collections

    Hi,

    Maybe this is not the most adequate forum to post this question, but I
    know many of you are using MyFaces together with Spring & Hibernate,
    so it would be great it you give me some comments.

    The problem I have comes with Lazy collections in my objects. Assuming
    you know how to use Hibernate & Spring, the problem comes when I try
    to paginate my DataTable using the DataScroller, because the
    OpenSessionInViewFilter pattern establishes the session Hibernate in
    the initial query (the one that shows the first page of the
    DataTable). So, when the following page is needed, as MyFaces executes
    a new request, the session binded by the OpenSessionInViewFilter for
    this new request, is not obviously the same as the session previously
    established at the first request.

    Finally, I always get a Lazy initialization exception from Hibernate,
    as you surely have imagined...

    So my question is very simple:

    How do you manage objects with lazy collections being shown in
    different request with respect to the OpenSessionInViewFilter pattern?

    Thanks in advance. I'm looking forward to hearing your comments.

    Enrique Medina.
  • Enrique Medina at Jun 20, 2005 at 9:09 pm
    Hi Jonathan,

    Yes, I know that issue, but it does not fit into my scenario because:

    a) I really want to do lazy loading
    b) I'm currently using the Criteria API, as I have a dynamic set of
    criterion in my form, where the user can enter either all the criteria
    or just something or even none, so the SQL must be dynamically
    created. The Criteria by Example is perfect for this, while using HQL
    would lead to annoying if...then... clauses

    So in resume, I could have made the lazy collections to be prefecthed
    also using the Criteria API, but that's not the behaviour I was
    requiring ;-)

    2005/6/20, Jonathan Eric Miller <jemiller@uchicago.edu>:
    I don't know if you already know this and there's a reason why you aren't
    doing it this way or not, but, in HQL, you can use "fetch" to tell it to do
    an immediate load of collections even if the mapping files specify them as
    lazy.

    Jon

    ----- Original Message -----
    From: "Enrique Medina" <e.medina.m@gmail.com>
    To: "MyFaces Discussion" <users@myfaces.apache.org>
    Sent: Saturday, June 18, 2005 1:16 PM
    Subject: DataScroller & Lazy loading collections
    Hi,

    Maybe this is not the most adequate forum to post this question, but I
    know many of you are using MyFaces together with Spring & Hibernate,
    so it would be great it you give me some comments.

    The problem I have comes with Lazy collections in my objects. Assuming
    you know how to use Hibernate & Spring, the problem comes when I try
    to paginate my DataTable using the DataScroller, because the
    OpenSessionInViewFilter pattern establishes the session Hibernate in
    the initial query (the one that shows the first page of the
    DataTable). So, when the following page is needed, as MyFaces executes
    a new request, the session binded by the OpenSessionInViewFilter for
    this new request, is not obviously the same as the session previously
    established at the first request.

    Finally, I always get a Lazy initialization exception from Hibernate,
    as you surely have imagined...

    So my question is very simple:

    How do you manage objects with lazy collections being shown in
    different request with respect to the OpenSessionInViewFilter pattern?

    Thanks in advance. I'm looking forward to hearing your comments.

    Enrique Medina.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupusers @
categoriesmyfaces
postedJun 18, '05 at 6:17p
activeJun 22, '05 at 1:29a
posts15
users3
websitemyfaces.apache.org

People

Translate

site design / logo © 2019 Grokbase