is possible call microsoft sql server's freetext function on column_list using jpa criteriabuilder?
the sql server's freetext function can called natively on either single column, or list of columns: https://docs.microsoft.com/en-us/sql/t-sql/queries/freetext-transact-sql
i can call freetext on single column after finding this: https://stackoverflow.com/a/18534291/6659983
when try call freetext on multiple columns, can't find way hibernate put brackets around column_list when call freetext.
i overrode paramaterizedfunctionexpression.renderarguments()
, managed generated hql (or intermediate sort of ql) looked this:
select generatedalias0 package.model.entity generatedalias0 inner join generatedalias0.categories generatedalias1 inner join generatedalias1.unspsc generatedalias2 inner join generatedalias0.buyer generatedalias3 inner join generatedalias0.otherentity generatedalias4 ( function('freetext', ( generatedalias0.title, generatedalias0.description, generatedalias0.code, generatedalias3.name, generatedalias3.legalname, generatedalias2.title ) , :param0) ) , ( generatedalias0.state=:param1 ) , ( generatedalias0.state<>:param2 ) , ( generatedalias0.state<>:param3 ) , ( generatedalias0.state<>:param4 ) order generatedalias0.closingdate asc]
and got error:
java.lang.illegalargumentexception: org.hibernate.hql.internal.ast.querysyntaxexception: unexpected ast node: function (freetext) near line 1, column 319 [select generatedalias0 package.model.entity generatedalias0 inner join generatedalias0.categories generatedalias1 inner join generatedalias1.unspsc generatedalias2 inner join generatedalias0.buyer generatedalias3 inner join generatedalias0.entityboxes generatedalias4 ( function('freetext', ( generatedalias0.title, generatedalias0.description, generatedalias0.code, generatedalias3.name, generatedalias3.legalname, generatedalias2.title ) , :param0) ) , ( generatedalias0.state=:param1 ) , ( generatedalias0.state<>:param2 ) , ( generatedalias0.state<>:param3 ) , ( generatedalias0.state<>:param4 ) order generatedalias0.closingdate asc] @ org.hibernate.internal.exceptionconverterimpl.convert(exceptionconverterimpl.java:131) @ org.hibernate.internal.exceptionconverterimpl.convert(exceptionconverterimpl.java:155) @ org.hibernate.internal.exceptionconverterimpl.convert(exceptionconverterimpl.java:162) @ org.hibernate.internal.abstractsharedsessioncontract.createquery(abstractsharedsessioncontract.java:663) @ org.hibernate.internal.sessionimpl.createquery(sessionimpl.java:3318) @ org.hibernate.query.criteria.internal.criteriaqueryimpl$1.buildcompiledquery(criteriaqueryimpl.java:318) @ org.hibernate.query.criteria.internal.compile.criteriacompiler.compile(criteriacompiler.java:127) @ org.hibernate.internal.sessionimpl.createquery(sessionimpl.java:3611) @ org.hibernate.internal.sessionimpl.createquery(sessionimpl.java:203) @ package.entity.dao.entitydaoimpl.search(entitydaoimpl.java:241)
here effort extend parameterizedfunctionexpression:
/** * overrides {@link parameterizedfunctionexpression.renderarguments()} function * freetext search can created properly. */ private class freetextexpression extends parameterizedfunctionexpression<boolean> implements predicate { /** * eclipse generated uid. */ private static final long serialversionuid = -1219262363097942038l; private list<expression<?>> argumentexpressions; /** * constructs 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 arguments except first within brackets in order define mssql 'column_list'. */ @override protected void renderarguments(stringbuilder buffer, renderingcontext renderingcontext) { string sep = ""; buffer.append(" ( "); (int = 0; < argumentexpressions.size() - 1 ; ++) { 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; } }
here how use it:
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);
oops, realised need register function this, freetext:
registerfunction("contains", new sqlfunctiontemplate(standardbasictypes.boolean, "contains(?1, ?2) , 1"));
hibernate + mssql + fulltext search via contains sqlfunctiontemplate
will post code once i've worked out, unless can beat me it!
Say, you got a nice article post.Really thank you! Really Great.
ReplyDeleteazure training
java training
salesforce training