From 29bcd09403595930f80ea1458c393dcf133724c6 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 8 Jun 2016 10:17:51 +0200 Subject: [PATCH] DATAJPA-904 - Guard against null values from JPA's ManagedType.getJavaType(). Some persistence providers (Hibernate *cough*) return null for a ManagedType's JavaType, which we perviously didn't expect in the implementation of JpaPersistentPropertyImpl.isEntity(). We now eagerly extract all managed types from the Metamodel and gracefully skip nulls so that we don't have to look up the types repeatedly. --- .../mapping/JpaPersistentPropertyImpl.java | 36 +++++++++++++------ .../JpaPersistentPropertyImplUnitTests.java | 16 ++++++++- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java b/src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java index b0699ba45..358763ef0 100644 --- a/src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java +++ b/src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java @@ -88,10 +88,10 @@ class JpaPersistentPropertyImpl extends AnnotationBasedPersistentProperty associationTargetType; private final boolean updateable; + private final Set> managedTypes; /** * Creates a new {@link JpaPersistentPropertyImpl} @@ -109,10 +109,10 @@ class JpaPersistentPropertyImpl extends AnnotationBasedPersistentProperty type : metamodel.getManagedTypes()) { - if (type.getJavaType().equals(getActualType())) { - return true; - } - } - - return false; + return managedTypes.contains(getActualType()); } /* @@ -303,4 +296,27 @@ class JpaPersistentPropertyImpl extends AnnotationBasedPersistentProperty> getManagedTypes(Metamodel metamodel) { + + Set> managedTypes = metamodel.getManagedTypes(); + Set> types = new HashSet>(managedTypes.size()); + + for (ManagedType managedType : metamodel.getManagedTypes()) { + + Class type = managedType.getJavaType(); + + if (type != null) { + types.add(type); + } + } + + return Collections.unmodifiableSet(types); + } } diff --git a/src/test/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImplUnitTests.java b/src/test/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImplUnitTests.java index bc2312021..be1c05158 100644 --- a/src/test/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImplUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImplUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2016 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. @@ -17,6 +17,7 @@ package org.springframework.data.jpa.mapping; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import static org.mockito.Mockito.*; import java.util.Collections; @@ -28,6 +29,7 @@ import javax.persistence.Embedded; import javax.persistence.ManyToOne; import javax.persistence.OneToOne; import javax.persistence.Transient; +import javax.persistence.metamodel.ManagedType; import javax.persistence.metamodel.Metamodel; import org.junit.Before; @@ -184,6 +186,18 @@ public class JpaPersistentPropertyImplUnitTests { assertThat(getProperty(WithReadOnly.class, "updatable").isWritable(), is(true)); } + /** + * @see DATAJPA-904 + */ + @Test + public void isEntityWorksEvenWithManagedTypeWithNullJavaType() { + + ManagedType managedType = mock(ManagedType.class); + doReturn(Collections.singleton(managedType)).when(model).getManagedTypes(); + + assertThat(getProperty(Sample.class, "other").isEntity(), is(false)); + } + private JpaPersistentProperty getProperty(Class ownerType, String propertyName) { JpaPersistentEntity entity = context.getPersistentEntity(ownerType);