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