Spring Boot+Spring Data应用在Liberty Core中JPA Fetch Size不生效
我明白你遇到的困扰:在嵌入式Tomcat里spring.jpa.properties.hibernate.jdbc.fetch_size = 500能正常生效,但部署到WebSphere Liberty Core后就失效了,而且不想改用手动EntityManager的方式来设置。下面给你几个可行的解决方案,按全局到局部的优先级排序:
1. 全局配置:通过Spring Boot的Hibernate属性定制器
这个方法能确保不管容器是什么,Hibernate都会加载到抓取大小配置,是最可靠的全局方案。
创建一个自定义的HibernatePropertiesCustomizer Bean,直接向Hibernate的配置中注入fetch size属性:
import org.hibernate.cfg.AvailableSettings; import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; import org.springframework.stereotype.Component; import java.util.Map; @Component public class GlobalFetchSizeCustomizer implements HibernatePropertiesCustomizer { @Override public void customize(Map<String, Object> hibernateProperties) { // 直接设置Hibernate的JDBC抓取大小属性 hibernateProperties.put(AvailableSettings.JDBC_FETCH_SIZE, 500); } }
这个类会被Spring Boot自动识别,在初始化Hibernate配置时把fetch size参数加进去,完全绕过容器对数据源的管理限制,不管是Tomcat还是Liberty都能生效。
2. 驱动层面配置:在Liberty数据源中设置Oracle驱动默认抓取大小
Oracle JDBC驱动本身支持通过defaultRowPrefetch参数设置默认的行预取大小,你可以在Liberty的server.xml中直接给数据源添加这个属性:
<dataSource jndiName="jdbc/example" type="oracle.jdbc.xa.client.OracleXADataSource"> <jdbcDriver libraryRef="OracleLib"/> <properties.oracle URL="jdbc:oracle:thin:@//s123456.fr.net.intra:1521/test" databaseName="test" driverType="thin" password="dev123" portNumber="1521" serverName="s123456.fr.net.intra" user="dev" defaultRowPrefetch="500"/> <!-- 添加这一行 --> </dataSource>
这个配置是从JDBC驱动层面生效,所有使用这个数据源的查询都会默认用500的抓取大小。如果Hibernate没有单独设置fetch size,就会继承这个驱动的配置。
3. 局部配置:给Spring Data Repository方法添加查询提示
如果只需要给特定的Repository方法设置抓取大小,可以用@QueryHints注解:
import org.springframework.data.jpa.repository.QueryHints; import org.springframework.data.repository.CrudRepository; import javax.persistence.QueryHint; import java.util.List; public interface EmployeeRepository extends CrudRepository<Employee, Long> { @QueryHints(@QueryHint(name = "org.hibernate.fetchSize", value = "500")) List<Employee> findAll(); // 其他需要设置的方法也可以添加这个注解 }
这个方法适合需要不同抓取大小的场景,灵活性更高,但需要逐个方法配置。
为什么原来的配置在Liberty里不生效?
主要原因是WebSphere Liberty Core作为容器管理数据源和JPA上下文时,Spring Boot的application.properties中部分Hibernate属性可能没有被正确传递到Hibernate的会话工厂中——嵌入式Tomcat是Spring Boot完全管理数据源和JPA,而Liberty是容器接管了数据源的创建,导致Hibernate的配置加载路径不同。上面的方案都是绕过或修正了这个加载问题。
内容的提问来源于stack exchange,提问作者napster

