change of a property of a collection's item

8 posts / 0 new
Last post
atao
Offline
Joined: 10/15/2008
change of a property of a collection's item

Vincent

I have a 1-n link with an attribute on the one side component which  must be updated each time an attribute of any instance on the N side is changed.

With a bidirectional link, it's ok as I can get the one side's component in a listener defined in an extension class on the N side.

But I want to set this link as unidirectional. Is there a simple way to proceed in such a case?

 

Regards

Pierre

vvandens
Offline
Joined: 05/29/2008
change of a property of a collection's item

Hi Pierre,

The only way I can think of consists in registering a collection property processor (extends the org.jspresso.framework.util.bean.integrity.EmptyCollectionPropertyProcessor adapter) on the master entity (the 1 side) that you will attach to the collection property. It will be notified every time the collection changes. Now you need to be able to listen to single property changes on each of the collection element.

In the postprocessAdder method, add a property change listener to the added collection element that will be notified each time one of the element property is updated (you may write a service delegate and attach it to your master entity so that it implements PropertyChangeListener and thus can itself listen to change events).

In the postprocessRemover method, remove your property change listener from the removed collection element to clean-up things.

The only problem I can foresee right now with this approach - and that is certainly missing in the framework - is the capacity to be notified when an entity is (re)loaded from the store to perform some extra initialization (in your case, re-attach the listener to each of the existing collection elements). This is due to the fact that property processors are by-passed (which is normal) when an entity is (re)loaded from the store.

It shouldn't be too difficult to improve (we should complete the ILifecycleInterceptor and ILifecycleCapable interfaces with an onLoad method that will be triggered each time the state of an entity is restored from the backend store).

If you can confirm me that this solution meets your needs (maybe you can experiment it until the onLoad missing feature), I will be glad to work the last part hopefully this week.

 

Regards,

Vincent

 

atao
Offline
Joined: 10/15/2008
change of a property of a collection's item

Vincent,

Sorry for this late answer.

I just finished to "experiment" with your propositions. It seems ok. I put the list item listeners in the list postprocessAdder/remover where they fire a list change.

And even not this week, I'm waiting for the onLoad feature...

Regards

Pierre

 

vvandens
Offline
Joined: 05/29/2008
change of a property of a collection's item

Hi Pierre,

I took some time this morning to implement the onLoad interceptor. It should only be used to perform technical initializations like the one you have to do since Hibernate postLoad event listeners are tied to the session factory and thus have to be considered as stateless singletons (can't use anything linked to the application session in it).

One note about it : onLoad will be called each time the entity is actually loaded by Hibernate but also internally by the framework when cloning an entity to the "unit of work" (so that the cloned entity is also initialized with your listener) and when merging "unit of work" entities back in the application session (the collection might have new items added in the "unit of work" and silently cloned back in the application session). This implies that initializations made inside the onLoad interceptor has to be idempotent (in your case, before attaching the listener to the collection elements, check that you haven't already done so to avoid duplicate attachments).

Finally, inlined components also benefit from the lifecycle interceptor, and thus the new onLoad one.

The Jspresso snapshot repository has been updated in both branches with the feature.

Don't hesitate to post back if you face any problem.

 

Best regards,

Vincent

atao
Offline
Joined: 10/15/2008
change of a property of a collection's item

Vincent,

I try this code:

public class ContractInterceptor
extends EmptyLifecycleInterceptor<Contract> {

    @Override
    public void onLoad(Contract contract) {
        for(ContractPeriod period:contract.getPeriods()) {
        }
    }
   
}

and I get on "getPeriods":

Caused by: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions

Is there anything to do with the collection Contract.periods specified with default "lazy-loading"?

Regards

Pierre

atao
Offline
Joined: 10/15/2008
change of a property of a collection's item

Vincent

 

I found a work around: I replaced

    contract.getPeriods()

 

by

    (List<ContractPeriod>) contract.straightGetProperty("periods")

 

But I still don't understand why it's necessary.

 

Regards

Pierre

 

 

vvandens
Offline
Joined: 05/29/2008
change of a property of a collection's item

Hi Pierre,

Thanks for reporting the anomaly. There was actually a problem that should be fixed now. It is linked to the way Jspresso manages the Hibernate session(s) and copes with lazy initialization.

You can update to the latest snapshot and remove your workaround. Tell me if it works for you.

 

Regards,

Vincent

atao
Offline
Joined: 10/15/2008
change of a property of a collection's item

Vincent,

Everything runs fine.

Thanks

Pierre