In grails-neo4j plug-in,how can i define relationship among nodes and properties of relationship.
I can define my nodes as domain classes but what if i want to connect nodes i.e. i want to map relationship of nodes in some form.
I found spring-neo4j framework which works well for this case and i can map relationship to java class but didn't find any grails compatibility layer for this.
the plugin doesn't map the domain classes directly to nodes or relations in neo4j. It uses its own structure, like:
root -> domainClass.name -> relation -> domain class instance
I'd recommend to define your domain classes as nodes, and the plugin should handle them properly. Another way: abandon the plugin >)
Mapping domain classes as relationships is not yet supported in the Neo4j Grails plugin. I have this on my list of stuff to add.
You're right, Spring Data Neo4j already is capable of doing this. Be aware that Spring Data Neo4j and the Grails Neo4j plugin have nothing in common (aside that they use Neo4j to persist). The persistence layer is a completely separate code base.
It is now much later than when this question was originally asked - 4 years later. The plugin now supports Neo4j relationships being created as Grails domain classes and the relationship can have attributes. However, constraints on these attributes do not work yet. Below is the full code for a working, one-way relationship.
package neo4j.authentication.demo
import grails.neo4j.Relationship
import groovy.transform.CompileStatic
#CompileStatic
class BelongsTo implements Relationship<Car, Owner> {
String sinceWhen
String toString() {
sinceWhen
}
}
Related
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.
Is there a way to add more belongs-to relationships to an imported GORM domain class? Specifically, I'm attempting to use table-per-class to extend a shared subclass, but if I do this in two (or more) locations, and the locations do not have knowledge of each-other then things like:
set.addToParents(parentSet)
Start leading to:
org.hibernate.WrongClassException: Object [id=3482] was not of the specified subclass [com.acumenllc.domaincore.DbSet] : Discriminator: com.acumenllc.tickets.domain.TicketSet
happening everywhere.
A little more background, I'm working on a closure table to keep track of related objects. The base class recognizes the parent-child bi-directional relationship, as well as the ancestor-descendant extension of it. Different applications then extend this class with belongsTo relationships on objects to be represented as nodes in the resultant graph. We specifically want to be able to more-or-less ignore some of these other classes in other applications that happen to share the same database.
Ideally, it would be possible to import our base domain class into a new application and, rather than extending into a subclass, re-define the set of relationships that the base class recognizes in the scope of the application.
The only practical way I can see of doing this is with .hbm.xml files. The GORM approach of including hasMany/belongsTo in the code and JPA's approach using annotations are both fairly inflexible to support this sort of mapping. But if you separate the configuration from the code, you can define the relationships for different applications however you like. Creating a hibernate.cfg.xml file and the hbm.xml files is described here in the docs.
I have 3 table like v_ims_circuits , v_ims_productcodes and v_ims_domainmain and i want to fetch data from this table using grails domain.
Internally query should be build like below query using grails domain.
select cir.circuitname, cir.status, cir.oldname, cir.speed, null "Count of Subs",cir.productcode, cir.ordernr,
cir.createuser, cir.createdate, cir.acquisitiondate,dom.domainname
from v_ims_circuits cir, v_ims_productcodes pc, v_ims_domainmain dom
where cir.productcode = pc.product
and pc.domainid = dom.id
and cir.circuitname = ?
Can any one help me on this.
GORM (and Hibernate) require a different mindset than SQL. The first step is to create domain classes for your three tables; circuits, productcodes, and domainmain. Chapter 7 of the Grails reference guide Object Relational Mapping (GORM) is a good place to start.
Once your domain objects are built section 7.4 Querying with GORM describes several ways you can fetch your data. I also find the Domain Classes Quick Reference to be helpful.
The spring data neo4j can put a "Person" into neo4j with two labels ("Person", "_Person").
How can I change it to com.xxxx.xxxx.Person?
Are there two classes named Person in different packages?
Slightly buried towards the end of the documentation you will find Section 20.15 Entity Type Representation.
As some type information is also stored in labels, node/relationship-properties and/or indexes it might amount to a substantial amount of data in the graph. It is possible to use an #TypeAlias("name") annotation on nodes and relationships to have a short constant name for each type which is (unlike the default approach) renaming-refactoring-safe. From 3.0 onwards, Spring Data Neo4j uses the simple class name as the default whilst previous versions used to default to the fully qualified name. If you would like to use the fully qualified class name by default, you can
Register a Neo4jMappingContext bean configured with an instance of org.springframework.data.neo4j.support.mapping.ClassNameAlias
Override the spring "entityAlias" bean with an instance of org.springframework.data.neo4j.support.mapping.ClassNameAlias. For example, using XML config this would look as follows:
<bean id="entityAlias" class="org.springframework.data.neo4j.support.mapping.ClassNameAlias" />
As to why you want two different classes named Person in your domain, that's another question...