Wildfly 9.0.2.Final の Deltaspike バージョン 1.7.2
エンティティ Bean でJPA@EntityListeners(AuditEntityListener.class)
と Deltaspike Data ( @CreatedOn
、@ModifiedOn
および注釈) の監査機能を使用していますが、 + OR aを UTC の日付と時刻に変換@ModifiedBy
するカスタム実装があるという違いがあります。java.time.ChronoLocalDateTime
LocalDateTime
ZoneOffset
ZonedDateTime
UTCDateTime
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
}
エンティティ Bean のパーツ
@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
}
エポック値がデータベースに保存されるため、UTCDateTime クラスのカスタム AttributeConverter もあります。
@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;
}
}
エンティティを永続化すると、次の例外が発生します (本当の原因の最後のビット)。
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)
org.apache.deltaspike.data.impl.audit.PrePersistAuditListener
独自のものを実装し、org.apache.deltaspike.data.impl.audit.PreUpdateAuditListener
それらを使用して のインスタンスを作成する方法はありますUTCDateTime
か?
独自の EntityListener を作成して -->アプローチの次の場所でUTCDateTimeAuditListener
使用するのは正しいでしょうか?@EntityListeners(UTCDateTimeAuditEntityListener.class)
UTCDateTimeAuditListener
org.apache.deltaspike.data.impl.audit.AuditEntityListener
次に、インスタンスの構築方法を知ってUTCDateTimeAuditEntityListener
いる正しい実装への参照を確実に取得するために、どこかで CDI 修飾子を使用する必要がありPrePersistAuditListener
ますか?PreUpdateAuditListener
UTCDateTime
最後に、関連性があるかどうかはわかりませんが、org.apache.deltaspike.data.impl.audit.TimestampsProvider
このシナリオのどこに当てはまりますか?
アップデート
質問への回答が少し進みました。私がこれまでにやってきたこと。カスタムの必要はありませんAuditEntityListener
。DeltaSpike が提供するもので十分です。
オブジェクトTimestampsProvider
を処理できる の新しい実装を作成しました。UTCDateTime
@Alternative
@Dependent
public class UTCDateTimeAuditProvider implements PrePersistAuditListener, PreUpdateAuditListener {
// implementation details not important
}
beans.xml には、これも CDI @Alternative としてリストされています。
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="annotated">
<alternatives>
<class>systems.apace.data.manufacturer.model.UTCDateTimeAuditProvider</class>
</alternatives>
</beans>
の内容apache-deltaspike.properties
globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy=org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy
問題は、両方のAuditProvider
インスタンスが実行されることです。最初に実装 ( UTCDateTimeAuditProvider
) が実行され、次にデフォルトが実行されます。TimestampsProvider
2016-12-13 01:29:22,929 INFO Apace-BPS s.a.d.m.m.UTCDateTimeAuditProvider [ServerService Thread Pool -- 319] [Unknown Id] - prePersist: class systems.apace.data.manufacturer.model.UTCDateTimeAuditProvider
2016-12-13 01:29:22,931 INFO Apace-BPS s.a.d.m.m.UTCDateTimeAuditProvider [ServerService Thread Pool -- 319] [Unknown Id] - Updated property Manufacturer.insertedOn with 2016-12-12T23:29:22.930
2016-12-13 01:29:22,932 INFO Apace-BPS z.c.t.c.b.e.EntityManagerProducer [ServerService Thread Pool -- 319] [Unknown Id] - username of Principal: anonymous
2016-12-13 01:29:22,932 FINER [org.apache.deltaspike.data.impl.audit.AuditProvider] (ServerService Thread Pool -- 319) Updated Manufacturer.updatedBy with anonymous
2016-12-13 01:29:22,935 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 319) MSC000001: Failed to start service jboss.deployment.subunit."bpsserver.ear"."systems-apace-data-model-1.0-SNAPSHOT.jar".component.ManufacturerSi
ngleton.START: org.jboss.msc.service.StartException in service jboss.deployment.subunit."bpsserver.ear"."systems-apace-data-model-1.0-SNAPSHOT.jar".component.ManufacturerSingleton.START: java.lang.IllegalStateException: WFLYEE0042: Failed
to construct component instance
at org.jboss.as.ee.component.ComponentStartService$1.run(ComponentStartService.java:57)
...
Caused by: org.apache.deltaspike.data.impl.audit.AuditPropertyException: Failed to set property Manufacturer.insertedOn, is this a temporal type?
at org.apache.deltaspike.data.impl.audit.TimestampsProvider.setProperty(TimestampsProvider.java:86)
at org.apache.deltaspike.data.impl.audit.TimestampsProvider.updateTimestamps(TimestampsProvider.java:67)
at org.apache.deltaspike.data.impl.audit.TimestampsProvider.prePersist(TimestampsProvider.java:43)
at org.apache.deltaspike.data.impl.audit.AuditEntityListener.persist(AuditEntityListener.java:42)
...
Caused by: java.lang.IllegalArgumentException: Annotated field is not a date class: class za.co.t9.common.utils.time.UTCDateTime
at org.apache.deltaspike.data.impl.audit.TimestampsProvider.now(TimestampsProvider.java:115)
at org.apache.deltaspike.data.impl.audit.TimestampsProvider.setProperty(TimestampsProvider.java:79)
... 115 more
@Alternative 実装をアノテーションのみ、またはbeans.xmlのみ、およびクラスとbeans.xmlの両方で指定するさまざまな組み合わせを試しました。
TimestampsProvider
@Alternative の実装後にデフォルトが実行される理由を知っている人はいますか?
Wildfly 9.0.2 の Deltaspike バージョン 1.7.2.Final with Weld 2.2.16 (SP1)