deltaspike-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "John D. Ament" <johndam...@apache.org>
Subject Re: DeltaSpike Data - Custom PrePersistAuditListener and PreUpdateAuditListener
Date Tue, 20 Dec 2016 15:23:58 GMT
Ok, that makes sense.  I wanted to verify your behavior, which means
alternative makes no sense here.

So with that said, what I'm thinking is that you can forcibly veto the
class in a portable extension to disable its execution.  It would be as
simple as

    public void rejectDefaultClass(@Observes
ProcessAnnotatedType<TimestampsProvider> pat) {
        pat.veto();
    }


John

On Tue, Dec 20, 2016 at 9:54 AM Nico Schlebusch <nicoschl@gmail.com> wrote:

> John,
>
> That loop executes the number of times there are implementations of the
> PrePersistAuditListener. When I have my own implementation deployed it
> executes 3 times. The PrincipalProvider, my custom implementation
> (UTCDateTimeAuditProvider) and then TimestampsProvider are executed in
> that order.
>
> Kind regards,
> Nico Schlebusch
> nicoschl@gmail.com <mailto:nicoschl@gmail.com>
>
>
> On 20/12/2016 16:33, John D. Ament wrote:
> > Nico,
> >
> > There's a for loop here
> >
> https://github.com/apache/deltaspike/blob/master/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditEntityListener.java#L38
> >
> > How many times does this for loop execute?
> >
> > John
> >
> > On Tue, Dec 20, 2016 at 9:23 AM Nico Schlebusch <nicoschl@gmail.com>
> wrote:
> >
> >> 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
> >> nicoschl@gmail.com
> >>
> >>
> >> 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 <nicoschl@gmail.com>
> >> 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
> >> nicoschl@gmail.com <mailto:nicoschl@gmail.com>
> >>
> >>
> >> 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
> >>> nicoschl@gmail.com <mailto:nicoschl@gmail.com>
> >>>
> >>>
> >>
> >>
> >>
>
>
>

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