Sql server 使用hibernate CriteriaBuilder在“列列表”上进行自由文本搜索

Sql server 使用hibernate CriteriaBuilder在“列列表”上进行自由文本搜索,sql-server,hibernate,jpa,Sql Server,Hibernate,Jpa,是否可以使用jpa CriteriaBuilder在列列表上调用Microsoft SQL Server的FREETEXT函数 SQL Server的FREETEXT函数可以在单个列或列列表上本机调用: 找到以下内容后,我可以在单个列上调用FREETEXT: 当我尝试在多个列上调用FREETEXT时,我找不到一种方法让hibernate在调用FREETEXT时在该列列表周围加上括号 我重写了ParamaterizedFunctionExpression.renderaguments,最终获得

是否可以使用jpa CriteriaBuilder在列列表上调用Microsoft SQL Server的FREETEXT函数

SQL Server的FREETEXT函数可以在单个列或列列表上本机调用:

找到以下内容后,我可以在单个列上调用FREETEXT:

当我尝试在多个列上调用FREETEXT时,我找不到一种方法让hibernate在调用FREETEXT时在该列列表周围加上括号

我重写了ParamaterizedFunctionExpression.renderaguments,最终获得了生成的HQL或某种中间类型的QL,如下所示:

select 
    generatedAlias0 
from 
    package.model.entity as generatedAlias0 
    inner join generatedAlias0.categories as generatedAlias1 
    inner join generatedAlias1.unspsc as generatedAlias2 
    inner join generatedAlias0.buyer as generatedAlias3 
    inner join generatedAlias0.otherEntity as generatedAlias4 
where 
    ( function('FREETEXT',  ( generatedAlias0.title, generatedAlias0.description, generatedAlias0.code, generatedAlias3.name, generatedAlias3.legalName, generatedAlias2.title ) , :param0) ) and ( generatedAlias0.state=:param1 ) 
    and ( generatedAlias0.state<>:param2 ) 
    and ( generatedAlias0.state<>:param3 ) 
    and ( generatedAlias0.state<>:param4 ) 
order by 
    generatedAlias0.closingDate asc]
我得到了这个错误:

    java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: function (FREETEXT) near line 1, column 319 [select generatedAlias0 from package.model.Entity as generatedAlias0 inner join generatedAlias0.categories as generatedAlias1 inner join generatedAlias1.unspsc as generatedAlias2 inner join generatedAlias0.buyer as generatedAlias3 inner join generatedAlias0.entityBoxes as generatedAlias4 where ( function('FREETEXT', ( generatedAlias0.title, generatedAlias0.description, generatedAlias0.code, generatedAlias3.name, generatedAlias3.legalName, generatedAlias2.title ) , :param0) ) and ( generatedAlias0.state=:param1 ) and ( generatedAlias0.state<>:param2 ) and ( generatedAlias0.state<>:param3 ) and ( generatedAlias0.state<>:param4 ) order by generatedAlias0.closingDate asc]
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:131)
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:162)
        at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:663)
        at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3318)
        at org.hibernate.query.criteria.internal.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:318)
        at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:127)
        at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3611)
        at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:203)
        at package.entity.dao.EntityDaoImpl.search(EntityDaoImpl.java:241)
以下是我扩展ParameterizedFunctionExpression的努力:

/**
     * Overrides the {@link ParameterizedFunctionExpression.renderArguments()} function
     * so that the FREETEXT search can be created properly.
     */
    private class FreeTextExpression extends ParameterizedFunctionExpression<Boolean> implements Predicate {

        /**
         * Eclipse Generated UID.
         */
        private static final long serialVersionUID = -1219262363097942038L;

        private List<Expression<?>> argumentExpressions;

        /**
         * Constructs a FreeTextExpression
         * @param criteriaBuilder
         * @param returnType
         * @param functionName
         * @param argumentExpressions
         */
        public FreeTextExpression(
                CriteriaBuilderImpl criteriaBuilder,
                String functionName,
                List<Expression<?>> argumentExpressions) {
            super( criteriaBuilder, (Class<Boolean>) Boolean.class , functionName , argumentExpressions);
            this.argumentExpressions = argumentExpressions;
        }

        /**
         * Places all arguments except the first within brackets in order to define a MSSQL 'column_list'.
         */
        @Override
        protected void renderArguments(StringBuilder buffer, RenderingContext renderingContext) {
            String sep = "";
            buffer.append(" ( ");
            for (int i = 0; i < argumentExpressions.size() - 1 ; i ++) {
                buffer.append( sep ).append( ( (Renderable) argumentExpressions.get(i) ).render( renderingContext ) );
                sep = ", ";
            }
            buffer.append(" ) ");
            buffer.append( sep ).append( ( (Renderable) argumentExpressions.get(argumentExpressions.size() - 1) ).render( renderingContext ) );
        }

        @Override
        public BooleanOperator getOperator() {
            return Predicate.BooleanOperator.AND;
        }

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

        @Override
        public List<Expression<Boolean>> getExpressions() {
            return Arrays.asList(this);
        }

        @Override
        public Predicate not() {
            return null;
        }
    }
以下是我如何使用它:

    List<Expression<?>> arguments = Arrays.asList(
                    entity.<String>get(Entity_.title),
                    entity.<String>get(Entity_.description),
                    entity.<String>get(Entity_.code),
                    buyer.<String>get(Business_.name),
                    buyer.<String>get(Business_.legalName),
                    unspsc.<String>get(Unspsc_.title),
                    (Expression<String>) keywords
            );

            Expression<Boolean> freeTextExpression = new FreeTextExpression(
                    (CriteriaBuilderImpl) builder, "FREETEXT", arguments);
            criteria.add((Predicate) freeTextExpression);
请试试这个:

select 
    generatedAlias0 
from 
    package.model.entity as generatedAlias0 
    inner join generatedAlias0.categories as generatedAlias1 
    inner join generatedAlias1.unspsc as generatedAlias2 
    inner join generatedAlias0.buyer as generatedAlias3 
    inner join generatedAlias0.otherEntity as generatedAlias4 
where 
    FREETEXT( generatedAlias0,@param0) ) and ( generatedAlias0,@param1 ) 
    and ( generatedAlias0.state<>:param2 ) 
    and ( generatedAlias0.state<>:param3 ) 
    and ( generatedAlias0.state<>:param4 ) 
order by 
    generatedAlias0.closingDate asc]

哎呀,我意识到我需要注册这样的函数,但对于FREETEXT:

registerFunction("CONTAINS", new SQLFunctionTemplate(StandardBasicTypes.BOOLEAN, "CONTAINS(?1, ?2) AND 1"));

一旦我算出了,我会发布代码的,除非有人能打败我

你能解释一下这是怎么回答这个问题的吗?代码是值得欣赏的,但没有解释,它只是一个代码转储。