2017年4月21日 星期五

自定義Hibernate Type

原始問題:
某個老舊的table設定,其中一個欄位設char(10)
結果裡面的值有長有短,不足10碼的就自動補空白
導致在後端處理的時候處理很麻煩

當然最簡單的方式是改DB欄位設定
但總不是如人所願
所以只好針對Hibernate轉Bean的時候下手

先談失敗的改法:
我修改Hibernate塞Bean的時候一定要透過set方法 (找不到怎麼設的了QQ)
然後我在set方法中寫trim的動作
承原始問題,那些char設定很多都用在Primary Key
最後用Bean Update資料的時候就爆炸了
Exception在Hibernate這邊,還沒到DB
Exception的大意是Bean的Id被改過 (很久以前,也懶得還原當時情況了)

後來就改為現在這邊要介紹的方法

先自定義Hibernate Type
  1. public class CustomerTrimStringType implements UserType{
  2.  
  3. private int sqlType(){
  4. return Types.VARCHAR;
  5. }
  6.  
  7. @Override
  8. public Object assemble(Serializable arg0, Object arg1) throws HibernateException {
  9. return null;
  10. }
  11.  
  12. @Override
  13. public Object deepCopy(Object value) throws HibernateException {
  14. return value;
  15. }
  16.  
  17. @Override
  18. public Serializable disassemble(Object arg0) throws HibernateException {
  19. return null;
  20. }
  21.  
  22. @Override
  23. public boolean equals(Object value1, Object value2) throws HibernateException {
  24. if (value1 == null) {
  25. if (value2 != null) {
  26. return false;
  27. }
  28. return true;
  29. }
  30.  
  31. return value1.equals(value2);
  32. }
  33.  
  34. @Override
  35. public int hashCode(Object value) throws HibernateException {
  36. return value == null ? 0 : value.hashCode();
  37. }
  38.  
  39. @Override
  40. public boolean isMutable() {
  41. return false;
  42. }
  43.  
  44. @Override
  45. public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
  46. throws HibernateException, SQLException
  47. {
  48. Object value = rs.getString(names[0]);
  49. if ((value == null) || (rs.wasNull())){
  50. return null;
  51. }
  52.  
  53. return value.toString().trim();
  54. }
  55.  
  56. @Override
  57. public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor arg3)
  58. throws HibernateException, SQLException
  59. {
  60. if(value == null){
  61. st.setNull(index, sqlType());
  62. }else{
  63. st.setString(index, (String)value);
  64. }
  65. }
  66.  
  67. @Override
  68. public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {
  69. return null;
  70. }
  71.  
  72. @Override
  73. public Class returnedClass() {
  74. return String.class;
  75. }
  76.  
  77. @Override
  78. public int[] sqlTypes() {
  79. return new int[]{ Types.VARCHAR };
  80. }
  81. }

在45行nullSafeGet這個方法做修改
另外,沒意外的話nullSafeSet這個方法是Hibernate -> DB的動作

設定Hibernate Bean的欄位要使用自定義的Type
  1. public class TableBean {
  2.  
  3. private String column1;
  4.  
  5. @Column(name = "column1")
  6. @Type(type="packageName.CustomerTrimStringType")
  7. public String getColumn1() {
  8. return this.Column1;
  9. }
  10.  
  11. public void setColumn1(String column1){
  12. this.column1 = column1;
  13. }
  14. }

沒有留言:

張貼留言