2010-03-08 12 views
6

Tenemos algunas columnas con datos que siempre deben estar en mayúsculas para garantizar la exclusividad. Me preguntaba si hibernate puede forzar todas esas columnas a mayúsculas a través de algún cambio en el archivo de configuración.¿Puede Hibernate automáticamente mayúscula una columna en lectura/inserción a través de la configuración?

realmente usamos un UserType personalizado para cifrar/descifrar datos de la columna por alguna otra mesa, pero pensé que sería una exageración simplemente a mayúsculas todo ...

Alternativamente, estaba pensando acerca de cómo modificar los modelos de tal manera que todos los getters/setters en mayúsculas cualquier cadena que va y viene.

El peor de los casos (?) Es modificar la restricción de columna de Oracle para ignorar el caso mientras se comprueba la exclusividad.

¿Alguna idea?

Respuesta

1

que decidió implementar un UserType ... es lo más cercano a una configuración de hibernación como puedo conseguir ... aquí está el código ...

package model; 

import java.io.Serializable; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Types; 

import org.apache.commons.lang.builder.EqualsBuilder; 
import org.apache.commons.lang.builder.HashCodeBuilder; 
import org.hibernate.Hibernate; 
import org.hibernate.HibernateException; 
import org.hibernate.usertype.UserType; 

public class UpperCaseUserType implements UserType { 
    private static final int[] TYPES = {Types.VARCHAR}; 

public int[] sqlTypes() { 
     return TYPES; 
} 

public Class returnedClass() { 
     return String.class; 
} 

public boolean equals(Object x, Object y) throws HibernateException { 
     if (x == y) { 
      return true; 
     } 
     if (null == x || null == y) { 
      return false; 
     } 
     return new EqualsBuilder().append(x, y).isEquals(); 
} 

public int hashCode(Object o) throws HibernateException { 
     return new HashCodeBuilder().append(o).toHashCode(); 
} 

public Object nullSafeGet(ResultSet resultSet, String[] strings, Object object) throws HibernateException, SQLException { 
     return ((String) Hibernate.STRING.nullSafeGet(resultSet, strings[0])).toUpperCase(); 
} 

public void nullSafeSet(PreparedStatement preparedStatement, Object object, int i) throws HibernateException, SQLException { 
     String string = ((String) object).toUpperCase(); 
     Hibernate.STRING.nullSafeSet(preparedStatement, string, i); 
} 

public Object deepCopy(Object o) throws HibernateException { 
     if (null == o) { 
      return null; 
     } 
     return new String(o.toString()); 
} 

public boolean isMutable() { 
     return false; 
} 

public Serializable disassemble(Object o) throws HibernateException { 
     return (String) o; 
} 

public Object assemble(Serializable serializable, Object o) throws HibernateException { 
     return serializable; 
} 

public Object replace(Object o, Object arg1, Object arg2) throws HibernateException { 
     return o; 
} 
} 

consideran este elemento de propiedad

<property name="serialNumber" type="model.UpperCaseUserType"> 
    <column name="SERIAL_NUMBER" length="20" not-null="true" unique="true" /> 
</property> 

El razonamiento ... Como hibernación inserta los datos, este tipo convertirá la cadena en mayúsculas. Cuando hibernate selecciona datos, sucede lo mismo. La ventaja que tiene esta clase sobre simplemente cambiar el get/set del bean a mayúsculas es cuando uso un Criteria para seleccionar serialNumber. Hibernate también mayúsculas de mi parámetro, ya que emitirá/aplicará el mismo tipo como se define en la configuración de la tabla.

Por lo tanto, no necesito recordar manualmente mayúsculas todos mis criterios de búsqueda para números de serie ... hibernate se encarga de eso para mí ... ¡eso es exactamente lo que estoy tratando de lograr aquí!

Tengo un JUnit que demuestra todas estas cosas, pero creo que mi respuesta es demasiado grande, ya que es ...

1

No conozco ninguna configuración de configuración para que esto sea posible. Sin embargo, se podría tratar de usar un interceptor para fijar los datos en insert/update, como:

package interceptor; 

import java.io.Serializable; 

import org.hibernate.EmptyInterceptor; 
import org.hibernate.type.Type; 

public class CustomSaveInterceptor extends EmptyInterceptor { 
    public boolean onSave(Object entity, 
     Serializable id, 
     Object[] state, 
     String[] propertyNames, 
     Type[] types) 
    { 
     if (entity instanceof MyClass) { 
      MyClass myInstance = (MyClass)entity; 
      myInstance.setName(myInstance.getName().toUpperCase()); 
     } 
     return super.onSave(entity, id, state, propertyNames, types); 
    } 
} 
+0

tengo un interceptor que contiene otra "cosas" en las que puedo dejar caer tu idea ... pero no veo escribir mucha lógica para la docena de clases que necesitan que algunos de sus campos estén en mayúsculas. –

0

Yo sugiero revisar esta página: http://forum.springsource.org/archive/index.php/t-18214.html

Dispone de 3 maneras diferentes de hacer esto. Creo que la manera menos intrusiva es la siguiente:

<property name="upperCaseName" formula="upper(name)" lazy="true"/> 
+1

Puedo estar equivocado, pero no creo que el truco de la fórmula funcione para insertar o actualizar (creo que Hibernate trata los campos fomula como transitorios y no los guarda en la base de datos). –

3

varias soluciones:

  1. utilizar un trigger (no a través de la configuración sin embargo).
  2. Modificar el getter/setters (aunque no a través de la configuración).
  3. Utilice UserType para convertir el atributo a mayúsculas.
  4. Utilice interceptor o event listener.

La solución n. ° 1 es transparente para el código, pero no soy una gran admiradora de los activadores "detrás de su espalda" y no me gusta extender las reglas comerciales en todas partes. Las soluciones n. ° 3 y n. ° 4 dependen de Hibernate (aunque esto podría no ser un problema). La solución n. ° 2 es la solución más fácil y portátil si puede cambiar el código. Esa sería mi elección si esta es una opción.

+0

Me estaba inclinando también hacia el # 2, pero estaba buscando una configuración de hibernación que "simplemente funcionara" ... –

+0

@T Reddy Nada parecido a eso AFAIK. –

2

Mucho más limpio enfoque:

@Column(name = "DUMMY") 
@ColumnTransformer(read = "UPPER(DUMMY)") 
private String dummy 
Cuestiones relacionadas