CrudRepository<T>.findOne(Long id) and node type

514 views
Skip to first unread message

Tero Paananen

unread,
Dec 20, 2011, 6:00:27 PM12/20/11
to Neo4j
I'm having an issue with the findOne(Long id) method in SDN
CrudRepository
I'm having a bit of difficulty figuring out how to best deal with.

I've got multiple node types in my application, let's say A, B and C.

I've got repositories defined for each extending GraphRepository.

Let's say I have the following nodes in my graph:

nodeId 1, type A
nodeId 2, type B
nodeId 3, type C

If ARepository extends GraphRepository<A>, and I do a findOne(3)
using that repository, I get an object of type A back, even though it
really is of type C.

While my application logic generally speaking would never allow
that to happen, it's possible that due to invalid user input, such a
call could happen.

I need to basically treat this situation as if the node with that id
didn't exist.

How would I go about doing this? I can't seem to find a way to
figure out the "real type" of the node entity I got back.

-TPP

Michael Hunger

unread,
Dec 25, 2011, 5:27:35 AM12/25/11
to ne...@googlegroups.com
That is a good question, we discussed it a while ago and concluded as the node with that ID is really it the datastore it would be wrong to say that it doesn't exist.

you can do neo4jTemplate.getInfrastructure().getTypeRepresentationStrategies().getJavaType(node);

I could imagine exposing this through the template, or the crud-repository (also a method like "isJavaType(node)" could be possible).

Please raise a JIRA issue for that with spring.neo4j.org/issues

Thanks a lot

Michael

Tero Paananen

unread,
Sep 19, 2012, 6:15:39 PM9/19/12
to ne...@googlegroups.com
The way I solved this was with a facade type interface fronting the
repository queries:

public NodeA findNodeA(Long id) throws ObjectNotFoundException {
NodeA node = nodeRepository.findOne(id);
checkNodeType(node, NodeA.class, nodeRepository);
return node;
}

protected void checkNodeType(NodeBacked node, Class<?> type,
CRUDRepository<? extends NodeBacked> repository) throws
ObjectNotFoundException {
if (node == null) throw new ObjectNotFoundException();
if (!repository.getStoredJavaType(node).equals(type)) throw new
ObjectNotFoundException();
}

Application code never hits the repository methods directly, and the
only classes hitting the repository queries are the facade
implementing classes.

The facade implementations are all Spring beans instantiated
automatically by Spring Framework's component scanning feature.

-TPP

Steven Kalemkiewicz

unread,
Sep 20, 2012, 12:47:07 AM9/20/12
to ne...@googlegroups.com
Thanks Tero. Your approach is finally what I used.

Michael Hunger

unread,
Sep 20, 2012, 3:15:04 AM9/20/12
to ne...@googlegroups.com
Steven,

can you raise two JIRA issues for the 2 things.

We did enforcement early on but with failure on non-matching types.

This seems to be a bigger area, so perhaps you can discuss some of the approaches and pro/cons in the issue and link to this thread?

Thanks so much

Michael

Am 19.09.2012 um 23:51 schrieb Steven Kalemkiewicz:

Hello all:

Two questions here:

I'm running into a similar issue as Tero Paananen did back in December (I think his post describes it well so I'm going to include it below). Also relevant is the thread discussed here: http://forum.springsource.org/archive/index.php/t-123606.html

If I create extend a GraphRepository using GraphRepository<Individual> and use one of its built-in method like findOne(Long id), isn't it reasonable to expect to get back an object of type Individual that wraps a node that was originally of type Individual (i.e. __type__ == 'Individual')?

I understand that there may be a circumstance where one would want to get a node by ID and wrap it with a different type but it seems as if there should be something out-of-the-box that permits type enforcement as well.

If I don't care for the current implementation, would the recommended action be to extend AbstractGraphRepository and override the specific methods?


To work around this, I created a @Query in my repository that would take type into account. My query looks like this:

start n=node({id})
where n.__type__ = 'x.y.z.Individual'
return n


What struck me as strange is that if I specified an ID that didn't exist, the query wouldn't simply return null, it threw a DataRetrievalFailureException. This seems inconsistent with the behavior of findOne(Long id) which would quietly return null.

Is there a reason behind this? Shouldn't it simply return null as well?

Thanks,

-Steve
--
 
 

Michael Hunger

unread,
Sep 21, 2012, 2:13:28 AM9/21/12
to ne...@googlegroups.com
Ok, thanks.

Michael

Am 21.09.2012 um 05:35 schrieb Steven Kalemkiewicz:

Michael:

I'll think about it and its effects a little more before I write something up.

I'll post the query exception issue tomorrow; also I posted something about repositories for abstract types a little while ago...

Thank you.

-Steve

--
 
 


--
 
 

Reply all
Reply to author
Forward
Message has been deleted
Message has been deleted
0 new messages