Tôi có một kiểu người dùng Hibernate được định nghĩa để chuyển đổi dữ liệu trước khi nó đi vào cơ sở dữ liệu của chúng tôi và sau đó bỏ chuyển đổi nó khi được đọc lại từ db. Điều này hoạt động tốt khi tôi chèn một hàng hoặc nhận hàng bằng cách sử dụng ID của hàng hoặc một số cách khác để truy vấn hàng. Tuy nhiên, khi tôi cố gắng sử dụng một truy vấn để tìm một kỷ lục, tham số ràng buộc dường như thất bại:Hibernate - Không thể thực hiện truy vấn bằng UserType trong mệnh đề where
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [thisIsTheSearchString] did not match expected type [com.xxx.MyUserType (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [thisIsTheSearchString] did not match expected type [com.xxx.MyUserType (n/a)]
tôi đã cố gắng thực hiện LiteralType
và objectToSQLString
phương pháp nhưng nó không giống như phương pháp này là bao giờ gọi.
Là một ví dụ đơn giản:
public class MyUserType implements UserType, LiteralType {
@Override
public int[] sqlTypes() {
return new int[] {
Types.VARCHAR
};
}
@Override
public Class returnedClass() {
return MyUserType.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return ObjectUtils.equals(x, y);
}
@Override
public int hashCode(Object x) throws HibernateException {
assert (x != null);
return x.hashCode();
}
@Override
public Object nullSafeGet(
ResultSet rs,
String[] names,
SessionImplementor session,
Object owner)
throws HibernateException, SQLException
{
assert names.length == 1;
return untransform(rs.getString(names[0]););
}
String transform(String untransformed) {
//...
}
String untransform(String transformed) {
//...
}
@Override
public void nullSafeSet(
PreparedStatement st,
Object value,
int index,
SessionImplementor session)
throws HibernateException, SQLException
{
if (value == null) {
st.setNull(index, Types.VARCHAR);
} else {
final String untransformed = (String)value;
return transform(untransformed);
}
}
@Override
public Object deepCopy(Object value) throws HibernateException {
if (value == null) {
return null;
}
return (String)value;
}
@Override
public boolean isMutable() {
return true;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) deepCopy(value);
}
@Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return deepCopy(cached);
}
@Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return deepCopy(original);
}
// THIS NEVER GETS CALLED
@Override
public String objectToSQLString(Object value, Dialect dialect)
throws Exception
{
if (value == null) {
return null;
}
String transformed = transform((String)value);
StringType stringType = new StringType();
String sqlString = stringType.objectToSQLString(transformed, dialect);
return sqlString;
}
}
Thực thể trông giống như:
@Entity
@Table(name = "blah_blah")
@TypeDefs(value = { @TypeDef(name = "transformedText", typeClass = MyUserType.class)})
public class BlahBlah implements Serializable, Persistable<Long> {
//...
@Column(name = "transformed")
@Type(type = "transformedText")
String transformed;
//...
}
truy vấn của tôi:
@Query(value =
"select b " +
"from BlahBlah b " +
"where b.transformed = ?1 ")
public List<BlahBlah> findTransformed(String text);
Trong truy vấn của bạn ("nơi b.transformed =? 1") sau dấu chấm hỏi bạn có 1, đó có phải là lỗi đánh máy trong thời điểm đăng câu hỏi này hay nó thực sự tồn tại trong mã của bạn không? :) – Bikku
Rin, rằng "? 1" là trong mã. Tôi tin rằng đó là chính xác - đó là cách thay thế tham số hoạt động. –