diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/AuditableEmbeddable.java b/src/test/java/org/springframework/data/jpa/domain/sample/AuditableEmbeddable.java new file mode 100644 index 0000000000..562e7341d4 --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/domain/sample/AuditableEmbeddable.java @@ -0,0 +1,54 @@ +/* + * Copyright 2008-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.domain.sample; + +import java.time.Instant; + +import javax.persistence.Embeddable; + +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +/** + * JPA {@link Embeddable} to test out {@link org.springframework.data.jpa.domain.support.AuditingEntityListener}. + * + * @author Greg Turnquist + */ +@Embeddable +public class AuditableEmbeddable { + + @CreatedDate // + private Instant dateCreated; + + @LastModifiedDate // + private Instant dateUpdated; + + public Instant getDateCreated() { + return dateCreated; + } + + public void setDateCreated(Instant dateCreated) { + this.dateCreated = dateCreated; + } + + public Instant getDateUpdated() { + return dateUpdated; + } + + public void setDateUpdated(Instant dateUpdated) { + this.dateUpdated = dateUpdated; + } +} diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/AuditableEntity.java b/src/test/java/org/springframework/data/jpa/domain/sample/AuditableEntity.java new file mode 100644 index 0000000000..b1fcc7aff2 --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/domain/sample/AuditableEntity.java @@ -0,0 +1,78 @@ +/* + * Copyright 2008-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.domain.sample; + +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +/** + * JPA entity with an {@link Embedded} set of auditable data. + * + * @author Greg Turnquist + */ +@Entity +@EntityListeners(AuditingEntityListener.class) +public class AuditableEntity { + + @Id + @GeneratedValue // + private Long id; + + private String data; + + @Embedded // + private AuditableEmbeddable auditDetails; + + public AuditableEntity() { + this(null, null, null); + } + + public AuditableEntity(Long id, String data, AuditableEmbeddable auditDetails) { + + this.id = id; + this.data = data; + this.auditDetails = auditDetails; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public AuditableEmbeddable getAuditDetails() { + return auditDetails; + } + + public void setAuditDetails(AuditableEmbeddable auditDetails) { + this.auditDetails = auditDetails; + } +} diff --git a/src/test/java/org/springframework/data/jpa/domain/support/AuditingEntityWithEmbeddableListenerTests.java b/src/test/java/org/springframework/data/jpa/domain/support/AuditingEntityWithEmbeddableListenerTests.java new file mode 100644 index 0000000000..8f94078e5f --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/domain/support/AuditingEntityWithEmbeddableListenerTests.java @@ -0,0 +1,91 @@ +/* + * Copyright 2008-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.domain.support; + +import static org.assertj.core.api.Assertions.*; + +import java.time.Instant; +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.domain.sample.AuditableEmbeddable; +import org.springframework.data.jpa.domain.sample.AuditableEntity; +import org.springframework.data.jpa.repository.sample.AuditableEntityRepository; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +/** + * Integration test for {@link AuditingEntityListener}. + * + * @author Greg Turnquist + */ +@ExtendWith(SpringExtension.class) +@ContextConfiguration("classpath:auditing/auditing-entity-with-embeddable-listener.xml") +public class AuditingEntityWithEmbeddableListenerTests { + + @Autowired AuditableEntityRepository repository; + + private AuditableEntity entity; + private AuditableEmbeddable auditDetails; + + @BeforeEach + void setUp() { + + entity = new AuditableEntity(); + entity.setId(1L); + entity.setData("original value"); + + auditDetails = new AuditableEmbeddable(); + entity.setAuditDetails(auditDetails); + } + + @Test + void auditsEmbeddedCorrectly() { + + // when + repository.saveAndFlush(entity); + Optional optionalEntity = repository.findById(1L); + + // then + assertThat(optionalEntity).isNotEmpty(); + + AuditableEntity auditableEntity = optionalEntity.get(); + assertThat(auditableEntity.getData()).isEqualTo("original value"); + + assertThat(auditableEntity.getAuditDetails().getDateCreated()).isNotNull(); + assertThat(auditableEntity.getAuditDetails().getDateUpdated()).isNotNull(); + + Instant originalCreationDate = auditableEntity.getAuditDetails().getDateCreated(); + Instant originalDateUpdated = auditableEntity.getAuditDetails().getDateUpdated(); + + auditableEntity.setData("updated value"); + + repository.saveAndFlush(auditableEntity); + + Optional optionalRevisedEntity = repository.findById(1L); + + assertThat(optionalRevisedEntity).isNotEmpty(); + + AuditableEntity revisedEntity = optionalRevisedEntity.get(); + assertThat(revisedEntity.getData()).isEqualTo("updated value"); + + assertThat(revisedEntity.getAuditDetails().getDateCreated()).isEqualTo(originalCreationDate); + assertThat(revisedEntity.getAuditDetails().getDateUpdated()).isAfter(originalDateUpdated); + } +} diff --git a/src/test/java/org/springframework/data/jpa/repository/sample/AuditableEntityRepository.java b/src/test/java/org/springframework/data/jpa/repository/sample/AuditableEntityRepository.java new file mode 100644 index 0000000000..574e1abc9c --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/repository/sample/AuditableEntityRepository.java @@ -0,0 +1,24 @@ +/* + * Copyright 2008-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.repository.sample; + +import org.springframework.data.jpa.domain.sample.AuditableEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * {@link JpaRepository} to test {@link org.springframework.data.jpa.domain.support.AuditingEntityListener}. + */ +public interface AuditableEntityRepository extends JpaRepository {} diff --git a/src/test/resources/META-INF/persistence.xml b/src/test/resources/META-INF/persistence.xml index 4932fb86a9..30dcdadf07 100644 --- a/src/test/resources/META-INF/persistence.xml +++ b/src/test/resources/META-INF/persistence.xml @@ -10,6 +10,8 @@ org.springframework.data.jpa.domain.sample.AnnotatedAuditableUser org.springframework.data.jpa.domain.sample.AuditableRole org.springframework.data.jpa.domain.sample.AuditableUser + org.springframework.data.jpa.domain.sample.AuditableEntity + org.springframework.data.jpa.domain.sample.AuditableEmbeddable org.springframework.data.jpa.domain.sample.Category org.springframework.data.jpa.domain.sample.Child org.springframework.data.jpa.domain.sample.ConcreteType1 diff --git a/src/test/resources/META-INF/persistence2.xml b/src/test/resources/META-INF/persistence2.xml index 3e82937d79..683457aac8 100644 --- a/src/test/resources/META-INF/persistence2.xml +++ b/src/test/resources/META-INF/persistence2.xml @@ -6,6 +6,8 @@ org.springframework.data.jpa.domain.sample.AnnotatedAuditableUser org.springframework.data.jpa.domain.sample.AuditableRole org.springframework.data.jpa.domain.sample.AuditableUser + org.springframework.data.jpa.domain.sample.AuditableEntity + org.springframework.data.jpa.domain.sample.AuditableEmbeddable org.springframework.data.jpa.domain.sample.Category org.springframework.data.jpa.domain.sample.CustomAbstractPersistable org.springframework.data.jpa.domain.sample.EntityWithAssignedId diff --git a/src/test/resources/auditing/auditing-entity-with-embeddable-listener.xml b/src/test/resources/auditing/auditing-entity-with-embeddable-listener.xml new file mode 100644 index 0000000000..d874d03e86 --- /dev/null +++ b/src/test/resources/auditing/auditing-entity-with-embeddable-listener.xml @@ -0,0 +1,16 @@ + + + + + + + + + +