Dynamic Spring Data Classes for Neo4J based on an Ontology - neo4j

I have to create a web service that needs to interact with a Neo4J database using the Spring framework with Spring-Data-Neo4J. This requires a static data domain model, e.g. defined labels, relations, properties.
The Problem is, that my data is based on an Ontology (via the neosemantics plugin) which could be modified in the future. It would be great if the application could automatically adopt to it. This way, the data model could be extended by editing the ontology only and no additional programming knowledge would be necessary.
Does this mean I have to generate the Spring data classes dynamically (based on the Ontology) or is there a better way to achieve this with Spring-Data-Neo4J (or should I use a different framework)?

Sure, you could come up with a way to generate a set of classes from an ontology. But that is probably going to present more problems than it solves.
An automatically-generated set of classes may not correspond to an appropriate data model for your use cases. The determination of the appropriate data model still requires a human.
Also, the new classes may be incompatible with the existing client code. And you may have to migrate the existing DB over to the new data model. Fixing all that requires humans as well.

I ended up using the Java neo4j driver instead of Spring-Data-Neo4jand a generic node class implementation only having the fields id, list of labels and a map of properties. The set labels and properties can be checked against the ontology prior to creating the nodes in the database. This way I can enforce a specific set of node labels and properties by only modifying the ontology and without having to generate the specific Spring-Data-Neo4j data classes.

Related

How to implement DDD and Repository Design Pattern for a Remote data store and a local one?

I am new to DDD and the Repository Design Pattern thing, in fact I have no experience whatsoever on this. I came across it a while back and although I don't fully understand it yet I feel it's really flexible and I should give it a try. So I am working on this new Xamarin.Forms project and I'd like to implement this. The app involves fetching data from google firebase and persisting these data in the local database. Now from what I have read about repository pattern, the repository just serves as an abstraction of the actual data stores so that the client code has no idea how the persistence and fetching of data is done, so this way it is possible to change the data source/store without breaking the client code(please correct me if I am wrong). The first issue I came across was how to define my models, I read a lot of articles online on how to define models in DDD but all they do is talk and talk and talk with no specific answer, should my model definition mirror how my data is stored on firebase or how I am going to persist it on the local sqlite db?. This question was bugging me for a while then I realized both ways are wrong the domain model should have no relationship with how it is persisted, unless it is a persistence model, so I went online to read up on Domain Model and Persistence Model again and I got more talks. The bottom line is, can someone explain to me in simple terms with examples how to separate the domain model from its persistence model and how to design the repos for the two data stores, would I have one repo for the local one and another for the firebase one, then when and how do I work with the domain and persistence model?
In a perfect world you don't need a persistence model at all. How you persist your domain model is just an implementation details, and you should not worry about it when you build the domain model in the first place.
Of course, in practice you cannot really adhere to this principle 100% of the time.
should my model definition mirror how my data is stored on firebase
You may have a model with a one-to-one mapping to the data store. That's the Persistance Model for you. Usually is just an anemic propriety bag, full of setter and getter. And the point of the persistence model is that it's just an implementation details. You don't expose that to the user. You don't return it from any repositories.
Your concrete implementation of the repository will create and use the persistence model to save and retrieve data from the store. That's its only responsability. You should do this only if your tools (most likely an ORM) don't allow you to do otherwise.
At this point, you can:
Encapsulate the persistence model into the domain model. You can do this inside the repository, as the repository will alway and only return the domain model. Your domain model can deal with the persistence model, and hide this complexity away from the client.
To be honest, I find this solution really ugly, as the domain model must be aware of the persistence model in the first place.
Map from the persistence model to the domain model. You will need to needs to map the individual fields/proprieties in the persistence to the domain object. This may be time consuming, because usually this mean that you will need to create the domain model yourself ( inside the repository ) from the persistence model, and viceversa, but will give a clean separation between domain and persistence.
please correct me if I am wrong
Your basic idea is correct; Evans originally described the repository as a way of providing the illusion of an in memory collection. That is to say, the client doesn't talk directly to the persistence component; it talks to something that implements the repository api, and that implementation is responsible for the details of storage.
The bottom line is, can someone explain to me in simple terms with examples how to separate the domain model from its persistence model
It may help to re-affirm the basic motivation: we're trying to keep the domain model and the persistent model different, because they tend to change on different schedules -- we don't want to have to migrate the database every time we change the in memory representation of state.
The idea, then, is that we have two functions available in the repository
one takes the domain's in memory representation, and converts it to the form that gets stored
the other takes the stored form, and converts it to the in memory representation.
Often, the persisted form will have the characteristics of a message (being sent from the past to the present). It's common to use a sort of message builder approach when converting the persisted form to the current model used by the domain (the domain logic provides the builder, which has a stable api, but not necessarily a stable implementation).

Neo4j OGM Connect to existing Embeded DB

good day. i have some theoretical question.
i made application that uses neo4j to traverse graphs and make some external calculations on each node. traverse process initiated by external event.
during traverse process nodes properties may change according calculation results.
this made by
new GraphDatabaseFactory().newEmbeddedDatabase(new File (this.DB_PATH));
GraphDatabaseService.traversalDescription();
now i'd like to use neo4j OGM to use domain classes in path extenders code instead self-made node-wrappers. also i`d like to use domain classes to populate DB with nodes and relations , and change properties of nodes from external source (REST for example).
But i can't find way to get Session or SessionFactory to existing and operational database.
is it possible to connect to database , created as embedded and conducting some calculations in one module , from another module by BOLT protocol, execute some queries, use OGM features?
The OGM cannot be used from path expanders / traversals (at least not easily).
To use OGM with embedded database you have 2 options
use the standard configuration as described in the reference documentation
set use Components.setDriver to set the driver manually, see e.g. this answer for details

Using Neo4j in Grails without the Grails neo4j-plugin and GORM

Is it possible to use Grails to provide Controllers and Views, Neo4j as the database and (self written) domain classes that wrap the database access and CRUD operations without the neo4j plugin?
The data I have (~10^6 Nodes, 10^7 Relationships) are very well suited to be modeled by a graph DB. The Nodes and the relationships both need to have labels and properties so they can be accessed through traversal methods that only go via certain paths in the graph. I want to use grails for the web interface because I just starting learning programming a few weeks ago and it appears to be a pretty good point to begin.
From what I understand until know is that with the Grails Neo4j-plugin, it is not possible to set relationships with properties and labels. It seems very appealing and easy to write the classes that relate to the data using the plain Neo4j-Java-API.
Additionally, if my database is already structured in a way that directly relates to Objects, what is the benefit of using ORM (or object-graph-mapping in this case)?
Unless you require Grails scaffolding and you're not depending on domain classes in Grails you can go without the GORM plugin and do the dirty work on your own.
Add the neo4j jar dependencies to your BuildConfig.groovy and expose the GraphDatabaseService and optionally the ExecutionEngine to your application context, see http://grails.org/doc/latest/guide/spring.html#springdslAdditional.
In the near future there will be 2.0 version of the Neo4j GORM plugin that uses labels and relies solely on Cypher. Relationship properties is high on the list after this release.

Set parent entity defined in bundled Core Data model

I'm working on a static library that will help sync Core Data iOS apps with a remote SQL database. My library relies on a few sync-related attributes that each Core Data entity must have, so I've created a parent entity, SyncObject, that all other entities inherit from. SyncObject is defined in the static library's data model and is included in the resource bundle (how's my terminology?)
When I create a new app that uses this library, I merge the the app's data model with the library's data model and programmatically set all of the app's entities as sub-entities of SyncObject. Remarkably, this all works, but it feels clunky: when auto-generating entity class files, I have to manually change the base class to SyncObject (which is itself a subclass of NSManagedObject) in the .h file, and I can't define relationships between entities in the app's data model and entities in the bundled data model because the Xcode data model editor doesn't know about the entities defined in the external bundle.
Is it possible to make the editor aware of bundled data models? If so, how?
I would strongly recommend against this design. If all entities inherit from a single entity then your entire Core Data SQLite data structure will existing a single table. The performance cost for this is quite simply huge.
It is not possible to make the data modeler aware of the bundled data model.
Update
There is a difference between subclasses and sub-entities. There is nothing wrong with Subclassing. Creating sub-entities, however, is quite different and is designed to solve a different problem. Sub-entities are meant to intentionally combine so entities so that they share a common root and share a common set of properties or relationships. The cost of that is that they also share a common table. Which in the situation that they are intended for is not a significant cost.
The thread you referenced confused subclasses and sub-entities. They are not the same and they do not even need to align.
Trying to have an entire data model be sub-entities of a single parent entity is not the intended use of that feature of Core Data. It will cause horrific performance penalties and eventually stop your application from working. You would be better off working from a different design. For example, you could force them to subclass from your class which then subclasses NSManagedObject and do what you need to do in that subclass. You could further require an attribute to exist in each entity so that you can complete your goal.
mogenerator works in that vein (although it does not require an attribute to exist in the entities). There are also syncing frameworks that work off a similar design. They require that each entity have a unique identifier key, etc.
You could go even further and not necessarily require an attribute but instead require that the subclasses define a unique identifier so that you framework can uniquely identify each instance of an entity. You could then work with that uniqueID without requiring its definition be specific (a string, a number, etc.).

Neo4j project structure

I am looking to build a relatively complex Neo4J application, which I intend to split up in two separete projects, namely frontend and backend. The frontend will be HTML5 and is not relevant for this question, the backend will have a REST interface with Jersey, but it's the structure behind that REST interface that I have questions about.
Atm, this is how I envisioned it :
RESTimpl <-DATA-> Service <-DTO-> Repository <-NODE-> DAO <--> Neo4j Singleton
The general flow would be that the RESTimpl receives JSON and converts it to simple java objects like Strings, int, ... Those are then passed on to the service who creates a DTO with them. That DTO is passed on to the repository which performs all the DAO calls needed to write such a DTO to the database (one DTO may require several nodes and relations to be created). For DAO I was thinking of creating both a Core API and Cypher implementation, which has just very basic graph functions like creating a node, creating a relation, deleting a node, ... Methods which are useful for all repositories basically. The Neo4j singleton would then contain my GraphDatabaseService instance and some configuration stuff.
This is a relatively complex structure but I want the project to be very modular. Makes it easy to do Dependency Injection. (Everything will be written against an interface as well)
However, all the examples on the internet have a different implementation. They actually make their DTO's a wrapper around the Neo4J node or at least store the underlying node in the DTO. But it does allow for just a REST-Service-DAO structure.
But it doesn't allow me to change the repository implementations and put a different database behind the application.
What would be the "most correct way" to do what I want to do?
I use exactly what you've described above and I find that it works very well(one project in production, one almost there) and does not mix concerns. I don't use Spring Data but it is an option to consider.
I have defined my domain objects as standard POJO's- no Neo4j stuff in them at all. Their persistence is managed by DAO's- which contain mostly Cypher queries, and in some cases some core API work depending on complexity.
The GraphDatabase is a injected (I have two contexts- the EmbeddedGraph implementation is injected for production and the ImpermanentGraph for tests).
A REST service is exposed using Jersey which deals with domain objects and/or DTO's.
So Neo4j code is only seen in the persistence layer.
Got a couple of general convenience methods exposed to index/fetch by index etc.
I wouldn't go the wrap-Node way- tried it but found that it brings along its own set of problems and results in a somewhat smelly design. Looks like you're on the right track (to me at least)

Resources