Skip to content

Commit aa90065

Browse files
committed
Polishing.
Introduce EnversRevisionEntityInformation to reflect envers-specific revision information. Refactor DefaultRevisionEntityInformation to enum to keep a singleton around. Refine tests. See #2850 Original pull request: #4003
1 parent 8c3a067 commit aa90065

File tree

8 files changed

+156
-68
lines changed

8 files changed

+156
-68
lines changed

spring-data-envers/src/main/java/org/springframework/data/envers/repository/support/DefaultRevisionEntityInformation.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,27 @@
2424
* @author Oliver Gierke
2525
* @author Chaedong Im
2626
*/
27-
class DefaultRevisionEntityInformation implements RevisionEntityInformation {
27+
enum DefaultRevisionEntityInformation implements EnversRevisionEntityInformation {
2828

29+
INSTANCE;
30+
31+
@Override
2932
public Class<?> getRevisionNumberType() {
3033
return Integer.class;
3134
}
3235

36+
@Override
3337
public boolean isDefaultRevisionEntity() {
3438
return true;
3539
}
3640

41+
@Override
3742
public Class<?> getRevisionEntityClass() {
3843
return DefaultRevisionEntity.class;
3944
}
4045

41-
public String getRevisionTimestampFieldName() {
46+
@Override
47+
public String getRevisionTimestampPropertyName() {
4248
return "timestamp";
4349
}
4450
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.envers.repository.support;
17+
18+
import org.springframework.data.repository.history.support.RevisionEntityInformation;
19+
20+
/**
21+
* Envers-specific extension to {@link RevisionEntityInformation}.
22+
*
23+
* @author Mark Paluch
24+
* @since 4.0
25+
*/
26+
public interface EnversRevisionEntityInformation extends RevisionEntityInformation {
27+
28+
/**
29+
* Return the name of the timestamp property (annotated with {@link org.hibernate.envers.RevisionTimestamp}).
30+
*
31+
* @return the name of the timestamp property,
32+
*/
33+
String getRevisionTimestampPropertyName();
34+
35+
}

spring-data-envers/src/main/java/org/springframework/data/envers/repository/support/EnversRevisionRepositoryFactoryBean.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
import java.util.Optional;
2121

2222
import org.hibernate.envers.DefaultRevisionEntity;
23-
2423
import org.jspecify.annotations.Nullable;
24+
2525
import org.springframework.beans.factory.FactoryBean;
2626
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
2727
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
@@ -90,7 +90,7 @@ public RevisionRepositoryFactory(EntityManager entityManager, @Nullable Class<?>
9090
this.revisionEntityInformation = Optional.ofNullable(revisionEntityClass) //
9191
.filter(it -> !it.equals(DefaultRevisionEntity.class))//
9292
.<RevisionEntityInformation> map(ReflectionRevisionEntityInformation::new) //
93-
.orElseGet(DefaultRevisionEntityInformation::new);
93+
.orElse(DefaultRevisionEntityInformation.INSTANCE);
9494
}
9595

9696
@Override

spring-data-envers/src/main/java/org/springframework/data/envers/repository/support/EnversRevisionRepositoryImpl.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,10 @@ private Revision<N, T> createRevision(QueryResult<T> queryResult) {
218218
}
219219

220220
private String getRevisionTimestampFieldName() {
221-
if (revisionEntityInformation instanceof ReflectionRevisionEntityInformation reflection) {
222-
return reflection.getRevisionTimestampFieldName();
223-
} else if (revisionEntityInformation instanceof DefaultRevisionEntityInformation defaultInfo) {
224-
return defaultInfo.getRevisionTimestampFieldName();
221+
if (revisionEntityInformation instanceof EnversRevisionEntityInformation reflection) {
222+
return reflection.getRevisionTimestampPropertyName();
225223
} else {
226-
return "timestamp";
224+
return DefaultRevisionEntityInformation.INSTANCE.getRevisionTimestampPropertyName();
227225
}
228226
}
229227

spring-data-envers/src/main/java/org/springframework/data/envers/repository/support/ReflectionRevisionEntityInformation.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
* @author Oliver Gierke
3131
* @author Chaedong Im
3232
*/
33-
public class ReflectionRevisionEntityInformation implements RevisionEntityInformation {
33+
public class ReflectionRevisionEntityInformation implements EnversRevisionEntityInformation {
3434

3535
private final Class<?> revisionEntityClass;
3636
private final Class<?> revisionNumberType;
@@ -54,22 +54,25 @@ public ReflectionRevisionEntityInformation(Class<?> revisionEntityClass) {
5454
this.revisionNumberType = revisionNumberFieldCallback.getRequiredType();
5555
this.revisionTimestampFieldName = revisionTimestampFieldCallback.getRequiredField().getName();
5656
this.revisionEntityClass = revisionEntityClass;
57-
5857
}
5958

59+
@Override
6060
public boolean isDefaultRevisionEntity() {
6161
return false;
6262
}
6363

64+
@Override
6465
public Class<?> getRevisionEntityClass() {
6566
return this.revisionEntityClass;
6667
}
6768

69+
@Override
6870
public Class<?> getRevisionNumberType() {
6971
return this.revisionNumberType;
7072
}
7173

72-
public String getRevisionTimestampFieldName() {
74+
@Override
75+
public String getRevisionTimestampPropertyName() {
7376
return this.revisionTimestampFieldName;
7477
}
7578
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.envers.repository.support;
17+
18+
import static org.assertj.core.api.Assertions.*;
19+
20+
import org.junit.jupiter.api.Test;
21+
22+
/**
23+
* Unit tests for {@link DefaultRevisionEntityInformation}.
24+
*
25+
* @author Mark Paluch
26+
* @author Chaedong Im
27+
*/
28+
class DefaultRevisionEntityInformationUnitTests {
29+
30+
@Test // GH-2850
31+
void defaultRevisionEntityInformationReturnsStandardTimestampFieldName() {
32+
33+
DefaultRevisionEntityInformation revisionInfo = DefaultRevisionEntityInformation.INSTANCE;
34+
35+
assertThat(revisionInfo.getRevisionTimestampPropertyName()).isEqualTo("timestamp");
36+
}
37+
38+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.envers.repository.support;
17+
18+
import static org.assertj.core.api.Assertions.*;
19+
20+
import org.hibernate.envers.RevisionNumber;
21+
import org.hibernate.envers.RevisionTimestamp;
22+
import org.junit.jupiter.api.Test;
23+
24+
import org.springframework.data.envers.sample.CustomRevisionEntity;
25+
26+
/**
27+
* Unit tests for {@link ReflectionRevisionEntityInformation}.
28+
*
29+
* @author Mark Paluch
30+
* @author Chaedong Im
31+
*/
32+
class ReflectionRevisionEntityInformationUnitTests {
33+
34+
@Test // GH-2850
35+
void reflectionRevisionEntityInformationDetectsStandardTimestampField() {
36+
37+
ReflectionRevisionEntityInformation revisionInfo = new ReflectionRevisionEntityInformation(
38+
CustomRevisionEntity.class);
39+
40+
assertThat(revisionInfo.getRevisionTimestampPropertyName()).isEqualTo("timestamp");
41+
}
42+
43+
@Test // GH-2850
44+
void reflectionRevisionEntityInformationDetectsCustomTimestampField() {
45+
46+
ReflectionRevisionEntityInformation revisionInfo = new ReflectionRevisionEntityInformation(
47+
WithCustomTimestampPropertyName.class);
48+
49+
assertThat(revisionInfo.getRevisionTimestampPropertyName()).isEqualTo("myCustomTimestamp");
50+
}
51+
52+
/**
53+
* Custom revision entity with a non-standard timestamp field name to test dynamic timestamp property detection.
54+
*
55+
* @author Chaedong Im
56+
*/
57+
private static class WithCustomTimestampPropertyName {
58+
59+
@RevisionNumber private int revisionId;
60+
61+
@RevisionTimestamp private long myCustomTimestamp; // Non-standard field name
62+
}
63+
64+
}

spring-data-envers/src/test/java/org/springframework/data/envers/sample/CustomRevisionEntityWithDifferentTimestamp.java

Lines changed: 0 additions & 56 deletions
This file was deleted.

0 commit comments

Comments
 (0)