我们有一些数据列必须始终为大写以确保唯一性。我想知道hibernate是否可以通过一些配置文件更改强制所有这些列为大写?
我们实际上使用自定义UserType来加密/解密其他一些表的列数据,但我认为仅仅为了大写所有内容都是过度的...
或者,我正在考虑修改模型,以便所有getter / setter都将大写任何来来往往的字符串。
最糟糕的(?)情况是修改Oracle列约束以在检查唯一性时忽略大小写。
有什么想法吗?
答案 0 :(得分:6)
更清洁的方法:
@Column(name = "DUMMY")
@ColumnTransformer(read = "UPPER(DUMMY)")
private String dummy
答案 1 :(得分:3)
几种解决方案:
UserType
将属性转换为大写。解决方案#1对于代码是透明的,但我不是“背后”触发器的忠实粉丝,我不喜欢在任何地方传播业务规则。解决方案#3和#4依赖于Hibernate(但这可能不是问题)。如果您可以更改代码,解决方案#2是最简单,最便携的解决方案。如果这是一个选项,那将是我的选择。
答案 2 :(得分:1)
我不知道有任何配置设置可以实现这一点。但是,您可以尝试使用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);
}
}
答案 3 :(得分:1)
我决定实现一个UserType ...它尽可能接近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选择数据时,会发生同样的事情。这个类的优点就是当我使用Criteria在serialNumber上选择时,只需将bean的get / set更改为大写。 Hibernate也将使我的参数大写,因为它将转换/应用表配置中定义的相同类型。
因此,我不需要记住手动大写我的序列号的所有搜索条件... hibernate为我照顾...这正是我想要在这里实现的!
我有一个演示所有这些内容的JUnit,但我认为我的回答太大了......
答案 4 :(得分:0)
我建议您查看此页面:http://forum.springsource.org/archive/index.php/t-18214.html
它有3种不同的方法可以做到这一点。我认为最不具侵入性的方式是:
<property name="upperCaseName" formula="upper(name)" lazy="true"/>