Hi John,

Thanks for the answer.

The AuditEntityListener is called once from my debugging sessions.

I'll definitely raise a feature request, it might just not be in the next 2 weeks. Would the feature request be to take @Alternative beans into considerations when looking up the beans that implements the 2 interfaces, PrePersistAuditListener & PreUpdateAuditListener? Meaning that lines 40-41 and 53-54 from the link below, need to filter out the @Default beans when an @Alternative is available? Or should I phrase it differently?

Kind regards,
Nico Schlebusch
[email protected] <mailto:[email protected]>


On 20/12/2016 15:56, John D. Ament wrote:
Nico,

Seems the logic in DeltaSpike is to loop through the beans. Can you check if you're seeing this loop is called multiple times? https://github.com/apache/deltaspike/blob/master/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditEntityListener.java

Anyways, would be good to have this support direct in deltaspike. Mind raising a feature request? https://issues.apache.org/jira/browse/DELTASPIKE

John

On Tue, Dec 13, 2016 at 2:58 AM Nico Schlebusch <[email protected] <mailto:[email protected]>> wrote:

    Good day,

    I have made some progress in answering my question, but I'm facing
    a new
    problem. Please see the updated Q on SO -
    
http://stackoverflow.com/questions/41057116/deltaspike-data-cdi-jpa-custom-prepersistauditlistener-and-preupdateauditlis

    Thank you

    Kind regards,
    Nico Schlebusch
    [email protected] <mailto:[email protected]>
    <mailto:[email protected] <mailto:[email protected]>>


    On 07/12/2016 12:22, Nico Schlebusch wrote:
    > Good day,
    >
    > I'm using the @EntityListeners(AuditEntityListener.class) and
    > @CreatedOn, @ModifiedOn and @ModifiedBy annotations on an Entity
    bean
    > with the difference that I have a custom implementation of
    > java.time.ChronoLocalDateTime which converts any LocalDateTime +
    > ZoneOffset OR a ZonedDateTime to be the UTC date & time.
    >
    >     public class UTCDateTime implements
    >     ChronoLocalDateTime<LocalDate>, Serializable {
    >
    >       private static final long serialVersionUID =
    6492792765662073566L;
    >       private static final ZoneOffset UTC = ZoneOffset.UTC;
    >       private final LocalDateTime datetime;
    >
    >       // a lot of other details left out
    >     }
    >
    > The entity bean parts
    >
    >     @MappedSuperclass
    >     public class InsertableAuditableBean extends BaseBean implements
    >     InsertableAuditable {
    >
    >       @NotNull
    >       @Size(min = 1, max = 50)
    >       @Column(name = "zz_inserted_by", length = 50, nullable =
    false)
    >       private String insertedBy;
    >
    >     @CreatedOn
    >       @NotNull
    >       @Temporal(value = TemporalType.TIMESTAMP)
    >       @Column(name = "zz_inserted_on", nullable = false)
    >       private UTCDateTime insertedOn;
    >
    >       // getters & setters
    >     }
    >
    >     @MappedSuperclass
    >     public class UpdateableAuditableBean extends
    >     InsertableAuditableBean implements UpdateableAuditable {
    >
    >     @ModifiedBy
    >       @Size(min = 1, max = 50)
    >       @Column(name = "zz_updated_by", length = 50, nullable = true)
    >       private String updatedBy;
    >
    >     @ModifiedOn
    >       @Temporal(value = TemporalType.TIMESTAMP)
    >       @Column(name = "zz_updated_on", nullable = true)
    >       private UTCDateTime updatedOn;
    >
    >       // getters & setters
    >     }
    >
    >     @Entity
    >     @EntityListeners(AuditEntityListener.class)
    >     @Table(schema = "data", name = "manufacturer",
    uniqueConstraints = {
    >         @UniqueConstraint(columnNames = { "man_name",
    "man_country" })
    >     })
    >     @AttributeOverrides({
    >         @AttributeOverride(name = "primaryKey", column =
    @Column(name
    >     = "man_serial")),
    >         @AttributeOverride(name = "insertedBy", column =
    @Column(name
    >     = "man_inserted_by")),
    >         @AttributeOverride(name = "insertedOn", column =
    @Column(name
    >     = "man_inserted_on")),
    >         @AttributeOverride(name = "updatedBy", column =
    @Column(name =
    >     "man_updated_by")),
    >         @AttributeOverride(name = "updatedOn", column =
    @Column(name =
    >     "man_updated_on"))
    >     })
    >     @SequenceGenerator(name = "default_seq", schema = "data",
    >     sequenceName = "manufacturer_man_serial_seq",
    >         allocationSize = 1)
    >     public class Manufacturer extends
    MirroredUpdateableAuditableBean
    >     implements IManufacturer {
    >       // nothing special here
    >     }
    >
    > There is also a custom AttributeConverter for the UTCDateTime class
    > because the epoch value is saved in the database.
    >
    >     @Converter(autoApply = true)
    >     public class UTCDateTimePersistenceConverter implements
    >     AttributeConverter<UTCDateTime, Long> {
    >
    >       @Override
    >       public Long convertToDatabaseColumn(final UTCDateTime
    entityValue) {
    >         Long res = null;
    >         if (entityValue != null) {
    >           res = entityValue.toMillis();
    >         }
    >         return res;
    >       }
    >
    >       @Override
    >       public UTCDateTime convertToEntityAttribute(final Long
    >     databaseValue) {
    >         UTCDateTime res = null;
    >         if (databaseValue != null) {
    >           res = new
    UTCDateTime(Instant.ofEpochMilli(databaseValue));
    >         }
    >         return res;
    >       }
    >     }
    >
    > Now when I persist the entity I get the following exception (the
    last
    > bit with the real cause):
    >
    >     Caused by:
    >  org.apache.deltaspike.data.api.QueryInvocationException: Failed
    >     calling Repository:
    >
     
[Repository=systems.apace.data.manufacturer.model.dao.ManufacturerDAO,entity=systems.apace.data.manufacturer.model.Manufacturer,method=persist,exception=class
    >  java.lang.reflect.InvocationTargetException,message=null
    >             at
    >
     
systems.apace.data.manufacturer.services.ManufacturerServiceBeanIntegrationTest.testInsertBean(ManufacturerServiceBeanIntegrationTest.java:55)
    >     Caused by: java.lang.reflect.InvocationTargetException
    >             at
    >
     
systems.apace.data.manufacturer.services.ManufacturerServiceBeanIntegrationTest.testInsertBean(ManufacturerServiceBeanIntegrationTest.java:55)
    >     Caused by:
    >  org.apache.deltaspike.data.impl.audit.AuditPropertyException:
    >     Failed to set property Manufacturer.insertedOn, is this a
    temporal
    >     type?
    >             at
    >
     
systems.apace.data.manufacturer.services.ManufacturerServiceBeanIntegrationTest.testInsertBean(ManufacturerServiceBeanIntegrationTest.java:55)
    >     Caused by: java.lang.IllegalArgumentException: Annotated
    field is
    >     not a date class: class za.co.t9.common.utils.time.UTCDateTime
    >             at
    >
     
systems.apace.data.manufacturer.services.ManufacturerServiceBeanIntegrationTest.testInsertBean(ManufacturerServiceBeanIntegrationTest.java:55)
    >
    > Is there a way to implement my own
    > org.apache.deltaspike.data.impl.audit.PrePersistAuditListener and
    > org.apache.deltaspike.data.impl.audit.PreUpdateAuditListener and use
    > them to create the instance of UTCDateTime?
    >
    > Would it be correct to write my own EntityListener -->
    > UTCDateTimeAuditListener and use it
    > @EntityListeners(UTCDateTimeAuditEntityListener.class) where
    > UTCDateTimeAuditListener follows the
    > org.apache.deltaspike.data.impl.audit.AuditEntityListener approach?
    > Secondly, do I need to use a CDI Qualifier somewhere to make
    sure that
    > my UTCDateTimeAuditEntityListener gets a reference to the correct
    > PrePersistAuditListener and PreUpdateAuditListener that knows how to
    > construct the UTCDateTime instance?
    >
    > Lastly, I don't know if it is relevant, but where does
    > org.apache.deltaspike.data.impl.audit.TimestampsProvider fit
    into this
    > scenario?
    >
    > Thank you for your time
    >
    > Kind regards,
    > Nico Schlebusch
    > [email protected] <mailto:[email protected]>
    <mailto:[email protected] <mailto:[email protected]>>
    >
    >




Reply via email to