Contributions from @ractive

build-helper-maven-plugin added so that the generated sources are used as source folder in eclipse
Making the import or com.mysema.query optional
Clear the dynamic properties map in calls to setPropertiesFrom to make sure that non existent properties get deleted
This commit is contained in:
Jean-Pierre Bergamin
2012-11-30 17:35:55 +01:00
committed by Michael Hunger
parent df09eedcd4
commit b9c0f5fa8c
18 changed files with 94 additions and 54 deletions

View File

@@ -1,7 +1,7 @@
<ivy-module version="2.0" xmlns:m="http://ant.apache.org/ivy/maven">
<info organisation="org.springframework.data.neo4j.examples" module="hello-worlds"/>
<dependencies>
<dependency org="org.springframework.data" name="spring-data-neo4j-aspects" rev="2.0.0.RELEASE">
<dependency org="org.springframework.data" name="spring-data-neo4j-aspects" rev="2.0.1.RELEASE">
<exclude module="jms"/>
<exclude module="jmxtools"/>
<exclude module="jmxri"/>

View File

@@ -87,13 +87,13 @@ public privileged aspect Neo4jNodeBacking { // extends AbstractTypeAnnotatingMix
protected pointcut entityFieldGet(NodeBacked entity) :
get(* NodeBacked+.*) &&
get(!transient * NodeBacked+.*) &&
this(entity) &&
!get(* NodeBacked.*);
protected pointcut entityFieldSet(NodeBacked entity, Object newVal) :
set(* NodeBacked+.*) &&
set(!transient * NodeBacked+.*) &&
this(entity) &&
args(newVal) &&
!set(* NodeBacked.*);

View File

@@ -72,13 +72,13 @@ public aspect Neo4jRelationshipBacking {
protected pointcut entityFieldGet(RelationshipBacked entity) :
get(* RelationshipBacked+.*) &&
get(!transient * RelationshipBacked+.*) &&
this(entity) &&
!get(* RelationshipBacked.*);
protected pointcut entityFieldSet(RelationshipBacked entity, Object newVal) :
set(* RelationshipBacked+.*) &&
set(!transient * RelationshipBacked+.*) &&
this(entity) &&
args(newVal) &&
!set(* RelationshipBacked.*);

View File

@@ -238,6 +238,10 @@ public class Person {
this.personalProperties = personalProperties;
}
public void personalPropertiesFromMap(Map<String, Object> props) {
this.personalProperties.setPropertiesFrom(props);
}
public void setNickname(String nickname) {
this.nickname = nickname;
}

View File

@@ -135,6 +135,32 @@ public class DynamicPropertiesTests extends EntityTestBase {
assertProperties(nodeFor(p));
}
@Test
@Transactional
public void testRemovePropertyFromMap() {
Person p = persistedPerson("James", 36);
Map<String, Object> propertyMap = new HashMap<String, Object>();
propertyMap.put("s", "String");
propertyMap.put("x", 100);
propertyMap.put("pi", 3.1415);
p.personalPropertiesFromMap(propertyMap);
persist(p);
assertEquals(3, IteratorUtil.count(p.getPersonalProperties().getPropertyKeys()));
assertProperties(nodeFor(p));
propertyMap.remove("s");
p.personalPropertiesFromMap(propertyMap);
persist(p);
Node node = nodeFor(p);
assertEquals(2, IteratorUtil.count(p.getPersonalProperties().getPropertyKeys()));
assertFalse(node.hasProperty("personalProperties-s"));
assertEquals(100, node.getProperty("personalProperties-x"));
assertEquals(3.1415, ((Double) node.getProperty("personalProperties-pi")).doubleValue(), 0.000000001);
}
@Test
@Transactional
public void testAsMap() {

View File

@@ -19,8 +19,7 @@ Import-Template:
org.neo4j.cypher.*;version="0";resolution:=optional,
org.w3c.dom.*;version="0",
org.aspectj.*;version="[1.6.5, 2.0.0)",
org.apache.commons.configuration.*;version="0",
org.objectweb.jotm.*;version="0",
org.objectweb.jotm.*;version="0";resolution:=optional,
org.apache.lucene.*;version="0",
org.slf4j.*;version="0",
javax.validation.*;version="0";resolution:=optional,

View File

@@ -33,7 +33,6 @@ import java.io.File;
* @author mh
* @since 31.01.11
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:org/springframework/data/neo4j/config/DataGraphNamespaceHandlerTest-cross-store-context.xml")
public class DataGraphNamespaceHandlerCrossStoreTests {
@@ -45,8 +44,8 @@ public class DataGraphNamespaceHandlerCrossStoreTests {
@Test public void injectionForCrossStore() {
Assert.assertNotNull("template", template);
EmbeddedGraphDatabase graphDatabaseService = (EmbeddedGraphDatabase) template.getGraphDatabaseService();
File directory = new File("target", "config-test");
Assert.assertTrue("store-dir", graphDatabaseService.getStoreDir().equals(directory.getPath()));
String fileSeparator = "target" + System.getProperty("file.separator") + "config-test";
Assert.assertTrue("store-dir", graphDatabaseService.getStoreDir().endsWith(fileSeparator));
Assert.assertNotNull("graphDatabaseService", graphDatabaseService);
Assert.assertNotNull("transactionManager", transactionManager);
}

View File

@@ -19,8 +19,7 @@ Import-Template:
org.neo4j.cypher.*;version="0";resolution:=optional,
org.w3c.dom.*;version="0",
org.aspectj.*;version="[1.6.5, 2.0.0)",
org.apache.commons.configuration.*;version="0",
org.objectweb.jotm.*;version="0",
org.objectweb.jotm.*;version="0";resolution:=optional,
org.apache.lucene.*;version="0",
org.slf4j.*;version="0",
javax.validation.*;version="0";resolution:=optional,

View File

@@ -1,7 +1,7 @@
<ivy-module version="2.0" xmlns:m="http://ant.apache.org/ivy/maven">
<info organisation="org.springframework.data.neo4j.examples" module="hello-worlds"/>
<dependencies>
<dependency org="org.springframework.data" name="spring-data-neo4j" rev="2.0.0.RELEASE">
<dependency org="org.springframework.data" name="spring-data-neo4j" rev="2.0.1.RELEASE">
<exclude module="jms"/>
<exclude module="jmxtools"/>
<exclude module="jmxri"/>

View File

@@ -195,10 +195,10 @@
<artifactId>blueprints-neo4j-graph</artifactId>
<version>${blueprints.version}</version>
<exclusions>
<exclusion>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-management</artifactId>
</exclusion>
<exclusion>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-management</artifactId>
</exclusion>
<exclusion>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
@@ -254,7 +254,26 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-test-source</id>
<!-- Why is it not working with the generate-test-sources phase and add-test-source goal? -->
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-test-sources/querydsl</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

View File

@@ -24,10 +24,8 @@ import org.springframework.data.neo4j.fieldaccess.DynamicPropertiesFieldAccessor
* A {@link DynamicProperties} property on a @NodeEntity stores all its properties dynamically
* on the underlying node itself.
* <p>
* This dynamic property only is available inside a transaction, i.e. when the entity has been saved.
* <p>
* The key/value pairs of the {@link DynamicProperties} property are stored on the node with the keys
* prefixed with the property name that is returned by {@link org.springframework.data.neo4j.mapping.Neo4jPersistentProperty#getNeo4jPropertyName()}.
* The key/value pairs of the {@link DynamicProperties} member are stored on the node with the keys
* prefixed with the property name that is returned by {@link DelegatingFieldAccessorFactory#getNeo4jPropertyName(Field)}.
* <pre>
* &#064;NodeEntity
* class Person {

View File

@@ -70,6 +70,7 @@ public class DynamicPropertiesContainer implements DynamicProperties {
@Override
public void setPropertiesFrom(Map<String, Object> m) {
map.clear();
map.putAll(m);
}

View File

@@ -189,9 +189,10 @@ public class PrefixedDynamicProperties implements DynamicProperties {
}
@Override
public void setPropertiesFrom(final Map<String, Object> map) {
for (String key : map.keySet()) {
baseSetProperty(key, map.get(key));
public void setPropertiesFrom(final Map<String, Object> propertiesMap) {
this.map.clear();
for (String key : propertiesMap.keySet()) {
baseSetProperty(key, propertiesMap.get(key));
}
}

View File

@@ -29,7 +29,6 @@ public interface IndexProvider {
@SuppressWarnings("unchecked")
<S extends PropertyContainer, T> Index<S> getIndex(Neo4jPersistentEntity<T> persistentEntity, String indexName, IndexType indexType);
@SuppressWarnings("unchecked")
<T extends PropertyContainer> Index<T> getIndex(String indexName);
boolean isNode(Class<? extends PropertyContainer> type);
@@ -52,4 +51,4 @@ public interface IndexProvider {
*/
String customizeIndexName(String indexName, Class<?> type);
}
}

View File

@@ -39,13 +39,13 @@ public class NullReadableIndex<S extends PropertyContainer> implements ReadableI
}
@Override
public GraphDatabaseService getGraphDatabase() {
return graphDatabaseService;
public Class<S> getEntityType() {
return null;
}
@Override
public Class<S> getEntityType() {
return null;
public GraphDatabaseService getGraphDatabase() {
return graphDatabaseService;
}
@Override

View File

@@ -48,6 +48,10 @@ public abstract class AbstractIndexingTypeRepresentationStrategy<S extends Prope
typesIndex = createTypesIndex();
}
private Object indexValueForType(Object alias) {
return indexProvider == null ? alias : indexProvider.createIndexValueForType(alias);
}
@SuppressWarnings("unchecked")
private Index<S> createTypesIndex() {
return (Index<S>) graphDb.createIndex(clazz, INDEX_NAME, IndexType.SIMPLE);
@@ -63,8 +67,7 @@ public abstract class AbstractIndexingTypeRepresentationStrategy<S extends Prope
@Override
public long count(StoredEntityType type) {
long count = 0;
Object value = type.getAlias();
final IndexHits<S> hits = get(value);
final IndexHits<S> hits = get(type.getAlias());
while (hits.hasNext()) {
hits.next();
count++;
@@ -74,10 +77,10 @@ public abstract class AbstractIndexingTypeRepresentationStrategy<S extends Prope
private IndexHits<S> get(Object value) {
try {
return typesIndex.get(INDEX_KEY, value);
return typesIndex.get(INDEX_KEY, indexValueForType(value));
} catch(IllegalStateException ise) {
typesIndex=createTypesIndex();
return typesIndex.get(INDEX_KEY, value);
return typesIndex.get(INDEX_KEY, indexValueForType(value));
}
}
@@ -109,11 +112,7 @@ public abstract class AbstractIndexingTypeRepresentationStrategy<S extends Prope
protected void addToTypesIndex(S element, StoredEntityType type) {
if (type == null) return;
Object value = type.getAlias();
if (indexProvider != null) {
value = indexProvider.createIndexValueForType(type.getAlias());
}
add(element, value);
add(element, type.getAlias());
for (StoredEntityType superType : type.getSuperTypes()) {
addToTypesIndex(element,superType);
}
@@ -121,20 +120,16 @@ public abstract class AbstractIndexingTypeRepresentationStrategy<S extends Prope
private void add(S element, Object value) {
try {
typesIndex.add(element, INDEX_KEY, value);
typesIndex.add(element, INDEX_KEY, indexValueForType(value));
} catch(IllegalStateException ise) {
typesIndex = createTypesIndex();
typesIndex.add(element, INDEX_KEY, value);
typesIndex.add(element, INDEX_KEY, indexValueForType(value));
}
}
@SuppressWarnings("hiding")
private ClosableIterable<S> findAllRelBacked(StoredEntityType type) {
Object value = type.getAlias();
if (indexProvider != null)
value = indexProvider.createIndexValueForType(type.getAlias());
final IndexHits<S> allEntitiesOfType = get(value);
final IndexHits<S> allEntitiesOfType = get(type.getAlias());
return new ClosableIndexHits<S>(allEntitiesOfType);
}

View File

@@ -46,7 +46,6 @@ import static org.junit.Assert.assertTrue;
* @author mh
* @since 31.01.11
*/
public class DataGraphNamespaceHandlerTests {
static class Config {
@@ -122,8 +121,8 @@ public class DataGraphNamespaceHandlerTests {
Neo4jTemplate template = config.neo4jTemplate;
Assert.assertNotNull("template", template);
AbstractGraphDatabase graphDatabaseService = (AbstractGraphDatabase) template.getGraphDatabaseService();
File directory = new File("target", "config-test");
Assert.assertEquals("store-dir", directory.getPath(),graphDatabaseService.getStoreDir());
String fileSeparator = "target" + System.getProperty("file.separator") + "config-test";
Assert.assertTrue("store-dir", graphDatabaseService.getStoreDir().endsWith(fileSeparator));
Assert.assertNotNull("graphDatabaseService",config.graphDatabaseService);
Assert.assertNotNull("transactionManager",config.transactionManager);
config.graphDatabaseService.shutdown();

View File

@@ -20,8 +20,8 @@ Import-Template:
org.neo4j.cypher.*;version="0";resolution:=optional,
org.w3c.dom.*;version="0",
org.aspectj.*;version="[1.6.5, 2.0.0)",
org.apache.commons.configuration.*;version="0",
org.objectweb.jotm.*;version="0",
org.apache.commons.configuration.*;version="0";resolution:=optional,
org.objectweb.jotm.*;version="0";resolution:=optional,
org.apache.lucene.*;version="0",
org.slf4j.*;version="0",
javax.lang.model.*;version="0";resolution:=optional,
@@ -33,8 +33,9 @@ Import-Template:
javax.persistence.*;version="[1.0.0, 3.0.0)";resolution:=optional,
javax.persistence.spi.*;version="[1.0.0, 3.0.0)";resolution:=optional,
javax.transaction.*;version="[1.0.1, 2.0.0)";resolution:=optional,
com.mysema.query.annotations.*;version="0",
com.mysema.query.apt.*;version="0",
com.mysema.query.annotations.*;version="0";resolution:=optional,
com.mysema.query.apt.*;version="0";resolution:=optional,
com.mysema.query.types.*;version="0";resolution:=optional,
com.tinkerpop.blueprints.*;version="[0.8,1.0)";resolution:=optional,
com.tinkerpop.gremlin.*;version="[1.1,2.0)";resolution:=optional,
com.tinkerpop.pipes.util.*;version="[0.8,1.0)";resolution:=optional