you don't need to actually implement GraphRepository but extend it. the principals of Spring-Data
is that all the boiler-plate CRUD code is taken care of (by proxying at startup time) so all you have to do is create an interface for your specific entity extending GraphRepository and then add only specific methods that you require.
for example; if i have an entity CustomerNode
, to create standard CRUD methods, i can create a new interface CustomerNodeRepository extends GraphRepository<CustomerNode,Long>
. all the methods from GraphRepository
(e.g. save, findAll, findOne, delete, deleteAll, etc.) are now accessible from CustomerNodeRepository
and implemented by Spring-Data-Neo4J without having to write a single line of implementation code.
the pattern now allows you to work on your specific repository code (e.g. findByNameAndDateOfBirth) rather than the simple CRUD stuff.
Spring-Data package is very useful for repository interaction. it can reduce huge amounts of code (have seen 80%+ reduction in code lines) and would highly recommend using it
edit: implementing custom execution
if you want to add your own custom behavior to a Repository method, you create the concept of merging interfaces and custom implementation. for example, lets say i want to create a method called findCustomerNodeBySomeStrangeCriteria
and to do this, i actually want to link off to a relational database to perform the function.
first we define a separate, standalone interface that only includes our 'extra' method.
public interface CustomCustomerNodeRepository {
List<CustomerNode> findCustomerNodeBySomeStrangeCriteria(Object strangeCriteria);
}
next we update our normal interface to extend not only GraphRepository, but our new custom one too
public interface CustomerNodeRepository extends GraphRepository<CustomerNode,Long>, CustomCustomerNodeRepository {
}
the last piece, is to actually implement our findCustomerNodeBySomeStrangeCriteria
method
public class CustomerNodeRepositoryImpl implements CustomCustomerNodeRepository {
public List<CustomerNode> findCustomerNodeBySomeStrangeCriteria(Object criteria) {
//implementation code
}
}
so, there's a couple of points to note;
- we create a separate interface to define any custom methods that have custom implementations (as distinct from Spring-Data compatible "findBy..." methods)
- our CustomerNodeRepository interface (our 'main' interface) extends both the GraphRepository and our 'custom' one
- we implement only the 'custom' method in a class that implements only the custom interface
- the 'custom' implementation class must (by default) be called our 'main' interface
Impl
to be picked up by Spring Data (so in this case CustomNodeRepositoryImpl
)
under the covers, Spring Data delivers a proxy implementation of CustomerNodeRepository
as a merge of the auto-built GraphRepository
and our class implementing CustomCustomerNodeRepository
. the reason for the name of the class is to allow Spring Data to pick it up easily/successfully (this can be overwritten so it doesn't look for *Impl)