Spring Boot中Hibernate能否在实体表创建后执行data.sql初始化数据
解决方案
你可以根据自己的需求选择下面两种适配方案:
方案1:全局延迟data.sql执行(所有Hibernate实体表创建完成后执行)
这是最轻量的实现方式,仅需修改配置即可完成需求:
- 在
application.properties或application.yml中添加如下配置:
# 开启数据源初始化延迟,让data.sql在Hibernate完成所有表结构生成后再执行 spring.jpa.defer-datasource-initialization=true # 配置Hibernate表结构生成策略,可根据需求替换为create/create-drop/update spring.jpa.hibernate.ddl-auto=update
- 把你需要执行的插入语句放入
src/main/resources/data.sql文件即可。注意你提供的INSERT语句中包含summary字段,但你的UserProfile实体类未定义该属性,要么在实体类中补充summary字段,要么删除SQL中的summary字段,否则执行会报错,修正后的SQL参考:
INSERT INTO userprofile (id,theme,userName) VALUES (1, 1 , 'John Doee'), (2, 2 , 'Jenny Doee'), (3, 3 , 'James Doee');
方案2:仅监听特定表创建完成后执行初始化(不影响全局初始化逻辑)
如果你不需要全局调整初始化顺序,只想在userprofile表创建完成后单独执行这段插入逻辑,可以通过Hibernate的扩展点实现:
- 自定义Schema创建监听器:
package io.fall.config; import org.hibernate.boot.Metadata; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.integrator.spi.Integrator; import org.hibernate.service.spi.SessionFactoryServiceRegistry; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; public class UserProfileSchemaListener implements Integrator { private final DataSource dataSource; public UserProfileSchemaListener(DataSource dataSource) { this.dataSource = dataSource; } @Override public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { // 检测userprofile表是否已经被Hibernate生成 boolean tableExists = metadata.getEntityBindings().stream() .anyMatch(persistentClass -> "userprofile".equals(persistentClass.getTable().getName())); if (tableExists) { JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); // 先判断表中是否已有数据,避免重复插入 Integer count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM userprofile", Integer.class); if (count == null || count == 0) { jdbcTemplate.update("INSERT INTO userprofile (id,theme,userName) VALUES (1, 1 , 'John Doee'), (2, 2 , 'Jenny Doee'), (3, 3 , 'James Doee')"); } } } @Override public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { // 无需实现逻辑 } }
- 把监听器注册到Spring容器中:
package io.fall.config; import org.hibernate.jpa.boot.spi.IntegratorProvider; import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; import java.util.Collections; @Configuration public class HibernateConfig { @Bean public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(DataSource dataSource) { return hibernateProperties -> { hibernateProperties.put("hibernate.integrator_provider", (IntegratorProvider) () -> Collections.singletonList(new UserProfileSchemaListener(dataSource))); }; } }
内容的提问来源于stack exchange,提问作者Shiru99
相关产品推荐
相关产品推荐

