Java 如何将参数传递给hibernate AttributeConverter

Java 如何将参数传递给hibernate AttributeConverter,java,hibernate,Java,Hibernate,如果我有一个AttributeConverter,它在将输入持久化到数据库之前更改了输入的长度,那么有什么正确的方法来确保修改后的输入不超过该列允许的最大长度(不在转换器中硬编码) @列(长度=1024) @转换(converter=MyConverter.class) 私有字符串注释; 公共类MyConverter实现AttributeConverter{ @凌驾 公共字符串convertToDatabaseColumn(字符串属性){ 返回“hello world”+属性; } ... }

如果我有一个
AttributeConverter
,它在将输入持久化到数据库之前更改了输入的长度,那么有什么正确的方法来确保修改后的输入不超过该列允许的最大长度(不在转换器中硬编码)

@列(长度=1024)
@转换(converter=MyConverter.class)
私有字符串注释;
公共类MyConverter实现AttributeConverter{
@凌驾
公共字符串convertToDatabaseColumn(字符串属性){
返回“hello world”+属性;
}
...
}

您可以通过实现
动态参数化类型
接口的hibernate实现您想要的功能

下面您可以看到一个简单的声明自定义类型示例,它读取@Column注释的
length
属性

import java.io.Serializable;
导入java.lang.annotation.annotation;
导入java.sql.PreparedStatement;
导入java.sql.ResultSet;
导入java.sql.SQLException;
导入java.sql.Types;
导入java.util.Objects;
导入java.util.Properties;
导入javax.persistence.Column;
导入org.hibernate.hibernateeexception;
导入org.hibernate.engine.spi.SharedSessionCompactmentor;
导入org.hibernate.usertype.DynamicParameterizedType;
导入org.hibernate.usertype.usertype;
公共类PersistableString实现UserType、DynamicParameterizedType
{
私有int-sqlType;
私有int列长度;
公共持久化字符串()
{
this.sqlType=Types.VARCHAR;
}
@凌驾
公共void setParameterValues(属性参数)
{
ParameterType读取器=(ParameterType)parameters.get(参数类型);
this.columnLength=getLength(读卡器);
}
私有int getLength(参数类型读取器)
{
int length=-1;//默认长度
对于(注释:reader.getAnnotationsMethod()){
if(列的注释实例){
长度=((列)注释).length();
}
}
返回长度;
}
@凌驾
公共int[]sqlTypes()
{
返回新的int[]{sqlType};
}
@凌驾
公共类returnedClass()
{
返回字符串.class;
}
@凌驾
公共布尔等于(对象x,对象y)抛出HibernateException
{
返回对象。等于(x,y);
}
@凌驾
public int hashCode(对象x)抛出HibernateeException
{
返回Objects.hashCode(x);
}
/*
当hibernate初始化实体的
相应数据库表行中的字段
*/
@凌驾
公共对象nullSafeGet(结果集rs,
字符串[]名称,
SharedSession顾问会议,
对象所有者)抛出HibernateeException、SQLException
{
//你可以在这里使用这个.columnLength
返回rs.getString(名称[0]);
}
/*
当hibernate持久化实体的字段时,将调用此方法
到相应的数据库表行
*/
@凌驾
公共无效nullSafeSet(已编制报表st,
对象值,
整数索引,
SharedSessionCompactCompleteMentor会话)引发HibernateException、SQLException
{
//你可以在这里使用这个.columnLength
如果(值==null){
st.setNull(索引,sqlType);
}
否则{
字符串val=(字符串)值;
st.setString(索引,val);
}
}
@凌驾
公共对象deepCopy(对象值)引发HibernateException
{
返回值;
}
@凌驾
公共布尔可交换()
{
返回false;
}
@凌驾
公共可序列化反汇编(对象值)引发HibernateException
{
返回Objects.toString(值);
}
@凌驾
公共对象汇编(可序列化缓存,对象所有者)引发HibernateException
{
返回缓存;
}
@凌驾
公共对象替换(对象原始、对象目标、对象所有者)引发HibernateException
{
归还原件;
}
}
使用方法:

import org.hibernate.annotations.Type;
@实体
@桌子
公共类帐户
{
@列(name=“acc_name”,长度=50)
@类型(Type=“com.example.hibernate.PersistableString”)
私有字符串名称;
@列(name=“acc_pass”,长度=30)
@类型(Type=“com.example.hibernate.PersistableString”)
私人串通;
@列(name=“acc_email”,长度=355)
@类型(Type=“com.example.hibernate.PersistableString”)
私人字符串电子邮件;
}

Hibernate不会自动检查转换结果的长度吗?我想这是我的问题。我假设这取决于我是放置
@Length
还是
@size
还是
@Column(Length)
。所以您需要一个转换器,它可以为
@Length
@size
@Column(Length)设置的任何长度工作
在任何
字符串
实体列上?基本上,我希望一切都像没有转换器一样运行。当没有转换器时:*我可以通过注释轻松设置列的长度(我不知道正确的注释是什么)*如果试图持久化的字符串的长度大于列的大小,则存在一个有意义的异常。但是,转换器会更改输入长度,我怀疑(可能取决于注释)检查是在转换器发生之前进行的。当扩展字符串的长度超过列长度时,需要什么行为?好的,谢谢。如果注释是@Length或@Size呢?@BobJI我完全重写了我的答案。它似乎不支持您想要的功能。但是你可以通过使用hibernate自定义基本类型来实现它。是否没有其他方法确保要持久化的内容不超过列长度?不幸的是,我不知道这种方法。