DATAMONGO-461 - Fixed potential NullPointerException in MappedConstructor.

Reject PersistentEntity instances that don't have a PersistenceConstructor as this indicates a mapping problem (either a constructor needed to be annotated or a custom converter registered).
This commit is contained in:
Oliver Gierke
2012-06-19 17:46:54 +02:00
parent b02e81c481
commit 783cec0325
2 changed files with 59 additions and 3 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.data.mongodb.core.convert;
import java.util.HashSet;
import java.util.Set;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PreferredConstructor;
@@ -25,6 +26,7 @@ import org.springframework.data.mapping.PreferredConstructor.Parameter;
import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.context.PersistentPropertyPath;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.util.TypeInformation;
@@ -37,6 +39,9 @@ import org.springframework.util.Assert;
*/
class MappedConstructor {
private static final String REJECT_CONSTRUCTOR = String.format("Entity doesn't have a usable constructor, either "
+ "provide a custom converter or annotate a constructor with @%s!", PersistenceConstructor.class.getSimpleName());
private final Set<MappedConstructor.MappedParameter> parameters;
/**
@@ -44,13 +49,19 @@ class MappedConstructor {
*
* @param entity must not be {@literal null}.
* @param context must not be {@literal null}.
* @throws MappingException in case the {@link MongoPersistentEntity} handed in does not have a
* {@link PreferredConstructor}.
*/
public MappedConstructor(MongoPersistentEntity<?> entity,
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context) {
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context) throws MappingException {
Assert.notNull(entity);
Assert.notNull(context);
if (entity.getPreferredConstructor() == null) {
throw new MappingException(REJECT_CONSTRUCTOR);
}
this.parameters = new HashSet<MappedConstructor.MappedParameter>();
for (Parameter<?> parameter : entity.getPreferredConstructor().getParameters()) {
@@ -83,6 +94,7 @@ class MappedConstructor {
*
* @param parameter must not be {@literal null}.
* @return
* @throws MappingException in case no {@link MappedParameter} can be found for the given {@link Parameter}.
*/
public MappedParameter getFor(Parameter<?> parameter) {
@@ -92,7 +104,7 @@ class MappedConstructor {
}
}
throw new IllegalStateException(String.format("Didn't find a MappedParameter for %s!", parameter.toString()));
throw new MappingException(String.format("Didn't find a MappedParameter for %s!", parameter.toString()));
}
/**
@@ -165,4 +177,4 @@ class MappedConstructor {
return this.property.equals(property);
}
}
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2012 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
*
* http://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.mongodb.core.convert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
/**
* Unit tests for {@link MappedConstructor}.
*
* @author Oliver Gierke
*/
@RunWith(MockitoJUnitRunner.class)
public class MappedConstructorUnitTests {
@Mock
MongoPersistentEntity<?> entity;
@Mock
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
@Test(expected = MappingException.class)
public void rejectsEntityWithoutPersistenceConstructor() {
new MappedConstructor(entity, mappingContext);
}
}