Improve robustness of HibernateJpaParametersParameterAccessor.

This change avoids errors when no transactional EntityManager is available.

Closes #2540
Original pull request #2542
This commit is contained in:
Cedomir Igaly
2022-05-23 11:19:42 +02:00
committed by Jens Schauder
parent 0aa6d7d6e7
commit 718f9201fc
3 changed files with 84 additions and 3 deletions

View File

@@ -16,7 +16,7 @@
package org.springframework.data.jpa.provider;
import jakarta.persistence.EntityManager;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.TypeHelper;
import org.hibernate.jpa.TypedParameterValue;
import org.hibernate.type.Type;
@@ -49,8 +49,7 @@ class HibernateJpaParametersParameterAccessor extends JpaParametersParameterAcce
super(parameters, values);
Session session = em.unwrap(Session.class);
this.typeHelper = session.getSessionFactory().getTypeHelper();
this.typeHelper = em.getEntityManagerFactory().unwrap(SessionFactory.class).getTypeHelper();
}
@Override

View File

@@ -0,0 +1,49 @@
package org.springframework.data.jpa.provider;
import jakarta.persistence.EntityManager;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.query.JpaParameters;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import java.lang.reflect.Method;
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:hjppa-test.xml")
public class HibernateJpaParametersParameterAccessorUnitTests {
@Autowired
private EntityManager em;
@Autowired
private PlatformTransactionManager transactionManager;
@Test
void withoutTransaction() throws NoSuchMethodException {
simpleTest();
}
@Test
void withinTransaction() throws Exception {
final TransactionStatus tx = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
simpleTest();
} finally {
transactionManager.rollback(tx);
}
}
private void simpleTest() throws NoSuchMethodException {
final Method method = EntityManager.class.getMethod("flush");
final JpaParameters parameters = new JpaParameters(method);
final HibernateJpaParametersParameterAccessor accessor = new HibernateJpaParametersParameterAccessor(parameters, new Object[]{}, em);
Assertions.assertEquals(0, accessor.getValues().length);
Assertions.assertEquals(parameters, accessor.getParameters());
}
}

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc https://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="entityManagerFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<array>
<value>org.springframework.data.jpa.domain</value>
<value>org.springframework.data.jpa.domain.sample</value>
</array>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="defaultEntityManager"
class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="synchronizedWithTransaction" value="true" />
</bean>
<jdbc:embedded-database id="dataSource" type="HSQL" generate-name="true">
<jdbc:script execution="INIT" separator="/;" location="classpath:scripts/hsqldb-init.sql"/>
<jdbc:script execution="INIT" separator="/;" location="classpath:scripts/schema-stored-procedures.sql"/>
</jdbc:embedded-database>
</beans>