簡體   English   中英

如何將參數傳遞給休眠的 AttributeConverter

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM