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.
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;
<dependency>
<groupId>io.github.Mom0aut</groupId>
<artifactId>dynamic-relations</artifactId>
<version>1.0.4</version>
</dependency>
- Add the @Relation to your Entity
- Implement RelationIdentity
- Import Config Module for Component Scan
- Use the RelationService
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 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 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);
}
}
@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!
@Autowired
private RelationService relationService;
void deleteRelation() {
relationService.deleteRelation(relationToBeDeleted);
}
@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);
}
@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();
}
- Java with Spring
- Sql Database (tested with Postgres)
Every contribution is welcome, please follow the Contribution Guidelines
See our Code of Conduct