Spring Boot打包Jar运行触发LazyInit异常,本地IDE运行正常求助
问题
我正在开发一个Spring Boot应用,遇到了如下问题:本地IntelliJ IDE中运行一切正常,但执行mvn clean package生成Jar包部署到Windows服务器后,出现大量懒加载初始化异常,本地却没有这个问题。
本地和服务器均使用Java 11和MySQL 8。
pom.xml内容
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.6</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>de.schuessler-plan.</groupId> <artifactId>acquisition.backend</artifactId> <version>0.0.1-SNAPSHOT</version> <name>acquisition.backend</name> <description>Backend for SP acquisition</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.modelmapper</groupId> <artifactId>modelmapper</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>net.sf.ucanaccess</groupId> <artifactId>ucanaccess</artifactId> <version>5.0.1</version> </dependency> <dependency> <groupId>com.monitorjbl</groupId> <artifactId>xlsx-streamer</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>com.vaadin.external.google</groupId> <artifactId>android-json</artifactId> <version>0.0.20131108.vaadin1</version> <scope>compile</scope> </dependency> <dependency> <groupId>me.tongfei</groupId> <artifactId>progressbar</artifactId> <version>0.9.3</version> </dependency> <dependency> <groupId>customJAR</groupId> <artifactId>SimbaJDBCClient42</artifactId> <version>4.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${project.parent.version}</version> <executions> <execution> <configuration> <mainClass>de.schuesslerplan.acquisition.backend.Application</mainClass> </configuration> </execution> </executions> <configuration> <executable>true</executable> <jvmArguments> -Xms256m -Xmx1g </jvmArguments> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>in-project</id> <name>In Project Repo</name> <url>file://${project.basedir}\libs\</url> </repository> </repositories> </project>
异常示例
"failed to lazily initialize a collection of role: backend.model.mysql.Employee.registeredWork, could not initialize proxy - no Session"
环境配置文件差异(application.yml)
spring: profiles: active: dev servlet: multipart: max-request-size: 10MB max-file-size: 10MB --- spring: profiles: dev jpa: show-sql: 'true' mysql: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/schema_name password: pass-local username: username-local jpa: hibernate: ddl-auto: update properties: hibernate: dialect: org.hibernate.dialect.MySQL8Dialect server: port: 8080 --- spring: profiles: prod jpa: open-in-view: false mysql: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/schema_name password: pass-server username: username-server jpa: hibernate: ddl-auto: update properties: hibernate: dialect: org.hibernate.dialect.MySQL8Dialect server: port: 8443 ssl: key-store-password: keystorepass key-store: classpath:keystore.p12 enabled: 'true' keyStoreType: PKCS12
问题原因与解决方案
核心原因
本地dev环境默认开启了spring.jpa.open-in-view(Spring Boot 2.x默认值为true),而生产prod环境手动设置为false,这是导致差异的关键:
- 当
open-in-view=true时,Spring会在整个请求生命周期内保持Hibernate Session打开,懒加载的关联对象可以在Controller甚至JSON序列化时正常初始化; - 生产环境关闭该配置后,Session在Service层结束后就会关闭,此时如果代码中在Session关闭后尝试访问懒加载的集合/对象(比如ModelMapper转换实体、序列化返回JSON时),就会抛出懒加载初始化异常。
本地IDE运行正常是因为dev环境没显式关闭open-in-view,而生产环境主动关闭的配置暴露了代码中不合理的懒加载使用方式。
解决方案
方案1:修复代码(推荐)
从根源解决问题,避免依赖open-in-view的隐式Session管理:
- 在Repository查询时使用
@EntityGraph或者JOIN FETCH,主动加载关联数据,确保在Session关闭前获取到所需内容:@Repository public interface EmployeeRepository extends JpaRepository<Employee, Long> { @EntityGraph(attributePaths = {"registeredWork"}) Optional<Employee> findById(Long id); } - 或者在Service层主动触发懒加载(比如调用集合的
size()方法),确保在事务内完成数据加载; - 检查ModelMapper的转换逻辑,避免转换时触发未加载的懒加载关联。
方案2:临时开启生产环境的open-in-view(不推荐)
如果需要快速验证问题,可以在prod配置中设置spring.jpa.open-in-view=true,但这会延长Session生命周期,可能带来性能和连接泄漏风险,不建议长期使用。
内容的提问来源于stack exchange,提问作者nb13
相关产品推荐
相关产品推荐

