Re: Persisting a GlazedList in Hibernate

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

Re: Persisting a GlazedList in Hibernate

Bruce Alspaugh-2
Holger Brands wrote:
> Hm, we did not add a new member but instead implemented the constructor like this:
>
> public PersistentEventList(SessionImplementor session) {
>   super(session);
>   list = new BasicEventList(); // list is a protected member
> }
>
> We had not problems with it so far.
>  
I figured the general user list may be getting tired of all the
back-and-forth on this, and if this will be a new feature of Glazed
Lists it probably belongs on the developer list.

I should probably elaborate on why I did what I did.  If you look at the
Hibernate source for PersistentEventList, it goes to great lengths not
to create the list member until it absolutely has to--I think to
accommodate lazy loading.  The execution path is rather circuitous, but
it eventually will call the wrapper class function
EventListType.instantiate() to create the list protected member.

I created the BasicEventList member so that users could call
getReadWriteLock() and other EventList specific functions without
triggering Hibernate's lazy load.  As soon as a stock list function is
called, it will trigger the lazy load resulting in initializing the list
member with a different BasicEventList.  Therein lies the rub.  As it is
now if I register a listener on a PersistentEventList, it registers on
the empty BasicEventList, not the one that is created by
EventListType.instantiate() which would hold the actual data.  What I
need to be able to do is to create the lock and the publisher in the
PersistentEventList constructor, and somehow get the BasicEventList that
gets created in EventListType.instantiate() to use them.

I wish I knew more about exactly how Hibernate replaces proxy list
elements with the actual elements, because I'm concerned that the
replacement process might fire events.

Did you look at the Javolution article?  They never even implemented a
separate persistent collection class and fell back on Hibernate's
implementation.

http://www.javalobby.org/java/forums/t18339.html

I still don't know how Javolution handles concurrency without
synchronization.  Sounds like black magic to me.

Bruce

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

Reply | Threaded
Open this post in threaded view
|

Re: Persisting a GlazedList in Hibernate

James Lemieux
Bruce,

   My neophyte's understanding is that you're creating a BasicEventList so that users can do things like attach ListEventListeners without causing Hibernate to load a bunch of data prematurely.

   Imagine that a user:

1. Creates a PersistentEventList.
2. Attaches 3 ListEventListeners to it. (which are thus saved in a private BasicEventList)
3. Invokes a normal List method which lazily creates the delegate List, a NEW BasicEventList, and faults data.

How do the 3 registered ListEventListeners from step 2 become registered to the new delegate BasicEventList? Or do they somehow stay where they are?

If you are building a temporary BasicEventList anyway, is there a way to initialize the delegate List without causing Hibernate to load data? Does Holger's solution of setting the list member directly accomplish that already?

James

On 8/16/06, Bruce Alspaugh <[hidden email]> wrote:
Holger Brands wrote:
> Hm, we did not add a new member but instead implemented the constructor like this:
>
> public PersistentEventList(SessionImplementor session) {
>   super(session);
>   list = new BasicEventList(); // list is a protected member
> }
>
> We had not problems with it so far.
>
I figured the general user list may be getting tired of all the
back-and-forth on this, and if this will be a new feature of Glazed
Lists it probably belongs on the developer list.

I should probably elaborate on why I did what I did.  If you look at the
Hibernate source for PersistentEventList, it goes to great lengths not
to create the list member until it absolutely has to--I think to
accommodate lazy loading.  The execution path is rather circuitous, but
it eventually will call the wrapper class function
EventListType.instantiate() to create the list protected member.

I created the BasicEventList member so that users could call
getReadWriteLock() and other EventList specific functions without
triggering Hibernate's lazy load.  As soon as a stock list function is
called, it will trigger the lazy load resulting in initializing the list
member with a different BasicEventList.  Therein lies the rub.  As it is
now if I register a listener on a PersistentEventList, it registers on
the empty BasicEventList, not the one that is created by
EventListType.instantiate () which would hold the actual data.  What I
need to be able to do is to create the lock and the publisher in the
PersistentEventList constructor, and somehow get the BasicEventList that
gets created in EventListType.instantiate () to use them.

I wish I knew more about exactly how Hibernate replaces proxy list
elements with the actual elements, because I'm concerned that the
replacement process might fire events.

Did you look at the Javolution article?  They never even implemented a
separate persistent collection class and fell back on Hibernate's
implementation.

http://www.javalobby.org/java/forums/t18339.html

I still don't know how Javolution handles concurrency without
synchronization.  Sounds like black magic to me.

Bruce

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


Reply | Threaded
Open this post in threaded view
|

Re: Persisting a GlazedList in Hibernate

Bruce Alspaugh-2
James Lemieux wrote:
> Bruce,
>
>    My neophyte's understanding is that you're creating a
> BasicEventList so that users can do things like attach
> ListEventListeners without causing Hibernate to load a bunch of data
> prematurely.
Yes, that is what I am trying to do.

>
>    Imagine that a user:
>
> 1. Creates a PersistentEventList.
> 2. Attaches 3 ListEventListeners to it. (which are thus saved in a
> private BasicEventList)
> 3. Invokes a normal List method which lazily creates the delegate
> List, a NEW BasicEventList, and faults data.
>
> How do the 3 registered ListEventListeners from step 2 become
> registered to the new delegate BasicEventList? Or do they somehow stay
> where they are?
That is the essence of the problem--they stay where they are.
>
> If you are building a temporary BasicEventList anyway, is there a way
> to initialize the delegate List without causing Hibernate to load
> data? Does Holger's solution of setting the list member directly
> accomplish that already?
Holger's solution would be simpler.  I just have to convince myself that
that pre-initializing the delegate List instead of allowing Hibernate to
instantiate it won't confuse Hibernate.

Does GlazedLists have a way to construct a BasicEventList where I can
supply the lock and the publisher it will use?  If I could delegate
EventList specific methods to lock, publisher, and listener list members
in the PersistentEventList, and then get EventListType.instantiate() to
supply that lock, publisher, and listener list to the BasicEventList it
creates, it should make whole the issue go away.

Bruce

>
> James
>
> On 8/16/06, *Bruce Alspaugh* <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Holger Brands wrote:
>     > Hm, we did not add a new member but instead implemented the
>     constructor like this:
>     >
>     > public PersistentEventList(SessionImplementor session) {
>     >   super(session);
>     >   list = new BasicEventList(); // list is a protected member
>     > }
>     >
>     > We had not problems with it so far.
>     >
>     I figured the general user list may be getting tired of all the
>     back-and-forth on this, and if this will be a new feature of Glazed
>     Lists it probably belongs on the developer list.
>
>     I should probably elaborate on why I did what I did.  If you look
>     at the
>     Hibernate source for PersistentEventList, it goes to great lengths not
>     to create the list member until it absolutely has to--I think to
>     accommodate lazy loading.  The execution path is rather
>     circuitous, but
>     it eventually will call the wrapper class function
>     EventListType.instantiate() to create the list protected member.
>
>     I created the BasicEventList member so that users could call
>     getReadWriteLock() and other EventList specific functions without
>     triggering Hibernate's lazy load.  As soon as a stock list function is
>     called, it will trigger the lazy load resulting in initializing
>     the list
>     member with a different BasicEventList.  Therein lies the rub.  As
>     it is
>     now if I register a listener on a PersistentEventList, it registers on
>     the empty BasicEventList, not the one that is created by
>     EventListType.instantiate () which would hold the actual data.  What I
>     need to be able to do is to create the lock and the publisher in the
>     PersistentEventList constructor, and somehow get the
>     BasicEventList that
>     gets created in EventListType.instantiate () to use them.
>
>     I wish I knew more about exactly how Hibernate replaces proxy list
>     elements with the actual elements, because I'm concerned that the
>     replacement process might fire events.
>
>     Did you look at the Javolution article?  They never even
>     implemented a
>     separate persistent collection class and fell back on Hibernate's
>     implementation.
>
>     http://www.javalobby.org/java/forums/t18339.html
>
>     I still don't know how Javolution handles concurrency without
>     synchronization.  Sounds like black magic to me.
>
>     Bruce
>
>     ---------------------------------------------------------------------
>     To unsubscribe, e-mail: [hidden email]
>     <mailto:[hidden email]>
>     For additional commands, e-mail: [hidden email]
>     <mailto:[hidden email]>
>
>

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

Reply | Threaded
Open this post in threaded view
|

Re: Persisting a GlazedList in Hibernate

James Lemieux
The constructor:

public BasicEventList(ListEventPublisher publisher, ReadWriteLock readWriteLock)

has existed for a few months and is what you're looking for.

I'm still concerned about moving ListEventListeners between your initial BasicEventList and your lazily created BasicEventList. That does need to be accomplished, right?

James

On 8/16/06, Bruce Alspaugh <[hidden email]> wrote:
James Lemieux wrote:
> Bruce,
>
>    My neophyte's understanding is that you're creating a
> BasicEventList so that users can do things like attach
> ListEventListeners without causing Hibernate to load a bunch of data
> prematurely.
Yes, that is what I am trying to do.

>
>    Imagine that a user:
>
> 1. Creates a PersistentEventList.
> 2. Attaches 3 ListEventListeners to it. (which are thus saved in a
> private BasicEventList)
> 3. Invokes a normal List method which lazily creates the delegate
> List, a NEW BasicEventList, and faults data.
>
> How do the 3 registered ListEventListeners from step 2 become
> registered to the new delegate BasicEventList? Or do they somehow stay
> where they are?
That is the essence of the problem--they stay where they are.
>
> If you are building a temporary BasicEventList anyway, is there a way
> to initialize the delegate List without causing Hibernate to load
> data? Does Holger's solution of setting the list member directly
> accomplish that already?
Holger's solution would be simpler.  I just have to convince myself that
that pre-initializing the delegate List instead of allowing Hibernate to
instantiate it won't confuse Hibernate.

Does GlazedLists have a way to construct a BasicEventList where I can
supply the lock and the publisher it will use?  If I could delegate
EventList specific methods to lock, publisher, and listener list members
in the PersistentEventList, and then get EventListType.instantiate() to
supply that lock, publisher, and listener list to the BasicEventList it
creates, it should make whole the issue go away.

Bruce

>
> James
>
> On 8/16/06, *Bruce Alspaugh* <[hidden email]
> <mailto: [hidden email]>> wrote:
>
>     Holger Brands wrote:
>     > Hm, we did not add a new member but instead implemented the
>     constructor like this:
>     >
>     > public PersistentEventList(SessionImplementor session) {
>     >   super(session);
>     >   list = new BasicEventList(); // list is a protected member
>     > }
>     >
>     > We had not problems with it so far.
>     >
>     I figured the general user list may be getting tired of all the
>     back-and-forth on this, and if this will be a new feature of Glazed
>     Lists it probably belongs on the developer list.
>
>     I should probably elaborate on why I did what I did.  If you look
>     at the
>     Hibernate source for PersistentEventList, it goes to great lengths not
>     to create the list member until it absolutely has to--I think to
>     accommodate lazy loading.  The execution path is rather
>     circuitous, but
>     it eventually will call the wrapper class function
>     EventListType.instantiate() to create the list protected member.
>
>     I created the BasicEventList member so that users could call
>     getReadWriteLock() and other EventList specific functions without
>     triggering Hibernate's lazy load.  As soon as a stock list function is
>     called, it will trigger the lazy load resulting in initializing
>     the list
>     member with a different BasicEventList.  Therein lies the rub.  As
>     it is
>     now if I register a listener on a PersistentEventList, it registers on
>     the empty BasicEventList, not the one that is created by
>     EventListType.instantiate () which would hold the actual data.  What I
>     need to be able to do is to create the lock and the publisher in the
>     PersistentEventList constructor, and somehow get the
>     BasicEventList that
>     gets created in EventListType.instantiate () to use them.
>
>     I wish I knew more about exactly how Hibernate replaces proxy list
>     elements with the actual elements, because I'm concerned that the
>     replacement process might fire events.
>
>     Did you look at the Javolution article?  They never even
>     implemented a
>     separate persistent collection class and fell back on Hibernate's
>     implementation.
>
>     http://www.javalobby.org/java/forums/t18339.html

>
>     I still don't know how Javolution handles concurrency without
>     synchronization.  Sounds like black magic to me.
>
>     Bruce
>
>     ---------------------------------------------------------------------
>     To unsubscribe, e-mail: [hidden email]
>     <mailto:[hidden email]>
>     For additional commands, e-mail: [hidden email]
>     <mailto:[hidden email]>
>
>

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


Reply | Threaded
Open this post in threaded view
|

Re: Persisting a GlazedList in Hibernate

Bruce Alspaugh-2
Yes, that does need to be accomplished if we want Hibernate to lazily create a BasicEventList.  Do you break out the list of ListEventListeners into a separate object that could be shuttled between the initial BasicEventList, and the lazily created one?

On the other hand, if Holger's solution to pre-initialize the protected list member does not confuse Hibernate I would say go with that.  It would be a much simpler solution if we know it doesn't cause any issues.

Bruce

On 8/16/06, James Lemieux <[hidden email]> wrote:
The constructor:

public BasicEventList(ListEventPublisher publisher, ReadWriteLock readWriteLock)

has existed for a few months and is what you're looking for.

I'm still concerned about moving ListEventListeners between your initial BasicEventList and your lazily created BasicEventList. That does need to be accomplished, right?

James

On 8/16/06, Bruce Alspaugh <[hidden email]> wrote:
James Lemieux wrote:
> Bruce,
>
>    My neophyte's understanding is that you're creating a
> BasicEventList so that users can do things like attach
> ListEventListeners without causing Hibernate to load a bunch of data
> prematurely.
Yes, that is what I am trying to do.

>
>    Imagine that a user:
>
> 1. Creates a PersistentEventList.
> 2. Attaches 3 ListEventListeners to it. (which are thus saved in a
> private BasicEventList)
> 3. Invokes a normal List method which lazily creates the delegate
> List, a NEW BasicEventList, and faults data.
>
> How do the 3 registered ListEventListeners from step 2 become
> registered to the new delegate BasicEventList? Or do they somehow stay
> where they are?
That is the essence of the problem--they stay where they are.
>
> If you are building a temporary BasicEventList anyway, is there a way
> to initialize the delegate List without causing Hibernate to load
> data? Does Holger's solution of setting the list member directly
> accomplish that already?
Holger's solution would be simpler.  I just have to convince myself that
that pre-initializing the delegate List instead of allowing Hibernate to
instantiate it won't confuse Hibernate.

Does GlazedLists have a way to construct a BasicEventList where I can
supply the lock and the publisher it will use?  If I could delegate
EventList specific methods to lock, publisher, and listener list members
in the PersistentEventList, and then get EventListType.instantiate() to
supply that lock, publisher, and listener list to the BasicEventList it
creates, it should make whole the issue go away.

Bruce

>
> James
>
> On 8/16/06, *Bruce Alspaugh* <[hidden email]
> <mailto: [hidden email]>> wrote:
>
>     Holger Brands wrote:
>     > Hm, we did not add a new member but instead implemented the
>     constructor like this:
>     >
>     > public PersistentEventList(SessionImplementor session) {
>     >   super(session);
>     >   list = new BasicEventList(); // list is a protected member
>     > }
>     >
>     > We had not problems with it so far.
>     >
>     I figured the general user list may be getting tired of all the
>     back-and-forth on this, and if this will be a new feature of Glazed
>     Lists it probably belongs on the developer list.
>
>     I should probably elaborate on why I did what I did.  If you look
>     at the
>     Hibernate source for PersistentEventList, it goes to great lengths not
>     to create the list member until it absolutely has to--I think to
>     accommodate lazy loading.  The execution path is rather
>     circuitous, but
>     it eventually will call the wrapper class function
>     EventListType.instantiate() to create the list protected member.
>
>     I created the BasicEventList member so that users could call
>     getReadWriteLock() and other EventList specific functions without
>     triggering Hibernate's lazy load.  As soon as a stock list function is
>     called, it will trigger the lazy load resulting in initializing
>     the list
>     member with a different BasicEventList.  Therein lies the rub.  As
>     it is
>     now if I register a listener on a PersistentEventList, it registers on
>     the empty BasicEventList, not the one that is created by
>     EventListType.instantiate () which would hold the actual data.  What I
>     need to be able to do is to create the lock and the publisher in the
>     PersistentEventList constructor, and somehow get the
>     BasicEventList that
>     gets created in EventListType.instantiate () to use them.
>
>     I wish I knew more about exactly how Hibernate replaces proxy list
>     elements with the actual elements, because I'm concerned that the
>     replacement process might fire events.
>
>     Did you look at the Javolution article?  They never even
>     implemented a
>     separate persistent collection class and fell back on Hibernate's
>     implementation.
>
>     <a href="http://www.javalobby.org/java/forums/t18339.html" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">http://www.javalobby.org/java/forums/t18339.html

>
>     I still don't know how Javolution handles concurrency without
>     synchronization.  Sounds like black magic to me.
>
>     Bruce
>
>     ---------------------------------------------------------------------
>     To unsubscribe, e-mail: [hidden email]
>     <mailto:[hidden email]>
>     For additional commands, e-mail: [hidden email]
>     <mailto:[hidden email] >
>
>

---------------------------------------------------------------------

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



Reply | Threaded
Open this post in threaded view
|

Re: Persisting a GlazedList in Hibernate

Holger
In reply to this post by Bruce Alspaugh-2
Hi,

sorry for the short delay.

>Yes, that does need to be accomplished if we want Hibernate to lazily create a BasicEventList.  Do you break out the list of ListEventListeners into a separate object that could be shuttled between the initial BasicEventList, and the lazily created one?
>
>
> On the other hand, if Holger's solution to pre-initialize the protected list member does not confuse Hibernate I would say go with that.  It would be a much simpler solution if we know it doesn't cause any issues.
>
>
> Bruce
>
>

Ok, let's recap what we have.
Here is our original implementation of PersistentEventList:

/**
 * PersistentEventList for storing a BasicEventList with Hibernate.
 */
public final class PersistentEventList extends PersistentList implements EventList {

    /** SerialUID. */
    static final long serialVersionUID = 0L;

    /**
     * Der Konstruktor.
     *
     * @param session
     *            die Session
     */
    public PersistentEventList(SessionImplementor session) {
        super(session);
        // instantiate list here to avoid NullPointerExceptions with lazy loading.
        list = new BasicEventList();
    }

    /**
     * Der Konstruktor.
     *
     * @param session
     *            die Session
     * @param newList
     *            die Liste
     */
    public PersistentEventList(SessionImplementor session, EventList newList) {
        super(session, newList);
    }

    /**
     * {@inheritDoc}
     */
    public void addListEventListener(ListEventListener listChangeListener) {
        ((EventList) list).addListEventListener(listChangeListener);
    }

    /**
     * {@inheritDoc}
     */
    public ListEventPublisher getPublisher() {
        return ((EventList) list).getPublisher();
    }

    /**
     * {@inheritDoc}
     */
    public ReadWriteLock getReadWriteLock() {
        return ((EventList) list).getReadWriteLock();
    }

    /**
     * {@inheritDoc}
     */
    public void removeListEventListener(ListEventListener listChangeListener) {
        ((EventList) list).removeListEventListener(listChangeListener);
    }
}

This solution works with lazy loading such that calling methods like getPublisher() or
addListEventListener(...) does *not* trigger the initialization of a lazy loaded collection.
Instantiating the BasicEventList in the constructor avoids NullPointerExceptions when the
EventList-specific functions are called on a collection which is not initialized yet.

But this solution also has the problem James mentioned:
When a 'normal' list method is called, initialization of the collection is triggered which
leads to the assignment of a new BasicEventList to the list member. See the following method
of PersistentList:

        public void beforeInitialize(CollectionPersister persister) {
                this.list = (List) persister.getCollectionType().instantiate();
        }

One option would be to override this method in PersistentEventList like :

        public void beforeInitialize(CollectionPersister persister) {
            if (this.list == null) {
                    this.list = (List) persister.getCollectionType().instantiate();
            }
        }

This way the list member would not get reassigned and we would continue with 'old' list member.
But I don't know if this has any other side effects?!

Another option would be to stick with the following implementation:

/**
 * PersistentEventList for storing a BasicEventList with Hibernate.
 * Every method call on the list will trigger initialization of a lazy loaded collection.
 */
public final class PersistentEventList extends PersistentList implements EventList {

    /** SerialUID. */
    static final long serialVersionUID = 0L;

    /**
     * Der Konstruktor.
     *
     * @param session
     *            die Session
     */
    public PersistentEventList(SessionImplementor session) {
        super(session);
    }

    /**
     * Der Konstruktor.
     *
     * @param session
     *            die Session
     * @param newList
     *            die Liste
     */
    public PersistentEventList(SessionImplementor session, EventList newList) {
        super(session, newList);
    }

    /**
     * {@inheritDoc}
     */
    public void addListEventListener(ListEventListener listChangeListener) {
        // ensure proper initialization
        // we do not call write() because it would mark the list as dirty
          read();
        ((EventList) list).addListEventListener(listChangeListener);
    }

    /**
     * {@inheritDoc}
     */
    public ListEventPublisher getPublisher() {
        // ensure proper initialization
          read();
        return ((EventList) list).getPublisher();
    }

    /**
     * {@inheritDoc}
     */
    public ReadWriteLock getReadWriteLock() {
        // ensure proper initialization
          read();
        return ((EventList) list).getReadWriteLock();
    }

    /**
     * {@inheritDoc}
     */
    public void removeListEventListener(ListEventListener listChangeListener) {
        // removing listeners makes sense only for initialized lists
        if (list != null) {
            ((EventList) list).removeListEventListener(listChangeListener);
        }
    }
}

This implementation is clean and simple but has the disadvantage, that EventList-specific
method calls will also trigger initialization of a lazy loaded collection.

Bruce, do you have a use case which would require your proposed optimization for
*not* initializing the collection when calling EventList-specific methods?

If we decide to optimize and overriding beforeInitialization(...) turns out to be a bad idea
then we would have to find a way to transfer the listeners of one EventList to another one
which also requires to ensure the consistency of the internal datastructures of the
ListEventAssembler and ListEventPublisher in use. I'm not sure if this is possible right now ...

What do you think?

Holger

P.S.: I did not test the new suggested stuff, only our original implementation is in use.

______________________________________________________________
Verschicken Sie romantische, coole und witzige Bilder per SMS!
Jetzt bei WEB.DE FreeMail: http://f.web.de/?mc=021193

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

Reply | Threaded
Open this post in threaded view
|

Re: Persisting a GlazedList in Hibernate

Bruce Alspaugh-2
Hi Holger and James,

I like the idea of taking the original implementation and overriding beforeInitialize(...) so it would look something like this:

/**
 * PersistentEventList for storing a BasicEventList with Hibernate.
 */
public final class PersistentEventList extends PersistentList implements EventList {

    /** SerialUID. */
    static final long serialVersionUID = 0L;

    /**
     * Der Konstruktor.
     *
     * @param session
     *            die Session
     */
    public PersistentEventList(SessionImplementor session) {
        super(session);
        // instantiate list here to avoid NullPointerExceptions with lazy loading.
        list = new BasicEventList();
    }

    /**
     * Der Konstruktor.
     *
     * @param session
     *            die Session
     * @param newList
     *            die Liste
     */
    public PersistentEventList(SessionImplementor session, EventList newList) {
        super(session, newList);
    }
   
    /**
     * {@inheritDoc}
     */
    public void beforeInitialize(CollectionPersister persister) {
        // avoid overwriting the list if it has already been created
        if (this.list == null) {
            this.list = (List) persister.getCollectionType().instantiate();
        }
    }

    /**
     * {@inheritDoc}
     */
    public void addListEventListener(ListEventListener listChangeListener) {
        ((EventList) list).addListEventListener(listChangeListener);
    }

    /**
     * {@inheritDoc}
     */
    public ListEventPublisher getPublisher() {
        return ((EventList) list).getPublisher();
    }

    /**
     * {@inheritDoc}
     */
    public ReadWriteLock getReadWriteLock() {
        return ((EventList) list).getReadWriteLock();
    }

    /**
     * {@inheritDoc}
     */
    public void removeListEventListener(ListEventListener listChangeListener) {
        ((EventList) list).removeListEventListener(listChangeListener);
    }
}

This way we don't trigger lazy loading when methods like getPublisher() and addListEventListener(...) are called, but also prevent the list member from being overwritten by beforeInitialize(..) when a 'normal' list method triggers lazy loading.  It avoids the complications involved in trying to reassign listeners and other data structures from one list to another.

I kept searching the Hibernate source code looking for possible side-effects, but I wasn't able to find any.  

I guess it's time to start testing it and see if there are any problems.  Are we using the same implementation for the UserCollectionType?

This looks promising. :)

Bruce




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

Reply | Threaded
Open this post in threaded view
|

Re: Persisting a GlazedList in Hibernate

James Lemieux
Hey guys,

   I like the direction I'm seeing. Just a few minor suggestions:

1. If the constructors can guarantee the list member variable is initialized to something non-null (currently the 2 arg constructor does not, it should test and throw an exception after its call to super), then beforeInitialize(...) should probably just become a no-op, or one that throws an IllegalStateException if the list member is null. (subclasses could unexpectedly destroy this invariant, so I guess I prefer the IllegalStateException)

2. I like chaining constructors, so my personal style would implement the single arg constructor like so:

   public PersistentEventList(SessionImplementor session) {
       this(session,
new BasicEventList());
   }

but that's mostly a style issue, IMO.

3. The only way we could shuttle listeners between BasicEventList A and BasicEventList B would be to store the registered listeners in *another* data structure within PersistentEventList. ListEventPublisher does not support querying for registered listeners at the moment, and this would probably not be a strong enough case for us to open up that API.

4. I'd guess that delaying the loading of data until *after* your EventList pipeline is fully initialized is a virtuous goal. So, I'd discard Holger's second solution for the reason he stated (that read() invokes a lazy load, and thus EventList methods would cause loading)

James

On 8/17/06, Bruce Alspaugh <[hidden email]> wrote:
Hi Holger and James,

I like the idea of taking the original implementation and overriding beforeInitialize(...) so it would look something like this:

/**
* PersistentEventList for storing a BasicEventList with Hibernate.
*/
public final class PersistentEventList extends PersistentList implements EventList {

    /** SerialUID. */
    static final long serialVersionUID = 0L;

    /**
     * Der Konstruktor.
     *
     * @param session
     *            die Session
     */
    public PersistentEventList(SessionImplementor session) {
        super(session);
        // instantiate list here to avoid NullPointerExceptions with lazy loading.
        list = new BasicEventList();
    }

    /**
     * Der Konstruktor.
     *
     * @param session
     *            die Session
     * @param newList
     *            die Liste
     */
    public PersistentEventList(SessionImplementor session, EventList newList) {
        super(session, newList);
    }

    /**
     * {@inheritDoc}
     */
    public void beforeInitialize(CollectionPersister persister) {
        // avoid overwriting the list if it has already been created
        if (this.list == null) {
            this.list = (List) persister.getCollectionType().instantiate();
        }
    }

    /**
     * {@inheritDoc}
     */
    public void addListEventListener(ListEventListener listChangeListener) {
        ((EventList) list).addListEventListener(listChangeListener);
    }

    /**
     * {@inheritDoc}
     */
    public ListEventPublisher getPublisher() {
        return ((EventList) list).getPublisher();
    }

    /**
     * {@inheritDoc}
     */
    public ReadWriteLock getReadWriteLock() {
        return ((EventList) list).getReadWriteLock();
    }

    /**
     * {@inheritDoc}
     */
    public void removeListEventListener(ListEventListener listChangeListener) {
        ((EventList) list).removeListEventListener(listChangeListener);
    }
}

This way we don't trigger lazy loading when methods like getPublisher() and addListEventListener(...) are called, but also prevent the list member from being overwritten by beforeInitialize(..) when a 'normal' list method triggers lazy loading.  It avoids the complications involved in trying to reassign listeners and other data structures from one list to another.

I kept searching the Hibernate source code looking for possible side-effects, but I wasn't able to find any.

I guess it's time to start testing it and see if there are any problems.  Are we using the same implementation for the UserCollectionType?

This looks promising. :)

Bruce




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


Reply | Threaded
Open this post in threaded view
|

Re: Persisting a GlazedList in Hibernate

Bruce Alspaugh-2
James,

I have a quick comment about suggestion 2.  Be careful about calling the
two-argument constructor in PersistentEventList.  Right now, it calls
the inherited two-argument constructor from PersistentList. If you look
at the source code for that constructor, you will see this:

public PersistentList(SessionImplementor session, List list) {
    super(session);
    this.list = list;
    setInitialized();
    setDirectlyAccessible(true);
}

The calls to setInitialized() and setDirectlyAccessible(true) bother
me.  I'm concerned they might put the PersistentList into a state where
it thinks it is already loaded.  The inherited single-argument
constructor does not make those calls.

Bruce

James Lemieux wrote:

> Hey guys,
>
>    I like the direction I'm seeing. Just a few minor suggestions:
>
> 1. If the constructors can guarantee the list member variable is
> initialized to something non-null (currently the 2 arg constructor
> does not, it should test and throw an exception after its call to
> super), then beforeInitialize(...) should probably just become a
> no-op, or one that throws an IllegalStateException if the list member
> is null. (subclasses could unexpectedly destroy this invariant, so I
> guess I prefer the IllegalStateException)
>
> 2. I like chaining constructors, so my personal style would implement
> the single arg constructor like so:
>
>    public PersistentEventList(SessionImplementor session) {
>        this(session, new BasicEventList());
>    }
>
> but that's mostly a style issue, IMO.
>
> 3. The only way we could shuttle listeners between BasicEventList A
> and BasicEventList B would be to store the registered listeners in
> *another* data structure within PersistentEventList.
> ListEventPublisher does not support querying for registered listeners
> at the moment, and this would probably not be a strong enough case for
> us to open up that API.
>
> 4. I'd guess that delaying the loading of data until *after* your
> EventList pipeline is fully initialized is a virtuous goal. So, I'd
> discard Holger's second solution for the reason he stated (that read()
> invokes a lazy load, and thus EventList methods would cause loading)
>
> James
>
> On 8/17/06, *Bruce Alspaugh* <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Hi Holger and James,
>
>     I like the idea of taking the original implementation and
>     overriding beforeInitialize(...) so it would look something like this:
>
>     /**
>     * PersistentEventList for storing a BasicEventList with Hibernate.
>     */
>     public final class PersistentEventList extends PersistentList
>     implements EventList {
>
>         /** SerialUID. */
>         static final long serialVersionUID = 0L;
>
>         /**
>          * Der Konstruktor.
>          *
>          * @param session
>          *            die Session
>          */
>         public PersistentEventList(SessionImplementor session) {
>             super(session);
>             // instantiate list here to avoid NullPointerExceptions
>     with lazy loading.
>             list = new BasicEventList();
>         }
>
>         /**
>          * Der Konstruktor.
>          *
>          * @param session
>          *            die Session
>          * @param newList
>          *            die Liste
>          */
>         public PersistentEventList(SessionImplementor session,
>     EventList newList) {
>             super(session, newList);
>         }
>
>         /**
>          * {@inheritDoc}
>          */
>         public void beforeInitialize(CollectionPersister persister) {
>             // avoid overwriting the list if it has already been created
>             if (this.list == null) {
>                 this.list = (List)
>     persister.getCollectionType().instantiate();
>             }
>         }
>
>         /**
>          * {@inheritDoc}
>          */
>         public void addListEventListener(ListEventListener
>     listChangeListener) {
>             ((EventList) list).addListEventListener(listChangeListener);
>         }
>
>         /**
>          * {@inheritDoc}
>          */
>         public ListEventPublisher getPublisher() {
>             return ((EventList) list).getPublisher();
>         }
>
>         /**
>          * {@inheritDoc}
>          */
>         public ReadWriteLock getReadWriteLock() {
>             return ((EventList) list).getReadWriteLock();
>         }
>
>         /**
>          * {@inheritDoc}
>          */
>         public void removeListEventListener(ListEventListener
>     listChangeListener) {
>             ((EventList)
>     list).removeListEventListener(listChangeListener);
>         }
>     }
>
>     This way we don't trigger lazy loading when methods like
>     getPublisher() and addListEventListener(...) are called, but also
>     prevent the list member from being overwritten by
>     beforeInitialize(..) when a 'normal' list method triggers lazy
>     loading.  It avoids the complications involved in trying to
>     reassign listeners and other data structures from one list to
>     another.
>
>     I kept searching the Hibernate source code looking for possible
>     side-effects, but I wasn't able to find any.
>
>     I guess it's time to start testing it and see if there are any
>     problems.  Are we using the same implementation for the
>     UserCollectionType?
>
>     This looks promising. :)
>
>     Bruce
>
>
>
>
>     ---------------------------------------------------------------------
>     To unsubscribe, e-mail: [hidden email]
>     <mailto:[hidden email]>
>     For additional commands, e-mail: [hidden email]
>     <mailto:[hidden email]>
>
>

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

Reply | Threaded
Open this post in threaded view
|

Re: Persisting a GlazedList in Hibernate

Holger
In reply to this post by Bruce Alspaugh-2
Hey guys,

thanks for your feedback.
I started a hibernate extension in CVS taking into account your
comments and suggestions.
Please see

https://glazedlists.dev.java.net/source/browse/glazedlists/extensions/hibernate/source/ca/odell/glazedlists/hibernate/

if it meets your expections.

James, I like your first suggestion and implemented it.
Like Bruce I think your second suggestion would mean a
change in semantics which is not desired. The collection would be
marked is initialized although it shouldn't.

Build integration and tests for the extension will follow.

Let me know any problems or suggestions.

Thanks,
Holger


> James,
>
> I have a quick comment about suggestion 2.  Be careful about calling the
> two-argument constructor in PersistentEventList.  Right now, it calls
> the inherited two-argument constructor from PersistentList. If you look
> at the source code for that constructor, you will see this:
>
> public PersistentList(SessionImplementor session, List list) {
>     super(session);
>     this.list = list;
>     setInitialized();
>     setDirectlyAccessible(true);
> }
>
> The calls to setInitialized() and setDirectlyAccessible(true) bother
> me.  I'm concerned they might put the PersistentList into a state where
> it thinks it is already loaded.  The inherited single-argument
> constructor does not make those calls.
>
> Bruce
>
> James Lemieux wrote:
> > Hey guys,
> >
> >    I like the direction I'm seeing. Just a few minor suggestions:
> >
> > 1. If the constructors can guarantee the list member variable is
> > initialized to something non-null (currently the 2 arg constructor
> > does not, it should test and throw an exception after its call to
> > super), then beforeInitialize(...) should probably just become a
> > no-op, or one that throws an IllegalStateException if the list member
> > is null. (subclasses could unexpectedly destroy this invariant, so I
> > guess I prefer the IllegalStateException)
> >
> > 2. I like chaining constructors, so my personal style would implement
> > the single arg constructor like so:
> >
> >    public PersistentEventList(SessionImplementor session) {
> >        this(session, new BasicEventList());
> >    }
> >
> > but that's mostly a style issue, IMO.
> >
> > 3. The only way we could shuttle listeners between BasicEventList A
> > and BasicEventList B would be to store the registered listeners in
> > *another* data structure within PersistentEventList.
> > ListEventPublisher does not support querying for registered listeners
> > at the moment, and this would probably not be a strong enough case for
> > us to open up that API.
> >
> > 4. I'd guess that delaying the loading of data until *after* your
> > EventList pipeline is fully initialized is a virtuous goal. So, I'd
> > discard Holger's second solution for the reason he stated (that read()
> > invokes a lazy load, and thus EventList methods would cause loading)
> >
> > James
> >
> > On 8/17/06, *Bruce Alspaugh* <[hidden email]
> > <mailto:[hidden email]>> wrote:
> >
> >     Hi Holger and James,
> >
> >     I like the idea of taking the original implementation and
> >     overriding beforeInitialize(...) so it would look something like this:
> >
> >     /**
> >     * PersistentEventList for storing a BasicEventList with Hibernate.
> >     */
> >     public final class PersistentEventList extends PersistentList
> >     implements EventList {
> >
> >         /** SerialUID. */
> >         static final long serialVersionUID = 0L;
> >
> >         /**
> >          * Der Konstruktor.
> >          *
> >          * @param session
> >          *            die Session
> >          */
> >         public PersistentEventList(SessionImplementor session) {
> >             super(session);
> >             // instantiate list here to avoid NullPointerExceptions
> >     with lazy loading.
> >             list = new BasicEventList();
> >         }
> >
> >         /**
> >          * Der Konstruktor.
> >          *
> >          * @param session
> >          *            die Session
> >          * @param newList
> >          *            die Liste
> >          */
> >         public PersistentEventList(SessionImplementor session,
> >     EventList newList) {
> >             super(session, newList);
> >         }
> >
> >         /**
> >          * {@inheritDoc}
> >          */
> >         public void beforeInitialize(CollectionPersister persister) {
> >             // avoid overwriting the list if it has already been created
> >             if (this.list == null) {
> >                 this.list = (List)
> >     persister.getCollectionType().instantiate();
> >             }
> >         }
> >
> >         /**
> >          * {@inheritDoc}
> >          */
> >         public void addListEventListener(ListEventListener
> >     listChangeListener) {
> >             ((EventList) list).addListEventListener(listChangeListener);
> >         }
> >
> >         /**
> >          * {@inheritDoc}
> >          */
> >         public ListEventPublisher getPublisher() {
> >             return ((EventList) list).getPublisher();
> >         }
> >
> >         /**
> >          * {@inheritDoc}
> >          */
> >         public ReadWriteLock getReadWriteLock() {
> >             return ((EventList) list).getReadWriteLock();
> >         }
> >
> >         /**
> >          * {@inheritDoc}
> >          */
> >         public void removeListEventListener(ListEventListener
> >     listChangeListener) {
> >             ((EventList)
> >     list).removeListEventListener(listChangeListener);
> >         }
> >     }
> >
> >     This way we don't trigger lazy loading when methods like
> >     getPublisher() and addListEventListener(...) are called, but also
> >     prevent the list member from being overwritten by
> >     beforeInitialize(..) when a 'normal' list method triggers lazy
> >     loading.  It avoids the complications involved in trying to
> >     reassign listeners and other data structures from one list to
> >     another.
> >
> >     I kept searching the Hibernate source code looking for possible
> >     side-effects, but I wasn't able to find any.
> >
> >     I guess it's time to start testing it and see if there are any
> >     problems.  Are we using the same implementation for the
> >     UserCollectionType?
> >
> >     This looks promising. :)
> >
> >     Bruce
> >
> >
> >
> >
> >     ---------------------------------------------------------------------
> >     To unsubscribe, e-mail: [hidden email]
> >     <mailto:[hidden email]>
> >     For additional commands, e-mail: [hidden email]
> >     <mailto:[hidden email]>
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>


______________________________________________________________
Verschicken Sie romantische, coole und witzige Bilder per SMS!
Jetzt bei WEB.DE FreeMail: http://f.web.de/?mc=021193

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

Reply | Threaded
Open this post in threaded view
|

Re: Persisting a GlazedList in Hibernate

James Lemieux
Looks good. EventListType.java has a small typo in the class doc:
{@link BasisEventList}
Nice catch on the super's difference in constructors, Bruce. Chaining isn't such a good idea here I guess.

Holger, I see you uploaded the hibernate jar to the file repository. Maybe we could rename hibernate3.jar to just hibernate.jar? We have informally adopted the strategy of including the version in the folder structure but not the filename. The hope is that when hibernate4.jar comes out and we upgrade our support, we only have to change the build file to download the hibernate jar from a different path, but its name remains consistent throughout the build file's classpaths.

James

On 8/17/06, Holger Brands <[hidden email]> wrote:
Hey guys,

thanks for your feedback.
I started a hibernate extension in CVS taking into account your
comments and suggestions.
Please see

https://glazedlists.dev.java.net/source/browse/glazedlists/extensions/hibernate/source/ca/odell/glazedlists/hibernate/

if it meets your expections.

James, I like your first suggestion and implemented it.
Like Bruce I think your second suggestion would mean a
change in semantics which is not desired. The collection would be
marked is initialized although it shouldn't.

Build integration and tests for the extension will follow.

Let me know any problems or suggestions.

Thanks,
Holger


> James,
>
> I have a quick comment about suggestion 2.  Be careful about calling the
> two-argument constructor in PersistentEventList.  Right now, it calls
> the inherited two-argument constructor from PersistentList. If you look
> at the source code for that constructor, you will see this:
>
> public PersistentList(SessionImplementor session, List list) {
>     super(session);
>     this.list = list;
>     setInitialized();
>     setDirectlyAccessible(true);
> }
>
> The calls to setInitialized() and setDirectlyAccessible(true) bother
> me.  I'm concerned they might put the PersistentList into a state where
> it thinks it is already loaded.  The inherited single-argument
> constructor does not make those calls.
>
> Bruce
>

> James Lemieux wrote:
> > Hey guys,
> >
> >    I like the direction I'm seeing. Just a few minor suggestions:
> >
> > 1. If the constructors can guarantee the list member variable is
> > initialized to something non-null (currently the 2 arg constructor
> > does not, it should test and throw an exception after its call to
> > super), then beforeInitialize(...) should probably just become a
> > no-op, or one that throws an IllegalStateException if the list member
> > is null. (subclasses could unexpectedly destroy this invariant, so I
> > guess I prefer the IllegalStateException)
> >

> > 2. I like chaining constructors, so my personal style would implement
> > the single arg constructor like so:
> >
> >    public PersistentEventList(SessionImplementor session) {
> >        this(session, new BasicEventList());
> >    }
> >
> > but that's mostly a style issue, IMO.
> >
> > 3. The only way we could shuttle listeners between BasicEventList A
> > and BasicEventList B would be to store the registered listeners in
> > *another* data structure within PersistentEventList.
> > ListEventPublisher does not support querying for registered listeners
> > at the moment, and this would probably not be a strong enough case for
> > us to open up that API.
> >
> > 4. I'd guess that delaying the loading of data until *after* your
> > EventList pipeline is fully initialized is a virtuous goal. So, I'd
> > discard Holger's second solution for the reason he stated (that read()
> > invokes a lazy load, and thus EventList methods would cause loading)
> >
> > James
> >
> > On 8/17/06, *Bruce Alspaugh* < [hidden email]
> > <mailto:[hidden email]>> wrote:
> >
> >     Hi Holger and James,
> >
> >     I like the idea of taking the original implementation and
> >     overriding beforeInitialize(...) so it would look something like this:
> >
> >     /**
> >     * PersistentEventList for storing a BasicEventList with Hibernate.
> >     */
> >     public final class PersistentEventList extends PersistentList
> >     implements EventList {
> >
> >         /** SerialUID. */
> >         static final long serialVersionUID = 0L;
> >
> >         /**
> >          * Der Konstruktor.
> >          *
> >          * @param session
> >          *            die Session
> >          */
> >         public PersistentEventList(SessionImplementor session) {
> >             super(session);
> >             // instantiate list here to avoid NullPointerExceptions
> >     with lazy loading.
> >             list = new BasicEventList();
> >         }
> >
> >         /**
> >          * Der Konstruktor.
> >          *
> >          * @param session
> >          *            die Session
> >          * @param newList
> >          *            die Liste
> >          */
> >         public PersistentEventList(SessionImplementor session,
> >     EventList newList) {
> >             super(session, newList);
> >         }
> >
> >         /**
> >          * {@inheritDoc}
> >          */
> >         public void beforeInitialize(CollectionPersister persister) {
> >             // avoid overwriting the list if it has already been created
> >             if (this.list == null) {
> >                 this.list = (List)
> >     persister.getCollectionType().instantiate();
> >             }
> >         }
> >
> >         /**
> >          * {@inheritDoc}
> >          */
> >         public void addListEventListener(ListEventListener
> >     listChangeListener) {
> >             ((EventList) list).addListEventListener(listChangeListener);
> >         }
> >
> >         /**
> >          * {@inheritDoc}
> >          */
> >         public ListEventPublisher getPublisher() {
> >             return ((EventList) list).getPublisher();
> >         }
> >
> >         /**
> >          * {@inheritDoc}
> >          */
> >         public ReadWriteLock getReadWriteLock() {
> >             return ((EventList) list).getReadWriteLock();
> >         }
> >
> >         /**
> >          * {@inheritDoc}
> >          */
> >         public void removeListEventListener(ListEventListener
> >     listChangeListener) {
> >             ((EventList)
> >     list).removeListEventListener(listChangeListener);
> >         }
> >     }
> >
> >     This way we don't trigger lazy loading when methods like
> >     getPublisher() and addListEventListener(...) are called, but also
> >     prevent the list member from being overwritten by
> >     beforeInitialize(..) when a 'normal' list method triggers lazy
> >     loading.  It avoids the complications involved in trying to
> >     reassign listeners and other data structures from one list to
> >     another.
> >
> >     I kept searching the Hibernate source code looking for possible
> >     side-effects, but I wasn't able to find any.
> >
> >     I guess it's time to start testing it and see if there are any
> >     problems.  Are we using the same implementation for the
> >     UserCollectionType?
> >
> >     This looks promising. :)
> >
> >     Bruce
> >
> >
> >
> >
> >     ---------------------------------------------------------------------
> >     To unsubscribe, e-mail: [hidden email]
> >     <mailto:[hidden email]>
> >     For additional commands, e-mail: [hidden email]
> >     <mailto:[hidden email]>
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>


______________________________________________________________
Verschicken Sie romantische, coole und witzige Bilder per SMS!
Jetzt bei WEB.DE FreeMail: http://f.web.de/?mc=021193

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


Reply | Threaded
Open this post in threaded view
|

Re: Persisting a GlazedList in Hibernate

Holger
In reply to this post by Bruce Alspaugh-2
James,

no problem, done.
The Ant build now supports the hibernate extension as well.
Tests still to come.
Could you or Jesse create a subcomponent 'hibernate' in the issue tracker?
Then I could file an issue for this enhancement.

Thanks,
Holger

> Looks good. EventListType.java has a small typo in the class doc:
> {@link BasisEventList}Nice catch on the super's difference in constructors, Bruce. Chaining isn't such a good idea here I guess.
>
> Holger, I see you uploaded the hibernate jar to the file repository. Maybe we could rename hibernate3.jar to just hibernate.jar? We have informally adopted the strategy of including the version in the folder structure but not the filename. The hope is that when hibernate4.jar comes out and we upgrade our support, we only have to change the build file to download the hibernate jar from a different path, but its name remains consistent throughout the build file's classpaths.
>
>
> James
>
>
> On 8/17/06, Holger Brands <[hidden email]> wrote:
> Hey guys,
>
> thanks for your feedback.
> I started a hibernate extension in CVS taking into account your
> comments and suggestions.
> Please see
>
> https://glazedlists.dev.java.net/source/browse/glazedlists/extensions/hibernate/source/ca/odell/glazedlists/hibernate/
>
> if it meets your expections.
>
> James, I like your first suggestion and implemented it.
>
> Like Bruce I think your second suggestion would mean a
> change in semantics which is not desired. The collection would be
> marked is initialized although it shouldn't.
>
> Build integration and tests for the extension will follow.
>
>
> Let me know any problems or suggestions.
>
> Thanks,
> Holger
>
>
> > James,
> >
> > I have a quick comment about suggestion 2.  Be careful about calling the
> > two-argument constructor in PersistentEventList.  Right now, it calls
>
> > the inherited two-argument constructor from PersistentList. If you look
> > at the source code for that constructor, you will see this:
> >
> > public PersistentList(SessionImplementor session, List list) {
>
> >     super(session);
> >     this.list = list;
> >     setInitialized();
> >     setDirectlyAccessible(true);
> > }
> >
> > The calls to setInitialized() and setDirectlyAccessible(true) bother
>
> > me.  I'm concerned they might put the PersistentList into a state where
> > it thinks it is already loaded.  The inherited single-argument
> > constructor does not make those calls.
> >
> > Bruce
> >
> > James Lemieux wrote:
> > > Hey guys,
> > >
> > >    I like the direction I'm seeing. Just a few minor suggestions:
> > >
> > > 1. If the constructors can guarantee the list member variable is
>
> > > initialized to something non-null (currently the 2 arg constructor
> > > does not, it should test and throw an exception after its call to
> > > super), then beforeInitialize(...) should probably just become a
>
> > > no-op, or one that throws an IllegalStateException if the list member
> > > is null. (subclasses could unexpectedly destroy this invariant, so I
> > > guess I prefer the IllegalStateException)
> > >
> > > 2. I like chaining constructors, so my personal style would implement
> > > the single arg constructor like so:
> > >
> > >    public PersistentEventList(SessionImplementor session) {
>
> > >        this(session, new BasicEventList());
> > >    }
> > >
> > > but that's mostly a style issue, IMO.
> > >
> > > 3. The only way we could shuttle listeners between BasicEventList A
>
> > > and BasicEventList B would be to store the registered listeners in
> > > *another* data structure within PersistentEventList.
> > > ListEventPublisher does not support querying for registered listeners
>
> > > at the moment, and this would probably not be a strong enough case for
> > > us to open up that API.
> > >
> > > 4. I'd guess that delaying the loading of data until *after* your
> > > EventList pipeline is fully initialized is a virtuous goal. So, I'd
>
> > > discard Holger's second solution for the reason he stated (that read()
> > > invokes a lazy load, and thus EventList methods would cause loading)
> > >
> > > James
> > >
> > > On 8/17/06, *Bruce Alspaugh* <
> [hidden email]
> > > <mailto:[hidden email]>> wrote:
> > >
> > >     Hi Holger and James,
>
> > >
> > >     I like the idea of taking the original implementation and
> > >     overriding beforeInitialize(...) so it would look something like this:
> > >
> > >     /**
> > >     * PersistentEventList for storing a BasicEventList with Hibernate.
>
> > >     */
> > >     public final class PersistentEventList extends PersistentList
> > >     implements EventList {
> > >
> > >         /** SerialUID. */
> > >         static final long serialVersionUID = 0L;
>
> > >
> > >         /**
> > >          * Der Konstruktor.
> > >          *
> > >          * @param session
> > >          *            die Session
> > >          */
> > >         public PersistentEventList(SessionImplementor session) {
>
> > >             super(session);
> > >             // instantiate list here to avoid NullPointerExceptions
> > >     with lazy loading.
> > >             list = new BasicEventList();
> > >         }
>
> > >
> > >         /**
> > >          * Der Konstruktor.
> > >          *
> > >          * @param session
> > >          *            die Session
> > >          * @param newList
>
> > >          *            die Liste
> > >          */
> > >         public PersistentEventList(SessionImplementor session,
> > >     EventList newList) {
> > >             super(session, newList);
>
> > >         }
> > >
> > >         /**
> > >          * {@inheritDoc}
> > >          */
> > >         public void beforeInitialize(CollectionPersister persister) {
> > >             // avoid overwriting the list if it has already been created
>
> > >             if (this.list == null) {
> > >                 this.list = (List)
> > >     persister.getCollectionType().instantiate();
> > >             }
> > >         }
> > >
>
> > >         /**
> > >          * {@inheritDoc}
> > >          */
> > >         public void addListEventListener(ListEventListener
> > >     listChangeListener) {
> > >             ((EventList) list).addListEventListener(listChangeListener);
>
> > >         }
> > >
> > >         /**
> > >          * {@inheritDoc}
> > >          */
> > >         public ListEventPublisher getPublisher() {
> > >             return ((EventList) list).getPublisher();
>
> > >         }
> > >
> > >         /**
> > >          * {@inheritDoc}
> > >          */
> > >         public ReadWriteLock getReadWriteLock() {
> > >             return ((EventList) list).getReadWriteLock();
>
> > >         }
> > >
> > >         /**
> > >          * {@inheritDoc}
> > >          */
> > >         public void removeListEventListener(ListEventListener
> > >     listChangeListener) {
>
> > >             ((EventList)
> > >     list).removeListEventListener(listChangeListener);
> > >         }
> > >     }
> > >
> > >     This way we don't trigger lazy loading when methods like
>
> > >     getPublisher() and addListEventListener(...) are called, but also
> > >     prevent the list member from being overwritten by
> > >     beforeInitialize(..) when a 'normal' list method triggers lazy
>
> > >     loading.  It avoids the complications involved in trying to
> > >     reassign listeners and other data structures from one list to
> > >     another.
> > >
> > >     I kept searching the Hibernate source code looking for possible
>
> > >     side-effects, but I wasn't able to find any.
> > >
> > >     I guess it's time to start testing it and see if there are any
> > >     problems.  Are we using the same implementation for the
>
> > >     UserCollectionType?
> > >
> > >     This looks promising. :)
> > >
> > >     Bruce
> > >
> > >
> > >
> > >
> > >     ---------------------------------------------------------------------
>
> > >     To unsubscribe, e-mail: [hidden email]
> > >     <mailto:
> [hidden email]>
> > >     For additional commands, e-mail: [hidden email]
> > >     <mailto:
> [hidden email]>
> > >
> > >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail:
> [hidden email]
> > For additional commands, e-mail: [hidden email]
> >
>
>
> ______________________________________________________________
>
> Verschicken Sie romantische, coole und witzige Bilder per SMS!
> Jetzt bei WEB.DE FreeMail: http://f.web.de/?mc=021193
>
> ---------------------------------------------------------------------
>
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
>
>


______________________________________________________________
Verschicken Sie romantische, coole und witzige Bilder per SMS!
Jetzt bei WEB.DE FreeMail: http://f.web.de/?mc=021193

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

Reply | Threaded
Open this post in threaded view
|

Re: Persisting a GlazedList in Hibernate

James Lemieux
The hibernate subcomponent is now created. File away.

James

On 8/17/06, Holger Brands <[hidden email]> wrote:
James,

no problem, done.
The Ant build now supports the hibernate extension as well.
Tests still to come.
Could you or Jesse create a subcomponent 'hibernate' in the issue tracker?
Then I could file an issue for this enhancement.

Thanks,
Holger

> Looks good. EventListType.java has a small typo in the class doc:
> {@link BasisEventList}Nice catch on the super's difference in constructors, Bruce. Chaining isn't such a good idea here I guess.
>
> Holger, I see you uploaded the hibernate jar to the file repository. Maybe we could rename hibernate3.jar to just hibernate.jar? We have informally adopted the strategy of including the version in the folder structure but not the filename. The hope is that when hibernate4.jar comes out and we upgrade our support, we only have to change the build file to download the hibernate jar from a different path, but its name remains consistent throughout the build file's classpaths.
>
>
> James
>
>
> On 8/17/06, Holger Brands <[hidden email]> wrote:
> Hey guys,
>
> thanks for your feedback.
> I started a hibernate extension in CVS taking into account your
> comments and suggestions.
> Please see
>
> https://glazedlists.dev.java.net/source/browse/glazedlists/extensions/hibernate/source/ca/odell/glazedlists/hibernate/
>
> if it meets your expections.
>
> James, I like your first suggestion and implemented it.
>
> Like Bruce I think your second suggestion would mean a
> change in semantics which is not desired. The collection would be
> marked is initialized although it shouldn't.
>
> Build integration and tests for the extension will follow.
>
>
> Let me know any problems or suggestions.
>
> Thanks,
> Holger

>
>
> > James,
> >
> > I have a quick comment about suggestion 2.  Be careful about calling the
> > two-argument constructor in PersistentEventList.  Right now, it calls
>
> > the inherited two-argument constructor from PersistentList. If you look
> > at the source code for that constructor, you will see this:
> >
> > public PersistentList(SessionImplementor session, List list) {
>
> >     super(session);
> >     this.list = list;
> >     setInitialized();
> >     setDirectlyAccessible(true);
> > }
> >
> > The calls to setInitialized() and setDirectlyAccessible(true) bother
>
> > me.  I'm concerned they might put the PersistentList into a state where
> > it thinks it is already loaded.  The inherited single-argument
> > constructor does not make those calls.
> >
> > Bruce
> >
> > James Lemieux wrote:
> > > Hey guys,
> > >
> > >    I like the direction I'm seeing. Just a few minor suggestions:
> > >
> > > 1. If the constructors can guarantee the list member variable is
>
> > > initialized to something non-null (currently the 2 arg constructor
> > > does not, it should test and throw an exception after its call to
> > > super), then beforeInitialize(...) should probably just become a
>
> > > no-op, or one that throws an IllegalStateException if the list member
> > > is null. (subclasses could unexpectedly destroy this invariant, so I
> > > guess I prefer the IllegalStateException)
> > >
> > > 2. I like chaining constructors, so my personal style would implement
> > > the single arg constructor like so:
> > >

> > >    public PersistentEventList(SessionImplementor session) {
>
> > >        this(session, new BasicEventList());
> > >    }
> > >
> > > but that's mostly a style issue, IMO.
> > >
> > > 3. The only way we could shuttle listeners between BasicEventList A
>
> > > and BasicEventList B would be to store the registered listeners in
> > > *another* data structure within PersistentEventList.
> > > ListEventPublisher does not support querying for registered listeners
>
> > > at the moment, and this would probably not be a strong enough case for
> > > us to open up that API.
> > >
> > > 4. I'd guess that delaying the loading of data until *after* your
> > > EventList pipeline is fully initialized is a virtuous goal. So, I'd
>
> > > discard Holger's second solution for the reason he stated (that read()
> > > invokes a lazy load, and thus EventList methods would cause loading)
> > >
> > > James
> > >
> > > On 8/17/06, *Bruce Alspaugh* <
> [hidden email]
> > > <mailto:[hidden email]>> wrote:
> > >
> > >     Hi Holger and James,
>
> > >
> > >     I like the idea of taking the original implementation and
> > >     overriding beforeInitialize(...) so it would look something like this:
> > >
> > >     /**
> > >     * PersistentEventList for storing a BasicEventList with Hibernate.

>
> > >     */
> > >     public final class PersistentEventList extends PersistentList
> > >     implements EventList {
> > >
> > >         /** SerialUID. */
> > >         static final long serialVersionUID = 0L;
>
> > >
> > >         /**
> > >          * Der Konstruktor.
> > >          *
> > >          * @param session
> > >          *            die Session
> > >          */
> > >         public PersistentEventList(SessionImplementor session) {
>
> > >             super(session);
> > >             // instantiate list here to avoid NullPointerExceptions
> > >     with lazy loading.
> > >             list = new BasicEventList();
> > >         }
>
> > >
> > >         /**
> > >          * Der Konstruktor.
> > >          *
> > >          * @param session
> > >          *            die Session
> > >          * @param newList
>
> > >          *            die Liste
> > >          */
> > >         public PersistentEventList(SessionImplementor session,
> > >     EventList newList) {
> > >             super(session, newList);
>
> > >         }
> > >
> > >         /**
> > >          * {@inheritDoc}
> > >          */
> > >         public void beforeInitialize(CollectionPersister persister) {
> > >             // avoid overwriting the list if it has already been created
>
> > >             if (this.list == null) {
> > >                 this.list = (List)
> > >     persister.getCollectionType().instantiate();
> > >             }
> > >         }
> > >
>
> > >         /**
> > >          * {@inheritDoc}
> > >          */
> > >         public void addListEventListener(ListEventListener
> > >     listChangeListener) {
> > >             ((EventList) list).addListEventListener(listChangeListener);
>
> > >         }

> > >
> > >         /**
> > >          * {@inheritDoc}
> > >          */
> > >         public ListEventPublisher getPublisher() {
> > >             return ((EventList) list).getPublisher();
>
> > >         }
> > >
> > >         /**
> > >          * {@inheritDoc}
> > >          */
> > >         public ReadWriteLock getReadWriteLock() {
> > >             return ((EventList) list).getReadWriteLock();
>
> > >         }
> > >
> > >         /**
> > >          * {@inheritDoc}
> > >          */
> > >         public void removeListEventListener(ListEventListener
> > >     listChangeListener) {
>
> > >             ((EventList)
> > >     list).removeListEventListener(listChangeListener);
> > >         }
> > >     }
> > >
> > >     This way we don't trigger lazy loading when methods like
>
> > >     getPublisher() and addListEventListener(...) are called, but also
> > >     prevent the list member from being overwritten by
> > >     beforeInitialize(..) when a 'normal' list method triggers lazy
>
> > >     loading.  It avoids the complications involved in trying to
> > >     reassign listeners and other data structures from one list to
> > >     another.
> > >
> > >     I kept searching the Hibernate source code looking for possible
>

> > >     side-effects, but I wasn't able to find any.
> > >
> > >     I guess it's time to start testing it and see if there are any
> > >     problems.  Are we using the same implementation for the
>
> > >     UserCollectionType?
> > >
> > >     This looks promising. :)
> > >
> > >     Bruce
> > >
> > >
> > >
> > >
> > >     ---------------------------------------------------------------------
>
> > >     To unsubscribe, e-mail: [hidden email]
> > >     <mailto:
> [hidden email]>
> > >     For additional commands, e-mail: [hidden email]
> > >     <mailto:
> [hidden email]>
> > >
> > >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail:
> [hidden email]
> > For additional commands, e-mail: [hidden email]
> >
>
>
> ______________________________________________________________
>
> Verschicken Sie romantische, coole und witzige Bilder per SMS!
> Jetzt bei WEB.DE FreeMail: http://f.web.de/?mc=021193
>
> ---------------------------------------------------------------------
>
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
>
>


______________________________________________________________
Verschicken Sie romantische, coole und witzige Bilder per SMS!
Jetzt bei WEB.DE FreeMail: http://f.web.de/?mc=021193

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