代码之家  ›  专栏  ›  技术社区  ›  Tim Reddy

是否可以通过配置在读取/插入时自动休眠大写列?

  •  8
  • Tim Reddy  · 技术社区  · 16 年前

    我们有一些列的数据必须总是大写,以确保唯一性。我想知道hibernate是否可以通过一些配置文件的更改来强制所有这些列为大写?

    或者,我正在考虑修改模型,以便所有getter/setter都将任何字符串的大小写为大写。

    最坏的情况是在检查唯一性时修改Oracle列约束以忽略大小写。

    有什么想法吗?

    5 回复  |  直到 16 年前
        1
  •  11
  •   StasKolodyuk    10 年前

    更干净的方法:

    @Column(name = "DUMMY")
    @ColumnTransformer(read = "UPPER(DUMMY)")
    private String dummy
    
        2
  •  4
  •   Pascal Thivent    16 年前

    1. 使用数据库触发器(但不是通过配置)。
    2. 修改getter/setter(但不是通过配置)。
    3. UserType 将属性转换为大写。
    4. interceptor 或者一个 event listener

        3
  •  1
  •   Péter Török    16 年前

    我不知道任何配置设置,使这成为可能。但是,您可以尝试使用 interceptor 在插入/更新时修复数据,如:

    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);
        }
    }
    
        4
  •  1
  •   Tim Reddy    16 年前

    我决定实现一个用户类型…它是尽可能接近一个hibernate配置我可以得到…这里的代码。。。

    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;
    }
    }
    

    考虑这个属性元素

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

    所以推理…当hibernate插入数据时,这个类型将把字符串转换成大写。当hibernate选择数据时,同样的事情也会发生。与将bean的get/set改为大写相比,这个类的优势在于我使用条件来选择serialNumber。Hibernate还会将我的参数大写,因为它将强制转换/应用表配置中定义的相同类型。

    因此,我不需要记住手动大写所有序列号的搜索条件…hibernate为我处理这些…这正是我在这里要实现的!

        5
  •  0
  •   markthegrea    16 年前

    我建议查看以下页面: http://forum.springsource.org/archive/index.php/t-18214.html

    它有3种不同的方法来实现这一点。我认为最不具侵入性的方式是:

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