Why transactional relationships matter
You have spent your twenties going to university, graduating, and building some equity for your first home. Now unless your first job was as a hedge fund manager at Goldman Sachs, chances are that your plan to buy your first home will lead you to a bank to get a loan. You will typically sign a contract stating how much money you will loan from the bank and the bank will assign you an account that shows you which payments you already made and how much money is outstanding. At any point in time, you know how much you owe and what payments you already made to pay back your mortgage.
Unfortunately, not all transactions are equally straightforward. Let us say your friend Joe, an aspiring actor with an irregular income, broke his fridge and is missing the liquidity to buy a new one. He asks you to lend him some money to buy a new fridge for US $1,000. You decide to help him out and transfer him the money via a payment order. As his friend, you may not want to go through the struggle of setting up a loan contract and opening a bank account for him. Nonetheless, to keep track of how much he owes you, it would be really helpful to link any money he pays you back, to the initial transfer you made to lend him the money.
Introducing Order Relations
The scenario described above may sound familiar, but it is far from the only one where linking orders will be helpful or even critical for data and process management. We would therefore like to be able to model these kinds of relations in our application as well. When linking orders, we would like to know which orders are linked, why they were linked, and when. It should be possible to link orders programmatically or via the user interface. For example, when a user sells 100 shares, a broker might send us several execution orders via a REST or FIX interface. These orders should then be automatically linked to the order placed by the user. Conversely, in our example above there will most likely not be an integrated interface to document transactions between friends. Therefore, we would like to enable these kinds of order links via the GUI.
Modelling Relationships in Spring Boot
In its most basic form, our data model needs a relation table that stores the 2 orders to be linked and the type of relation. For the order relations, we are using @ManyToOne JOIN annotations, whereas we model the relation type via a JAVA Enumeration with the required metadata being properties of the relation type enumeration. Since orders are not the only entities with relations and there are other fields that we would like to model as entity extensions, we are introducing an inheritance hierarchy using the @MappedSuperclass class annotation. The annotation allows a class to act as an interface for child classes, effectively defining columns that will be created for every child class of the annotated superclass.
Data Transfer Objects for Relationships
Now that the relationship is mapped in the persistence layer, we want to enable the application to manage the relations in the front-end. Just like all other objects in the persistence layer, the relations will therefore get equivalent data transfer objects. Again, there are other entity extensions that will require similar functionality and we want to avoid redundant code which could endanger the reliability of the application. we want to be able to implement a custom mapping of each extension to their DTO object. To do so, we parameterize the DTO objects with their JPA entity and vice versa. That allows us to use mapping functions when communicating between the persistence layer and the interface layer. This changes the UML of the order relation as depicted below:
Relationships in the Angular Front-end
Order relations, like all order extensions, will be accessible in the GUI via a dialog. Each dialog is defined in an enumeration in the backend. It stores the name of the DTO property containing the extension data. Based on these definitions, the angular application generates the user interface via directives. Currently, the extension dialogs are all classified as either “lists” or “tables”. Extensions that typically have one value per item, like a key or a birthdate, are designed as lists, whereas extensions with multiple values, like relations, are defined in table dialogs. Order relations will therefore appear in the GUI as tables:
In the code, the rows of the table are read from an array, which gets copied into the order DTO in the front-end upon clicking “Save” in the dialog window. The modification of the order in the back-end will only happen once a workflow action has been executed.
This concludes our design of order relations. In the next article, we will bring entity relations to the next level, by exploring how orders will allow the management of relations between objects.