[英]How to pass a parameter to the hibernate AttributeConverter
If I have a AttributeConverter
that changes the length of the input before persisting it in the database, what would be the correct way to make sure that the modified input doesn't exceed the maximum length allowed by that column (without hardcoding it in the converter) ?如果我有一个
AttributeConverter
在将其保存在数据库中之前更改输入的长度,那么确保修改后的输入不超过该列允许的最大长度的正确方法是什么(无需在转换器中对其进行硬编码) ?
@Column(length = 1024)
@Convert(converter = MyConverter.class)
private String comment;
public class MyConverter implements AttributeConverter<String, String> {
@Override
public String convertToDatabaseColumn(String attribute) {
return "hello world " + attribute;
}
...
}
You can achieve what you want with hibernate custom basic type that implements DynamicParameterizedType
interface.您可以使用实现
DynamicParameterizedType
接口的 hibernate 自定义基本类型来实现您想要的。
Below you can see a simple example of declaration custom type that read the length
property of @Column annotation.下面你可以看到一个简单的声明自定义类型的例子,它读取@Column 注释的
length
属性。
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
import java.util.Properties;
import javax.persistence.Column;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.DynamicParameterizedType;
import org.hibernate.usertype.UserType;
public class PersistableString implements UserType, DynamicParameterizedType
{
private int sqlType;
private int columnLength;
public PersistableString()
{
this.sqlType = Types.VARCHAR;
}
@Override
public void setParameterValues(Properties parameters)
{
ParameterType reader = (ParameterType) parameters.get(PARAMETER_TYPE);
this.columnLength = getLength(reader);
}
private int getLength(ParameterType reader)
{
int length = -1; // default length
for (Annotation annotation : reader.getAnnotationsMethod()){
if (annotation instanceof Column) {
length = ((Column) annotation).length();
}
}
return length;
}
@Override
public int[] sqlTypes()
{
return new int[] {sqlType};
}
@Override
public Class<?> returnedClass()
{
return String.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException
{
return Objects.equals(x, y);
}
@Override
public int hashCode(Object x) throws HibernateException
{
return Objects.hashCode(x);
}
/*
This method will be called when hibernate initializes your entity's
field from the appropriate database table row
*/
@Override
public Object nullSafeGet(ResultSet rs,
String[] names,
SharedSessionContractImplementor session,
Object owner) throws HibernateException, SQLException
{
// you can use this.columnLength here
return rs.getString(names[0]);
}
/*
This method will be called when hibernate persists your entity's field
to the appropriate database table row
*/
@Override
public void nullSafeSet(PreparedStatement st,
Object value,
int index,
SharedSessionContractImplementor session) throws HibernateException, SQLException
{
// you can use this.columnLength here
if (value == null) {
st.setNull(index, sqlType);
}
else {
String val = (String) value;
st.setString(index, val);
}
}
@Override
public Object deepCopy(Object value) throws HibernateException
{
return value;
}
@Override
public boolean isMutable()
{
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException
{
return Objects.toString(value);
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException
{
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException
{
return original;
}
}
and usage:和用法:
import org.hibernate.annotations.Type;
@Entity
@Table
public class Account
{
@Column(name = "acc_name", length = 50)
@Type(type = "com.example.hibernate.PersistableString")
private String name;
@Column(name = "acc_pass", length = 30)
@Type(type = "com.example.hibernate.PersistableString")
private String pass;
@Column(name = "acc_email", length = 355)
@Type(type = "com.example.hibernate.PersistableString")
private String email;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.