DynamicRelations
DynamicRelations copied to clipboard
Dynamic Relations for Java Spring Projects
Dynamic Relations
In every relational database you must always know which relations are possible to your entities. But sometimes these relations are unknown or could change anytime. With Dynamic Relations you can add or delete custom relations between entities during runtime.
What is a Dynamic Relation?
A dynamic relation can be viewed as a directed graph with a fixed input(SourceObject) and a dynamic output(target).
flowchart LR
subgraph DynamicRelation
direction LR
SourceObject-->Target
end
For example with following entities:
- Person
- Dog
- Document
A person can have a dog and both entites could have documents(person info documents and dog info documents). Now you could add dynamic relations to all entities which could look like this:
graph TD;
Person-->Dog;
Person-->Person_Document
Dog-->Dog_Document;
Each connection is a dynamic relation and following relations will be generated:
- Person Relation with SourceObject Person
- Person_Document Relation with SourceObject Person_Document
- Dog Relation with SourceObject Dog
- Dog_Document Relation with SourceObject Dog_Document
Each relation got a dynamic target, that means you could create a relation to any other entity.
In this scenario a person have a dog and both got documents, now you could change the relation during runtime (no altering of your Entities or Models). For example, you could delete a Person_Document(got lost):
graph TD;
Person-->Dog;
Dog-->Dog_Document;
Maven dependency
<dependency>
<groupId>io.github.Mom0aut</groupId>
<artifactId>dynamic-relations</artifactId>
<version>1.0.4</version>
</dependency>
How to use
- Add the @Relation to your Entity
- Implement RelationIdentity
- Import Config Module for Component Scan
- Use the RelationService
Add the @Relation
Simply add the @Relation to your existing entity and the necessary dynamic relations entity will be generated. Dynamic relations are only working with classed which are annotated with @Entity!
@Relation(sourceClass = Person.class)
@Entity
@Getter
@Setter
public class Person implements RelationIdentity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Override
public String getType() {
return "PersonType";
}
}
Implement RelationIdentity
Implement the relationIdentity, each dynamic relation need a Long id and a String Type which you can define.
@Relation(sourceClass = Person.class)
@Entity
@Getter
@Setter
public class Person implements RelationIdentity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Override
public String getType() {
return "PersonType";
}
}
Import Config Module for Component Scan
Import the DrmConfig in your Spring Boot Application, so that you can use the RelationService
@SpringBootApplication
@Import(DrmConfig.class)
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
Use the RelationService
Create Relation
@Autowired
private RelationService relationService;
void createRelation() {
Person person = new person();
personDao.save(person);
Dog dog = new Dog();
dogDao.save(dog);
//Dynamic Relation can only be created with persisted Entities!
RelationLink relationLinkPersonToDog=relationService.createRelation(person, dog);
}
Dynamic relation can only be created with persisted Entities!
Delete Relation
@Autowired
private RelationService relationService;
void deleteRelation() {
relationService.deleteRelation(relationToBeDeleted);
}
Find Relations
@Autowired
private RelationService relationService;
void findRelations() {
Person person = new person();
personDao.save(person);
Dog dog = new Dog();
dogDao.save(dog);
Document document = new Document();
documentDaio.save(document);
//Dynamic Relation can only be created with persisted Entities!
RelationLink relationLinkPersonToDog = relationService.createRelation(person, dog);
RelationLink relationLinkPersonToDocument = relationService.createRelation(person, document);
RelationLink relationLinkDogToDocument = relationService.createRelation(dog, document);
//Return 1 Relation person -> dog
RelationLink foundRelation = relationService.findRelationBySourceObjectAndRelationIdentity(person, dog);
//Returns 2 Relations person -> dog and person -> document
List<RelationLink> relationBySourcePerson = relationService.findRelationBySourceObject(person);
//Returns 2 Relations from person -> document and dog -> document
Set<RelationLink> relationByTargetDocument = relationService.findRelationByTargetRelationIdentity(document);
}
Get the SourceObject by Relation
@Autowired
private RelationService relationService;
void getSourceObject() {
RelationLink foundRelation = relationService.findRelationBySourceObjectAndRelationIdentity(person, dog);
//Can be cast to Person because we know it is from Person.class
Person sourceObject = (Person) foundRelation.getSourceObject();
}
Limitations
- Java with Spring
- Sql Database (tested with Postgres)
Contributors
Contribution
Every contribution is welcome, please follow the Contribution Guidelines
Code of Conduct
See our Code of Conduct