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
>>>>>
>>
>
>