Spring Data @Query注入application.yml属性失败,遇EL1008E错误求解决
解决Spring Data JPA @Query中注入application.yml属性的EL1008E错误
嘿,这个问题我之前帮人解决过不少——你碰到的EL1008E错误,核心原因是Spring Data JPA的@Query默认的SpEL上下文里,并没有直接暴露你application.yml中的env属性,而principal能直接用是因为Spring Security特意把它集成到了SpEL上下文里。咱们得手动把自定义配置属性加到这个上下文里才行,给你两种靠谱的解决办法:
方法一:通过自定义Bean持有配置属性(简单直接)
首先,创建一个专门的Bean来持有你需要的配置属性,让Spring把yml里的值注入进来:
@Component("configProps") // 给Bean起个名字,方便SpEL引用 public class ConfigPropertiesHolder { // 这里的${env}要和你application.yml里的属性键完全对应,比如yml里是env: dev就写${env},嵌套的话比如app.env就写${app.env} @Value("${env}") private String env; // 提供getter方法,SpEL会自动识别属性名对应getter public String getEnv() { return env; } }
然后修改你的Repository方法,在SpEL表达式里通过@Bean名.属性名的方式引用这个属性:
public interface MyRepository extends JpaRepository<MyEntity, Long> { @Query("select e from MyEntity e where e.foo = :foo and e.env = ?#{@configProps.env}") MyEntity findByFoo(@Param("foo") String foo); }
这里的@configProps就是引用咱们刚才创建的Bean,env对应它的getter方法,这样SpEL就能找到正确的属性值了。
方法二:扩展SpEL上下文(更优雅,类似principal的用法)
如果你想和principal一样直接在SpEL里用env或者自定义前缀,可以通过EvaluationContextExtension来扩展SpEL上下文:
@Component public class ConfigEvaluationContextExtension implements EvaluationContextExtension { @Value("${env}") private String env; @Override public String getExtensionId() { return "config"; // 这个ID是你在SpEL里要用到的前缀 } @Override public Map<String, Object> getProperties() { Map<String, Object> props = new HashMap<>(); props.put("env", env); // 把属性加入上下文,key就是你要在SpEL里用的名称 return props; } }
之后你的Repository方法就可以像用principal一样直接写:
public interface MyRepository extends JpaRepository<MyEntity, Long> { @Query("select e from MyEntity e where e.foo = :foo and e.env = ?#{config.env}") MyEntity findByFoo(@Param("foo") String foo); }
这种方式把配置属性直接集成到了SpEL上下文里,用法更简洁,和Spring Security提供principal的逻辑一致。
注意事项
- 确保你的application.yml属性键和
@Value里的完全匹配,比如yml里写的是app.environment: prod,那@Value就要写${app.environment}。 - 确认这些自定义Bean所在的包被Spring的组件扫描覆盖到了,不然Spring找不到它们,依然会报错。
- 可以先在Holder类里加个日志打印
env值,确认配置属性已经被正确注入,排除是属性没读到的问题。
内容的提问来源于stack exchange,提问作者saimonsez
相关产品推荐
相关产品推荐

