我正在使用hibernate 3.6.1,我对hql生成的sql有一个奇怪的行为。
这是hql:
from Floor as floor where (floor.type != :var1)
type是一个复合用户类型(参见bottom),如果两个值中的至少一个不同,则由long和int两个值组成,Type与另一个Type不同。 我想提取所有类型与指定类型不同的楼层,因此所有楼层都有floor.oid<> oi1 OR 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;
}
}
有什么我错的吗?
感谢您的帮助
答案 0 :(得分:0)
这肯定是Hibernate中的一个错误,请report it随意。
作为一种解决方法,您可以使用Critera进行此查询,但它没有此错误。
另请注意,CompositeUserType
通常用于保留其他类,而不是同一个类,因此Type
的实现可能会造成混淆,请参阅6.4.3. Custom types using org.hibernate.usertype.CompositeUserType。