0

mysql 5 でビットごとの AND (&) とビットごとの OR (|) を実行する関数を hibernate に登録しようとしています。

これまでのところ、カスタム mysql 方言があります。

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">com.***.hibernate.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
    <property name="packagesToScan">...</property>
</bean>

これが私のカスタム方言コードです:

public class MySQLDialect extends org.hibernate.dialect.MySQL5Dialect {
    public MySQLDialect() {
        super();
        registerFunction("bitwise_and", new BitwiseAndFunction("bitwise_and"));
    }
}

ここに私のカスタム関数があります:

public class BitwiseAndFunction extends StandardSQLFunction implements SQLFunction {

public BitwiseAndFunction(String name) {
    super(name);
}

public BitwiseAndFunction(String name, Type type) {
    super(name, type);
}

public String render(List args, SessionFactoryImplementor factory)
        throws QueryException {
    if (args.size() != 2) {
        throw new IllegalArgumentException(
                "the function must be passed 2 arguments");
    }
    StringBuffer buffer = new StringBuffer(args.get(0).toString());
    buffer.append(" & ").append(args.get(1));
    return buffer.toString();
}

}

問題は、HQL クエリで bitwise_and を使用するたびに、次で始まる長いスタック トレースが表示されることです。

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: bitwise_and near line 1, column 354 [select sqrt(pow(rideRequest.startLatitude - p.latitude, 2) + pow(rideRequest.startLongitude - p.longitude, 2)) as distance, p.polyLine.rideOffer as rideOffer, p.polyLine.rideOffer.user, p.polyLine.rideOffer.user.role from com.freeride.lib.domain.Point p, com.freeride.lib.domain.RideRequest rideRequest where rideRequest.id=? and (rideOffer.permissions bitwise_and rideRequest.permissions) = rideRequest.permissions group by p.polyLine.rideOffer order by distance asc]
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54)
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47)
at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:79)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:276)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:180)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:105)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
4

1 に答える 1

4

私は自分の解決策を見つけました。カスタム hql 関数を実行する古い方法は、Hibernate 3.6.0 で廃止されたため、最新バージョン (4.2.5) では次を使用する必要がありました。

import java.lang.Integer;
public class MyDialect extends org.hibernate.dialect.MySQL5Dialect {
    public MyDialect() {
        super();
        //THIS DOES NOT WORK!
        registerFunction("bitwise_andOne", new BitwiseAndFunction("poop"));
        //THIS WORKS!
        registerFunction("bitwise_andTwo", new SQLFunctionTemplate(IntegerType.INSTANCE, "(?1 & ?2)"));
    }
}

基本的に、2 番目の方法は機能しますが、前の方法は機能しません。どうしてか分かりません。

プログラムで任意の hql クエリで bitwise_and2 を呼び出すことができます。例えば:

sessionFactory.getCurrentSession.createQuery("select * from people person where bitwise_andTwo(person.permissions, 7)

結果のSQLは次のようになります

select * from people where people.permissions & 7 = パーミッション

これで問題が解決しました。

于 2013-09-17T18:16:41.567 に答える