Skip to content

Commit 862e652

Browse files
committed
DATAJPA-1064 - Improvements in JpaPersistentEntity/Property.
Better use of Optional in implementations.
1 parent 8aa1e28 commit 862e652

File tree

3 files changed

+44
-57
lines changed

3 files changed

+44
-57
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@ public JpaProxyAwareIdentifierAccessor(JpaPersistentEntity<?> entity, Object bea
132132
*/
133133
@Override
134134
public Optional<Object> getIdentifier() {
135-
return proxyIdAccessor.shouldUseAccessorFor(bean) ? Optional.ofNullable(proxyIdAccessor.getIdentifierFrom(bean))
135+
136+
return proxyIdAccessor.shouldUseAccessorFor(bean) //
137+
? Optional.ofNullable(proxyIdAccessor.getIdentifierFrom(bean))//
136138
: super.getIdentifier();
137139
}
138140
}

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

Lines changed: 30 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
*/
1616
package org.springframework.data.jpa.mapping;
1717

18-
import java.beans.PropertyDescriptor;
1918
import java.lang.annotation.Annotation;
20-
import java.lang.reflect.Field;
2119
import java.util.Collection;
2220
import java.util.Collections;
2321
import java.util.HashSet;
@@ -49,6 +47,7 @@
4947
import org.springframework.data.mapping.model.Property;
5048
import org.springframework.data.mapping.model.SimpleTypeHolder;
5149
import org.springframework.data.util.ClassTypeInformation;
50+
import org.springframework.data.util.Optionals;
5251
import org.springframework.data.util.TypeInformation;
5352
import org.springframework.util.Assert;
5453

@@ -91,8 +90,8 @@ class JpaPersistentPropertyImpl extends AnnotationBasedPersistentProperty<JpaPer
9190
UPDATEABLE_ANNOTATIONS = Collections.unmodifiableSet(annotations);
9291
}
9392

94-
private final Boolean usePropertyAccess;
95-
private final TypeInformation<?> associationTargetType;
93+
private final Optional<Boolean> usePropertyAccess;
94+
private final Optional<TypeInformation<?>> associationTargetType;
9695
private final boolean updateable;
9796
private final JpaMetamodel metamodel;
9897

@@ -112,7 +111,7 @@ public JpaPersistentPropertyImpl(Metamodel metamodel, Property property,
112111
Assert.notNull(metamodel, "Metamodel must not be null!");
113112

114113
this.usePropertyAccess = detectPropertyAccess();
115-
this.associationTargetType = isAssociation() ? detectAssociationTargetType() : null;
114+
this.associationTargetType = detectAssociationTargetType();
116115
this.updateable = detectUpdatability();
117116
this.metamodel = new JpaMetamodel(metamodel);
118117
}
@@ -123,7 +122,7 @@ public JpaPersistentPropertyImpl(Metamodel metamodel, Property property,
123122
*/
124123
@Override
125124
public Class<?> getActualType() {
126-
return associationTargetType == null ? super.getActualType() : associationTargetType.getType();
125+
return associationTargetType.isPresent() ? associationTargetType.get().getType() : super.getActualType();
127126
}
128127

129128
/*
@@ -132,8 +131,8 @@ public Class<?> getActualType() {
132131
*/
133132
@Override
134133
public Iterable<? extends TypeInformation<?>> getPersistentEntityType() {
135-
return associationTargetType == null ? super.getPersistentEntityType()
136-
: Collections.singleton(associationTargetType);
134+
return associationTargetType.isPresent() ? Collections.singleton(associationTargetType.get())
135+
: super.getPersistentEntityType();
137136
}
138137

139138
/*
@@ -142,14 +141,7 @@ public Iterable<? extends TypeInformation<?>> getPersistentEntityType() {
142141
*/
143142
@Override
144143
public boolean isIdProperty() {
145-
146-
for (Class<? extends Annotation> annotation : ID_ANNOTATIONS) {
147-
if (isAnnotationPresent(annotation)) {
148-
return true;
149-
}
150-
}
151-
152-
return false;
144+
return ID_ANNOTATIONS.stream().anyMatch(it -> isAnnotationPresent(it));
153145
}
154146

155147
/*
@@ -168,17 +160,11 @@ public boolean isEntity() {
168160
@Override
169161
public boolean isAssociation() {
170162

171-
for (Class<? extends Annotation> annotationType : ASSOCIATION_ANNOTATIONS) {
172-
if (findAnnotation(annotationType) != null) {
173-
return true;
174-
}
175-
}
176-
177-
if (getType().isAnnotationPresent(Embeddable.class)) {
163+
if (ASSOCIATION_ANNOTATIONS.stream().anyMatch(it -> findAnnotation(it).isPresent())) {
178164
return true;
179165
}
180166

181-
return false;
167+
return getType().isAnnotationPresent(Embeddable.class);
182168
}
183169

184170
/*
@@ -205,7 +191,7 @@ protected Association<JpaPersistentProperty> createAssociation() {
205191
*/
206192
@Override
207193
public boolean usePropertyAccess() {
208-
return usePropertyAccess != null ? usePropertyAccess : super.usePropertyAccess();
194+
return usePropertyAccess.orElseGet(() -> super.usePropertyAccess());
209195
}
210196

211197
/*
@@ -234,72 +220,61 @@ public boolean isWritable() {
234220
*
235221
* @return
236222
*/
237-
private Boolean detectPropertyAccess() {
223+
private Optional<Boolean> detectPropertyAccess() {
238224

239225
Optional<org.springframework.data.annotation.AccessType> accessType = findAnnotation(
240226
org.springframework.data.annotation.AccessType.class);
241227

242228
if (accessType.isPresent()) {
243-
return Type.PROPERTY.equals(accessType.get().value());
229+
return accessType.map(it -> Type.PROPERTY.equals(it.value()));
244230
}
245231

246232
Optional<Access> access = findAnnotation(Access.class);
247233

248234
if (access.isPresent()) {
249-
return AccessType.PROPERTY.equals(access.get().value());
235+
return access.map(it -> AccessType.PROPERTY.equals(it.value()));
250236
}
251237

252238
accessType = findPropertyOrOwnerAnnotation(org.springframework.data.annotation.AccessType.class);
253239

254240
if (accessType.isPresent()) {
255-
return Type.PROPERTY.equals(accessType.get().value());
241+
return accessType.map(it -> Type.PROPERTY.equals(it.value()));
256242
}
257243

258244
access = findPropertyOrOwnerAnnotation(Access.class);
259-
return access.map(t -> AccessType.PROPERTY.equals(t.value())).orElse(null);
245+
return access.map(t -> AccessType.PROPERTY.equals(t.value()));
260246
}
261247

262248
/**
263249
* Inspects the association annotations on the property and returns the target entity type if specified.
264250
*
265251
* @return
266252
*/
267-
private TypeInformation<?> detectAssociationTargetType() {
268-
269-
for (Class<? extends Annotation> associationAnnotation : ASSOCIATION_ANNOTATIONS) {
270-
271-
Optional<? extends Annotation> annotation = findAnnotation(associationAnnotation);
272-
if(annotation.isPresent()) {
253+
private Optional<TypeInformation<?>> detectAssociationTargetType() {
273254

274-
Object targetEntity = AnnotationUtils.getValue(annotation.get(), "targetEntity");
275-
276-
if (targetEntity != null && !void.class.equals(targetEntity)) {
277-
return ClassTypeInformation.from((Class<?>) targetEntity);
278-
}
279-
}
255+
if (!isAssociation()) {
256+
return Optional.empty();
280257
}
281258

282-
return null;
259+
return ASSOCIATION_ANNOTATIONS.stream()//
260+
.flatMap(it -> Optionals.toStream(findAnnotation(it)))//
261+
.map(it -> AnnotationUtils.getValue(it, "targetEntity"))//
262+
.filter(it -> it != null && !void.class.equals(it))//
263+
.map(it -> (Class<?>) it)//
264+
.findFirst().map(it -> (TypeInformation<?>) ClassTypeInformation.from(it));
283265
}
284266

285267
/**
286-
* Checks whether {@code updateable} attribute of any of the {@link #UPDATEABLE_ANNOTATIONS} is configured to
268+
* Checks whether {@code updatable} attribute of any of the {@link #UPDATEABLE_ANNOTATIONS} is configured to
287269
* {@literal true}.
288270
*
289271
* @return
290272
*/
291273
private final boolean detectUpdatability() {
292274

293-
for (Class<? extends Annotation> annotationType : UPDATEABLE_ANNOTATIONS) {
294-
295-
Optional<? extends Annotation> annotation = findAnnotation(annotationType);
296-
297-
if (annotation.isPresent() && AnnotationUtils.getValue(annotation.get(), "updatable").equals(Boolean.FALSE)) {
298-
return false;
299-
}
300-
}
301-
302-
return true;
275+
return !UPDATEABLE_ANNOTATIONS.stream()//
276+
.flatMap(it -> Optionals.toStream(findAnnotation(it)))//
277+
.map(it -> AnnotationUtils.getValue(it, "updatable"))//
278+
.anyMatch(it -> it.equals(Boolean.FALSE));
303279
}
304-
305280
}

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
*/
1616
package org.springframework.data.jpa.mapping;
1717

18+
import static org.assertj.core.api.Assertions.assertThat;
1819
import static org.hamcrest.Matchers.*;
19-
import static org.junit.Assert.*;
20+
import static org.junit.Assert.assertThat;
2021
import static org.mockito.Mockito.*;
2122

2223
import java.util.Collections;
@@ -157,6 +158,15 @@ public void isEntityWorksEvenWithManagedTypeWithNullJavaType() {
157158
assertThat(getProperty(Sample.class, "other").isEntity(), is(false));
158159
}
159160

161+
@Test // DATAJPA-1064
162+
public void simplePropertyIsNotConsideredAnAssociation() {
163+
164+
JpaPersistentEntityImpl<?> entity = context.getRequiredPersistentEntity(WithReadOnly.class);
165+
JpaPersistentProperty property = entity.getRequiredPersistentProperty("updatable");
166+
167+
assertThat(property.isAssociation()).isFalse();
168+
}
169+
160170
private JpaPersistentProperty getProperty(Class<?> ownerType, String propertyName) {
161171

162172
JpaPersistentEntity<?> entity = context.getRequiredPersistentEntity(ownerType);

0 commit comments

Comments
 (0)