deltaspike-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nico Schlebusch <nicos...@gmail.com>
Subject DeltaSpike Data - Custom PrePersistAuditListener and PreUpdateAuditListener
Date Wed, 07 Dec 2016 10:22:26 GMT
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
nicoschl@gmail.com <mailto:nicoschl@gmail.com>



Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message