## 7 Bottlenecks Investigation
### Reducing Spring Data JPA Bottlenecks  
The first attempt to reduce the bottlenecks was to override the void delete(Ticket) method from the created SimpleJpaRepository<Ticket, ID>. To do this, we created an interface that extends CrudRepository<Ticket, ID>:  
@NoRepositoryBean  public interface CustomCrudRepository<ID> extends CrudRepository<Ticket, ID> {  void delete(Ticket entity);  } An implementation of this interface was needed to override the method and skip the queries given to the database:  
public class CustomJpaRepository<ID> extends SimpleJpaRepository<Ticket, ID>  implements CustomCrudRepository<ID> { private EntityManager entityManager;  
@Override public void delete(Ticket entity) {  this.entityManager.remove(this.entityManager.contains(entity)?  entity : this.entityManager.merge(entity));  } } After creating the repository bean and injecting the EntityManager dependency into it, profiling was performed again. There was an improvement of about 10% in the execution times, but it was still not close to the other two ORM frameworks tested.  
There were also interesting pop-up messages while the investigation with YourKit finished for Spring Data JPA runs: \"Potential deadlock: Frozen threads found -> frozen for at least 19 min 10 s\". This happened for a run with PostgreSQL and Spring Data JPA with 100k entries, but also for runs with other RDBMSs. The record was established with a PostgreSQL run with Spring Data JPA with 500k entries: 1 d 0 h 47 min 18 s, which explains why the biggest scenario runs for so long.  
The problem is not a deadlock, but a long starvation, as the program finishes its run successfully. Because of that, another attempt to reduce the bottlenecks was to replace the transaction management completed by Spring Data JPA.  
Removing the @EnableTransactionManagement annotation was the first step in the process. Then, the EntityManagerFactory used for the JPA implementation was used to replace the factory used by Spring Data JPA.  
The CustomCrudRepository<ID> interface was also modified. The logic for all CRUD operations did not change too much; they were overridden to use custom transaction management through the EntityManagerFactory. After these changes took place, the execution times for 50k entries for each CRUD operation for each RDBMS tested with Spring Data JPA were remeasured and the results are presented in Tables 2 and 3.  
Comparing the new results with the Hibernate ones proves a significant decrease in time for Spring Data JPA when the transaction management is changed.  
It emphasizes that the purpose of changing Spring Data JPA's transaction management is experimental, with the purpose of investigating how the classic EntityManager behaves in Spring's environment. It does not intend to solve the bottlenecks; further research on transaction management needs to be conducted.  
Some of the previous papers provided experiments focusing on particular RDBMSs or on improving access to the databases using optimizer hints, optimization of the execution plans, prediction, diagnosis, and tuning approaches. Other previous work focused on contemporary challenges such as the work with Big Data, Cloud Computing, or using machine learning to obtain better performances.  
Our research differentiates itself from the previously published ones with the extensive combination of four types of databases and three ORM frameworks. Alongside this, we investigated the critical execution sections (bottlenecks) and the improvements that the JVM warm-up brings.