Вы можете достичь желаемого с помощью hibernate custom basi c type , который реализует интерфейс DynamicParameterizedType
.
Ниже вы можете увидеть простой пример объявления пользовательского типа, который читает length
свойство аннотации @Column.
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;
}