I'm not giving up on them, just running out of time to work on the issue. I 
have a tight deadline for delivering a working prototype to test the concept. 
After that's done I can figure out what the best way to do something is, and go 
back and make that work. Listeners do look like a great way for separate code 
sections to watch what's happening to each other.

Right now, I'm fighting against the caching hanging on to empty results 
(separate thread). Trying to find a workaround.

Joe

On Aug 4, 2011, at 10:45 AM, Andrus Adamchik wrote:

> Still odd. We were using trunk builds of Cayenne to test it, that are fairly 
> close to M2 (and I don't see any recent listener-related bugfixes). So there 
> has to be something else. 
> 
> Glad you found a workaround, still don't give up on the listeners in general 
> - they do work. There has to be some simple reason why they didn't.
> 
> Andrus
> 
> 
> On Aug 4, 2011, at 8:21 PM, Joseph Senecal wrote:
>> Thanks. It looks like I was doing it right, but it just wasn't working for 
>> me using Cayenne 3.1M2. 
>> 
>> For now I'm generating code in the validation methods. Which given the 
>> operations I'm doing, might actually be a better place. What I'm doing is 
>> automatically setting or updating fields used internally but in the external 
>> business logic: creationDate, lastModDate, and modCount. The more I think 
>> about it the more putting these specific operations into the generated 
>> superclass template makes sense.
>> 
>> Joe
>> 
>> On Aug 4, 2011, at 5:03 AM, Dzmitry Kazimirchyk wrote:
>> 
>>> Hi Joe,
>>> 
>>> Behaviour that you've described seems little bit strange to me. Trying to 
>>> reproduce it I've written following:
>>> 
>>> ObjEntity in my map.xml:
>>> 
>>> <obj-entity name="Artist" className="org.test.cayenne.persistent.Artist" 
>>> dbEntityName="Artist">
>>> <obj-attribute name="name" type="java.lang.String" 
>>> db-attribute-path="NAME"/>
>>> <entity-listener class="org.test.cayenne.listen.TestListener">
>>> <pre-persist method-name="onPrePersist"/>
>>> <pre-update method-name="onPreUpdate"/>
>>> </entity-listener>
>>> </obj-entity>
>>> 
>>> Also I registered same listener for DataMap.
>>> 
>>> <entity-listener class="org.test.cayenne.listen.TestListener">
>>> <pre-persist method-name="onPrePersist"/>
>>> <pre-update method-name="onPreUpdate"/>
>>> </entity-listener>
>>> 
>>> The listener class itself:
>>> 
>>> public class TestListener {
>>> 
>>> void onPrePersist (Object object) {
>>>     System.out.println("pre-persist");
>>> }
>>> 
>>> void onPreUpdate (Object object) {
>>>     System.out.println("pre-update");
>>> }
>>> }
>>> 
>>> Place where events are actually triggered:
>>> 
>>>     ServerRuntime cayenneRuntime = new 
>>> ServerRuntime("cayenne-testDomain.xml");
>>> 
>>>     ObjectContext context = cayenneRuntime.getContext();
>>> 
>>>     // testing persist events
>>>     Artist a = context.newObject(Artist.class);
>>>     context.commitChanges();
>>> 
>>>     //testing update events
>>>     a.setName("name");
>>>     context.commitChanges();
>>> 
>>> Both pre-persist and pre-update events were triggered correctly calling 
>>> corresponding listener methods. I've tried this also for other events but 
>>> got the same result.
>>> Am I missing something important in your particular case?
>>> 
>>> On 08/03/2011 11:04 PM, Joseph Senecal wrote:
>>>> Perhaps I'm just missing something simple. I've tried using individual 
>>>> listener configurations, and they don't work either.
>>>> 
>>>> Here is a sample entry:
>>>>            <entity-listener class="com.apple.mqm.db.PDCAListener">
>>>>                    <pre-persist method-name="onPrePersist"/>
>>>>                    <pre-update method-name="onPreUpdate"/>
>>>>            </entity-listener>
>>>> 
>>>> 
>>>> And here is my listener class:
>>>> package com.apple.mqm.db;
>>>> 
>>>> import java.util.Date;
>>>> 
>>>> import org.apache.cayenne.CayenneDataObject;
>>>> 
>>>> public class PDCAListener {
>>>> 
>>>>    void onPrePersist (Object object) {
>>>>            CayenneDataObject dataObject = (CayenneDataObject) object;
>>>>            if (dataObject.readProperty(Product.CREATION_DATE_PROPERTY) == 
>>>> null) {
>>>>                    
>>>> dataObject.writeProperty(Product.CREATION_DATE_PROPERTY, new Date());
>>>>            }
>>>>            if (dataObject.readProperty(Product.LAST_MOD_DATE_PROPERTY) == 
>>>> null) {
>>>>                    
>>>> dataObject.writeProperty(Product.LAST_MOD_DATE_PROPERTY, new Date());
>>>>            }
>>>>            dataObject.writeProperty(Product.MOD_COUNT_PROPERTY, 1);
>>>>    }
>>>> 
>>>>    void onPreUpdate (Object object) {
>>>>            CayenneDataObject dataObject = (CayenneDataObject) object;
>>>>            dataObject.writeProperty(Product.LAST_MOD_DATE_PROPERTY, new 
>>>> Date());
>>>>            dataObject.writeProperty(Product.MOD_COUNT_PROPERTY, 
>>>> ((Integer)dataObject.readProperty(Product.LAST_MOD_DATE_PROPERTY))+1);
>>>>    }
>>>> }
>>>> 
>>>> 
>>>> I don't have any code to activate the listeners. When testing I'm getting 
>>>> a validation error that for a field that this listener sets onPrePersist. 
>>>> And I never reach a breakpoint in the listener code.
>>>> 
>>>> Joe
>>>> 
>>>> 
>>>> On Aug 3, 2011, at 11:12 AM, Andrus Adamchik wrote:
>>>> 
>>>>> Ok, we'll need to re-test this case, and implement the missing 
>>>>> registration API.
>>>>> 
>>>>> On Aug 3, 2011, at 9:09 PM, Joseph Senecal wrote:
>>>>>> Andrus,
>>>>>> 
>>>>>> Yes, I was using a per DataMap listener.
>>>>>> 
>>>>>> I'll try using individual class listeners for the prototype and see how 
>>>>>> that works.
>>>>>> 
>>>>>> These listeners are really part of the basic operation of the DB 
>>>>>> interface, so they are common to all programs using the database. 
>>>>>> Currently I'm considering having the template generate the listener 
>>>>>> methods in each class, along with code that will install the listener 
>>>>>> for that class the first time the class is referenced (probably using a 
>>>>>> static initializer). This will allow the listener methods to be 
>>>>>> customized for each class instead of having to check the model. 
>>>>>> Annotations will help there.
>>>>>> 
>>>>>> Joe
>>>>>> 
>>>>>> On Aug 3, 2011, at 10:50 AM, Andrus Adamchik wrote:
>>>>>> 
>>>>>>> Hi Joe,
>>>>>>> 
>>>>>>> On Aug 3, 2011, at 10:29 AM, Joseph Senecal wrote:
>>>>>>> 
>>>>>>>> I'm trying to configure a single listener object to listen to a couple 
>>>>>>>> of events for all objects. This is to update modCounts and 
>>>>>>>> lastModTimes just before the commit.
>>>>>>>> 
>>>>>>>> The documentation says this is configured in the Cayenne modeler, but 
>>>>>>>> doesn't explain how. I found how to specify a class and methods, but 
>>>>>>>> it doesn't seem to be getting called.
>>>>>>> This is odd. This certainly works for me. Here is an example from one 
>>>>>>> of my map.xml files (created by the Modeler) :
>>>>>>> 
>>>>>>> This part is a listener within<obj-enntity>  tags:
>>>>>>> 
>>>>>>>         <entity-listener class="com.foo.listener.MyListener">
>>>>>>>                 <post-persist method-name="objectPostPersistCallback"/>
>>>>>>>         </entity-listener>
>>>>>>> 
>>>>>>> This part is callbacks on persistent objects themselves:
>>>>>>> 
>>>>>>>         <post-add method-name="onPostAdd"/>
>>>>>>>         <pre-update method-name="onPreUpdate"/>
>>>>>>> 
>>>>>>> These are per-entity callbacks/listeners. Are you setting a listener 
>>>>>>> per DataMap? (I personally haven't used "global" listeners, but those 
>>>>>>> should work too). Could you confirm - we'll re-test this case then.
>>>>>>> 
>>>>>>>> I can see how to do it programmatically, but is there a cleaner 
>>>>>>>> solution that I'm missing?
>>>>>>> Personally I am moving to setting everything programmatically, as it 
>>>>>>> allows me to have different listeners for the same shared entities in 
>>>>>>> different Java projects. So my preferred method is the latest 3.1M2 API 
>>>>>>> based on annotations:
>>>>>>> 
>>>>>>> runtime.getChannel().getEntityResolver().getCallbackRegistry().addListener(listener)
>>>>>>> 
>>>>>>> But again - this is for per-entity listeners. Not per-DataMap. (Which 
>>>>>>> reminds me - we need to support this flavor in per-DataMap case).
>>>>>>> 
>>>>>>> Cheers,
>>>>>>> Andrus
>>>>>> 
>>> 
>> 
>> 
> 

Reply via email to