I have been doing flame graph analysis to understand CPU usage for some of my applications. The application I was testing in this instance is a Spring Boot app using Spring data JPA + Hibernate with MySQL jdbc driver for persistence. The entity was saved successfully in the database and the functionality itself was not affected. From the flame graph (hibernate-exception.png), I saw that a lot of CPU was used in filling stack traces for an IllegalArgumentException which was never causing any issues. I have attached the graph with this issue. On looking at the stack, it looks like for entities with composite primary keys, Spring JPA is checking if id has to be derived for every property of the composite primary key (IdClass). This is done by calling Hibernate's managedType method in MetaModelImpl. The method is throwing IllegalArgumentException every time as the properties of my composite key are literals and id derivation is not required. In the example I tested, my composite key had 4 properties and 4 exceptions were thrown for each of them and this happens every time I persist an entity. It easily multiplies in write-heavy workloads. And this is consuming a lot of CPU as more time is spent on creating these exceptions and stack traces. Taking into account just Spring JPA's code, I don't think this situation warrants an exception to be thrown as it silently ignored and not adding any extra information. I don't know if throwing the exception is critical to other parts of Hibernate. Can managedType just return null if the provided class is not a managed type instead of throwing exception? |