DATAGRAPH-932 - Support non Long ID's on Repositories.

This commit is contained in:
Mark Angrish
2016-12-10 12:42:20 +11:00
committed by GitHub
parent c6bc350d78
commit f56994689c
41 changed files with 291 additions and 124 deletions

View File

@@ -13,11 +13,10 @@
package org.springframework.data.neo4j.repository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
/**
* Neo4j OGM specific extension of {@link org.springframework.data.repository.Repository}.
@@ -25,8 +24,7 @@ import org.springframework.data.repository.PagingAndSortingRepository;
* @author Vince Bickers
* @author Mark ANgrish
*/
@NoRepositoryBean
public interface GraphRepository<T> extends PagingAndSortingRepository<T, Long> {
public interface GraphRepository<T> extends Neo4jRepository<T, Long> {
<S extends T> S save(S s, int depth);

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) [2011-2016] "Pivotal Software, Inc." / "Neo Technology" / "Graph Aware Ltd."
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product may include a number of subcomponents with
* separate copyright notices and license terms. Your use of the source
* code for these subcomponents is subject to the terms and
* conditions of the subcomponent's license, as noted in the LICENSE file.
*
*/
package org.springframework.data.neo4j.repository;
import java.io.Serializable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
/**
* Neo4j OGM specific extension of {@link org.springframework.data.repository.Repository}.
*
* @author Vince Bickers
* @author Mark ANgrish
*/
@NoRepositoryBean
public interface Neo4jRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
<S extends T> S save(S s, int depth);
<S extends T> Iterable<S> save(Iterable<S> entities, int depth);
T findOne(ID id, int depth);
Iterable<T> findAll();
Iterable<T> findAll(int depth);
Iterable<T> findAll(Sort sort);
Iterable<T> findAll(Sort sort, int depth);
Iterable<T> findAll(Iterable<ID> ids);
Iterable<T> findAll(Iterable<ID> ids, int depth);
Iterable<T> findAll(Iterable<ID> ids, Sort sort);
Iterable<T> findAll(Iterable<ID> ids, Sort sort, int depth);
/**
* Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
* {@link Page#getTotalPages()} returns an estimation of the total number of pages and should not be relied upon for accuracy.
*
* @param pageable
* @return a page of entities
*/
Page<T> findAll(Pageable pageable);
/**
* Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
* {@link Page#getTotalPages()} returns an estimation of the total number of pages and should not be relied upon for accuracy.
*
* @param pageable
* @param depth
* @return a page of entities
*/
Page<T> findAll(Pageable pageable, int depth);
}

View File

@@ -25,7 +25,7 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.support.Neo4jRepositoryFactoryBean;
import org.springframework.data.neo4j.repository.support.SessionBeanDefinitionRegistrarPostProcessor;
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
@@ -94,7 +94,7 @@ public class Neo4jRepositoryConfigurationExtension extends RepositoryConfigurati
*/
@Override
protected Collection<Class<?>> getIdentifyingTypes() {
return Collections.<Class<?>>singleton(GraphRepository.class);
return Collections.<Class<?>>singleton(Neo4jRepository.class);
}
/*

View File

@@ -13,6 +13,10 @@
package org.springframework.data.neo4j.repository.support;
import org.neo4j.ogm.MetaData;
import org.neo4j.ogm.entity.io.EntityAccessManager;
import org.neo4j.ogm.metadata.ClassInfo;
import org.neo4j.ogm.metadata.FieldInfo;
import org.springframework.data.repository.core.support.AbstractEntityInformation;
import java.io.Serializable;
@@ -20,20 +24,36 @@ import java.io.Serializable;
/**
* @author Mark Angrish
*/
public class GraphEntityInformation<ID extends Serializable, T> extends AbstractEntityInformation<T, Long> {
public class GraphEntityInformation<T, ID extends Serializable> extends AbstractEntityInformation<T, ID> {
public GraphEntityInformation(Class<T> type) {
private final MetaData metaData;
public GraphEntityInformation(MetaData metaData, Class<T> type) {
super(type);
this.metaData = metaData;
}
@Override
public Long getId(T entity) {
throw new UnsupportedOperationException("Not implemented yet.");
public ID getId(T entity) {
final ClassInfo classInfo = metaData.classInfo(getJavaType().getName());
final FieldInfo primaryIndex = classInfo.primaryIndexField();
if (primaryIndex != null) {
return (ID) EntityAccessManager.getPropertyReader(classInfo, primaryIndex.getName()).readProperty(entity);
}
else {
return (ID) EntityAccessManager.getPropertyReader(classInfo, classInfo.identityField().getName()).readProperty(entity);
}
}
@Override
public Class<Long> getIdType() {
return Long.class;
public Class<ID> getIdType() {
final FieldInfo primaryIndex = metaData.classInfo(getJavaType().getName()).primaryIndexField();
if (primaryIndex != null) {
return (Class<ID>) primaryIndex.convertedType();
}
return (Class<ID>) Long.class;
}
}

View File

@@ -15,6 +15,7 @@ package org.springframework.data.neo4j.repository.support;
import java.io.Serializable;
import org.neo4j.ogm.session.Neo4jSession;
import org.neo4j.ogm.session.Session;
import org.springframework.data.neo4j.repository.query.GraphQueryLookupStrategy;
import org.springframework.data.repository.core.EntityInformation;
@@ -52,7 +53,9 @@ public class Neo4jRepositoryFactory extends RepositoryFactorySupport {
@Override
public <T, ID extends Serializable> EntityInformation<T, ID> getEntityInformation(Class<T> type) {
return new GraphEntityInformation(type);
Assert.notNull(type);
Assert.notNull(session);
return new GraphEntityInformation(((Neo4jSession)session).metaData(), type);
}
@Override
@@ -62,7 +65,7 @@ public class Neo4jRepositoryFactory extends RepositoryFactorySupport {
@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata repositoryMetadata) {
return SimpleGraphRepository.class;
return SimpleNeo4jRepository.class;
}
@Override

View File

@@ -13,6 +13,8 @@
package org.springframework.data.neo4j.repository.support;
import java.io.Serializable;
import org.neo4j.ogm.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mapping.context.MappingContext;
@@ -31,7 +33,7 @@ import org.springframework.util.Assert;
* @author Luanne Misquitta
* @author Mark Angrish
*/
public class Neo4jRepositoryFactoryBean<T extends Repository<S, Long>, S> extends TransactionalRepositoryFactoryBeanSupport<T, S, Long> {
public class Neo4jRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> {
private Session session;

View File

@@ -13,18 +13,21 @@
package org.springframework.data.neo4j.repository.support;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.neo4j.ogm.MetaData;
import org.neo4j.ogm.cypher.query.Pagination;
import org.neo4j.ogm.cypher.query.SortOrder;
import org.neo4j.ogm.session.Neo4jSession;
import org.neo4j.ogm.session.Session;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
@@ -41,7 +44,7 @@ import org.springframework.util.Assert;
*/
@Repository
@Transactional(readOnly = true)
public class SimpleGraphRepository<T> implements GraphRepository<T> {
public class SimpleNeo4jRepository<T, ID extends Serializable> implements Neo4jRepository<T, ID> {
private static final int DEFAULT_QUERY_DEPTH = 1;
private static final String ID_MUST_NOT_BE_NULL = "The given id must not be null!";
@@ -50,12 +53,15 @@ public class SimpleGraphRepository<T> implements GraphRepository<T> {
private Session session;
/**
* Creates a new {@link SimpleGraphRepository} to manage objects of the given domain type.
* Creates a new {@link SimpleNeo4jRepository} to manage objects of the given domain type.
*
* @param domainClass must not be {@literal null}.
* @param session must not be {@literal null}.
*/
public SimpleGraphRepository(Class<T> domainClass, Session session) {
public SimpleNeo4jRepository(Class<T> domainClass, Session session) {
Assert.notNull(domainClass);
Assert.notNull(session);
this.clazz = domainClass;
this.session = session;
}
@@ -81,13 +87,13 @@ public class SimpleGraphRepository<T> implements GraphRepository<T> {
}
@Override
public T findOne(Long id) {
public T findOne(ID id) {
Assert.notNull(id, ID_MUST_NOT_BE_NULL);
return session.load(clazz, id);
}
@Override
public boolean exists(Long id) {
public boolean exists(ID id) {
return findOne(id) != null;
}
@@ -98,7 +104,7 @@ public class SimpleGraphRepository<T> implements GraphRepository<T> {
@Transactional
@Override
public void delete(Long id) {
public void delete(ID id) {
Object o = findOne(id);
if (o != null) {
session.delete(o);
@@ -140,7 +146,7 @@ public class SimpleGraphRepository<T> implements GraphRepository<T> {
}
@Override
public T findOne(Long id, int depth) {
public T findOne(ID id, int depth) {
return session.load(clazz, id, depth);
}
@@ -156,13 +162,13 @@ public class SimpleGraphRepository<T> implements GraphRepository<T> {
}
@Override
public Iterable<T> findAll(Iterable<Long> longs) {
public Iterable<T> findAll(Iterable<ID> longs) {
return findAll(longs, DEFAULT_QUERY_DEPTH);
}
@Override
public Iterable<T> findAll(Iterable<Long> ids, int depth) {
return session.loadAll(clazz, (Collection<Long>) ids, depth);
public Iterable<T> findAll(Iterable<ID> ids, int depth) {
return session.loadAll(clazz, (Collection<ID>) ids, depth);
}
@Override
@@ -176,13 +182,13 @@ public class SimpleGraphRepository<T> implements GraphRepository<T> {
}
@Override
public Iterable<T> findAll(Iterable<Long> ids, Sort sort) {
public Iterable<T> findAll(Iterable<ID> ids, Sort sort) {
return findAll(ids, sort, DEFAULT_QUERY_DEPTH);
}
@Override
public Iterable<T> findAll(Iterable<Long> ids, Sort sort, int depth) {
return session.loadAll(clazz, (Collection<Long>) ids, convert(sort), depth);
public Iterable<T> findAll(Iterable<ID> ids, Sort sort, int depth) {
return session.loadAll(clazz, (Collection<ID>) ids, convert(sort), depth);
}
@Override

View File

@@ -16,12 +16,12 @@ package org.springframework.data.neo4j.examples.friends.repo;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.examples.friends.domain.Friendship;
import org.springframework.data.neo4j.examples.friends.domain.Person;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
/**
* @author Luanne Misquitta
*/
public interface FriendshipRepository extends GraphRepository<Friendship> {
public interface FriendshipRepository extends Neo4jRepository<Friendship, Long> {
@Query("MATCH (person1)-[rel:IS_FRIEND]->(person2) WHERE ID(person1)={0} AND ID(person2)={1} return rel")
Friendship getFriendship(Person person1, Person person2);

View File

@@ -17,6 +17,7 @@ import org.neo4j.ogm.model.Result;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.examples.galaxy.domain.World;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
/**

View File

@@ -14,12 +14,12 @@
package org.springframework.data.neo4j.examples.jsr303.repo;
import org.springframework.data.neo4j.examples.jsr303.domain.Adult;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
/**
* @author Vince Bickers
*/
@Repository
public interface AdultRepository extends GraphRepository<Adult> {
public interface AdultRepository extends Neo4jRepository<Adult, Long> {
}

View File

@@ -14,12 +14,12 @@
package org.springframework.data.neo4j.examples.movies.repo;
import org.springframework.data.neo4j.examples.movies.domain.AbstractAnnotatedEntity;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
/**
* @author Michal Bachman
*/
@Repository
public interface AbstractAnnotatedEntityRepository extends GraphRepository<AbstractAnnotatedEntity> {
public interface AbstractAnnotatedEntityRepository extends Neo4jRepository<AbstractAnnotatedEntity, Long> {
}

View File

@@ -14,12 +14,12 @@
package org.springframework.data.neo4j.examples.movies.repo;
import org.springframework.data.neo4j.examples.movies.domain.AbstractEntity;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
/**
* @author Michal Bachman
*/
@Repository
public interface AbstractEntityRepository extends GraphRepository<AbstractEntity> {
public interface AbstractEntityRepository extends Neo4jRepository<AbstractEntity, Long> {
}

View File

@@ -14,12 +14,12 @@
package org.springframework.data.neo4j.examples.movies.repo;
import org.springframework.data.neo4j.examples.movies.domain.Actor;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
/**
* @author Michal Bachman
*/
public interface ActorRepository extends GraphRepository<Actor> {
public interface ActorRepository extends Neo4jRepository<Actor, Long> {
}

View File

@@ -21,7 +21,7 @@ import org.springframework.data.neo4j.annotation.Depth;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.examples.movies.domain.Cinema;
import org.springframework.data.neo4j.examples.movies.domain.queryresult.CinemaQueryResultInterface;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.examples.movies.domain.queryresult.CinemaQueryResult;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@@ -35,7 +35,7 @@ import java.util.List;
* @author Jasper Blues
*/
@Repository
public interface CinemaRepository extends GraphRepository<Cinema> {
public interface CinemaRepository extends Neo4jRepository<Cinema, Long> {
Collection<Cinema> findByName(String name);

View File

@@ -18,6 +18,6 @@ import org.springframework.data.neo4j.examples.movies.domain.Director;
/**
* @author Luanne Misquitta
*/
public interface DirectorRepository extends PersonRepository<Director> {
public interface DirectorRepository extends PersonRepository<Director, Long> {
}

View File

@@ -14,12 +14,12 @@
package org.springframework.data.neo4j.examples.movies.repo;
import org.springframework.data.neo4j.examples.movies.domain.Genre;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
/**
* @author Michal Bachman
*/
@Repository
public interface GenreRepository extends GraphRepository<Genre> {
public interface GenreRepository extends Neo4jRepository<Genre, Long> {
}

View File

@@ -13,15 +13,16 @@
package org.springframework.data.neo4j.examples.movies.repo;
import java.io.Serializable;
import java.util.Collection;
import org.springframework.data.neo4j.examples.movies.domain.Person;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
/**
* @author Luanne Misquitta
*/
public interface PersonRepository<T extends Person> extends GraphRepository<T> {
public interface PersonRepository<T extends Person, ID extends Serializable> extends Neo4jRepository<T, ID> {
Collection<T> findByName(String name);
}

View File

@@ -16,13 +16,13 @@ package org.springframework.data.neo4j.examples.movies.repo;
import java.util.List;
import org.springframework.data.neo4j.examples.movies.domain.Rating;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
/**
* @author Luanne Misquitta
* @author Vince Bickers
*/
public interface RatingRepository extends GraphRepository<Rating> {
public interface RatingRepository extends Neo4jRepository<Rating, Long> {
List<Rating> findByStars(int stars);

View File

@@ -14,10 +14,10 @@
package org.springframework.data.neo4j.examples.movies.repo;
import org.springframework.data.neo4j.examples.movies.domain.TempMovie;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
/**
* @author Michal Bachman
*/
public interface TempMovieRepository extends GraphRepository<TempMovie> {
public interface TempMovieRepository extends Neo4jRepository<TempMovie, Long> {
}

View File

@@ -32,7 +32,7 @@ import java.util.Map;
* @author Luanne Misquitta
*/
@Repository
public interface UserRepository extends PersonRepository<User> {
public interface UserRepository extends PersonRepository<User, Long> {
Collection<User> findByMiddleName(String middleName);

View File

@@ -13,19 +13,18 @@
package org.springframework.data.neo4j.examples.restaurants.repo;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.neo4j.examples.restaurants.domain.Restaurant;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
/**
* @author Jasper Blues
*/
public interface RestaurantRepository extends GraphRepository<Restaurant> {
public interface RestaurantRepository extends Neo4jRepository<Restaurant, Long> {
List<Restaurant> findByNameAndLocationNear(String name, Distance distance, Point point);

View File

@@ -12,8 +12,10 @@
*/
package org.springframework.data.neo4j.extensions;
import java.io.Serializable;
import org.neo4j.ogm.session.Session;
import org.springframework.data.neo4j.repository.support.SimpleGraphRepository;
import org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository;
import org.springframework.stereotype.Repository;
/**
@@ -24,7 +26,7 @@ import org.springframework.stereotype.Repository;
* @author Mark Angrish
*/
@Repository
public class CustomGraphRepositoryImpl<T> extends SimpleGraphRepository<T> implements CustomGraphRepository<T> {
public class CustomGraphRepositoryImpl<T, ID extends Serializable> extends SimpleNeo4jRepository<T, ID> implements CustomNeo4jRepository<T, ID> {
public CustomGraphRepositoryImpl(Class<T> clazz, Session session) {
super(clazz, session);

View File

@@ -12,7 +12,9 @@
*/
package org.springframework.data.neo4j.extensions;
import org.springframework.data.neo4j.repository.GraphRepository;
import java.io.Serializable;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.NoRepositoryBean;
/**
@@ -22,7 +24,7 @@ import org.springframework.data.repository.NoRepositoryBean;
* @author: Vince Bickers
*/
@NoRepositoryBean
public interface CustomGraphRepository<T> extends GraphRepository<T> {
public interface CustomNeo4jRepository<T, ID extends Serializable> extends Neo4jRepository<T, ID> {
boolean sharedCustomMethod();

View File

@@ -19,5 +19,5 @@ import org.springframework.stereotype.Repository;
* @author: Vince Bickers
*/
@Repository
public interface UserRepository extends CustomGraphRepository<User> {
public interface UserRepository extends CustomNeo4jRepository<User, Long> {
}

View File

@@ -14,14 +14,14 @@
package org.springframework.data.neo4j.integration.conversion;
import org.springframework.data.neo4j.integration.conversion.domain.JavaElement;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
/**
* @author Adam George
*/
@Repository
public interface JavaElementRepository extends GraphRepository<JavaElement> {
public interface JavaElementRepository extends Neo4jRepository<JavaElement, Long> {
// no additional repository methods

View File

@@ -14,14 +14,14 @@
package org.springframework.data.neo4j.integration.conversion;
import org.springframework.data.neo4j.integration.conversion.domain.PensionPlan;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
/**
* @author Adam George
*/
@Repository
public interface PensionRepository extends GraphRepository<PensionPlan> {
public interface PensionRepository extends Neo4jRepository<PensionPlan, Long> {
// no additional repository methods

View File

@@ -14,14 +14,14 @@
package org.springframework.data.neo4j.integration.conversion;
import org.springframework.data.neo4j.integration.conversion.domain.SiteMember;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
/**
* @author Adam George
*/
@Repository
public interface SiteMemberRepository extends GraphRepository<SiteMember> {
public interface SiteMemberRepository extends Neo4jRepository<SiteMember, Long> {
// no additional repository methods

View File

@@ -17,6 +17,7 @@ import java.util.List;
import org.springframework.data.neo4j.repositories.domain.User;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
/**

View File

@@ -15,6 +15,8 @@ package org.springframework.data.neo4j.repositories.support;
import static org.junit.Assert.*;
import java.io.Serializable;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -23,9 +25,9 @@ import org.mockito.runners.MockitoJUnitRunner;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.testutil.MultiDriverTestClass;
import org.springframework.aop.framework.Advised;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.support.Neo4jRepositoryFactory;
import org.springframework.data.neo4j.repository.support.SimpleGraphRepository;
import org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository;
import org.springframework.transaction.annotation.Transactional;
/**
@@ -72,21 +74,21 @@ public class GraphRepositoryFactoryIT extends MultiDriverTestClass {
@Test
public void usesConfiguredRepositoryBaseClass() {
factory.setRepositoryBaseClass(CustomGraphRepository.class);
factory.setRepositoryBaseClass(CustomNeo4jRepository.class);
ObjectRepository repository = factory.getRepository(ObjectRepository.class);
assertEquals(CustomGraphRepository.class, ((Advised) repository).getTargetClass());
assertEquals(CustomNeo4jRepository.class, ((Advised) repository).getTargetClass());
}
private interface ObjectRepository extends GraphRepository<Object> {
private interface ObjectRepository extends Neo4jRepository<Object, Long> {
@Override
@Transactional
Object findOne(Long id);
}
static class CustomGraphRepository<T> extends SimpleGraphRepository<T> {
static class CustomNeo4jRepository<T, ID extends Serializable> extends SimpleNeo4jRepository<T, ID> {
public CustomGraphRepository(Class<T> clazz, Session session) {
public CustomNeo4jRepository(Class<T> clazz, Session session) {
super(clazz, session);
}
}

View File

@@ -46,7 +46,7 @@ public class Neo4jRepositoryIT extends MultiDriverTestClass {
@Autowired Session session;
GraphRepository<SampleEntity> repository;
Neo4jRepository<SampleEntity, Long> repository;
@Before
public void setUp() {
@@ -68,7 +68,7 @@ public class Neo4jRepositoryIT extends MultiDriverTestClass {
}
private interface SampleEntityRepository extends GraphRepository<SampleEntity> {
private interface SampleEntityRepository extends Neo4jRepository<SampleEntity, Long> {
}

View File

@@ -17,6 +17,7 @@ import java.util.List;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.domain.sample.User;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.transaction.annotation.Transactional;

View File

@@ -18,6 +18,7 @@ import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
@@ -32,7 +33,7 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.domain.Persistable;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
@@ -42,7 +43,7 @@ import org.springframework.data.repository.core.support.RepositoryFactorySupport
@RunWith(MockitoJUnitRunner.class)
public class Neo4jRepositoryFactoryBeanTests {
Neo4jRepositoryFactoryBean<SimpleSampleRepository, User> factoryBean;
Neo4jRepositoryFactoryBean<SimpleSampleRepository, User, Long> factoryBean;
@Mock
Session session;
@@ -114,8 +115,8 @@ public class Neo4jRepositoryFactoryBeanTests {
factoryBean.afterPropertiesSet();
}
private class DummyNeo4jRepositoryFactoryBean<T extends GraphRepository<S>, S> extends
Neo4jRepositoryFactoryBean<T, S> {
private class DummyNeo4jRepositoryFactoryBean<T extends Neo4jRepository<S, ID>, S, ID extends Serializable> extends
Neo4jRepositoryFactoryBean<T, S, ID> {
/*
* (non-Javadoc)
@@ -131,7 +132,7 @@ public class Neo4jRepositoryFactoryBeanTests {
}
}
private interface SimpleSampleRepository extends GraphRepository<User> {
private interface SimpleSampleRepository extends Neo4jRepository<User, Long> {
}

View File

@@ -20,6 +20,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -62,15 +63,23 @@ public class WebIntegrationIT extends MultiDriverTestClass {
private MockMvc mockMvc;
private User adam;
private User daniela;
private User michal;
private User vince;
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
User adam = new User("Adam");
User daniela = new User("Daniela");
User michal = new User("Michal");
User vince = new User("Vince");
adam = new User("Adam");
daniela = new User("Daniela");
michal = new User("Michal");
vince = new User("Vince");
adam.befriend(daniela);
daniela.befriend(michal);
@@ -88,39 +97,37 @@ public class WebIntegrationIT extends MultiDriverTestClass {
userRepository.save(adam);
}
@Test
public void shouldNotShareSessionBetweenRequestsWithDifferentSession() throws Exception {
mockMvc.perform(get("/user/{name}/friends", "Adam"))
mockMvc.perform(get("/user/{uuid}/friends", adam.getUuid()))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().string("Daniela"));
mockMvc.perform(get("/user/{name}/friends", "Vince"))
mockMvc.perform(get("/user/{uuid}/friends", vince.getUuid()))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().string("Michal"));
Assert.assertFalse(((DelegatingTransactionManager) transactionManager).getTransactionDefinition().isReadOnly());
}
@Test
public void shouldShareSessionBetweenRequestsDuringSameSession() throws Exception {
MockHttpSession session = new MockHttpSession();
mockMvc.perform(get("/user/{name}/immediateFriends", "Adam").session(session))
mockMvc.perform(get("/user/{uuid}/immediateFriends", adam.getUuid()).session(session))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().string("Daniela"));
mockMvc.perform(get("/user/{name}/immediateFriends", "Daniela").session(session))
mockMvc.perform(get("/user/{uuid}/immediateFriends", daniela.getUuid()).session(session))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().string("Adam Michal"));
mockMvc.perform(get("/user/{name}/immediateFriends", "Michal").session(session))
mockMvc.perform(get("/user/{uuid}/immediateFriends", michal.getUuid()).session(session))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().string("Daniela Vince"));
mockMvc.perform(get("/user/{name}/immediateFriends", "Vince").session(session))
mockMvc.perform(get("/user/{uuid}/immediateFriends", vince.getUuid()).session(session))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().string("Michal"));
}
@@ -134,7 +141,7 @@ public class WebIntegrationIT extends MultiDriverTestClass {
public void run() {
if (j % 2 == 0) {
try {
mockMvc.perform(get("/user/{name}/friends", "Adam"))
mockMvc.perform(get("/user/{uuid}/friends", adam.getUuid()))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().string("Daniela"));
} catch (Exception e) {
@@ -143,7 +150,7 @@ public class WebIntegrationIT extends MultiDriverTestClass {
} else {
try {
mockMvc.perform(get("/user/{name}/friends", "Vince"))
mockMvc.perform(get("/user/{uuid}/friends", vince.getUuid()))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().string("Michal"));
} catch (Exception e) {

View File

@@ -26,6 +26,7 @@ import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
/**
* @author Michal Bachman
@@ -37,11 +38,11 @@ public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/user/{name}/friends")
@RequestMapping(value = "/user/{uuid}/friends")
@ResponseBody
@Transactional
public String listFriends(@PathVariable String name, HttpSession session) {
User user = userService.getUserByName(name);
public String listFriends(@PathVariable UUID uuid, HttpSession session) {
User user = userService.getUserByUuid(uuid);
if (user == null) {
return "No such user!";
@@ -55,11 +56,11 @@ public class UserController {
return result.toString().trim();
}
@RequestMapping(value = "/user/{name}/immediateFriends")
@RequestMapping(value = "/user/{uuid}/immediateFriends")
@ResponseBody
@Transactional
public String listImmediateFriends(@PathVariable String name, HttpSession session) {
User user = userService.getUserByName(name);
public String listImmediateFriends(@PathVariable UUID uuid, HttpSession session) {
User user = userService.getUserByUuid(uuid);
if (user == null) {
return "No such user!";

View File

@@ -13,28 +13,42 @@
package org.springframework.data.neo4j.web.domain;
import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.Index;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;
import org.neo4j.ogm.annotation.typeconversion.Convert;
import org.neo4j.ogm.typeconversion.UuidStringConverter;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
* @author Michal Bachman
* @author Mark Angrish
*/
@NodeEntity
public class Cinema {
@GraphId
private Long id;
@Convert(UuidStringConverter.class)
@Index(unique = true, primary = true)
private UUID uuid;
private String name;
@Relationship(direction = Relationship.INCOMING)
private Set<User> visited = new HashSet<>();
private Set<User> visited;
public Cinema() {
}
public Cinema(String name) {
this.visited = new HashSet<>();
this.uuid = UUID.randomUUID();
this.name = name;
}

View File

@@ -13,18 +13,35 @@
package org.springframework.data.neo4j.web.domain;
import java.util.UUID;
import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.Index;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.typeconversion.Convert;
import org.neo4j.ogm.typeconversion.UuidStringConverter;
/**
* @author Michal Bachman
* @author Mark Angrish
*/
@NodeEntity
public class Genre {
@GraphId
private Long id;
@Convert(UuidStringConverter.class)
@Index(unique = true, primary = true)
private UUID uuid;
private String name;
public Genre() {
}
public Genre(String name) {
this.uuid = UUID.randomUUID();
this.name = name;
}

View File

@@ -13,28 +13,46 @@
package org.springframework.data.neo4j.web.domain;
import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.Index;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;
import org.neo4j.ogm.annotation.typeconversion.Convert;
import org.neo4j.ogm.typeconversion.UuidStringConverter;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
* @author Michal Bachman
* @author Mark Angrish
*/
@NodeEntity
public class User {
@GraphId
private Long id;
@Convert(UuidStringConverter.class)
@Index(unique = true, primary = true)
private UUID uuid;
private String name;
private Collection<Genre> interested = new HashSet<>();
private Collection<Genre> interested;
@Relationship(type = "FRIEND_OF", direction = Relationship.UNDIRECTED)
private Set<User> friends = new HashSet<>();
private Set<User> friends;
public User() {
}
public User(String name) {
this.interested = new HashSet<>();
this.friends = new HashSet<>();
this.uuid = UUID.randomUUID();
this.name = name;
}
@@ -66,4 +84,8 @@ public class User {
public Collection<User> getFriends() {
return friends;
}
public UUID getUuid() {
return uuid;
}
}

View File

@@ -13,7 +13,9 @@
package org.springframework.data.neo4j.web.repo;
import org.springframework.data.neo4j.repository.GraphRepository;
import java.util.UUID;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.web.domain.Genre;
import org.springframework.stereotype.Repository;
@@ -22,6 +24,6 @@ import org.springframework.stereotype.Repository;
* @author Mark Angrish
*/
@Repository
public interface GenreRepository extends GraphRepository<Genre> {
public interface GenreRepository extends Neo4jRepository<Genre, UUID> {
}

View File

@@ -13,7 +13,10 @@
package org.springframework.data.neo4j.web.repo;
import java.util.UUID;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.web.domain.User;
import org.springframework.stereotype.Repository;
@@ -22,6 +25,6 @@ import org.springframework.stereotype.Repository;
* @author Mark Angrish
*/
@Repository
public interface UserRepository extends GraphRepository<User> {
public interface UserRepository extends Neo4jRepository<User, UUID> {
}

View File

@@ -16,13 +16,14 @@ package org.springframework.data.neo4j.web.service;
import org.springframework.data.neo4j.web.domain.User;
import java.util.Collection;
import java.util.UUID;
/**
* @author Michal Bachman
*/
public interface UserService {
User getUserByName(String name);
User getUserByUuid(UUID uuid);
Collection<User> getNetwork(User user);
}

View File

@@ -13,15 +13,11 @@
package org.springframework.data.neo4j.web.service;
import java.util.Collection;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
import java.util.*;
import org.neo4j.ogm.cypher.Filter;
import org.neo4j.ogm.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.web.domain.User;
import org.springframework.data.neo4j.web.repo.UserRepository;
import org.springframework.stereotype.Service;
/**
@@ -32,15 +28,11 @@ import org.springframework.stereotype.Service;
public class UserServiceImpl implements UserService {
@Autowired
private Session session;
private UserRepository userRepository;
@Override
public User getUserByName(String name) {
Iterable<User> users = findByProperty("name", name);
if (!users.iterator().hasNext()) {
return null;
}
return users.iterator().next();
public User getUserByUuid(UUID uuid) {
return userRepository.findOne(uuid);
}
@Override
@@ -64,8 +56,4 @@ public class UserServiceImpl implements UserService {
}
}
}
protected Iterable<User> findByProperty(String propertyName, Object propertyValue) {
return session.loadAll(User.class, new Filter(propertyName, propertyValue));
}
}