DATAGRAPH-482 Allow to override property-name with @GraphProperty

Added "Property" annotation to explicitly set Node property names (something similar to @Column annotation in Hibernate).

Example:
@NodeEntity
public class Artist extends IdentifiableEntity {

	@Property(name = "first_name")
	private String firstName;

	@Property(name = "last_name")
	private String lastName;

    public Artist() {
    }

    public Artist(String firstName, String lastName) {

        this.firstName = firstName;
        this.lastName = lastName;
    }
}

Moved Property.name into GraphProperty.propertyName (according to the discussion in the pull request #188)
Added control to test that GraphProperty.propertyName is not null and not empty.
Added test to ensure GraphProperty works fine even with GraphProperty.propertyName == "".
See @GraphProperty annotation on the Artist's attributes 'born' and 'died'.
This commit is contained in:
Lorenzo Speranzoni
2014-06-07 17:18:13 +02:00
committed by Michael Hunger
parent 44731a96b7
commit f81fd637e9
6 changed files with 219 additions and 2 deletions

View File

@@ -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 "";
}

View File

@@ -190,6 +190,8 @@ class Neo4jPersistentPropertyImpl extends AnnotationBasedPersistentProperty<Neo4
private String createNeo4jPropertyName() {
final Neo4jPersistentEntity<?> 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());
}

View File

@@ -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;
}
}

View File

@@ -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<Artist> {
}

View File

@@ -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")));
}
}

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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"
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">
<context:spring-configured/>
<context:annotation-config/>
<bean class="org.springframework.data.neo4j.config.Neo4jConfiguration">
<property name="basePackage" value="org.springframework.data.neo4j.annotation.graphproperty"/>
</bean>
<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase" destroy-method="shutdown"/>
<neo4j:repositories base-package="org.springframework.data.neo4j.annotation.graphproperty"/>
</beans>