Java 带有参数和单引号的自定义HQL函数

Java 带有参数和单引号的自定义HQL函数,java,spring,spring-boot,jpa,hql,Java,Spring,Spring Boot,Jpa,Hql,我正试图在hibernate中编写一个自定义函数来使用ts_vector(postgres),目前为止我的代码是: public class PostgresSQLFTSFunction implements SQLFunction { static final Logger LOG = LogManager.getLogger(); @Override public boolean hasArguments() { return true;

我正试图在hibernate中编写一个自定义函数来使用ts_vector(postgres),目前为止我的代码是:

public class PostgresSQLFTSFunction implements SQLFunction {

    static final Logger LOG = LogManager.getLogger();

    @Override
    public boolean hasArguments() {
        return true;
    }

    @Override
    public boolean hasParenthesesIfNoArguments() {
        return false;
    }

    @Override
    public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException {
        return new BooleanType();
    }

    @Override
    public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor factory) throws QueryException {
        if (arguments == null || arguments.size() < 2) {
            throw new IllegalArgumentException("The function must have at least 2 arguments");
        }

        String fragment, ftsConfig, field, value;

        if (arguments.size() == 3) {
            ftsConfig = (String) arguments.get(0);
            field = (String) arguments.get(1);
            value  = (String) arguments.get(2);
            fragment = "to_tsvector(" + ftsConfig + ", unaccent(" + field + ")) @@ to_tsquery(" + ftsConfig + ", unaccent(" + value + "))";
        } else {
            field = (String) arguments.get(0);
            value = (String) arguments.get(1);
            fragment = "to_tsvector(unaccent(" + field + ")) @@ " + "to_tsquery('" + value + ":*' )";
        }

        LOG.info(fragment);

        return fragment;
    }
}
Hibernate生成的输出查询是:

select city0_.id as id1_0_, city0_.created_at as created_2_0_, city0_.updated_at as updated_3_0_, city0_.version as version4_0_, city0_.lat as lat5_0_, city0_.lng as lng6_0_, city0_.name as name7_0_, city0_.state_id as state_id8_0_ from cities city0_ where to_tsvector(unaccent(city0_.name)) @@ to_tsquery('?:*' )=true
这里的问题是
to_tsquery('?:*')
不会将问号转换为命名参数(cityName),因为它包含在单引号中,但此处的单引号是必需的,否则查询将无法工作

例如,有效的查询是:

select city0_.id as id1_0_, city0_.created_at as created_2_0_, city0_.updated_at as updated_3_0_, city0_.version as version4_0_, city0_.lat as lat5_0_, city0_.lng as lng6_0_, city0_.name as name7_0_, city0_.state_id as state_id8_0_ from cities city0_ where to_tsvector(unaccent(city0_.name)) @@ to_tsquery('vi:*')=true;
因此,在上面的示例中,
cityName
问号应该由HQL翻译为“vi”。 我怎样才能做到这一点


谢谢

您是否使用扩展方言中的registerFunction注册了您的函数?我没有,我采用了另一种MetadataBuilderContributor方法。我刚刚用这个片段编辑了这个问题,谢谢!顺便说一句,函数正在被调用,问题是?被解释为文字,而不是变量,因为它在引号中。您是否使用扩展方言中的registerFunction注册了您的函数?我没有,我采用了其他MetadataBuilderContributor方法。我刚刚用这个片段编辑了这个问题,谢谢!顺便说一句,函数正在被调用,问题是?被解释为文字,而不是变量,因为它位于引号内。
select city0_.id as id1_0_, city0_.created_at as created_2_0_, city0_.updated_at as updated_3_0_, city0_.version as version4_0_, city0_.lat as lat5_0_, city0_.lng as lng6_0_, city0_.name as name7_0_, city0_.state_id as state_id8_0_ from cities city0_ where to_tsvector(unaccent(city0_.name)) @@ to_tsquery('?:*' )=true
select city0_.id as id1_0_, city0_.created_at as created_2_0_, city0_.updated_at as updated_3_0_, city0_.version as version4_0_, city0_.lat as lat5_0_, city0_.lng as lng6_0_, city0_.name as name7_0_, city0_.state_id as state_id8_0_ from cities city0_ where to_tsvector(unaccent(city0_.name)) @@ to_tsquery('vi:*')=true;