In einigen Legacy-Code, mit denen ich arbeite, habe ich ein Hibernate-Modell mit einem UserType-Attribut, um einen Boolean mit Ganzzahlen für die Indizierung darzustellen. Außerdem speichert es 'false' als null für die Oracle-Optimierung.Abfrage im Ruhezustand mit UserType Spalte macht keine Konvertierung mit nullSafeSet
/**
* Data type for a boolean value stored in a NUMBER oracle column. 1 evaluates
* to true, null evaluates to false.
*
* This is designed for oracle indexing, since null values are not indexed.
*
*
*/
public class BooleanUserType implements UserType {
private static final int[] SQL_TYPES = { Types.INTEGER };
public int[] sqlTypes() {
return SQL_TYPES;
}
public Class<?> returnedClass() {
return Boolean.class;
}
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
Boolean result = false;
resultSet.getInt(names[0]);
if (!resultSet.wasNull()) {
result = true;
}
return result;
}
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException {
Boolean input = (Boolean) value;
if (input == null || input == false) {
preparedStatement.setNull(index, Types.INTEGER);
} else {
preparedStatement.setInt(index, 1);
}
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public boolean isMutable() {
return false;
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y)
return true;
if (null == x || null == y)
return false;
return x.equals(y);
}
Dieser BooleanUserType als eine Spalte für dieses (bearbeitet) Modell:
public class CustomString implements Serializable{
private static final long serialVersionUID = -5311205585865001342L;
@Id
@Column(name="custom_string_id")
private Long id;
@Column(name="text")
private String text;
@Column(name="active")
@Type(type="my.org.BooleanUserType") // store false as 'null' -- an Oracle optimization
private Boolean active;
(...)
zu this StackOverflow reply Nach
nullSafeSet aufgerufen wird, sowohl wenn das Unternehmen gespeichert/aktualisiert wird und wenn Abfrageparameter gesetzt werden muss
Dies ist jedoch nicht das Verhalten, das ich beobachte, als wenn ich für dieses Modell mit einem Boolean für die active
Spalte abfragen, wird die Konvertierung nicht vorgenommen und ich bekomme nicht die erwarteten Ergebnisse.
Ich habe ein Custom Objekt auf der DB gespeichert:
new CustomString(1, "text", Boolean.FALSE);
ich die Abfrage machen, die nicht wie ich erwarten würde funktioniert:
Criteria c = session.createCriteria(CustomString.class);
c.add(Restrictions.eq("active", Boolean.FALSE));
c.list() // No results!
Wenn ich diese stattdessen tun, es funktioniert:
Criteria c = session.createCriteria(CustomString.class);
c.add(Restrictions.isNull("active"));
c.list() // Expected result!
Speichern auch das Objekt mit Boolean.TRUE
statt FALSE
, und dann für TRUE
Abfrage, funktioniert gut.
Ich habe einige Debug-Protokollzeilen in meiner nullSafeSet
-Methode hinzugefügt, und ich kann überprüfen, dass es nicht aufgerufen wird, wenn die Abfrage erstellt wird.
Sollte nullSafeSet
eigentlich von Hibernate aufgerufen werden und irgendwie nicht wie erwartet funktionieren, oder fehlt mir da etwas und ich sollte es anders angehen?
Was ist mit einem benutzerdefinierten Typ stattdessen? http://learningviacode.blogspot.ie/2011/09/creating-hibernate-custom-type-2.html – mendez8
Ich habe keine großen Hoffnungen dafür, aber Sie können dies überprüfen: http: // stackoverflow .com/questions/29145693/benutzerdefiniert-Prädikat-to-handle-custom-user-defined-types-hibernate-usertype –