diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/FieldAccessorFactoryProviders.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/FieldAccessorFactoryProviders.java index 813cbdef3..0e5493c1b 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/FieldAccessorFactoryProviders.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/FieldAccessorFactoryProviders.java @@ -50,9 +50,10 @@ public class FieldAccessorFactoryProviders { public List listeners() { if (fieldAccessorListenerFactories == null) return null; - final List listeners = new ArrayList(fieldAccessorListenerFactories.size()); - for (final FieldAccessorListenerFactory fieldAccessorListenerFactory : fieldAccessorListenerFactories) { - listeners.add(fieldAccessorListenerFactory.forField(property)); + int count = fieldAccessorListenerFactories.size(); + final List listeners = new ArrayList(count); + for (int i=0;i { } public Map getFieldAccessors() { - final Map result = new HashMap(fieldAccessorFactoryProviders.size(),1); - for (final FieldAccessorFactoryProvider fieldAccessorFactoryProvider : fieldAccessorFactoryProviders) { + int count = fieldAccessorFactoryProviders.size(); + final Map result = new HashMap(count,1); + for (int i = 0; i < count; i++) { + FieldAccessorFactoryProvider fieldAccessorFactoryProvider = fieldAccessorFactoryProviders.get(i); final FieldAccessor accessor = fieldAccessorFactoryProvider.accessor(); result.put(fieldAccessorFactoryProvider.getProperty(), accessor); } @@ -82,8 +85,10 @@ public class FieldAccessorFactoryProviders { } public Map> getFieldAccessListeners() { - final Map> result = new HashMap>(fieldAccessorFactoryProviders.size(),1); - for (final FieldAccessorFactoryProvider fieldAccessorFactoryProvider : fieldAccessorFactoryProviders) { + int count = fieldAccessorFactoryProviders.size(); + final Map> result = new HashMap>(count,1); + for (int i = 0; i < count; i++) { + FieldAccessorFactoryProvider fieldAccessorFactoryProvider = fieldAccessorFactoryProviders.get(i); final List listeners = (List) fieldAccessorFactoryProvider.listeners(); result.put(fieldAccessorFactoryProvider.getProperty(), listeners); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/QueryFieldAccessorFactory.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/QueryFieldAccessorFactory.java index d50993dd0..591a492b1 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/QueryFieldAccessorFactory.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/fieldaccess/QueryFieldAccessorFactory.java @@ -41,9 +41,8 @@ public class QueryFieldAccessorFactory implements FieldAccessorFactory { } @Override - public boolean accept(final Neo4jPersistentProperty f) { - final Query query = f.getAnnotation(Query.class); - return query != null && !query.value().isEmpty(); + public boolean accept(final Neo4jPersistentProperty property) { + return property.hasQuery(); } @@ -73,7 +72,7 @@ public class QueryFieldAccessorFactory implements FieldAccessorFactory { if ((this.annotationParams.length % 2) != 0) { throw new IllegalArgumentException("Number of parameters has to be even to construct a parameter map"); } - this.query = query.value(); + this.query = property.getQuery(); this.iterableResult = Iterable.class.isAssignableFrom(property.getType()); this.target = resolveTarget(query,property); queryEngine = this.template.queryEngineFor(QueryType.Cypher); diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/Neo4jPersistentProperty.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/Neo4jPersistentProperty.java index a7e48d441..b354293f9 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/Neo4jPersistentProperty.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/mapping/Neo4jPersistentProperty.java @@ -94,4 +94,8 @@ public interface Neo4jPersistentProperty extends PersistentProperty myAssociation; private String defaultValue; private Class propertyType; + private String query; + private final boolean isNeo4jEntityType; + private final String neo4jPropertyName; + private final int hash; public Neo4jPersistentPropertyImpl(Field field, PropertyDescriptor propertyDescriptor, PersistentEntity owner, SimpleTypeHolder simpleTypeHolder, Neo4jMappingContext ctx) { super(field, propertyDescriptor, owner, simpleTypeHolder); + this.hash = getField().hashCode(); this.annotations = extractAnnotations(field); this.relationshipInfo = extractRelationshipInfo(field, ctx); + this.propertyType = extractPropertyType(); + this.isNeo4jEntityType = isNeo4jPropertyType(getType()); + this.neo4jPropertyName = createNeo4jPropertyName(); + this.indexInfo = extractIndexInfo(); this.isIdProperty = annotations.containsKey(GraphId.class); this.defaultValue = extractDefaultValue(); this.myAssociation = isAssociation() ? super.getAssociation() == null ? createAssociation() : super.getAssociation() : null; - this.propertyType = extractPropertyType(); + this.query = extractQuery(); + } + + private String extractQuery() { + final Query query = getAnnotation(Query.class); + if (query == null) return null; + String value = query.value(); + return value.trim().isEmpty() ? null : value; } private Class extractPropertyType() { @@ -186,6 +195,10 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty fieldType) { @@ -359,6 +372,14 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty extends BasicPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity entity; private final Collection superTypes; private final EntityAlias entityAlias; + private final Class type; + private final boolean isNodeEntity; + private final boolean isRelationshipEntity; StoredEntityType(Neo4jPersistentEntity entity, Collection> superTypeEntities, final EntityAlias entityAlias) { this.entity = entity; this.entityAlias = entityAlias; this.superTypes = collectSuperTypes(superTypeEntities); this.alias = createAlias(); + type = this.entity.getType(); + isNodeEntity = this.entity.isNodeEntity(); + isRelationshipEntity = this.entity.isRelationshipEntity(); } private Collection collectSuperTypes(Collection> superTypeEntities) { @@ -92,15 +98,15 @@ public class StoredEntityType { } public Class getType() { - return entity.getType(); + return type; } public boolean isNodeEntity() { - return entity.isNodeEntity(); + return isNodeEntity; } public boolean isRelationshipEntity() { - return entity.isRelationshipEntity(); + return isRelationshipEntity; } @Override diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/AbstractIndexingTypeRepresentationStrategy.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/AbstractIndexingTypeRepresentationStrategy.java index b0ebb2b16..1e25c82e7 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/AbstractIndexingTypeRepresentationStrategy.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/AbstractIndexingTypeRepresentationStrategy.java @@ -37,6 +37,7 @@ public abstract class AbstractIndexingTypeRepresentationStrategy clazz; + private Index typesIndex; public AbstractIndexingTypeRepresentationStrategy(GraphDatabase graphDb, IndexProvider indexProvider, final String indexName, final Class clazz) { @@ -44,11 +45,11 @@ public abstract class AbstractIndexingTypeRepresentationStrategy getTypesIndex() { + private Index createTypesIndex() { return (Index) graphDb.createIndex(clazz, INDEX_NAME, IndexType.SIMPLE); } @@ -61,7 +62,8 @@ public abstract class AbstractIndexingTypeRepresentationStrategy hits = getTypesIndex().get(INDEX_KEY, type.getAlias()); + Object value = type.getAlias(); + final IndexHits hits = get(value); while (hits.hasNext()) { hits.next(); count++; @@ -69,9 +71,27 @@ public abstract class AbstractIndexingTypeRepresentationStrategy get(Object value) { + try { + return typesIndex.get(INDEX_KEY, value); + } catch(IllegalStateException ise) { + typesIndex=createTypesIndex(); + return typesIndex.get(INDEX_KEY, value); + } + } + @Override public void preEntityRemoval(S state) { - getTypesIndex().remove(state); + remove(state); + } + + private void remove(S state) { + try { + typesIndex.remove(state); + } catch(IllegalStateException ise) { + typesIndex=createTypesIndex(); + typesIndex.remove(state); + } } @Override @@ -92,19 +112,28 @@ public abstract class AbstractIndexingTypeRepresentationStrategy findAllRelBacked(StoredEntityType type) { Object value = type.getAlias(); if (indexProvider != null) value = indexProvider.createIndexValueForType(type.getAlias()); - final IndexHits allEntitiesOfType = getTypesIndex().get(INDEX_KEY, value); + final IndexHits allEntitiesOfType = get(value); return new ClosableIndexHits(allEntitiesOfType); }