How can I implement Object-Graph Mapping (OGM) in a graph database using AGE? - jdbc

I am using a AGE and its JDBC driver, and I want to implement Object-Graph Mapping (OGM) in my application. I have a graph database of employees where nodes represent Person, City, and Department.
In my Java application, I want to map these nodes to Java classes so that I can work with the data in an object-oriented way. For example, the Person node should map to a Person Java class, the City node should map to a City Java class, and the Department node should map to a Department Java class.
In addition, I want to store the relationships between nodes as Java object references. For example, if there is a relationship between a Person node and a City node, this relationship should be represented as a reference from the Person Java object to the City Java object.
I am looking for help on how to implement OGM in my graph database and Java application. Can someone provide me with an example or some guidance on how to achieve this mapping?

Related

Spring data with R2DBC(Mysql) Example for one to many association

Can I know how to do association(One to Many) in Spring data JDBC with R2DBC(Mysql).Please provide small code example or git link if possible.
For Example, I have one employee table and address table is child of employee.
One employee can have multiple addresses.
If I want to retrieve employee, I want address as well to corresponding employee as JSON.
Note: Software stack is Spring Functional Reactive, R2DBC with Mysql
Spring Data R2DBC currently does not support aggregates.
This means every entity gets mapped to just one table and can't have object references to other entities.
Therefore the correct way to model your example is to have no object reference between Empolyee and Address but have an employeeId in the Address and use that to select the desired addresses.

Spring Data Neo4j 5 - Dynamic Property Creation

I am new to Spring Data Neo4j and I am development application where I will map each Neo4J Node into POJO(NodeEntity) but I need dynamic mapping between Neo4j Node and NodeEntity Class in Spring.
Example : Lets say If I have Student Node ---> is mapped to ---> Student Node Entity
#NodeEntity
class Student
{
#Property(name="SName")
String studentName;
.
.
.
}
Later instead of Student , I might get Employee Node in Neo4j with different set of properties. In that case existing Student mapping will not work with Employee Node in Neo4j.
I need generic NodeEntity class which can be mapped to any Node in Neo4j ? Is doable ?
You can use #CompositeProperty annotation on a Map<String, Object> field in Your generic entity. You will be able to store different keys & values in the generic node. Check out the documentation. spring docs.

Association mapping in microservice

I have two Microservices. Let's say student & library.
student & library - eureka clients
The microservices have a common DB
The scenario is - A student can issue (or take) multiple books from the library.
In Monolithic Application:- This will be implemented by anotating#OneTOMany on List of LibraryBook in StudentEntity and adding one table where we will store each book id for student.
Currently what i have tried
I have loose mapping (or binding ) of data between the data. I have created a table in DB with two columns studentId and bookId and when a student takes a book from library I add the bookId in the table and delete the record when book is returned.
For saving -
StudentBook studentBook = new StudentBook();
studentBook.setStudentId(123);
studentBook.setBookId(456);
studentBookRepository.save(studentBook); // studentBookRepository extends JPA Repository
For Deleting-
studentBookRepository.deleteByBookIdAndStudentId(456,123);
The problem in this implementation is that I always have to verify the bookId before saving the records.
Is there any better way to implement this?
How to implement #OneToMany relationship in Microservices?
(Or can we even implement Association mapping in microservices)
(Or can we even implement Association mapping in microservices)

How to join nodes and relationships in Neo4j to make sentences?

I am currently doing a research project and I've built 2 ontologies of 2 domains using Neo4j graph database. Now there's a requirement for me to construct sentences using the nodes and relationships separately for the two domains for a string matching purpose. For example, if the nodes and relationship are as follows:
(n:Person{name:'John'})-[r:knows]->(m:Person{name:'Smith'})
I want to get the sentence "John knows Smith". Also, another important thing is in the ontologies there are different types of relationships. So I want to get the sentences without worrying about the relationship types. For example, if we take the above example I should be able to get the result without having to use the relationship type "knows" anywhere, simply by using a generic way.
I have built the ontologies on the same sandbox by giving "Finance" and "Politics" as node labels to differentiate them. I've given a property to each node as "name" and it states the word of the domain. For example, if there's a word in the financial domain as 'profit' the create query would be like CREATE(n:Finance{name:'profit'}). I want to get the name of the nodes and make the sentence.
Is there a suitable Neo4j query to do so or is there a way to accomplish this by using a Spring Boot backend API. I've already constructed a Spring Boot API to do some basic functionalities like adding nodes and relationships. What I'm asking is, is there a direct query to build sentences from nodes and relationships or is there a way to do so by using Java Spring Boot? But it would be great if anyone can suggest a neo4j query to accomplish this.
I if understand your question, you can use type() function.
match (a)-[r]->(b)
return a.name + " " + type(r) + " " + b.name

Getting all aggregate root entities child entities?

I am attempting to refactor my application from a repository per entity to a repository per aggregate root.
A basic example would be I have an entity root of Cars. Cars have hire contracts. As far as I can see contracts don't exist without cars hence cars is the aggregate root.
I am trying to implement a user view which will shows every contract in the system(all the child entities of the root entities). Before refactoring I could just go to my contracts repository and get All. As contracts repository has been removed (as its not a root) I now need to get all cars out of my repository and then get all their contracts.
My repository has the interface
public interface ICarRepository
{
IQueryable<Car> All { get; }
IQueryable<Car> AllIncluding(params Expression<Func<Car, object>>[] includeProperties);
Car Find(long id);
void InsertOrUpdate(Car car);
void Delete(long id);
void Save();
}
I thought of creating an ICarManagementService and having it have a GetAllContracts method (perhaps with filter parameters). Would that mean to get all contracts I need to pull all car entities out with their contracts and then retrieve each entities associated hire contracts and filter them?
I can then pass these to the controller and AutoMap the contracts as before.
Is this best practice?
Thanks
Graeme
As far as I can see contracts don't exist without cars hence cars is
the aggregate root.
This is not necessarily true. 'Don't exist without' is not enough for an entity to become a part of an Aggregate Root. Consider classic order processing domain. You have an Order that is an Aggregate Root. You also have a Customer that is an Aggregate Root. Order can not exist without a Customer but it does not mean that Orders are part of the Customer Aggregate. In DDD entities inside one Aggregate can have references to other Aggregate Roots. From DDD book:
Objects within the AGGREGATE can hold references to other AGGREGATE
roots.
Aggregate is a life cycle and data exchange unit. It is essentially a cluster of objects that enforces invariants. This is something you want to be locked if you have multiple users changing domain at the same time.
Back to your question, my understanding is that the domain is something like rent / lease a car / truck / limo / bulldozer. I think that HireContract may not be a part of Car aggregate because they may have different lifecycles and HireContract just makes sense on its own, without a Car. It seem to be more of a Order-Product relationship that is also a classic example of two different Aggregates referencing each other. This theory is also confirmed by the fact that business needs to see "All Contracts". They probably don't think of Car containing all Contracts. If this is true than you need to keep your ContractsRepository.
On an unrelated note, you might be interested in reading this answer about repository interface design.
Separate the concept of read/query from the write/command, as guided by CQRS it is preferable to design the application by separating read model which consists of read only queries and the write model on the other hand which consists of commands to execute certain logic on the domain model.
thus querying all aggregate roots or creating custom queries to join sets of data is not a good candidate of domain repository, instead put these queries into read repository (or better named Finders).
if you find yourself wanting to query a collection of objects in order to execute some domain logic then it is an indicator that you have to abstract this collection and put it into an aggregate root to encapsulate them and make the business operation or method act on them.
check out (http://moh-abed.com/2011/09/13/pure-old-ddd-with-a-twist-from-cqrs/) and (http://simon-says-architecture.com/2011/08/23/repository)

Resources