Merge pull request #110 from spaetzold/master
Type safety with find methods
This commit is contained in:
@@ -56,6 +56,7 @@ import org.springframework.data.neo4j.support.relationship.RelationshipEntityIns
|
|||||||
import org.springframework.data.neo4j.support.relationship.RelationshipEntityStateFactory;
|
import org.springframework.data.neo4j.support.relationship.RelationshipEntityStateFactory;
|
||||||
import org.springframework.data.neo4j.support.typerepresentation.ClassValueTypeInformationMapper;
|
import org.springframework.data.neo4j.support.typerepresentation.ClassValueTypeInformationMapper;
|
||||||
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
|
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
|
||||||
|
import org.springframework.data.neo4j.support.typesafety.TypeSafetyPolicy;
|
||||||
import org.springframework.data.support.IsNewStrategyFactory;
|
import org.springframework.data.support.IsNewStrategyFactory;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
@@ -117,6 +118,7 @@ public abstract class Neo4jConfiguration {
|
|||||||
factoryBean.setTransactionManager(neo4jTransactionManager());
|
factoryBean.setTransactionManager(neo4jTransactionManager());
|
||||||
factoryBean.setGraphDatabase(graphDatabase());
|
factoryBean.setGraphDatabase(graphDatabase());
|
||||||
factoryBean.setIsNewStrategyFactory(isNewStrategyFactory());
|
factoryBean.setIsNewStrategyFactory(isNewStrategyFactory());
|
||||||
|
factoryBean.setTypeSafetyPolicy(typeSafetyPolicy());
|
||||||
|
|
||||||
factoryBean.setIndexProvider(indexProvider());
|
factoryBean.setIndexProvider(indexProvider());
|
||||||
|
|
||||||
@@ -269,6 +271,11 @@ public abstract class Neo4jConfiguration {
|
|||||||
return new IndexProviderImpl(graphDatabase());
|
return new IndexProviderImpl(graphDatabase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TypeSafetyPolicy typeSafetyPolicy() throws Exception {
|
||||||
|
return new TypeSafetyPolicy();
|
||||||
|
}
|
||||||
|
|
||||||
public Set<? extends Class<?>> getInitialEntitySet() {
|
public Set<? extends Class<?>> getInitialEntitySet() {
|
||||||
return initialEntitySet;
|
return initialEntitySet;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.springframework.data.neo4j.support.node.EntityStateFactory;
|
|||||||
import org.springframework.data.neo4j.support.query.CypherQueryExecutor;
|
import org.springframework.data.neo4j.support.query.CypherQueryExecutor;
|
||||||
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategies;
|
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategies;
|
||||||
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
|
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
|
||||||
|
import org.springframework.data.neo4j.support.typesafety.TypeSafetyPolicy;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
@@ -68,4 +69,6 @@ public interface Infrastructure {
|
|||||||
TypeRepresentationStrategy<Node> getNodeTypeRepresentationStrategy();
|
TypeRepresentationStrategy<Node> getNodeTypeRepresentationStrategy();
|
||||||
|
|
||||||
TypeRepresentationStrategy<Relationship> getRelationshipTypeRepresentationStrategy();
|
TypeRepresentationStrategy<Relationship> getRelationshipTypeRepresentationStrategy();
|
||||||
|
|
||||||
|
TypeSafetyPolicy getTypeSafetyPolicy();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.springframework.data.neo4j.support.node.EntityStateFactory;
|
|||||||
import org.springframework.data.neo4j.support.query.CypherQueryExecutor;
|
import org.springframework.data.neo4j.support.query.CypherQueryExecutor;
|
||||||
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategies;
|
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategies;
|
||||||
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
|
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
|
||||||
|
import org.springframework.data.neo4j.support.typesafety.TypeSafetyPolicy;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
@@ -59,8 +60,9 @@ public class MappingInfrastructure implements Infrastructure {
|
|||||||
private final IndexProvider indexProvider;
|
private final IndexProvider indexProvider;
|
||||||
private final GraphDatabaseService graphDatabaseService;
|
private final GraphDatabaseService graphDatabaseService;
|
||||||
private final GraphDatabase graphDatabase;
|
private final GraphDatabase graphDatabase;
|
||||||
|
private final TypeSafetyPolicy typeSafetyPolicy;
|
||||||
|
|
||||||
public MappingInfrastructure(GraphDatabase graphDatabase, GraphDatabaseService graphDatabaseService, IndexProvider indexProvider, ResultConverter resultConverter, PlatformTransactionManager transactionManager, TypeRepresentationStrategies typeRepresentationStrategies, EntityRemover entityRemover, Neo4jEntityPersister entityPersister, EntityStateHandler entityStateHandler, CypherQueryExecutor cypherQueryExecutor, Neo4jMappingContext mappingContext, TypeRepresentationStrategy<Relationship> relationshipTypeRepresentationStrategy, TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy, Validator validator, ConversionService conversionService) {
|
public MappingInfrastructure(GraphDatabase graphDatabase, GraphDatabaseService graphDatabaseService, IndexProvider indexProvider, ResultConverter resultConverter, PlatformTransactionManager transactionManager, TypeRepresentationStrategies typeRepresentationStrategies, EntityRemover entityRemover, Neo4jEntityPersister entityPersister, EntityStateHandler entityStateHandler, CypherQueryExecutor cypherQueryExecutor, Neo4jMappingContext mappingContext, TypeRepresentationStrategy<Relationship> relationshipTypeRepresentationStrategy, TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy, Validator validator, ConversionService conversionService, TypeSafetyPolicy typeSafetyPolicy) {
|
||||||
this.graphDatabase = graphDatabase;
|
this.graphDatabase = graphDatabase;
|
||||||
this.graphDatabaseService = graphDatabaseService;
|
this.graphDatabaseService = graphDatabaseService;
|
||||||
this.indexProvider = indexProvider;
|
this.indexProvider = indexProvider;
|
||||||
@@ -76,6 +78,7 @@ public class MappingInfrastructure implements Infrastructure {
|
|||||||
this.nodeTypeRepresentationStrategy = nodeTypeRepresentationStrategy;
|
this.nodeTypeRepresentationStrategy = nodeTypeRepresentationStrategy;
|
||||||
this.validator = validator;
|
this.validator = validator;
|
||||||
this.conversionService = conversionService;
|
this.conversionService = conversionService;
|
||||||
|
this.typeSafetyPolicy = typeSafetyPolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -147,4 +150,9 @@ public class MappingInfrastructure implements Infrastructure {
|
|||||||
public TypeRepresentationStrategy<Relationship> getRelationshipTypeRepresentationStrategy() {
|
public TypeRepresentationStrategy<Relationship> getRelationshipTypeRepresentationStrategy() {
|
||||||
return relationshipTypeRepresentationStrategy;
|
return relationshipTypeRepresentationStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeSafetyPolicy getTypeSafetyPolicy() {
|
||||||
|
return typeSafetyPolicy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import org.springframework.data.neo4j.support.relationship.RelationshipEntityIns
|
|||||||
import org.springframework.data.neo4j.support.relationship.RelationshipEntityStateFactory;
|
import org.springframework.data.neo4j.support.relationship.RelationshipEntityStateFactory;
|
||||||
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategies;
|
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategies;
|
||||||
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
|
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
|
||||||
|
import org.springframework.data.neo4j.support.typesafety.TypeSafetyPolicy;
|
||||||
import org.springframework.data.support.IsNewStrategyFactory;
|
import org.springframework.data.support.IsNewStrategyFactory;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||||
@@ -79,6 +80,7 @@ public class MappingInfrastructureFactoryBean implements FactoryBean<Infrastruct
|
|||||||
private GraphDatabaseService graphDatabaseService;
|
private GraphDatabaseService graphDatabaseService;
|
||||||
private GraphDatabase graphDatabase;
|
private GraphDatabase graphDatabase;
|
||||||
private IsNewStrategyFactory isNewStrategyFactory;
|
private IsNewStrategyFactory isNewStrategyFactory;
|
||||||
|
private TypeSafetyPolicy typeSafetyPolicy;
|
||||||
|
|
||||||
private MappingInfrastructure mappingInfrastructure;
|
private MappingInfrastructure mappingInfrastructure;
|
||||||
private TypeRepresentationStrategyFactory.Strategy typeRepresentationStrategy;
|
private TypeRepresentationStrategyFactory.Strategy typeRepresentationStrategy;
|
||||||
@@ -153,7 +155,10 @@ public class MappingInfrastructureFactoryBean implements FactoryBean<Infrastruct
|
|||||||
if (this.indexProvider == null) {
|
if (this.indexProvider == null) {
|
||||||
this.indexProvider = new IndexProviderImpl(graphDatabase);
|
this.indexProvider = new IndexProviderImpl(graphDatabase);
|
||||||
}
|
}
|
||||||
this.mappingInfrastructure = new MappingInfrastructure(graphDatabase, graphDatabaseService, indexProvider, resultConverter, transactionManager, typeRepresentationStrategies, entityRemover, entityPersister, entityStateHandler, cypherQueryExecutor, mappingContext, relationshipTypeRepresentationStrategy, nodeTypeRepresentationStrategy, validator, conversionService);
|
if (this.typeSafetyPolicy == null) {
|
||||||
|
this.typeSafetyPolicy = new TypeSafetyPolicy();
|
||||||
|
}
|
||||||
|
this.mappingInfrastructure = new MappingInfrastructure(graphDatabase, graphDatabaseService, indexProvider, resultConverter, transactionManager, typeRepresentationStrategies, entityRemover, entityPersister, entityStateHandler, cypherQueryExecutor, mappingContext, relationshipTypeRepresentationStrategy, nodeTypeRepresentationStrategy, validator, conversionService, typeSafetyPolicy);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("error initializing "+getClass().getName(),e);
|
throw new RuntimeException("error initializing "+getClass().getName(),e);
|
||||||
}
|
}
|
||||||
@@ -293,6 +298,14 @@ public class MappingInfrastructureFactoryBean implements FactoryBean<Infrastruct
|
|||||||
isNewStrategyFactory = newStrategyFactory;
|
isNewStrategyFactory = newStrategyFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTypeSafetyPolicy(TypeSafetyPolicy typeSafetyPolicy) {
|
||||||
|
this.typeSafetyPolicy = typeSafetyPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeSafetyPolicy getTypeSafetyPolicy() {
|
||||||
|
return typeSafetyPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Infrastructure getObject() {
|
public Infrastructure getObject() {
|
||||||
return mappingInfrastructure;
|
return mappingInfrastructure;
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import org.springframework.data.mapping.model.MappingException;
|
|||||||
import org.springframework.data.neo4j.mapping.*;
|
import org.springframework.data.neo4j.mapping.*;
|
||||||
import org.springframework.data.neo4j.mapping.ManagedEntity;
|
import org.springframework.data.neo4j.mapping.ManagedEntity;
|
||||||
import org.springframework.data.neo4j.support.Neo4jTemplate;
|
import org.springframework.data.neo4j.support.Neo4jTemplate;
|
||||||
|
import org.springframework.data.neo4j.support.typesafety.TypeSafetyOption;
|
||||||
|
import org.springframework.data.neo4j.support.typesafety.TypeSafetyPolicy;
|
||||||
import org.springframework.data.util.ClassTypeInformation;
|
import org.springframework.data.util.ClassTypeInformation;
|
||||||
import org.springframework.data.util.TypeInformation;
|
import org.springframework.data.util.TypeInformation;
|
||||||
|
|
||||||
@@ -78,14 +80,24 @@ public class Neo4jEntityConverterImpl<T,S extends PropertyContainer> implements
|
|||||||
// retrieve meta-information about the type
|
// retrieve meta-information about the type
|
||||||
@SuppressWarnings("unchecked") final Neo4jPersistentEntityImpl<R> persistentEntity = (Neo4jPersistentEntityImpl<R>) mappingContext.getPersistentEntity(targetType);
|
@SuppressWarnings("unchecked") final Neo4jPersistentEntityImpl<R> persistentEntity = (Neo4jPersistentEntityImpl<R>) mappingContext.getPersistentEntity(targetType);
|
||||||
|
|
||||||
if (mappingPolicy==null) {
|
// 4) check type safety
|
||||||
mappingPolicy = persistentEntity.getMappingPolicy();
|
TypeSafetyPolicy typeSafetyPolicy = template.getInfrastructure().getTypeSafetyPolicy();
|
||||||
|
if (typeSafetyPolicy.isTypeSafetyEnabled() && !storedAndRequestedTypesMatch(requestedType, source)) {
|
||||||
|
if (typeSafetyPolicy.getTypeSafetyOption() == TypeSafetyOption.RETURNS_NULL) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (typeSafetyPolicy.getTypeSafetyOption() == TypeSafetyOption.THROWS_EXCEPTION) {
|
||||||
|
throw new InvalidEntityTypeException("Requested a entity of type '" + requestedType + "', but the stored entity is of type '" + typeMapper.readType(source).getType() + "'.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4) create object instance
|
// 5) create object instance
|
||||||
|
if (mappingPolicy == null) {
|
||||||
|
mappingPolicy = persistentEntity.getMappingPolicy();
|
||||||
|
}
|
||||||
final R createdEntity = entityInstantiator.createEntityFromState(source, targetType.getType(), mappingPolicy);
|
final R createdEntity = entityInstantiator.createEntityFromState(source, targetType.getType(), mappingPolicy);
|
||||||
|
|
||||||
// 5) connect state
|
// 6) connect state
|
||||||
entityStateHandler.setPersistentState(createdEntity,source);
|
entityStateHandler.setPersistentState(createdEntity,source);
|
||||||
|
|
||||||
if (persistentEntity.isManaged()) return createdEntity;
|
if (persistentEntity.isManaged()) return createdEntity;
|
||||||
@@ -104,6 +116,11 @@ public class Neo4jEntityConverterImpl<T,S extends PropertyContainer> implements
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <R extends T> boolean storedAndRequestedTypesMatch(Class<R> requestedType, S source) {
|
||||||
|
TypeInformation<?> storedType = typeMapper.readType(source);
|
||||||
|
return storedType.getType().isAssignableFrom(requestedType);
|
||||||
|
}
|
||||||
|
|
||||||
private <R extends T> void cascadeFetch(Neo4jPersistentEntityImpl<R> persistentEntity, final BeanWrapper<Neo4jPersistentEntity<R>, R> wrapper, final MappingPolicy policy, final Neo4jTemplate template) {
|
private <R extends T> void cascadeFetch(Neo4jPersistentEntityImpl<R> persistentEntity, final BeanWrapper<Neo4jPersistentEntity<R>, R> wrapper, final MappingPolicy policy, final Neo4jTemplate template) {
|
||||||
persistentEntity.doWithAssociations(new AssociationHandler<Neo4jPersistentProperty>() {
|
persistentEntity.doWithAssociations(new AssociationHandler<Neo4jPersistentProperty>() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.springframework.data.neo4j.support.typesafety;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum of all type safety options which are available in the system.
|
||||||
|
*
|
||||||
|
* @author spaetzold
|
||||||
|
*/
|
||||||
|
public enum TypeSafetyOption {
|
||||||
|
|
||||||
|
/** Sets the system to not be type safe (default setting). */
|
||||||
|
NONE,
|
||||||
|
|
||||||
|
/** Sets the system to return null if a entity should be loaded which is not of the requested type. */
|
||||||
|
RETURNS_NULL,
|
||||||
|
|
||||||
|
/** Sets the system to throw an exception if a entity should be loaded which is not of the requested type. */
|
||||||
|
THROWS_EXCEPTION
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package org.springframework.data.neo4j.support.typesafety;
|
||||||
|
|
||||||
|
import org.springframework.data.neo4j.support.ParameterCheck;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type safety policy describes how repositories behave when loading entities from Neo4j.
|
||||||
|
*
|
||||||
|
* @author spaetzold
|
||||||
|
*/
|
||||||
|
public class TypeSafetyPolicy {
|
||||||
|
|
||||||
|
private final TypeSafetyOption option;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of a type safety policy with the desired type safety option.
|
||||||
|
*
|
||||||
|
* @param option the type safety option
|
||||||
|
*/
|
||||||
|
public TypeSafetyPolicy(TypeSafetyOption option) {
|
||||||
|
ParameterCheck.notNull(option, "option");
|
||||||
|
this.option = option;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of a type safety policy with no type safety enabled.
|
||||||
|
*/
|
||||||
|
public TypeSafetyPolicy() {
|
||||||
|
this.option = TypeSafetyOption.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if type safety is enabled in the system.
|
||||||
|
*
|
||||||
|
* @return true if type safety is enabled, else false
|
||||||
|
*/
|
||||||
|
public boolean isTypeSafetyEnabled() {
|
||||||
|
return option != TypeSafetyOption.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the currently defined system type safety option.
|
||||||
|
*
|
||||||
|
* @return the type safety option
|
||||||
|
*/
|
||||||
|
public TypeSafetyOption getTypeSafetyOption() {
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2011 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.neo4j.support;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.neo4j.graphdb.NotFoundException;
|
||||||
|
import org.springframework.dao.DataRetrievalFailureException;
|
||||||
|
import org.springframework.data.neo4j.mapping.InvalidEntityTypeException;
|
||||||
|
import org.springframework.data.neo4j.model.Group;
|
||||||
|
import org.springframework.data.neo4j.model.Person;
|
||||||
|
import org.springframework.data.neo4j.template.Neo4jOperations;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author spaetzold
|
||||||
|
*/
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(locations = {"classpath:template-config-context-with-type-safety-throwing-exception.xml"})
|
||||||
|
public class ExceptionThrowingTypeSafetyNeo4jTemplateTests extends EntityTestBase {
|
||||||
|
|
||||||
|
private Neo4jOperations neo4jOperations;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
createTeam();
|
||||||
|
neo4jOperations = template;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidEntityTypeException.class)
|
||||||
|
@Transactional
|
||||||
|
public void testFindOneWithWrongTypeThrowsInvalidEntityTypeException() throws Exception {
|
||||||
|
neo4jOperations.findOne(testTeam.michael.getId(), Group.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
public void testFindOneWithRightTypeReturnsPerson() throws Exception {
|
||||||
|
final Person found = neo4jOperations.findOne(testTeam.michael.getId(), Person.class);
|
||||||
|
assertNotNull(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = DataRetrievalFailureException.class)
|
||||||
|
@Transactional
|
||||||
|
public void testFindOneWithNonExistingIdThrowsDataRetrievalFailureException() throws Exception {
|
||||||
|
neo4jOperations.findOne(Long.MAX_VALUE, Person.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2011 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.neo4j.support;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.neo4j.graphdb.NotFoundException;
|
||||||
|
import org.springframework.dao.DataRetrievalFailureException;
|
||||||
|
import org.springframework.data.neo4j.mapping.InvalidEntityTypeException;
|
||||||
|
import org.springframework.data.neo4j.model.Group;
|
||||||
|
import org.springframework.data.neo4j.model.Person;
|
||||||
|
import org.springframework.data.neo4j.template.Neo4jOperations;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author spaetzold
|
||||||
|
*/
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(locations = {"classpath:template-config-context-with-type-safety-returning-null.xml"})
|
||||||
|
public class NullReturningTypeSafetyNeo4jTemplateTests extends EntityTestBase {
|
||||||
|
|
||||||
|
private Neo4jOperations neo4jOperations;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
createTeam();
|
||||||
|
neo4jOperations = template;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
public void testFindOneWithWrongTypeReturnsNull() throws Exception {
|
||||||
|
final Group found = neo4jOperations.findOne(testTeam.michael.getId(), Group.class);
|
||||||
|
assertNull(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
public void testFindOneWithRightTypeReturnsPerson() throws Exception {
|
||||||
|
final Person found = neo4jOperations.findOne(testTeam.michael.getId(), Person.class);
|
||||||
|
assertNotNull(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = DataRetrievalFailureException.class)
|
||||||
|
@Transactional
|
||||||
|
public void testFindOneWithNonExistingIdThrowsDataRetrievalFailureException() throws Exception {
|
||||||
|
neo4jOperations.findOne(Long.MAX_VALUE, Person.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
|
||||||
|
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||||
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||||
|
http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
|
||||||
|
|
||||||
|
<context:annotation-config/>
|
||||||
|
<neo4j:config graphDatabaseService="graphDatabaseService"/>
|
||||||
|
<neo4j:repositories base-package="org.springframework.data.neo4j.model"/>
|
||||||
|
<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase" destroy-method="shutdown"/>
|
||||||
|
<bean id="typeSafetyPolicy" class="org.springframework.data.neo4j.support.typesafety.TypeSafetyPolicy">
|
||||||
|
<constructor-arg type="org.springframework.data.neo4j.support.typesafety.TypeSafetyOption"><value>RETURNS_NULL</value></constructor-arg>
|
||||||
|
</bean>
|
||||||
|
<tx:annotation-driven mode="aspectj"/>
|
||||||
|
</beans>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
|
||||||
|
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||||
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||||
|
http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
|
||||||
|
|
||||||
|
<context:annotation-config/>
|
||||||
|
<neo4j:config graphDatabaseService="graphDatabaseService"/>
|
||||||
|
<neo4j:repositories base-package="org.springframework.data.neo4j.model"/>
|
||||||
|
<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase" destroy-method="shutdown"/>
|
||||||
|
<bean id="typeSafetyPolicy" class="org.springframework.data.neo4j.support.typesafety.TypeSafetyPolicy">
|
||||||
|
<constructor-arg type="org.springframework.data.neo4j.support.typesafety.TypeSafetyOption"><value>THROWS_EXCEPTION</value></constructor-arg>
|
||||||
|
</bean>
|
||||||
|
<tx:annotation-driven mode="aspectj"/>
|
||||||
|
</beans>
|
||||||
Reference in New Issue
Block a user