spring-data-jpa 如何在JPQL Where子句中使用@ElementCollectionMap中的值

nwwlzxa7  于 2022-11-10  发布在  Spring
关注(0)|答案(1)|浏览(123)

我有一个带有Map<String,String>字段的实体,该字段是@ElementCollection。我想选择其Map字段值与某种模式匹配的实体。但是,我在运行时遇到错误,在本例中,是H2数据库。
下面是实体:

@Entity
@Table(name = "config")
public class Config {

    private String id;

    private String name;

    @ElementCollection
    @CollectionTable(name = "setting",
            joinColumns = @JoinColumn(name = "config_id", referencedColumnName = "id"))
    @MapKeyColumn(name = "name", columnDefinition = "varchar(1024)")
    @Column(name = "value", columnDefinition = "TEXT")
    Map<String, String> settings;

}

然后,在我的JPA存储库中,我有一个方法,它可以获取具有与给定前缀匹配的设置的配置:

@Query("select config.id, config.name from Config config " +
        "join config.settings setting " +
        "where value(setting) like concat(:prefix, '%')")
List<List<String>> findConfigBySettingPrefix(@Param("prefix") String prefix);

这将产生来自H2的错误:
引起的原因:org.h2.jdbc.JdbcSQL数据异常:标量子查询包含多行;
JPQL生成的SQL显示value()函数被扩展为子选择:

select config."id", config."name" from "config" config 
inner join "setting" setting on config."id"=setting."config_id" 
where (select setting."value" from "setting" setting where config."id"=setting."config_id") like (?||'%')

因此,当有多个匹配的设置(如预期的那样)时,这会产生一个错误,因为它们被传递到一个期望一个值的操作符中。

select config."id", config."name" from "config" config
inner join "setting" setting on config."id"=setting."config_id"
where setting."value" like (?||'%')

看起来我不能使用value()作为where条件,或者我只是没有正确地使用它。有没有更好的方法来实现这一点?我尝试过类似的变体,它们都在启动时编译,但它们在运行时产生同样的错误:

@Query("select config.id, config.name from Config config " +
        "join config.settings setting on value(setting) like concat(:prefix, '%')")

@Query("select config.id, config.name from Config config " +
        "where value(config.settings) like concat(:prefix, '%')")
pjngdqdw

pjngdqdw1#

这并没有准确地回答这个问题,但是它是使用JPQL的一种替代方法。

public interface ConfigRepository extends JpaRepository<Config, String> {
    List<Config> findAllBySettingsStartingWith(String prefix);
}

相关问题