[英]How to pass a parameter to the hibernate AttributeConverter
如果我有一個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;
}
...
}
您可以使用實現DynamicParameterizedType
接口的 hibernate 自定義基本類型來實現您想要的。
下面你可以看到一個簡單的聲明自定義類型的例子,它讀取@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;
}
}
和用法:
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.