Skip to content

Commit 1eaeaa0

Browse files
committed
DATAJPA-775 - Improvements to Spring Data @Version detection.
Moved the detection of an invalidly used @Version to the verification phase of the JpaPersistentEntity so that the MappingContext doesn't even bootstrap if a misconfiguration is detected. The previous approach would've detected the invalid stage at access time which might actually occur too late. Original pull request: spring-projects#153.
1 parent c9fee0c commit 1eaeaa0

File tree

4 files changed

+80
-23
lines changed

4 files changed

+80
-23
lines changed

src/main/java/org/springframework/data/jpa/mapping/JpaPersistentEntityImpl.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import javax.persistence.metamodel.Metamodel;
2121

22+
import org.springframework.data.annotation.Version;
2223
import org.springframework.data.jpa.provider.PersistenceProvider;
2324
import org.springframework.data.jpa.provider.ProxyIdAccessor;
2425
import org.springframework.data.mapping.IdentifierAccessor;
@@ -31,10 +32,15 @@
3132
* Implementation of {@link JpaPersistentEntity}.
3233
*
3334
* @author Oliver Gierke
35+
* @author Greg Turnquist
3436
* @since 1.3
3537
*/
36-
class JpaPersistentEntityImpl<T> extends BasicPersistentEntity<T, JpaPersistentProperty> implements
37-
JpaPersistentEntity<T> {
38+
class JpaPersistentEntityImpl<T> extends BasicPersistentEntity<T, JpaPersistentProperty>
39+
implements JpaPersistentEntity<T> {
40+
41+
private static final String INVALID_VERSION_ANNOTATION = "%s is annotated with "
42+
+ org.springframework.data.annotation.Version.class.getName() + " but needs to use "
43+
+ javax.persistence.Version.class.getName() + " to trigger optimistic locking correctly!";
3844

3945
private final ProxyIdAccessor proxyIdAccessor;
4046

@@ -70,6 +76,26 @@ public IdentifierAccessor getIdentifierAccessor(Object bean) {
7076
return new JpaProxyAwareIdentifierAccessor(this, bean, proxyIdAccessor);
7177
}
7278

79+
/*
80+
* (non-Javadoc)
81+
* @see org.springframework.data.mapping.model.BasicPersistentEntity#verify()
82+
*/
83+
@Override
84+
public void verify() {
85+
86+
super.verify();
87+
88+
JpaPersistentProperty versionProperty = getVersionProperty();
89+
90+
if (versionProperty == null) {
91+
return;
92+
}
93+
94+
if (versionProperty.isAnnotationPresent(Version.class)) {
95+
throw new IllegalArgumentException(String.format(INVALID_VERSION_ANNOTATION, versionProperty));
96+
}
97+
}
98+
7399
/**
74100
* {@link IdentifierAccessor} that tries to use a {@link ProxyIdAccessor} for id access to potentially avoid the
75101
* initialization of JPA proxies. We're falling back to the default behavior of {@link IdPropertyIdentifierAccessor}

src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -211,21 +211,12 @@ public boolean usePropertyAccess() {
211211
return usePropertyAccess != null ? usePropertyAccess : super.usePropertyAccess();
212212
}
213213

214-
/**
215-
* Lookup if the property is versioned. In the event it's versioned using Spring Data Commons and NOT JPA,
216-
* fail fast with a detailed error message.
217-
*
218-
* @return
214+
/*
215+
* (non-Javadoc)
216+
* @see org.springframework.data.mapping.model.AnnotationBasedPersistentProperty#isVersionProperty()
219217
*/
220218
@Override
221219
public boolean isVersionProperty() {
222-
223-
if (super.isVersionProperty() && !isAnnotationPresent(Version.class)) {
224-
throw new IllegalArgumentException(this.owner.getName() + "." + this.getName() + " is annotated with " +
225-
org.springframework.data.annotation.Version.class.getCanonicalName() + ". With Spring Data JPA, use " +
226-
Version.class.getCanonicalName() + ".");
227-
}
228-
229220
return isAnnotationPresent(Version.class);
230221
}
231222

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2015 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+
* http://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.jpa.mapping;
17+
18+
import static org.mockito.Mockito.*;
19+
20+
import java.util.Collections;
21+
22+
import javax.persistence.metamodel.Metamodel;
23+
24+
import org.junit.Test;
25+
import org.springframework.data.annotation.Version;
26+
27+
/**
28+
* Unit tests for {@link JpaMetamodelMappingContext}.
29+
*
30+
* @author Oliver Gierke
31+
*/
32+
public class JpaMetamodelMappingContextUnitTests {
33+
34+
/**
35+
* @see DATAJPA-775
36+
*/
37+
@Test
38+
public void jpaPersistentEntityRejectsSprignDataAtVersionAnnotation() {
39+
40+
Metamodel metamodel = mock(Metamodel.class);
41+
42+
JpaMetamodelMappingContext context = new JpaMetamodelMappingContext(Collections.singleton(metamodel));
43+
context.getPersistentEntity(Sample.class);
44+
}
45+
46+
static class Sample {
47+
@Version Long version;
48+
}
49+
}

src/test/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImplUnitTests.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,15 +158,6 @@ public void detectsJpaVersionAnnotation() {
158158
assertThat(getProperty(JpaVersioned.class, "version").isVersionProperty(), is(true));
159159
}
160160

161-
/**
162-
* @see DATAJPA-605
163-
* @see DATAJPA-775
164-
*/
165-
@Test(expected = IllegalArgumentException.class)
166-
public void detectsSpringDataVersionAnnotation() {
167-
getProperty(SpringDataVersioned.class, "version");
168-
}
169-
170161
/**
171162
* @see DATAJPA-664
172163
*/

0 commit comments

Comments
 (0)