How to implement database relationship using spring data JPA?
There are a lot of real world objects which impact a business case. Off those a few of them impact a specific use case of a business. Once we identify the real world objects that impact the specific business use case, then a database model is created. To be more precise an entity relationship diagram is made from that information. There would be a lot of relationship amongst those business objects or entities to be more precise, which have to be implemented in the software.
A relationship works by matching data in key columns — usually columns with the same name in both tables. In most cases, the relationship matches the primary key from one table, which provides a unique identifier for each row, with an entry in the foreign key in the other table.
Let’s say we are working for a telecommunication vendor, who wants to track his customers who have been shifting from one location to another and asking for a new connection, every time they move to a new location. So in this case a customer will be associated with an account. This account is tied to a specific location, which has the zip code. This seems to be like one customer can have only one account at a given location. If the same customer is allowed by business to have multiple accounts at a location, then it means that one customer can have multiple accounts at a location. This is an example of One to many relationship. Similarly that location can have multiple accounts. This leads to a many to one relationship in between account and location. Since the same customer is tied to the location so it is a one to one relationship in between them. There are three types of relationships between tables. The type of relationship that is created depends on how the related columns are defined.
1. One-to-Many Relationship
A one-to-many relationship is the most common type of relationship. In this type of relationship, a row in table A can have many matching rows in table B, but a row in table B can have only one matching row in table A. In the above example, a customer can have many accounts for a given location. So it’s one to many relationships.
2. Many-to-Many Relationships
In a many-to-many relationship, a row in table A can have many matching rows in table B, and vice versa. In the above example one customer can have many accounts at one location. So there can be many to many relationships in between accounts and customer, provided new customer id is given for a new account and is not tied to the same customer id. One can also maintain such a relationship by defining a third table, called a junction table, whose primary key consists of the foreign keys from both table A and table B. This might not be really required.
3. One-to-One Relationships
In a one-to-one relationship, a row in table A can have no more than one matching row in table B, and vice versa. A one-to-one relationship is created if both of the related columns are primary keys or have unique constraints. So in the above example one customer can be tied to one location.
There are multiple ways of solving this in java space. Following are the technologies:
1. Plain JDBC using a JDBC driver.
2. Spring Data JPA using Hibernate.
3. Spring JDBC which is essentially plain JDBC in itself.
4. Giving the objects to RDBMS with data to persist it. Essentially it’s RDBMS layer that can take care of the persistence.
In this article I would be talking about how to persist this using spring data.
Step 1: Use tools like STS, which has built in provision to create an entity objects.
Then you would see
Enter “JPA Project” to create a JPA Project. Here you can enter the value as per your understanding.
Click next unless otherwise you want to do some configuration.
Try to add a connection a new connection.
Pick the database type.
Enter the connection details.
Upon completion of this, Spring data JPA will create the java files for you which are required for the execution of the project. These java files will have the entity and the column mappings. Please make sure that you have the @Id mapping, or else you will have hibernate exception.
Now, in order to implement the one to many relationships, make sure that you have the line defined in the customer class.
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true,mappedBy="account")
Here the @OneToMany relationship makes sure that the one customer has many account. Now in the account class make sure that you have:
private Customer customer;
This ensures that the many to one relationship is established.
If you are creating a new child record for an existing parent, it’s essential to associate the child with the parent. One can create a record in child table by giving a parent id. But Spring Data JPA asks for the parent record, so as to be able to create the child.
Transactions and Spring Data JPA
It’s quite essential to understand how transactions and spring data JPA work together. Transactions have the following propagation levels:
Support a current transaction; throw an exception if none exists.
Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else.
Execute non-transactionally, throw an exception if a transaction exists.
Execute non-transactionally, suspend the current transaction if one exists.
Support a current transaction, create a new one if none exists.
Create a new transaction, and suspend the current transaction if one exists.
Support a current transaction, execute non-transactionally if none exists.
Transactions have the following isolation levels:
Use the default isolation level of the underlying datastore.
A constant indicating that dirty reads are prevented; non-repeatable reads and phantom reads can occur.
A constant indicating that dirty reads, non-repeatable reads and phantom reads can occur.
A constant indicating that dirty reads and non-repeatable reads are prevented; phantom reads can occur.
A constant indicating that dirty reads, non-repeatable reads and phantom reads are prevented.
Now when you are wanting to call the transactions, please make sure that the isolation levels which has been used are correct. Also, make sure that the propagation level over the method is done correctly.
How to achieve the batch insert using spring data JPA?
The JpaRepository has methods which have the provision to accept a collection of objects. This collection can be used to persist the records. Please do not assume that this is a batch insert. No it’s not. The <S extends T> List<S> save(Iterable<S> entities) actually iterates through the collection and saves record one by one.
After going through this article, one can replicate the Entity relationship diagram into Spring Data JPA entities and appropriately use the transactions to save them into database. By using spring data JPA, one leaves the responsibility of database with Spring JPA API. This way, one can focus on the business functionality more than on technical complexities of the database relationships.