oracle Hibernate 可以通过配置在读取/插入时自动大写一列吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2404285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can Hibernate automatically uppercase a column on read/insert via configuration?
提问by Tim Reddy
We have some columns with data that must always be in uppercase to ensure uniqueness. I was wondering if hibernate can force all such columns to uppercase via some configuration file change?
我们有一些列的数据必须始终为大写以确保唯一性。我想知道 hibernate 是否可以通过一些配置文件更改强制所有这些列大写?
We actually use a custom UserType for encrypting/decrypting column data for some other table, but I figured that would be overkill just to uppercase everything...
我们实际上使用自定义 UserType 来加密/解密某些其他表的列数据,但我认为仅将所有内容大写就太过分了......
Alternatively, I was thinking about modifying the models such that all getters/setters will uppercase any string coming and going.
或者,我正在考虑修改模型,以便所有 getter/setter 将大写任何来来往往的字符串。
The worst(?) case scenario is to modify the Oracle column constraint to ignore case while checking uniqueness.
最坏的(?)情况是修改 Oracle 列约束以在检查唯一性时忽略大小写。
Any thoughts?
有什么想法吗?
采纳答案by Tim Reddy
I decided to implement a UserType...it is as close to a hibernate configuration as I can get...here's the code...
我决定实现一个 UserType ......它尽可能接近休眠配置......这是代码......
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;
}
}
Consider this property element
考虑这个属性元素
<property name="serialNumber" type="model.UpperCaseUserType">
<column name="SERIAL_NUMBER" length="20" not-null="true" unique="true" />
</property>
So the reasoning...As hibernate inserts the data, this type will convert the string to uppercase. As hibernate selects data, the same thing happens. The advantage this class has over just changing the bean's get/set to uppercase everything is when I use a Criteria to select on serialNumber. Hibernate will also uppercase my parameter as it will cast/apply the same type as defined in the table configuration.
所以推理......当hibernate插入数据时,这种类型会将字符串转换为大写。当休眠选择数据时,也会发生同样的事情。这个类比仅仅将 bean 的 get/set 更改为大写的优势在于当我使用 Criteria 在 serialNumber 上进行选择时。Hibernate 还将大写我的参数,因为它将强制转换/应用与表配置中定义的相同类型。
Therefore, I don't need to remember to manually uppercase all of my search criteria for serial numbers...hibernate takes care of that for me...that's exactly what I'm trying to achieve here!
因此,我不需要记住手动将我所有的序列号搜索条件大写...hibernate 会为我处理这些...这正是我在这里想要实现的目标!
I have a JUnit that demonstrates all of this stuff, but I think my answer is way too big as it is...
我有一个 JUnit 来演示所有这些东西,但我认为我的答案太大了......
回答by StasKolodyuk
Much cleaner approach:
更干净的方法:
@Column(name = "DUMMY")
@ColumnTransformer(read = "UPPER(DUMMY)")
private String dummy
回答by Pascal Thivent
Several solutions:
几种解决方案:
- Use a database trigger (not via configuration though).
- Modify the getter/setters (not via configuration though).
- Use a
UserType
to convert the attribute to upper case. - Use an interceptoror an event listener.
Solution #1 is transparent for the code but I'm not a big fan of "behind your back" triggers and I don't like to spread business rules everywhere. Solution #3 and #4 are Hibernate dependent (but this might not be an issue though). Solution #2 is the easiest and most portable solution if you can change the code. That would be my choice if this is an option.
解决方案#1 对代码是透明的,但我不是“背后”触发器的忠实粉丝,我不喜欢到处传播业务规则。解决方案 #3 和 #4 依赖于 Hibernate(但这可能不是问题)。如果您可以更改代码,解决方案#2 是最简单、最便携的解决方案。如果这是一个选项,那将是我的选择。
回答by Péter T?r?k
I am not aware of any configuration settings to make this possible. However, you could try using an interceptorto fix the data upon insert / update, like:
我不知道有任何配置设置可以使这成为可能。但是,您可以尝试使用拦截器在插入/更新时修复数据,例如:
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);
}
}
回答by markthegrea
I suggest checking out this page: http://forum.springsource.org/archive/index.php/t-18214.html
我建议查看此页面:http: //forum.springsource.org/archive/index.php/t-18214.html
It has 3 different ways to do this. I believe the least intrusive way is this:
它有 3 种不同的方法来做到这一点。我相信干扰最少的方法是这样的:
<property name="upperCaseName" formula="upper(name)" lazy="true"/>