From aaa72aaf8c56882123d3949a5197af1e29cfe52b Mon Sep 17 00:00:00 2001 From: Lasse Westh-Nielsen Date: Thu, 14 Jun 2012 17:49:41 +0100 Subject: [PATCH] DATAGRAPH-251 @RelatedToVia, annotation-provided relationship type and precedence --- ...edToViaCollectionFieldAccessorFactory.java | 6 +- ...elatedToViaSingleFieldAccessorFactory.java | 6 +- .../neo4j/fieldaccess/RelationshipHelper.java | 5 + .../neo4j/mapping/Neo4jEntityConverter.java | 4 +- .../data/neo4j/mapping/RelationshipInfo.java | 4 +- .../data/neo4j/support/Neo4jTemplate.java | 9 +- .../support/mapping/EntityStateHandler.java | 45 ++++-- .../mapping/Neo4jEntityConverterImpl.java | 6 +- .../support/mapping/Neo4jEntityPersister.java | 23 +-- .../data/neo4j/annotation/City.java | 69 +++++++++ .../data/neo4j/annotation/CityRepository.java | 22 +++ .../data/neo4j/annotation/Country.java | 47 ++++++ .../neo4j/annotation/CountryRepository.java | 22 +++ .../neo4j/annotation/IdentifiableEntity.java | 35 +++++ .../annotation/InterCountryRelationship.java | 42 ++++++ .../data/neo4j/annotation/MetroLine.java | 28 ++++ .../neo4j/annotation/MetroLineRepository.java | 22 +++ .../neo4j/annotation/PerpetualRelations.java | 48 ++++++ .../data/neo4j/annotation/Player.java | 32 ++++ .../neo4j/annotation/PlayerRepository.java | 22 +++ .../data/neo4j/annotation/PlayerStatus.java | 50 +++++++ .../neo4j/annotation/RelatedToViaTests.java | 139 ++++++++++++++++-- .../data/neo4j/annotation/SuperState.java | 39 +++++ .../annotation/SuperStateRepository.java | 22 +++ .../data/neo4j/annotation/Team.java | 43 ++++++ .../data/neo4j/annotation/TeamRepository.java | 22 +++ .../annotation/TransportInfrastructure.java | 49 ++++++ .../data/neo4j/annotation/TubeStation.java | 26 +--- .../mapping/Neo4jEntityPersisterTest.java | 2 +- .../mapping/Neo4jPersistentTestBase.java | 2 +- 30 files changed, 818 insertions(+), 73 deletions(-) create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/City.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/CityRepository.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/Country.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/CountryRepository.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/IdentifiableEntity.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/InterCountryRelationship.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/MetroLine.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/MetroLineRepository.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/PerpetualRelations.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/Player.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/PlayerRepository.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/PlayerStatus.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/SuperState.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/SuperStateRepository.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/Team.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/TeamRepository.java create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/TransportInfrastructure.java diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/RelatedToViaCollectionFieldAccessorFactory.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/RelatedToViaCollectionFieldAccessorFactory.java index c45c5895f..37e34279d 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/RelatedToViaCollectionFieldAccessorFactory.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/RelatedToViaCollectionFieldAccessorFactory.java @@ -90,13 +90,13 @@ public class RelatedToViaCollectionFieldAccessorFactory implements FieldAccessor final Map endNodeToEntityMapping = loadEndNodeToRelationshipEntityMapping(newVal, startNode); relationshipHelper.removeMissingRelationshipsInStoreAndKeepOnlyNewRelationShipsInSet(startNode, endNodeToEntityMapping.keySet()); - persistEntities(endNodeToEntityMapping.values()); + persistEntities(endNodeToEntityMapping.values(), relationshipHelper.getRelationshipType()); return createManagedSet(entity, (Set) newVal, property.obtainMappingPolicy(mappingPolicy)); } - private void persistEntities(final Collection relationshipEntities) { + private void persistEntities( final Collection relationshipEntities, RelationshipType relationshipType ) { for (Object entity : relationshipEntities) { - template.save(entity); + template.save(entity, relationshipType); } } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/RelatedToViaSingleFieldAccessorFactory.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/RelatedToViaSingleFieldAccessorFactory.java index d11e7a089..679f74410 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/RelatedToViaSingleFieldAccessorFactory.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/RelatedToViaSingleFieldAccessorFactory.java @@ -78,7 +78,7 @@ public class RelatedToViaSingleFieldAccessorFactory implements FieldAccessorFact final Node startNode = relationshipHelper.checkAndGetNode(entity); final Map endNodeToEntityMapping = relationshipEntities.loadEndNodeToRelationshipEntityMapping(startNode, toSet(newVal), relatedType); relationshipHelper.removeMissingRelationshipsInStoreAndKeepOnlyNewRelationShipsInSet(startNode, endNodeToEntityMapping.keySet()); - persistEntities(endNodeToEntityMapping.values()); + persistEntities(endNodeToEntityMapping.values(), relationshipHelper.getRelationshipType() ); return newVal; } @@ -87,9 +87,9 @@ public class RelatedToViaSingleFieldAccessorFactory implements FieldAccessorFact return Collections.singleton(newVal); } - private void persistEntities(final Collection relationshipEntities) { + private void persistEntities( final Collection relationshipEntities, RelationshipType relationshipType ) { for (Object entity : relationshipEntities) { - template.save(entity); + template.save(entity, relationshipType); } } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/RelationshipHelper.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/RelationshipHelper.java index e3a79a3ed..de738a563 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/RelationshipHelper.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/RelationshipHelper.java @@ -148,4 +148,9 @@ public class RelationshipHelper { public Relationship getSingleRelationship(Node node) { return node.getSingleRelationship(type,direction); } + + public RelationshipType getRelationshipType() + { + return type; + } } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/Neo4jEntityConverter.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/Neo4jEntityConverter.java index 5c841b38d..2b533f6ee 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/Neo4jEntityConverter.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/Neo4jEntityConverter.java @@ -16,6 +16,7 @@ package org.springframework.data.neo4j.mapping; import org.neo4j.graphdb.PropertyContainer; +import org.neo4j.graphdb.RelationshipType; import org.springframework.core.convert.ConversionService; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.neo4j.support.Neo4jTemplate; @@ -27,7 +28,8 @@ import org.springframework.data.neo4j.support.mapping.Neo4jPersistentEntityImpl; */ public interface Neo4jEntityConverter { R read(Class type, S source, MappingPolicy mappingPolicy, final Neo4jTemplate template); - void write(T source, S sink, MappingPolicy mappingPolicy, final Neo4jTemplate template); + void write( T source, S sink, MappingPolicy mappingPolicy, final Neo4jTemplate template, RelationshipType + annotationProvidedRelationshipType ); MappingContext, Neo4jPersistentProperty> getMappingContext(); ConversionService getConversionService(); R loadEntity(R entity, S source, MappingPolicy mappingPolicy, Neo4jPersistentEntityImpl persistentEntity, final Neo4jTemplate template); diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/RelationshipInfo.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/RelationshipInfo.java index 6e3568b18..b1aeda446 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/RelationshipInfo.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/RelationshipInfo.java @@ -19,6 +19,7 @@ package org.springframework.data.neo4j.mapping; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.DynamicRelationshipType; import org.neo4j.graphdb.RelationshipType; +import org.springframework.data.mapping.model.MappingException; import org.springframework.data.neo4j.annotation.RelatedTo; import org.springframework.data.neo4j.annotation.RelatedToVia; import org.springframework.data.neo4j.annotation.RelationshipEntity; @@ -96,7 +97,8 @@ public class RelationshipInfo { final TypeInformation relationshipEntityType = elementClass(annotation, typeInformation); final RelationshipEntity relationshipEntity = relationshipEntityType.getType().getAnnotation(RelationshipEntity.class); if (!relationshipEntity.type().isEmpty()) return relationshipEntity.type(); - return field.getName(); + + throw new MappingException( "Relationship entity must have a default type" ); } private static TypeInformation elementClass(RelatedToVia annotation, TypeInformation typeInformation) { diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/Neo4jTemplate.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/Neo4jTemplate.java index 6fc95de4b..1d7745f8f 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/Neo4jTemplate.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/Neo4jTemplate.java @@ -293,7 +293,12 @@ public class Neo4jTemplate implements Neo4jOperations { @Override @SuppressWarnings("unchecked") public T save(T entity) { - return (T) infrastructure.getEntityPersister().persist(entity, getMappingPolicy(entity), this); + return save( entity, null ); + } + + public T save( T entity, RelationshipType annotationProvidedRelationshipType ) + { + return (T) infrastructure.getEntityPersister().persist(entity, getMappingPolicy(entity), this, annotationProvidedRelationshipType ); } public boolean isManaged(Object entity) { @@ -650,7 +655,7 @@ public class Neo4jTemplate implements Neo4jOperations { public MappingPolicy getMappingPolicy(Object entity) { ParameterCheck.notNull(entity,"entity"); - return getMappingPolicy(entity.getClass()); + return getMappingPolicy( entity.getClass() ); } public StoredEntityType getStoredEntityType(Object entity) { diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/EntityStateHandler.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/EntityStateHandler.java index 4b89e3035..a0ce3903b 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/EntityStateHandler.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/EntityStateHandler.java @@ -118,7 +118,8 @@ public class EntityStateHandler { } @SuppressWarnings("unchecked") - public S useOrCreateState(Object entity, S state) { + public S useOrCreateState( Object entity, S state, RelationshipType + annotationProvidedRelationshipType ) { if (state != null) return state; final S containedState = getPersistentState(entity); if (containedState != null) return containedState; @@ -131,7 +132,7 @@ public class EntityStateHandler { return (S) graphDatabase.createNode(null); } if (persistentEntity.isRelationshipEntity()) { - return getOrCreateRelationship(entity, persistentEntity); + return getOrCreateRelationship(entity, persistentEntity, annotationProvidedRelationshipType ); } throw new IllegalArgumentException("The entity " + persistentEntity.getEntityName() + " has to be either annotated with @NodeEntity or @RelationshipEntity"); } @@ -144,13 +145,13 @@ public class EntityStateHandler { } @SuppressWarnings("unchecked") - private S getOrCreateRelationship(Object entity, Neo4jPersistentEntity persistentEntity) { + private S getOrCreateRelationship( Object entity, Neo4jPersistentEntity persistentEntity, RelationshipType annotationProvidedRelationshipType ) { final RelationshipProperties relationshipProperties = persistentEntity.getRelationshipProperties(); final Neo4jPersistentProperty startNodeProperty = relationshipProperties.getStartNodeProperty(); Node startNode = (Node) getPersistentState(startNodeProperty.getValue(entity, startNodeProperty.getMappingPolicy())); final Neo4jPersistentProperty endNodeProperty = relationshipProperties.getEndNodeProperty(); Node endNode = (Node) getPersistentState(endNodeProperty.getValue(entity, endNodeProperty.getMappingPolicy())); - RelationshipType relationshipType = getRelationshipType(persistentEntity,entity); + RelationshipType relationshipType = getRelationshipType(persistentEntity,entity, annotationProvidedRelationshipType ); if (persistentEntity.isUnique()) { final Neo4jPersistentProperty uniqueProperty = persistentEntity.getUniqueProperty(); final IndexInfo indexInfo = uniqueProperty.getIndexInfo(); @@ -163,20 +164,36 @@ public class EntityStateHandler { return (S) graphDatabase.createRelationship(startNode, endNode, relationshipType, Collections.emptyMap()); } - private RelationshipType getRelationshipType(Neo4jPersistentEntity persistentEntity, Object entity) { + private RelationshipType getRelationshipType( Neo4jPersistentEntity persistentEntity, Object entity, + RelationshipType annotationProvidedRelationshipType ) + { final RelationshipProperties relationshipProperties = persistentEntity.getRelationshipProperties(); final Neo4jPersistentProperty typeProperty = relationshipProperties.getTypeProperty(); - Object relType; - if (typeProperty!=null) { - relType = typeProperty.getValue(entity, typeProperty.getMappingPolicy()); - } else { - relType = relationshipProperties.getRelationshipType(); + + if ( typeProperty != null ) + { + Object value = typeProperty.getValue( entity, typeProperty.getMappingPolicy() ); + + if ( value != null ) + { + return value instanceof RelationshipType ? (RelationshipType) value : DynamicRelationshipType + .withName( value.toString() ); + } } - if (relType instanceof RelationshipType) { - return (RelationshipType) relType; + + if ( annotationProvidedRelationshipType != null ) + { + return annotationProvidedRelationshipType; } - if (relType==null) throw new MappingException("Could not determine relationship-type for "+persistentEntity.getName()); - return DynamicRelationshipType.withName(relType.toString()); + + String relationshipTypeAsString = relationshipProperties.getRelationshipType(); + + if ( relationshipTypeAsString == null ) + { + throw new MappingException( "Could not determine relationship-type for " + persistentEntity.getName() ); + } + + return DynamicRelationshipType.withName( relationshipTypeAsString ); } public RelationshipResult relateTo(Object source, Object target, String type) { diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4jEntityConverterImpl.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4jEntityConverterImpl.java index c93aa5956..49d5db9f0 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4jEntityConverterImpl.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4jEntityConverterImpl.java @@ -16,6 +16,7 @@ package org.springframework.data.neo4j.support.mapping; import org.neo4j.graphdb.PropertyContainer; +import org.neo4j.graphdb.RelationshipType; import org.springframework.core.convert.ConversionService; import org.springframework.data.convert.TypeMapper; import org.springframework.data.mapping.Association; @@ -133,7 +134,8 @@ public class Neo4jEntityConverterImpl implements } @Override - public void write(T source, S sink, MappingPolicy mappingPolicy, final Neo4jTemplate template) { + public void write( T source, S sink, MappingPolicy mappingPolicy, final Neo4jTemplate template, RelationshipType + annotationProvidedRelationshipType ) { final Class sourceType = source.getClass(); @SuppressWarnings("unchecked") final Neo4jPersistentEntityImpl persistentEntity = (Neo4jPersistentEntityImpl) mappingContext.getPersistentEntity(sourceType); if (persistentEntity.isManaged()) { // todo check if typerepreentationstragegy is called ?? @@ -143,7 +145,7 @@ public class Neo4jEntityConverterImpl implements final BeanWrapper, T> wrapper = BeanWrapper., T>create(source, conversionService); if (sink == null) { - sink = entityStateHandler.useOrCreateState(source,sink); // todo handling of changed state + sink = entityStateHandler.useOrCreateState(source,sink, annotationProvidedRelationshipType ); // todo handling of changed state entityStateHandler.setPersistentState(source, sink); typeMapper.writeType(sourceType, sink); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4jEntityPersister.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4jEntityPersister.java index e9aecc7bc..0b3164e30 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4jEntityPersister.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4jEntityPersister.java @@ -18,6 +18,7 @@ package org.springframework.data.neo4j.support.mapping; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.PropertyContainer; import org.neo4j.graphdb.Relationship; +import org.neo4j.graphdb.RelationshipType; import org.springframework.core.convert.ConversionService; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.neo4j.mapping.*; @@ -173,8 +174,9 @@ public class Neo4jEntityPersister implements EntityPersister, Neo4jEntityConvert } @Override - public void write(Object source, S sink, MappingPolicy mappingPolicy, final Neo4jTemplate template) { - delegate.write(source,sink,mappingPolicy, template); + public void write( Object source, S sink, MappingPolicy mappingPolicy, final Neo4jTemplate template, + RelationshipType annotationProvidedRelationshipType ) { + delegate.write(source,sink,mappingPolicy, template, annotationProvidedRelationshipType ); } } @@ -220,12 +222,13 @@ public class Neo4jEntityPersister implements EntityPersister, Neo4jEntityConvert } - public Object persist(Object entity, final MappingPolicy mappingPolicy, final Neo4jTemplate template) { + public Object persist( Object entity, final MappingPolicy mappingPolicy, final Neo4jTemplate template, + RelationshipType annotationProvidedRelationshipType ) { final Class type = entity.getClass(); if (isManaged(entity)) { return ((ManagedEntity)entity).persist(); } else { - return persist(entity, type, mappingPolicy, template); + return persist(entity, type, mappingPolicy, template, annotationProvidedRelationshipType ); } } @@ -233,16 +236,17 @@ public class Neo4jEntityPersister implements EntityPersister, Neo4jEntityConvert return entityStateHandler.isManaged(entity); } - private Object persist(Object entity, Class type, MappingPolicy mappingPolicy, final Neo4jTemplate template) { + private Object persist( Object entity, Class type, MappingPolicy mappingPolicy, final Neo4jTemplate template, + RelationshipType annotationProvidedRelationshipType ) { if (isNodeEntity(type)) { final Node node = this.getPersistentState(entity); - this.nodeConverter.write(entity, node,mappingPolicy, template); + this.nodeConverter.write(entity, node,mappingPolicy, template, null ); return createEntityFromState(getPersistentState(entity),type, getMappingPolicy(type), template); //return entity; // TODO ? } if (isRelationshipEntity(type)) { final Relationship relationship = this.getPersistentState(entity); - this.relationshipConverter.write(entity, relationship,mappingPolicy, template); + this.relationshipConverter.write(entity, relationship,mappingPolicy, template, annotationProvidedRelationshipType ); return createEntityFromState(getPersistentState(entity),type, getMappingPolicy(type), template); // return entity; // TODO ? } @@ -291,8 +295,9 @@ public class Neo4jEntityPersister implements EntityPersister, Neo4jEntityConvert } @Override - public void write(Object source, Node sink, MappingPolicy mappingPolicy, final Neo4jTemplate template) { - nodeConverter.write(source,sink,mappingPolicy, template); + public void write( Object source, Node sink, MappingPolicy mappingPolicy, final Neo4jTemplate template, + RelationshipType annotationProvidedRelationshipType ) { + nodeConverter.write(source,sink,mappingPolicy, template, annotationProvidedRelationshipType ); } } diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/City.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/City.java new file mode 100644 index 000000000..247e1604e --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/City.java @@ -0,0 +1,69 @@ +/** + * 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.annotation; + +import java.util.HashSet; +import java.util.Set; + +@NodeEntity +public class City extends IdentifiableEntity { + private String name; + + @RelatedToVia + private Set existingMetroLines = new HashSet(); + + @RelatedToVia(type = "planned") + private Set plannedMetroLines = new HashSet(); + + public City() { + } + + public City( String name ) { + this.name = name; + } + + public void has( MetroLine... metroLines ) { + addTo( metroLines, existingMetroLines ); + } + + public void plans( MetroLine... metroLines ) { + addTo( metroLines, plannedMetroLines ); + } + + private void addTo( MetroLine[] metroLines, Set transportInfrastructures ) { + for ( MetroLine metroLine : metroLines ) { + transportInfrastructures.add( new TransportInfrastructure( this, metroLine ) ); + } + } + + public Set getCurrentMetroLines() { + return getMetroLines( existingMetroLines ); + } + + public Set getFutureMetroLines() { + return getMetroLines( plannedMetroLines ); + } + + private Set getMetroLines( Set transportInfrastructures ) { + HashSet metroLines = new HashSet(); + + for ( TransportInfrastructure transportInfrastructure : transportInfrastructures ) { + metroLines.add( transportInfrastructure.getMetroLine() ); + } + + return metroLines; + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/CityRepository.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/CityRepository.java new file mode 100644 index 000000000..b67d61acb --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/CityRepository.java @@ -0,0 +1,22 @@ +/** + * 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.annotation; + +import org.springframework.data.neo4j.repository.CRUDRepository; + +public interface CityRepository extends CRUDRepository +{ +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/Country.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/Country.java new file mode 100644 index 000000000..fa8416c73 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/Country.java @@ -0,0 +1,47 @@ +/** + * 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.annotation; + +@NodeEntity +public class Country extends IdentifiableEntity +{ + private String name; + + @RelatedToVia + private InterCountryRelationship acquaintance; + + @RelatedToVia(type = "special") + private InterCountryRelationship friend; + + public Country() + { + } + + public Country( String name ) + { + this.name = name; + } + + public void hasCordialRelationsWith( Country country, String description ) + { + acquaintance = new InterCountryRelationship(this, country, description ); + } + + public void hasSpecialRelationsWith( Country country ) + { + friend = new InterCountryRelationship( this, country, "The Special Relationship" ); + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/CountryRepository.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/CountryRepository.java new file mode 100644 index 000000000..f353bda02 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/CountryRepository.java @@ -0,0 +1,22 @@ +/** + * 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.annotation; + +import org.springframework.data.neo4j.repository.CRUDRepository; + +public interface CountryRepository extends CRUDRepository +{ +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/IdentifiableEntity.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/IdentifiableEntity.java new file mode 100644 index 000000000..4e8907a19 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/IdentifiableEntity.java @@ -0,0 +1,35 @@ +/** + * 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.annotation; + +public abstract class IdentifiableEntity { + @GraphId + private Long id; + + public Long getId() { + return id; + } + + @Override + public boolean equals( Object obj ) { + return obj instanceof IdentifiableEntity && id.equals( ((IdentifiableEntity) obj).getId() ); + } + + @Override + public int hashCode() { + return 0; + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/InterCountryRelationship.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/InterCountryRelationship.java new file mode 100644 index 000000000..36d57b415 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/InterCountryRelationship.java @@ -0,0 +1,42 @@ +/** + * 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.annotation; + +@RelationshipEntity(type = "cordial") +public class InterCountryRelationship +{ + @GraphId + private Long id; + + @StartNode + private Country a; + + @EndNode + private Country b; + + private String description; + + public InterCountryRelationship() + { + } + + public InterCountryRelationship( Country a, Country b, String description ) + { + this.a = a; + this.b = b; + this.description = description; + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/MetroLine.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/MetroLine.java new file mode 100644 index 000000000..bf39af8fb --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/MetroLine.java @@ -0,0 +1,28 @@ +/** + * 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.annotation; + +@NodeEntity +public class MetroLine extends IdentifiableEntity { + private String name; + + public MetroLine() { + } + + public MetroLine( String name ) { + this.name = name; + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/MetroLineRepository.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/MetroLineRepository.java new file mode 100644 index 000000000..e55aef45c --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/MetroLineRepository.java @@ -0,0 +1,22 @@ +/** + * 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.annotation; + +import org.springframework.data.neo4j.repository.CRUDRepository; + +public interface MetroLineRepository extends CRUDRepository +{ +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/PerpetualRelations.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/PerpetualRelations.java new file mode 100644 index 000000000..d3c1b41c1 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/PerpetualRelations.java @@ -0,0 +1,48 @@ +/** + * 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.annotation; + +@RelationshipEntity(type = "unrelated") +public class PerpetualRelations +{ + @GraphId + private Long id; + + @StartNode + private SuperState ss1; + + @EndNode + private SuperState ss2; + + @RelationshipType + private String status; + + public PerpetualRelations() + { + } + + public PerpetualRelations( SuperState ss1, SuperState ss2 ) + { + this.ss1 = ss1; + this.ss2 = ss2; + } + + public PerpetualRelations( SuperState ss1, SuperState ss2, String status ) + { + this(ss1, ss2 ); + this.status = status; + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/Player.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/Player.java new file mode 100644 index 000000000..569dfb7d7 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/Player.java @@ -0,0 +1,32 @@ +/** + * 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.annotation; + +@NodeEntity +public class Player extends IdentifiableEntity +{ + private String name; + + public Player() + { + + } + + public Player( String name ) + { + this.name = name; + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/PlayerRepository.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/PlayerRepository.java new file mode 100644 index 000000000..ff6476fe1 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/PlayerRepository.java @@ -0,0 +1,22 @@ +/** + * 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.annotation; + +import org.springframework.data.neo4j.repository.CRUDRepository; + +public interface PlayerRepository extends CRUDRepository +{ +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/PlayerStatus.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/PlayerStatus.java new file mode 100644 index 000000000..835912ca8 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/PlayerStatus.java @@ -0,0 +1,50 @@ +/** + * 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.annotation; + +@RelationshipEntity(type = "notplaying") +public class PlayerStatus +{ + @GraphId + private Long id; + + @StartNode + private Team team; + + @EndNode + private Player player; + + @RelationshipType + private String status; + + public PlayerStatus() + { + + } + + public PlayerStatus( Team team, Player player ) + { + this.team = team; + this.player = player; + } + + public PlayerStatus( Team team, Player player, String status ) + { + this( team, player ); + + this.status = status; + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/RelatedToViaTests.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/RelatedToViaTests.java index 156aa4180..2f990cdc9 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/RelatedToViaTests.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/RelatedToViaTests.java @@ -21,14 +21,18 @@ import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.junit.matchers.JUnitMatchers.hasItem; +import static org.neo4j.helpers.collection.IteratorUtil.first; -import java.io.IOException; +import java.util.HashSet; +import java.util.Set; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.neo4j.graphdb.Relationship; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.data.neo4j.support.Neo4jTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; @@ -36,23 +40,47 @@ import org.springframework.transaction.annotation.Transactional; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:related-to-via-test-context.xml"}) @Transactional -public class RelatedToViaTests -{ +public class RelatedToViaTests { public static final String DISTRICT_LINE = "District Line"; public static final String CENTRAL_LINE = "Central Line"; @Autowired private UndergroundRepository tfl; + @Autowired + private CountryRepository countries; + + @Autowired + private SuperStateRepository dystopia; + + @Autowired + private MetroLineRepository metroLines; + + @Autowired + private CityRepository cities; + + @Autowired + private PlayerRepository players; + + @Autowired + private TeamRepository teams; + + @Autowired + private Neo4jTemplate template; + @Before - public void before() - { + public void before() { tfl.deleteAll(); + countries.deleteAll(); + dystopia.deleteAll(); + metroLines.deleteAll(); + cities.deleteAll(); + players.deleteAll(); + teams.deleteAll(); } @Test - public void shouldMapRelationshipAsFirstClassCitizen() throws Exception - { + public void shouldMapRelationshipAsFirstClassCitizen() throws Exception { TubeStation westHam = tfl.save( new TubeStation( "West Ham" ) ); TubeStation stratford = tfl.save( new TubeStation( "Stratford" ) ); TubeStation mileEnd = new TubeStation( "Mile End" ); @@ -61,29 +89,108 @@ public class RelatedToViaTests tfl.save( mileEnd ); + assertThat( first( template.getNode( mileEnd.getId() ).getRelationships() ).getType().name(), is( "route" ) ); mileEnd = tfl.findOne( mileEnd.getId() ); - Line line = mileEnd.getLines().iterator().next(); - assertThat( mileEnd.getId(), is( equalTo( line.getOrigin().getId() ) ) ); + Line line = first( mileEnd.getLines()); + assertThat( mileEnd, is( equalTo( line.getOrigin() ) ) ); assertThat( asList( DISTRICT_LINE, CENTRAL_LINE ), hasItem( line.getName() ) ); - assertThat( asList( westHam.getId(), stratford.getId() ), hasItem( line.getDestination().getId() ) ); + assertThat( asList( westHam, stratford ), hasItem( line.getDestination() ) ); } @Test - public void shouldValidateEndNode() throws Exception - { + public void shouldGivePrecedenceToAnnotationProvidedRelationshipTypeOverDefault() throws Exception { + Country france = countries.save( new Country( "République française" ) ); + Country usa = countries.save( new Country( "United States of America" ) ); + Country uk = new Country( "United Kingdom of Great Britain and Northern Ireland" ); + uk.hasCordialRelationsWith( france, "Entente Cordiale" ); + uk.hasSpecialRelationsWith( usa ); + + countries.save( uk ); + + assertThat( getRelationshipNames( uk ), is( equalTo( asSet( "cordial", "special" ) ) ) ); + } + + @Test + public void shouldGivePrecedenceToAnnotationProvidedRelationshipTypeOverDefaultForCollections() throws Exception { + MetroLine m1 = metroLines.save( new MetroLine( "M1 - Vanløse to Vestamager" ) ); + MetroLine m2 = metroLines.save( new MetroLine( "M2 - Vanløse to Lufthavnen" ) ); + MetroLine m3 = metroLines.save( new MetroLine( "M3 - Cityringen" ) ); + MetroLine m4 = metroLines.save( new MetroLine( "M4 - Nørrebro to København H" ) ); + City copenhagen = new City( "Copenhagen" ); + copenhagen.has( m1, m2 ); + copenhagen.plans( m3, m4 ); + + cities.save( copenhagen ); + + assertThat( getRelationshipNames( copenhagen ), is( equalTo( asSet( "existing", "planned" ) ) ) ); + assertThat( copenhagen.getCurrentMetroLines(), is( equalTo( asSet( m1, m2 ) ) ) ); + assertThat( copenhagen.getFutureMetroLines(), is( equalTo( asSet( m3, m4 ) ) ) ); + } + + @Test + public void shouldGivePrecedenceToDynamicRelationshipTypeOverAnnotationProvidedRelationshipType() throws Exception { + SuperState eastasia = dystopia.save( new SuperState( "Eastasia" ) ); + SuperState eurasia = dystopia.save( new SuperState( "Eurasia" ) ); + SuperState oceania = new SuperState( "Oceania" ); + oceania.isAlliedWith( eastasia ); + + dystopia.save( oceania ); + + assertThat( getFirstRelationshipName( oceania ), is( equalTo( "alliedWith" ) ) ); + + oceania = dystopia.findOne( oceania.getId() ); + oceania.isAtWarWith( eurasia ); + + dystopia.save( oceania ); + + assertThat( getFirstRelationshipName( oceania ), is( equalTo( "atWarWith" ) ) ); + } + + @Test + public void shouldGivePrecedenceToDynamicRelationshipTypeOverAnnotationProvidedRelationshipTypeForCollections() + throws Exception { + Player jordan = players.save( new Player( "Michael Jordan" ) ); + Player pippen = players.save( new Player( "Scottie Pippen" ) ); + Team bulls = new Team( "Chicago Bulls" ); + bulls.add( new PlayerStatus( bulls, jordan ) ); + bulls.add( new PlayerStatus( bulls, pippen, "substitute" ) ); + + teams.save( bulls ); + + assertThat( getRelationshipNames( bulls ), is( equalTo( asSet( "starter", "substitute" ) ) ) ); + } + + @Test + public void shouldValidateEndNode() throws Exception { TubeStation mileEnd = new TubeStation( "East Ham" ); mileEnd.connectsTo( null, DISTRICT_LINE ); - try - { + try { tfl.save( mileEnd ); fail(); } - catch ( InvalidDataAccessApiUsageException e ) - { + catch ( InvalidDataAccessApiUsageException e ) { assertThat( e.getCause().getMessage(), is( equalTo( "End node must not be null (org.springframework.data" + ".neo4j.annotation.Line)" ) ) ); } } + + private String getFirstRelationshipName( IdentifiableEntity entity ) { + return first( template.getNode( entity.getId() ).getRelationships() ).getType().name(); + } + + private Set getRelationshipNames( IdentifiableEntity entity ) { + HashSet relationshipNames = new HashSet(); + + for ( Relationship relationship : template.getNode( entity.getId() ).getRelationships() ) { + relationshipNames.add( relationship.getType().name() ); + } + + return relationshipNames; + } + + private Set asSet( T... ts ) { + return new HashSet( asList( ts ) ); + } } diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/SuperState.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/SuperState.java new file mode 100644 index 000000000..5a2e46412 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/SuperState.java @@ -0,0 +1,39 @@ +/** + * 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.annotation; + +@NodeEntity +public class SuperState extends IdentifiableEntity { + private String name; + + @RelatedToVia(type = "alliedWith") + private PerpetualRelations neighbour; + + public SuperState() { + } + + public SuperState( String name ) { + this.name = name; + } + + public void isAlliedWith( SuperState superState ) { + neighbour = new PerpetualRelations( this, superState ); + } + + public void isAtWarWith( SuperState superState ) { + neighbour = new PerpetualRelations( this, superState, "atWarWith" ); + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/SuperStateRepository.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/SuperStateRepository.java new file mode 100644 index 000000000..a35357ed5 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/SuperStateRepository.java @@ -0,0 +1,22 @@ +/** + * 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.annotation; + +import org.springframework.data.neo4j.repository.CRUDRepository; + +public interface SuperStateRepository extends CRUDRepository +{ +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/Team.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/Team.java new file mode 100644 index 000000000..365991a3c --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/Team.java @@ -0,0 +1,43 @@ +/** + * 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.annotation; + +import java.util.HashSet; +import java.util.Set; + +@NodeEntity +public class Team extends IdentifiableEntity +{ + private String name; + + @RelatedToVia(type = "starter") + private Set starters = new HashSet(); + + public Team() + { + + } + + public Team( String name ) + { + this.name = name; + } + + public void add( PlayerStatus playerStatus ) + { + starters.add( playerStatus ); + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/TeamRepository.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/TeamRepository.java new file mode 100644 index 000000000..e0b16413d --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/TeamRepository.java @@ -0,0 +1,22 @@ +/** + * 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.annotation; + +import org.springframework.data.neo4j.repository.CRUDRepository; + +public interface TeamRepository extends CRUDRepository +{ +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/TransportInfrastructure.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/TransportInfrastructure.java new file mode 100644 index 000000000..27f89b9c1 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/TransportInfrastructure.java @@ -0,0 +1,49 @@ +/** + * 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.annotation; + +@RelationshipEntity(type = "existing") +public class TransportInfrastructure +{ + @GraphId + private Long id; + + @StartNode + private City city; + + @EndNode + private MetroLine metroLine; + + public TransportInfrastructure() + { + } + + public TransportInfrastructure( City city, MetroLine metroLine ) + { + this.city = city; + this.metroLine = metroLine; + } + + public Long getId() + { + return id; + } + + public MetroLine getMetroLine() + { + return metroLine; + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/TubeStation.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/TubeStation.java index 49b9e06a3..7dd0f4757 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/TubeStation.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/TubeStation.java @@ -19,43 +19,29 @@ import java.util.HashSet; import java.util.Set; @NodeEntity -public class TubeStation -{ - @GraphId - private Long id; - +public class TubeStation extends IdentifiableEntity { private String name; @RelatedToVia private Set lines = new HashSet(); - public TubeStation() - { + public TubeStation() { } - TubeStation( String name ) - { + TubeStation( String name ) { this.name = name; } - public Long getId() - { - return id; - } - - public void connectsTo( TubeStation tubeStation, String line ) - { + public void connectsTo( TubeStation tubeStation, String line ) { lines.add( new Line( this, tubeStation, line ) ); } - public Set getLines() - { + public Set getLines() { return lines; } - public String getName() - { + public String getName() { return name; } } diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jEntityPersisterTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jEntityPersisterTest.java index 176627f53..0d1d541dd 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jEntityPersisterTest.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jEntityPersisterTest.java @@ -62,7 +62,7 @@ public class Neo4jEntityPersisterTest extends Neo4jPersistentTestBase { @Test public void testPersist() throws Exception { - entityPersister.persist(michael, template.getMappingPolicy(michael), template); + entityPersister.persist(michael, template.getMappingPolicy(michael), template, null ); assertEquals((Long) michaelNode().getId(), michael.getId()); assertEquals(michaelNode(), entityPersister.getPersistentState(michael)); assertEquals(michaelNode().getProperty("name"), michael.getName()); diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jPersistentTestBase.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jPersistentTestBase.java index 6a96551f2..2268a544a 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jPersistentTestBase.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jPersistentTestBase.java @@ -192,7 +192,7 @@ public class Neo4jPersistentTestBase { } protected Object write(Object entity, Node node) { - entityPersister.write(entity, node, template.getMappingPolicy(entity), template); + entityPersister.write(entity, node, template.getMappingPolicy(entity), template, null ); return entity; }