简体   繁体   English

如何将参数传递给休眠的 AttributeConverter

[英]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.

相关问题 如何传入休眠配置参数 - how to pass in parameter of hibernate config 如何在Hibernate-Mapping XML(HBM 4.3)中使用JPA AttributeConverter? - How to use JPA AttributeConverter with Hibernate-Mapping XML (HBM 4.3)? 如何在没有 AttributeConverter 或 customUserType 的情况下使用 Hibernate 5.2.10 MySQL JSON 支持映射到 Java 实体类? - How to use Hibernate 5.2.10 MySQL JSON support without AttributeConverter or customUserType to map to Java Entity Class? 如果在JOIN中使用自定义查询,则Hibernate AttributeConverter会失败 - Hibernate AttributeConverter fails if using custom query with JOIN Hibernate Envers 因@Converter 和 AttributeConverter (JPA 2.1) 而失败 - Hibernate Envers fails with @Converter and AttributeConverter (JPA 2.1) Hibernate / SpringData:使用AttributeConverter对字段进行不正确的脏检查 - Hibernate/SpringData : Incorrect dirty check on field with AttributeConverter 如何在Hibernate createSQLQuery()中传递多个参数? - How do I pass more than one parameter in Hibernate createSQLQuery()? 如何使用休眠将数组作为参数传递给postgress函数? - How to pass array as a parameter to postgress function using hibernate? JPA / Hibernate:在复杂类上使用AttributeConverter时创建UserType是否明显? - JPA/Hibernate: is it obvious to create UserType when using AttributeConverter on complex class? Springboot 1.4 /单元测试错误(休眠AttributeConverter多次注册) - Springboot 1.4 / error on unit test (hibernate AttributeConverter registered multiple times)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM