Optimize settings for Hibernate ORM

* Optimize settings for Hibernate ORM
* Teach exception handler about the new BatchUpdateException exceptions

Closes #26162

Signed-off-by: Sebastian Hoeninger <Sebastian.Hoeninger@bosch.io>
Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
Co-authored-by: Sebastian Hoeninger <Sebastian.Hoeninger@bosch.io>
Co-authored-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
sebastianh6r 2024-05-27 10:20:19 +02:00 committed by GitHub
parent 29dee7ec63
commit f34a7c2af4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 35 additions and 2 deletions

View file

@ -32,6 +32,7 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException; import java.sql.SQLIntegrityConstraintViolationException;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -89,8 +90,12 @@ public class PersistenceExceptionConverter implements InvocationHandler {
Predicate<Throwable> throwModelDuplicateEx = throwable -> Predicate<Throwable> throwModelDuplicateEx = throwable ->
throwable instanceof EntityExistsException throwable instanceof EntityExistsException
|| throwable instanceof ConstraintViolationException || throwable instanceof ConstraintViolationException
|| throwable instanceof SQLIntegrityConstraintViolationException; // SQL state class 23 captures errors like 23505 = UNIQUE VIOLATION et al.
// This captures, for example, a BatchUpdateException which is not mapped to the other exception types
// https://en.wikipedia.org/wiki/SQLSTATE
|| (throwable instanceof SQLException bue && bue.getSQLState().startsWith("23"))
|| throwable instanceof SQLIntegrityConstraintViolationException;
throwModelDuplicateEx = throwModelDuplicateEx.or(checkDuplicationMessage); throwModelDuplicateEx = throwModelDuplicateEx.or(checkDuplicationMessage);

View file

@ -92,6 +92,34 @@
<properties> <properties>
<property name="jboss.as.jpa.managed" value="false"/> <property name="jboss.as.jpa.managed" value="false"/>
<!-- Execute multiple insert and update statements in a single call to improve bulk insert / update performance.
See https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#best-practices-jdbc-batching
and https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#batch-session-batch:
recommendation between 10 and 50 -->
<property name="hibernate.jdbc.batch_size" value="32" />
<!-- (optional) Allows for more batching for nested objects and less deadlocks, but according to
https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#batch-jdbcbatch
may also hava a negative impact on performance.
See also https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#best-practices-jdbc-batching.
Keycloak uses many nested objects spread across multiple tables, so a benefit is likely.
-->
<property name="hibernate.order_inserts" value="true" />
<property name="hibernate.order_updates" value="true" />
<!-- Batch fetching collections of entity proxies, default 1. Eases N+1 issues to some extent.
See https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#fetching-batch -->
<property name="hibernate.default_batch_fetch_size" value="8" />
<!-- Improve cache hits for execution plans.
See https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#configurations-query -->
<property name="hibernate.query.in_clause_parameter_padding" value="true"/>
<!-- Increase number of elements fetched at once from Oracle database query result up from 10.
MSSQL returns the whole result at once.
See https://docs.oracle.com/en/database/oracle/oracle-database/21/jjdbc/resultset.html -->
<property name="hibernate.jdbc.fetch_size" value="64" />
</properties> </properties>
</persistence-unit> </persistence-unit>
</persistence> </persistence>