Spring Boot中@GenericGenerator关联的自定义序列生成器如何读取application.properties
问题根本原因
CustomSequenceGenerator默认由Hibernate框架直接实例化,不属于Spring容器管理的Bean,因此@Value、@Autowired、@ConfigurationProperties这类Spring依赖注入注解全部无法生效,和配置文件加载顺序无关。
解决方案
方案1:将自定义序列生成器注册为Spring Bean(优先推荐)
Hibernate 5.3及以上版本支持直接使用Spring容器中的Bean作为标识符生成器,直接启用Spring注入能力即可:
- 给
CustomSequenceGenerator添加@Component注解,交给Spring容器管理:
@Component public class CustomSequenceGenerator implements IdentifierGenerator, Configurable { // 原有@Value注解可以保留,会正常注入 @Value("${seq.prefix}") private String sequencePrefix; // 原有其他代码全部保留 ....... }
- 修改实体类的
@GenericGenerator注解,strategy属性填写Spring Bean的名称(默认是类名首字母小写,即customSequenceGenerator):
@Id @GenericGenerator(name = "user_id_gen", strategy = "customSequenceGenerator", parameters = { @org.hibernate.annotations.Parameter(name = "sequence_name", value = "USER_SEQ")} ) @GeneratedValue(generator = "user_id_gen") @Column(name = "UserId", unique = true, nullable = false, length = 6) private String userId;
- 低版本适配:如果Hibernate版本低于5.3,需要在
application.properties中添加如下配置,启用Spring的标识符生成器解析能力:
spring.jpa.hibernate.identifier_generator_strategy_provider=org.springframework.orm.jpa.hibernate.SpringBeanIdentifierGeneratorStrategyProvider
方案2:通过Spring上下文工具类静态获取配置
如果不希望修改原有生成器的注册逻辑,可以通过静态工具类主动获取Spring上下文的配置值:
- 新增Spring上下文持有工具类:
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringContextHolder implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextHolder.applicationContext = applicationContext; } // 静态获取配置参数 public static String getProperty(String configKey) { return applicationContext.getEnvironment().getProperty(configKey); } }
- 在
CustomSequenceGenerator的ID生成方法中主动拉取配置,注意不要在构造方法或configure方法中调用(此时Spring上下文可能未初始化完成):
public class CustomSequenceGenerator implements IdentifierGenerator, Configurable { // 删掉原有@Value注解 private String sequencePrefix; @Override public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException { // 首次生成ID时懒加载配置 if (sequencePrefix == null) { sequencePrefix = SpringContextHolder.getProperty("seq.prefix"); } // 原有ID生成逻辑,直接使用sequencePrefix即可 ....... } // 原有其他代码全部保留 }
内容的提问来源于stack exchange,提问作者Tony_Ynot
相关产品推荐
相关产品推荐

