You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Arnaud Garcia <ar...@imagemed-87.com> on 2010/04/24 10:25:11 UTC

Wicket Cayenne

Hello,

I put my question in both forum, (wicket and this one)

Does anyone knows how to set up Cayenne for wicket ?

In my WicketPage I have :
 private DataContext ctxt = (DataContext)
DataContext.getThreadObjectContext();

but, I don't think it is the good way, since I suppose wicket will
serialized the full DataContext... (maybe I can put the
getThreadObjectContext() in a method or constructor to avoid the
serialization...)
-> Well, I don't know how what is the good way  ;-)



thanks,

Arnaud

Re: Wicket Cayenne

Posted by Nishant Neeraj <ni...@gmail.com>.
Well, I am also very new to both Wicket as well as Cayenne... but I guess
got lucky. Lets expect people are reading this over weekend. Find my in-line
responses below

> then you can remove the Cayenne Filter from your web.xml

Yes.

> Do you have an idea why the DataContext is bind to the current thread and
not to the user session ?

I am not sure that I am correct here but I think if you wish to bind
DataContext to current thread, you should create and bind for DataContext
every request. You can try putting

BaseContext.bindThreadObjectContext(DataContext.createDataContext())

in your extended request cycle under
         MyRequestCycle.onBeginRequest(){
              ........
              ........
          }

And then in your application, you may try
        DataContext context = DataContext.getThreadDataContext();


What I think it should do is, it creates a dataContext at each request binds
it to current request thread.... and I think the same is done in Cayenne's
WebApplicationContextFilter that binds the DataContext on each request and
unbinds when request ends.

I *haven't* tested this approach, not sure if it works. Let me know if you
try.

> Wicket users are abstracted from HTTPSession

I mean no bad. :)
I am from Struts-1 world where you do operations (directly) on
request.getSession(). In Wicket, afaik, it's not the best practice to access
HTTPSession, rather you are given WebSession which is very smart.

So, to use the suggested approach for web-apps using Cayenne [1]
HttpSession session;
DataContext context = ServletUtil.getSessionContext(session);

You need to pass session doing something like this
session = ((webrequest)getrequest()).gethttpservletrequest().getsession();

Hopefully this helps.

[1]
http://74.125.153.132/search?q=cache:HFEZ2Rs496UJ:cayenne.apache.org/doc20/obtaining-datacontext.html+http://cayenne.apache.org/doc30/obtaining-datacontext.html&cd=1&hl=en&ct=clnk&gl=in&client=firefox-a

- Nishant

On Sun, Apr 25, 2010 at 12:12 AM, Arnaud Garcia <ar...@imagemed-87.com>wrote:

> I did some tests, maybe it can interest you...,
> (these are some reflexions on my pretty bad  understanding of Cayenne, so I
> apolosize if it is wrong, it is my first cayenne/wicket project)
>
> If technically it seems ok to put the DataContext in the user session and
> retrieve it, as a normal java object,   then you can remove the Cayenne
> Filter from your web.xml, because you don't need it anymore, since you are
> in charge of the DataContext creation.
>
> I try it and :
>
> WicketMessage: Can't instantiate page using constructor public
> org.....HomePage()
>
> Root cause:
>
> java.lang.IllegalStateException: Current thread has no bound ObjectContext.
> If you look at the Cayenne Filter, it creates a DataContext and the bind it
> to the current Thread.
> So, using the same idea, you to rewrite your function like this:
> public DataContext getSessionDataContext(){
>       synchronized(this){
>           if(this.dataContext==null){
>
> BaseContext.bindThreadObjectContext(DataContext.createDataContext())
>               this.dataContext =   dataContext = (DataContext)
> DataContext.getThreadObjectContext();
>
>           }
>       }
>       return this.dataContext;
>   }
>
> So  I think, the Cayenne DataContext has to be related to the current
> thread
> and not to the user session.
>
> Do you have an idea why the DataContext is bind to the current thread and
> not to the user session ?
>
>
> 2/ About Wicket, what do you mean by " Wicket users are abstracted from
> HTTPSession" ?
>
>
> Arnaud
>
>
>
> 2010/4/24 Nishant Neeraj <ni...@gmail.com>
>
> > weirdly, while implementing I had the same doubt. Seeing into the doc
> > here[1] or better here[2], I realized that the idea suggested for
> web-apps
> > does not fit for Wicket because Wicket users are abstracted from
> > HTTPSession.
> >
> > Looking into  the code on how the servlet does this thing, in the method
> > org.apache.cayenne.conf.ServletUtil.getSessionContext(..) -- this is what
> > being done. see code snippet below. So, I did not evaluate much on gain
> in
> > using getThreadObjectContext() vs CreateDataContext() -- since the
> > Cayenne's
> > native implementation does that way therefore I followed.
> >
> > On thinking about this now, I think createDataContext() must not be a
> loss
> > in performance, because what we are doing, basically, is creating context
> > at
> > session start and holding the instance of DataContext all the time until
> > session expires -- so it should be, I hope, at least same as using
> > getThreadObjectContext().
> >
> > But I would like to know if there is a flaw in my thinking.
> >
> >
> > [CODE]
> >   /**
> >     * Returns default Cayenne DataContext associated with the
> HttpSession,
> > creating it on
> >     * the fly and storing in the session if needed.
> >     */
> >    public static DataContext getSessionContext(HttpSession session) {
> >        synchronized (session) {
> >            DataContext ctxt = (DataContext)
> > session.getAttribute(DATA_CONTEXT_KEY);
> >
> >            if (ctxt == null) {
> >                ctxt = DataContext.createDataContext();
> >                session.setAttribute(ServletUtil.DATA_CONTEXT_KEY, ctxt);
> >            }
> >
> >            return ctxt;
> >        }
> >    }
> >
> > [/CODE]
> >
> >
> > [1] http://cayenne.apache.org/doc30/obtaining-datacontext.htmlsomething's
> > wrong, all the code snippets are gone!
> > [2]
> >
> >
> http://74.125.153.132/search?q=cache:HFEZ2Rs496UJ:cayenne.apache.org/doc20/obtaining-datacontext.html+http://cayenne.apache.org/doc30/obtaining-datacontext.html&cd=1&hl=en&ct=clnk&gl=in&client=firefox-a
> >
> >
> > - Nishant
> >
> > On Sat, Apr 24, 2010 at 6:06 PM, Arnaud Garcia <arnaud@imagemed-87.com
> > >wrote:
> >
> > > ... OK, putting the dataContext in the session object is certainly a
> good
> > > idea, but for the creation of the DataContext do you think we have to
> use
> > > the createDataContext() or using the
> DataContext.getThreadObjectContext()
> > > since it is supposed to be attached to the current thread by the
> cayenne
> > > filter ...
> > >
> > > Arnaud
> > >
> > > 2010/4/24 Nishant Neeraj <ni...@gmail.com>
> > >
> > > > Hi Arnaud,
> > > >
> > > > I have used session to store my dataContext
> > > >
> > > > something like this
> > > >
> > > > public DataContext getSessionDataContext(){
> > > >        synchronized(this){
> > > >            if(this.dataContext==null){
> > > >                this.dataContext = DataContext.createDataContext();
> > > >            }
> > > >        }
> > > >        return this.dataContext;
> > > >    }
> > > >
> > > >
> > > > anywhere I need this, I perform this
> > > >
> > > > DataContext dctx =
> > ((MyAppSession)getSession()).getSessionDataContext();
> > > >
> > > > I think it may not solve the serialization issue, if session objects
> > are
> > > > serialized. But you avoid creating DataContext at every page.
> > > >
> > > > Not sure if this helps you.
> > > >
> > > > You may want to see how DataBinder[1] has implemented it.
> > > >
> > > > [1] http://databinder.net/wicket/show/overview/
> > > >
> > > > - Nishant
> > > >
> > > > On Sat, Apr 24, 2010 at 1:55 PM, Arnaud Garcia <
> arnaud@imagemed-87.com
> > > > >wrote:
> > > >
> > > > > Hello,
> > > > >
> > > > > I put my question in both forum, (wicket and this one)
> > > > >
> > > > > Does anyone knows how to set up Cayenne for wicket ?
> > > > >
> > > > > In my WicketPage I have :
> > > > >  private DataContext ctxt = (DataContext)
> > > > > DataContext.getThreadObjectContext();
> > > > >
> > > > > but, I don't think it is the good way, since I suppose wicket will
> > > > > serialized the full DataContext... (maybe I can put the
> > > > > getThreadObjectContext() in a method or constructor to avoid the
> > > > > serialization...)
> > > > > -> Well, I don't know how what is the good way  ;-)
> > > > >
> > > > >
> > > > >
> > > > > thanks,
> > > > >
> > > > > Arnaud
> > > > >
> > > >
> > >
> >
>

Re: Wicket Cayenne

Posted by Joe Baldwin <jf...@earthlink.net>.
Arnaud

> So  I think, the Cayenne DataContext has to be related to the current thread
> and not to the user session.
> 
> Do you have an idea why the DataContext is bind to the current thread and
> not to the user session ?

I did some testing on this some time ago and with the standard tomcat filter the behavior is fairly intuitive.  If I use the BaseContext.bindThreadObjectContext() method, then the Cayenne filter creates and returns a DataContext for each user session.  If the session goes out of scope or times-out, the it appears the DataContext does as well (because I get a new DataContext at that point).  This seems like reasonable behavior for most implementations.

I suppose you could configure so that you get a new DataContext for each new request (but that may not be the most optimum design).

Joe




Re: Wicket Cayenne

Posted by Arnaud Garcia <ar...@imagemed-87.com>.
I did some tests, maybe it can interest you...,
(these are some reflexions on my pretty bad  understanding of Cayenne, so I
apolosize if it is wrong, it is my first cayenne/wicket project)

If technically it seems ok to put the DataContext in the user session and
retrieve it, as a normal java object,   then you can remove the Cayenne
Filter from your web.xml, because you don't need it anymore, since you are
in charge of the DataContext creation.

I try it and :

WicketMessage: Can't instantiate page using constructor public
org.....HomePage()

Root cause:

java.lang.IllegalStateException: Current thread has no bound ObjectContext.
If you look at the Cayenne Filter, it creates a DataContext and the bind it
to the current Thread.
So, using the same idea, you to rewrite your function like this:
public DataContext getSessionDataContext(){
       synchronized(this){
           if(this.dataContext==null){

BaseContext.bindThreadObjectContext(DataContext.createDataContext())
               this.dataContext =   dataContext = (DataContext)
DataContext.getThreadObjectContext();

           }
       }
       return this.dataContext;
   }

So  I think, the Cayenne DataContext has to be related to the current thread
and not to the user session.

Do you have an idea why the DataContext is bind to the current thread and
not to the user session ?


2/ About Wicket, what do you mean by " Wicket users are abstracted from
HTTPSession" ?


Arnaud



2010/4/24 Nishant Neeraj <ni...@gmail.com>

> weirdly, while implementing I had the same doubt. Seeing into the doc
> here[1] or better here[2], I realized that the idea suggested for web-apps
> does not fit for Wicket because Wicket users are abstracted from
> HTTPSession.
>
> Looking into  the code on how the servlet does this thing, in the method
> org.apache.cayenne.conf.ServletUtil.getSessionContext(..) -- this is what
> being done. see code snippet below. So, I did not evaluate much on gain in
> using getThreadObjectContext() vs CreateDataContext() -- since the
> Cayenne's
> native implementation does that way therefore I followed.
>
> On thinking about this now, I think createDataContext() must not be a loss
> in performance, because what we are doing, basically, is creating context
> at
> session start and holding the instance of DataContext all the time until
> session expires -- so it should be, I hope, at least same as using
> getThreadObjectContext().
>
> But I would like to know if there is a flaw in my thinking.
>
>
> [CODE]
>   /**
>     * Returns default Cayenne DataContext associated with the HttpSession,
> creating it on
>     * the fly and storing in the session if needed.
>     */
>    public static DataContext getSessionContext(HttpSession session) {
>        synchronized (session) {
>            DataContext ctxt = (DataContext)
> session.getAttribute(DATA_CONTEXT_KEY);
>
>            if (ctxt == null) {
>                ctxt = DataContext.createDataContext();
>                session.setAttribute(ServletUtil.DATA_CONTEXT_KEY, ctxt);
>            }
>
>            return ctxt;
>        }
>    }
>
> [/CODE]
>
>
> [1] http://cayenne.apache.org/doc30/obtaining-datacontext.html something's
> wrong, all the code snippets are gone!
> [2]
>
> http://74.125.153.132/search?q=cache:HFEZ2Rs496UJ:cayenne.apache.org/doc20/obtaining-datacontext.html+http://cayenne.apache.org/doc30/obtaining-datacontext.html&cd=1&hl=en&ct=clnk&gl=in&client=firefox-a
>
>
> - Nishant
>
> On Sat, Apr 24, 2010 at 6:06 PM, Arnaud Garcia <arnaud@imagemed-87.com
> >wrote:
>
> > ... OK, putting the dataContext in the session object is certainly a good
> > idea, but for the creation of the DataContext do you think we have to use
> > the createDataContext() or using the DataContext.getThreadObjectContext()
> > since it is supposed to be attached to the current thread by the cayenne
> > filter ...
> >
> > Arnaud
> >
> > 2010/4/24 Nishant Neeraj <ni...@gmail.com>
> >
> > > Hi Arnaud,
> > >
> > > I have used session to store my dataContext
> > >
> > > something like this
> > >
> > > public DataContext getSessionDataContext(){
> > >        synchronized(this){
> > >            if(this.dataContext==null){
> > >                this.dataContext = DataContext.createDataContext();
> > >            }
> > >        }
> > >        return this.dataContext;
> > >    }
> > >
> > >
> > > anywhere I need this, I perform this
> > >
> > > DataContext dctx =
> ((MyAppSession)getSession()).getSessionDataContext();
> > >
> > > I think it may not solve the serialization issue, if session objects
> are
> > > serialized. But you avoid creating DataContext at every page.
> > >
> > > Not sure if this helps you.
> > >
> > > You may want to see how DataBinder[1] has implemented it.
> > >
> > > [1] http://databinder.net/wicket/show/overview/
> > >
> > > - Nishant
> > >
> > > On Sat, Apr 24, 2010 at 1:55 PM, Arnaud Garcia <arnaud@imagemed-87.com
> > > >wrote:
> > >
> > > > Hello,
> > > >
> > > > I put my question in both forum, (wicket and this one)
> > > >
> > > > Does anyone knows how to set up Cayenne for wicket ?
> > > >
> > > > In my WicketPage I have :
> > > >  private DataContext ctxt = (DataContext)
> > > > DataContext.getThreadObjectContext();
> > > >
> > > > but, I don't think it is the good way, since I suppose wicket will
> > > > serialized the full DataContext... (maybe I can put the
> > > > getThreadObjectContext() in a method or constructor to avoid the
> > > > serialization...)
> > > > -> Well, I don't know how what is the good way  ;-)
> > > >
> > > >
> > > >
> > > > thanks,
> > > >
> > > > Arnaud
> > > >
> > >
> >
>

Re: Wicket Cayenne

Posted by Nishant Neeraj <ni...@gmail.com>.
weirdly, while implementing I had the same doubt. Seeing into the doc
here[1] or better here[2], I realized that the idea suggested for web-apps
does not fit for Wicket because Wicket users are abstracted from
HTTPSession.

Looking into  the code on how the servlet does this thing, in the method
org.apache.cayenne.conf.ServletUtil.getSessionContext(..) -- this is what
being done. see code snippet below. So, I did not evaluate much on gain in
using getThreadObjectContext() vs CreateDataContext() -- since the Cayenne's
native implementation does that way therefore I followed.

On thinking about this now, I think createDataContext() must not be a loss
in performance, because what we are doing, basically, is creating context at
session start and holding the instance of DataContext all the time until
session expires -- so it should be, I hope, at least same as using
getThreadObjectContext().

But I would like to know if there is a flaw in my thinking.


[CODE]
   /**
     * Returns default Cayenne DataContext associated with the HttpSession,
creating it on
     * the fly and storing in the session if needed.
     */
    public static DataContext getSessionContext(HttpSession session) {
        synchronized (session) {
            DataContext ctxt = (DataContext)
session.getAttribute(DATA_CONTEXT_KEY);

            if (ctxt == null) {
                ctxt = DataContext.createDataContext();
                session.setAttribute(ServletUtil.DATA_CONTEXT_KEY, ctxt);
            }

            return ctxt;
        }
    }

[/CODE]


[1] http://cayenne.apache.org/doc30/obtaining-datacontext.html  something's
wrong, all the code snippets are gone!
[2]
http://74.125.153.132/search?q=cache:HFEZ2Rs496UJ:cayenne.apache.org/doc20/obtaining-datacontext.html+http://cayenne.apache.org/doc30/obtaining-datacontext.html&cd=1&hl=en&ct=clnk&gl=in&client=firefox-a


- Nishant

On Sat, Apr 24, 2010 at 6:06 PM, Arnaud Garcia <ar...@imagemed-87.com>wrote:

> ... OK, putting the dataContext in the session object is certainly a good
> idea, but for the creation of the DataContext do you think we have to use
> the createDataContext() or using the DataContext.getThreadObjectContext()
> since it is supposed to be attached to the current thread by the cayenne
> filter ...
>
> Arnaud
>
> 2010/4/24 Nishant Neeraj <ni...@gmail.com>
>
> > Hi Arnaud,
> >
> > I have used session to store my dataContext
> >
> > something like this
> >
> > public DataContext getSessionDataContext(){
> >        synchronized(this){
> >            if(this.dataContext==null){
> >                this.dataContext = DataContext.createDataContext();
> >            }
> >        }
> >        return this.dataContext;
> >    }
> >
> >
> > anywhere I need this, I perform this
> >
> > DataContext dctx = ((MyAppSession)getSession()).getSessionDataContext();
> >
> > I think it may not solve the serialization issue, if session objects are
> > serialized. But you avoid creating DataContext at every page.
> >
> > Not sure if this helps you.
> >
> > You may want to see how DataBinder[1] has implemented it.
> >
> > [1] http://databinder.net/wicket/show/overview/
> >
> > - Nishant
> >
> > On Sat, Apr 24, 2010 at 1:55 PM, Arnaud Garcia <arnaud@imagemed-87.com
> > >wrote:
> >
> > > Hello,
> > >
> > > I put my question in both forum, (wicket and this one)
> > >
> > > Does anyone knows how to set up Cayenne for wicket ?
> > >
> > > In my WicketPage I have :
> > >  private DataContext ctxt = (DataContext)
> > > DataContext.getThreadObjectContext();
> > >
> > > but, I don't think it is the good way, since I suppose wicket will
> > > serialized the full DataContext... (maybe I can put the
> > > getThreadObjectContext() in a method or constructor to avoid the
> > > serialization...)
> > > -> Well, I don't know how what is the good way  ;-)
> > >
> > >
> > >
> > > thanks,
> > >
> > > Arnaud
> > >
> >
>

Re: Wicket Cayenne

Posted by Arnaud Garcia <ar...@imagemed-87.com>.
... OK, putting the dataContext in the session object is certainly a good
idea, but for the creation of the DataContext do you think we have to use
the createDataContext() or using the DataContext.getThreadObjectContext()
since it is supposed to be attached to the current thread by the cayenne
filter ...

Arnaud

2010/4/24 Nishant Neeraj <ni...@gmail.com>

> Hi Arnaud,
>
> I have used session to store my dataContext
>
> something like this
>
> public DataContext getSessionDataContext(){
>        synchronized(this){
>            if(this.dataContext==null){
>                this.dataContext = DataContext.createDataContext();
>            }
>        }
>        return this.dataContext;
>    }
>
>
> anywhere I need this, I perform this
>
> DataContext dctx = ((MyAppSession)getSession()).getSessionDataContext();
>
> I think it may not solve the serialization issue, if session objects are
> serialized. But you avoid creating DataContext at every page.
>
> Not sure if this helps you.
>
> You may want to see how DataBinder[1] has implemented it.
>
> [1] http://databinder.net/wicket/show/overview/
>
> - Nishant
>
> On Sat, Apr 24, 2010 at 1:55 PM, Arnaud Garcia <arnaud@imagemed-87.com
> >wrote:
>
> > Hello,
> >
> > I put my question in both forum, (wicket and this one)
> >
> > Does anyone knows how to set up Cayenne for wicket ?
> >
> > In my WicketPage I have :
> >  private DataContext ctxt = (DataContext)
> > DataContext.getThreadObjectContext();
> >
> > but, I don't think it is the good way, since I suppose wicket will
> > serialized the full DataContext... (maybe I can put the
> > getThreadObjectContext() in a method or constructor to avoid the
> > serialization...)
> > -> Well, I don't know how what is the good way  ;-)
> >
> >
> >
> > thanks,
> >
> > Arnaud
> >
>

Re: Wicket Cayenne

Posted by Nishant Neeraj <ni...@gmail.com>.
Hi Arnaud,

I have used session to store my dataContext

something like this

public DataContext getSessionDataContext(){
        synchronized(this){
            if(this.dataContext==null){
                this.dataContext = DataContext.createDataContext();
            }
        }
        return this.dataContext;
    }


anywhere I need this, I perform this

DataContext dctx = ((MyAppSession)getSession()).getSessionDataContext();

I think it may not solve the serialization issue, if session objects are
serialized. But you avoid creating DataContext at every page.

Not sure if this helps you.

You may want to see how DataBinder[1] has implemented it.

[1] http://databinder.net/wicket/show/overview/

- Nishant

On Sat, Apr 24, 2010 at 1:55 PM, Arnaud Garcia <ar...@imagemed-87.com>wrote:

> Hello,
>
> I put my question in both forum, (wicket and this one)
>
> Does anyone knows how to set up Cayenne for wicket ?
>
> In my WicketPage I have :
>  private DataContext ctxt = (DataContext)
> DataContext.getThreadObjectContext();
>
> but, I don't think it is the good way, since I suppose wicket will
> serialized the full DataContext... (maybe I can put the
> getThreadObjectContext() in a method or constructor to avoid the
> serialization...)
> -> Well, I don't know how what is the good way  ;-)
>
>
>
> thanks,
>
> Arnaud
>