diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/annotation/GraphProperty.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/annotation/GraphProperty.java index db2685596..115d7bfdc 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/annotation/GraphProperty.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/annotation/GraphProperty.java @@ -24,12 +24,12 @@ import java.lang.annotation.Target; /** * Annotation to explcitely declare a property handled by datastore-graph. Automatically indexes the property. * Only required in partial mode. Otherwise properties are handled by default if they are primitive or convertible to - * a String using the built in conversion services. + * a String using the built in conversion services. You can explicitly assign node property names too. * * @author Michael Hunger * @since 27.08.2010 */ -@Retention(RetentionPolicy.RUNTIME) +@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD,ElementType.METHOD}) public @interface GraphProperty { @@ -37,4 +37,5 @@ public @interface GraphProperty { String defaultValue() default UNSET_DEFAULT; Class propertyType() default String.class; + String propertyName() default ""; } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4JPersistentPropertyImpl.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4JPersistentPropertyImpl.java index d0d55aa1f..dad0e016f 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4JPersistentPropertyImpl.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4JPersistentPropertyImpl.java @@ -190,6 +190,8 @@ class Neo4jPersistentPropertyImpl extends AnnotationBasedPersistentProperty entityClass = (Neo4jPersistentEntity) getOwner(); + final GraphProperty annotation = getAnnotation(GraphProperty.class); + if (annotation != null && annotation.propertyName() != null && !annotation.propertyName().isEmpty()) return annotation.propertyName(); if (entityClass.useShortNames()) return getName(); return String.format("%s.%s", entityClass.getType().getSimpleName(), getName()); } diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/graphproperty/Artist.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/graphproperty/Artist.java new file mode 100644 index 000000000..7870c2575 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/graphproperty/Artist.java @@ -0,0 +1,102 @@ +/** + * 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.graphproperty; + +import java.util.Date; + +import org.springframework.data.annotation.TypeAlias; +import org.springframework.data.neo4j.annotation.GraphProperty; +import org.springframework.data.neo4j.annotation.IdentifiableEntity; +import org.springframework.data.neo4j.annotation.NodeEntity; + +@NodeEntity +@TypeAlias("ARTIST") +public class Artist extends IdentifiableEntity { + + @GraphProperty(propertyName = "first_name") + private String firstName; + + @GraphProperty(propertyName = "second_name") + private String secondName; + + @GraphProperty(propertyName = "last_name") + private String lastName; + + @GraphProperty() + private Date born; + + @GraphProperty(propertyName = "") + private Date died; + + public Artist() { + } + + public Artist(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public Artist(String firstName, String secondName, String lastName) { + this(firstName, lastName); + this.secondName = secondName; + } + + public Artist(String firstName, String secondName, String lastName, Date born, Date died) { + this(firstName, secondName, lastName); + this.born = born; + this.died = died; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getSecondName() { + return secondName; + } + + public void setSecondName(String secondName) { + this.secondName = secondName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public Date getBorn() { + return born; + } + + public void setBorn(Date born) { + this.born = born; + } + + public Date getDied() { + return died; + } + + public void setDied(Date died) { + this.died = died; + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/graphproperty/ArtistRepository.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/graphproperty/ArtistRepository.java new file mode 100644 index 000000000..27eabc5bc --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/graphproperty/ArtistRepository.java @@ -0,0 +1,21 @@ +/** + * 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.graphproperty; + +import org.springframework.data.neo4j.repository.CRUDRepository; + +public interface ArtistRepository extends CRUDRepository { +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/graphproperty/GraphPropertyAnnotationTests.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/graphproperty/GraphPropertyAnnotationTests.java new file mode 100644 index 000000000..75f532e77 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/annotation/graphproperty/GraphPropertyAnnotationTests.java @@ -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.annotation.graphproperty; + +import static org.junit.Assert.assertEquals; + +import java.util.Calendar; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.neo4j.graphdb.Node; +import org.springframework.beans.factory.annotation.Autowired; +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; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = {"classpath:graphproperty-annotation-test-context.xml"}) +@Transactional +public class GraphPropertyAnnotationTests { + @Autowired + Neo4jTemplate neo4jTemplate; + + @Autowired + ArtistRepository artistRepository; + + @Test + public void shouldSaveANodeWithRenamedPropertyNames() throws Exception { + Calendar born = Calendar.getInstance(); + Calendar died = Calendar.getInstance(); + + born.set(1853, Calendar.MARCH, 30, 0, 0, 0); + died.set(1890, Calendar.JULY , 29, 0, 0, 0); + + Artist vanGogh = new Artist("Vincent", "Willem", "Van Gogh", born.getTime(), died.getTime()); + + Artist vanGoghSavedNode = artistRepository.save(vanGogh); + Artist vanGoghRetrievedNode = artistRepository.findOne(vanGoghSavedNode.getId()); + + assertEquals("Vincent", vanGoghRetrievedNode.getFirstName()); + assertEquals("Willem", vanGoghRetrievedNode.getSecondName()); + assertEquals("Van Gogh", vanGoghRetrievedNode.getLastName()); + assertEquals(born.getTime(), vanGoghRetrievedNode.getBorn()); + assertEquals(died.getTime(), vanGoghRetrievedNode.getDied()); + + Node node = this.neo4jTemplate.getNode(vanGoghSavedNode.getId()); + + assertEquals("Vincent", node.getProperty("first_name")); + assertEquals("Willem", node.getProperty("second_name")); + assertEquals("Van Gogh", node.getProperty("last_name")); + assertEquals(born.getTimeInMillis(), Long.parseLong((String) node.getProperty("born"))); + assertEquals(died.getTimeInMillis(), Long.parseLong((String) node.getProperty("died"))); + } +} diff --git a/spring-data-neo4j/src/test/resources/graphproperty-annotation-test-context.xml b/spring-data-neo4j/src/test/resources/graphproperty-annotation-test-context.xml new file mode 100644 index 000000000..f99d91dda --- /dev/null +++ b/spring-data-neo4j/src/test/resources/graphproperty-annotation-test-context.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + +