簡體   English   中英

使用復合用戶類型的hql查詢生成的sql

[英]sql generated with hql query with composite user type

我正在使用休眠3.6.1,並且在hql生成的sql上我有一個奇怪的行為。

這是hql:

from Floor as floor where (floor.type != :var1)

type是一個復合用戶類型(請參閱底部),由兩個值long和一個int組成,並且如果兩個值中的至少一個不同,則Type與另一個Type不同。 我要提取類型與指定樓層不同的所有樓層,因此所有樓層都為floor.oid <> oi1或floor.number1 <> num1,其中oi1和number1來自指定的Type。 但是生成的sql有一個AND而不是OR:

select
    floor0_.id as id0_,
    floor0_.number as number0_,
    floor0_.oid as oid0_,
    floor0_.number1 as number4_0_ 
from
    Floor floor0_ 
where
    floor0_.oid<>? 
    and floor0_.number1<>?

我希望條件應該是

floor0_.oid<>? 
or floor0_.number1<>?

發言權實施:

public class Floor {
    private Long id;
    private Integer number;
    private Type type;


    public Type getType() {
        return type;
    }

    public void setType(Type type) {
        this.type = type;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }



    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }
}

類型實現:

public class Type implements CompositeUserType {
    private Long oid;
    public Long getOid() {
        return oid;
    }
    public void setOid(Long oid) {
        this.oid = oid;
    }
    private Integer number1;


    public Integer getNumber1() {
        return number1;
    }
    public void setNumber1(Integer number1) {
        this.number1 = number1;
    }


    @Override
    public String[] getPropertyNames() {
        String[] names = {"oid", "number1"};
        return names;
    }
    @Override
    public org.hibernate.type.Type[] getPropertyTypes() {
        BasicTypeRegistry registry = new BasicTypeRegistry();
        org.hibernate.type.Type longType = registry.getRegisteredType(LongType.INSTANCE.getRegistrationKeys()[0]);
        org.hibernate.type.Type intType = registry.getRegisteredType(IntegerType.INSTANCE.getRegistrationKeys()[0]);
        org.hibernate.type.Type[] types = { longType, intType };
        return types;
    }
    @Override
    public Object getPropertyValue(Object component, int property)
            throws HibernateException {
        if (component == null) return null;
        if (! (component instanceof Type)) {
            throw new HibernateException("wrong component type");
        }
        Type type = (Type) component;
        switch(property) {
        case 0:
            return type.oid;
        case 1: 
            return type.number1;
        default:
            throw new HibernateException("wrong component type");
        }
    }
    @Override
    public void setPropertyValue(Object component, int property, Object value)
            throws HibernateException {
        // boh!!!
        if (component == null) {
            throw new HibernateException("set property invoked on a null instance");
        }
        if (! (component instanceof Type)) {
            throw new HibernateException("set property invoked on a wrong component type");
        }
        Type type = (Type) component;
        String valueString = value.toString();
        switch(property) {
        case 0:
            type.oid  = Long.parseLong(valueString);
        case 1: 
            type.number1 = Integer.parseInt(valueString);
        default:
            throw new HibernateException("set property invoked on a wrong component type");
        }

    }
    @Override
    public Class returnedClass() {
        // TODO Auto-generated method stub
        return Type.class;
    }
    @Override
    public boolean equals(Object x, Object y) throws HibernateException {
        if(x == y) return true;
        if (x == null && y != null) return false;
        if (x != null && y == null) return false;
        if(! (x instanceof Type) || ! (y instanceof Type)) {
            return false;   
        }
        Type xt = (Type)x;
        Type yt = (Type)y;
        return (xt.oid == yt.oid && xt.number1 == yt.number1);
    }

    @Override
    public int hashCode(Object x) throws HibernateException {
        if (x == null) {
            return 0;
        } else {
            if (x instanceof Type) {
                Type xt = (Type) x;
                return xt.number1.hashCode() * 17 + xt.oid.hashCode();
            } else {
                throw new HibernateException("hashCode invoked on a non Type instance");
            }
        }
    }
    @Override
    public Object nullSafeGet(ResultSet rs, String[] names,
            SessionImplementor session, Object owner)
            throws HibernateException, SQLException {

        Type t = null;
        if (!rs.wasNull()){
            t = new Type();

            Long id = rs.getLong(names[0]);
            Integer number = rs.getInt(names[1]);

            t.oid = id;
            t.number1 = number;
        }
        return t;
    }
    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index,
            SessionImplementor session) throws HibernateException, SQLException {
        Type t = (Type) value;

        st.setLong(0, t.oid);
        st.setInt(1, t.number1);

    }

    @Override
    public Object deepCopy(Object value) throws HibernateException {
        if (value == null)
            return null;

        Type oldType = (Type) value;

        Type t = new Type();
        t.setOid(oldType.getOid());
        t.setNumber1(oldType.getNumber1());

        return t;
    }

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

    @Override
    public Serializable disassemble(Object value, SessionImplementor session)
            throws HibernateException {
        return value.toString();
    }

    @Override
    public Object assemble(Serializable cached, SessionImplementor session,
            Object owner) throws HibernateException {
        return cached;
    }
    @Override
    public Object replace(Object original, Object target,
            SessionImplementor session, Object owner) throws HibernateException {

        return original;
    }

}

我有什么問題嗎?

謝謝你的幫助

在Hibernate中肯定是一個錯誤,請隨時進行報告

作為解決方法,您可以使用Critera進行此查詢,因為它沒有此錯誤。

還要注意, CompositeUserType通常用於持久化另一個類,而不是同一個類,因此您對Type的實現可能會令人困惑,請參見6.4.3。 使用org.hibernate.usertype.CompositeUserType的自定義類型

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM