Can we have custom iterators in Spring Data Neo4j for Node Entities?
I have an existing code which has CustomHashCollection as an iterable. I want to convert the project to use Neo4j. Can I use the custom iterator as it is a private member in most of the NodeEntity classes.
Thanks in advance.
What is different with your Iterable?
As far as I remember there is no custom extensibility for iterable types, so far the JDK collection were good enough.
Related
I am trying to implement a solution using SDN which was aimed to create a dynamic cypher where my label vary w.r.t input type(n types) irrespective of properties of Node.
Hoping a solultion similiar to what mentioned on this link would help me.
Is it possible to dynamically construct a neo4j cypher query using the GraphRepository pattern
I found the below information in Release notes.
Deprecation of Neo4jTemplate
It is highly recommended for users starting new SDN projects to use the OGM Session directly. Neo4jTemplate has been kept to give upgrading users a better experience.
The Neo4jTemplate has been slimmed-down significantly for SDN 4. It contains the exact same methods as Session. In fact Neo4jTemplate is just a very thin wrapper with an ability to support SDN Exception Translation. Many of the operations are no longer needed or can be expressed with a straightforward Cypher query.
If you do use Neo4jTemplate, then you should code against its Neo4jOperations interface instead of the template class.
The following table shows the Neo4jTemplate functions that have been retained for version 4 of Spring Data Neo4j. In some cases the method names have changed but the same functionality is offered under the new version.
To achieve the old template.fetch(entity) equivalent behaviour, you should call one of the load methods specifying the fetch depth as a parameter.
It’s also worth noting that exec(GraphCallback) and the create…() methods have been made obsolete by Cypher. Instead, you should now issue a Cypher query to the new execute method to create the nodes or relationships that you need.
Dynamic labels, properties and relationship types are not supported as of this version, server extensions should be considered instead.
from this link https://docs.spring.io/spring-data/neo4j/docs/5.0.0.RELEASE/reference/html/
Could anyone help me in achieving the equivalent solution in
SDN 5.X
Thanks!!!
I took the advice to use the session directly in place of the Neo4jOperations mechanism.
#Autowired
SessionFactory sessionFactory
public void doCustomQuery() {
Session session = sessionFactory.openSession();
Iterable<NodeEntity> nodes = session.query(NodeEntity.class, "MATCH (n) RETURN n", params);
}
guys
I am try to wrapper Spring Data Neo4j (SDN version:3.2.3) for developers who are not familiar with SDN. As I do not know how many relationships and relationship types will be owned by domain objects which are created by developers in the future, I need the collection type like Map> annotated by #RelatedTo and #RelatedToVia to support developers to add relationship and relationship type in runtime, which can make SDN transparent to developers.
However, I find that current SDN only support the collection type Set which can be annotated by #RelatedTo and #RelatedToVia to indicate relationship owned by domain object. In this case, developers have to hard code each relationship using collection type Set annotated by #RelatedTo and #RelatedToVia in domain object, which exposes SDN to developers.
Why SDN does not support collection type Map to represent relationship, and how to make SDN support this collection type?
I think it's best to use a repository with an annotated query method to return this kind of data.
I think this is quite specific, in theory it could be supported with a custom FieldAccessor which could be implemented similar to the other Relationship-FieldAccessors, but using a separate annotation, or even better a dedicated result type (e.g. AllRelationships)
Not sure if you want this, what you gain over the plain Neo4j APIs, i.e. node.getRelationships()
I have created a POC with SDN 3.3.1 in which I have deployed a plugin inside the Neo4j server. The plugin contains domain objects, repositories and controllers.
From my application, I'm making rest calls to the controllers to execute repositories methods and return the response.
The issue is that in my queries, I'm returning multiple nodes and relationships. So, to map the response, I created wrapper classes using #QueryResult, #ResultColumn containing references to domain objects for each query. This is because each query has a different result set.
Since, my application has around 150 such queries I will have to create similar number of intermediate wrapper classes.
This is quite tedious and number of wrapper classes will only increase in future as more and more queries are added.
Is there any smarter way to do this?
I tried to have all of my domain objects as references in a single wrapper class. So that I can use it for any of my queries. But it gives exception if any of the fields in the wrapper class is not present in the query result.
Another issue is that, some of my queries are written to return all different nodes connected to a particular node, e.g,
Match (a)-[rel]->(b)-[tempRel]->(tempNodes) Return b,tempRel,tempNodes
I'm not sure how to map this result set to a wrapper class.
Is there any way to achieve it without refactoring the queries to match indvidual paths?
Regards,
Rahul
Good idea to have it ignore unknown classes and fields in both directions perhaps as an additional annotation on the class can you raise a Spring JIRA issue?
something like this e.g.
#QueryResult(requireFields=false, require=false)
class MyResult {
String name;
int age;
}
but you still have them focused on one area or use-case and not 1 for all 150 use-cases but perhaps 15-30 different ones.
As a complete novice programmer I am trying to populate my neo4j DB with data from heterogeneous sources. For this I am trying to use the Neo4jClient C# API. The heterogeneity of my data comes from a custom, continuously evolving DSL/DSML/metamodel that defines the possible types of elements, i.e. models, thus creating classes for each type would not be ideal.
As I understand, my options are the following:
Have a predefined class for each type of element: This way I can easily serialize my objects that is if all properties are primitive types or arrays/lists.
Have a base class (with a Dictionary to hold properties) that I use as an interface between the models that I'm trying to serialize and neo4j. I've seen an example for this at Can Neo4j store a dictionary in a node?, but I don't understand how to use the converter (defined in the answer) to add a node. Also, I don't see how an int-based dictionary would allow me to store Key-Value pairs where the keys (that are strings) would translate to Property names in neo4j.
Generate a custom query dynamically, as seen at https://github.com/Readify/Neo4jClient/wiki/cypher#manual-queries-highly-discouraged. This is not recommended and possibly is not performant.
Ultimately, what I would like to achieve is to avoid the need to define a separate class for every type of element that I have, but still be able to add properties that are defined by types in my metamodel.
I would also be interested to somehow influencing the serializer to ignore non-compatible properties (similarly to XmlIgnore), so that I would not need to create a separate class for each class that has more than just primitive types.
Thanks,
J
There are 2 problems you're trying to solve - the first is how to program the C# part of this, the second is how to store the solution to the first problem.
At some point you'll need to access this data in your C# code - unless you're going fully dynamic you'll need to have some sort of class structure.
Taking your 3 options:
Please have a look at this question: neo4jclient heterogenous data return which I think covers this scenario.
In that answer, the converter does the work for you, you would create, delete etc as before, the converter just handles the IDictionary instance in that case. The IDictionary<int, string> in the answer is an example, you can use whatever you want, you could use IDictionary<string, string> if you wanted, in fact - in that example, all you'd need to do would be changing the IntString property to be an IDictionary<string,string> and it should just work.
Even if you went down the route of using custom queries (which you really shouldn't need to) you will still need to bring back objects as classes. Nothing changes, it just makes your life a lot harder.
In terms of XmlIgnore - have you tried JsonIgnore?
Alternatively - look at the custom converter and get the non-compatible properties into your DB.
I just wanted to know the meaning and the situations where DataModel is used in JSF. I was not able to get a clear picture of it in the Java EE doc here.
I find the linked javadoc quite clear:
DataModel is an abstraction around arbitrary data binding technologies
that can be used to adapt a variety of data sources for use by
JavaServer Faces components that support per-row processing for their
child components.
DataModel is used as a wrapper class to the data you want to display in a component supporting a per-row processing. This is typically the case of h:dataTable.
There is for instance ResultSetDataModel which is a subclass of DataModel and helps to display a SQL ResultSet in a h:dataTable. Without the ResultSetDataModel abstraction, you would have to transform the underlying ResultSet into a normal Collection. Thanks to ResultSetDataModel you don't have to do any transformation and you can plug the ResultSet directly in the JSF component.