6

私はハイバネートマッピングされたJavaオブジェクトである​​を持っています。これは通常のハイバネートマッピング可能なフィールド(文字列や整数など)がいっぱいです。FunctionalJavaオプションのマッピング<Type>とHibernate

asdffj.data.Option<ASDF>という新しい埋め込みフィールドが追加されました(同じテーブルにあり、マッピングではありません)。私は、このフィールドに実際に何も含まれていないことを明らかにするオプションを作っています(それにアクセスするたびにnullを処理する必要がありません)。

JKL.hbm.xmlファイルにマッピングを設定するにはどうすればよいですか?私は自動的にnullnonefj.data.Option<ASDF>に変換するために休止状態にしたいと思います。 ASDFのヌル以外のインスタンスをsomefj.data.Option<ASDF>に変換する必要があります。私がしなければならない他のトリッキーはありますか?ありがとうございました。

答えて

12

アクセサー(ゲッターとセッター)にFunctionalJavaのOptionを導入することをお勧めします。一方、Hibernateはnullであることが許されている単純なJavaフィールドを処理するままにしておきます。

例えば、オプションのIntegerフィールドのために:

// SQL 
CREATE TABLE `JKL` (
    `JKL_ID` INTEGER PRIMARY KEY, 
    `MY_FIELD` INTEGER DEFAULT NULL 
) 

あなたが直接休止プライベートフィールドをマップすることができます。

// Java 
@Column(nullable = true) 
private Integer myField; 

あなたはその後、アクセサ境界でOptionを導入できます。

// Java 
public fj.data.Option<Integer> getMyField() { 
    return fj.data.Option.fromNull(myField); 
} 

public void setMyField(fj.data.Option<Integer> value) { 
    myField = value.toNull(); 
} 

あなたのニーズに適していますか?

2

Hibernateのカスタムマッピングタイプを使用できます。ドキュメントはhereです。以下は、Hibernateマッピングに対するmapping Scala's Optionの類似した例です。

簡単に言えば、org.hibernate.UserTypeインターフェイスを拡張する必要があります。また、Scalaの例に似ている​​タイプのサブタイプを持つジェネリック型ベース・クラスを作成することもできます。

0

私はgetter/setterを使用して簡単ですが、ここで私はそれを動作させるためにやったことの一例だと思う:

(それは数や文字列のではなく、日付@Temporal注釈付き(エラー)のために正常に動作します)。

import com.cestpasdur.helpers.PredicateHelper; 
import com.google.common.annotations.VisibleForTesting; 
import com.google.common.base.Optional; 
import org.apache.commons.lang.ObjectUtils; 
import org.apache.commons.lang.StringUtils; 
import org.hibernate.HibernateException; 
import org.hibernate.usertype.UserType; 
import org.joda.time.DateTime; 

import java.io.Serializable; 
import java.sql.*; 

public class OptionUserType implements UserType { 


@Override 
public int[] sqlTypes() { 
    return new int[]{ 
      Types.NULL 
    }; 
} 

@Override 
public Class returnedClass() { 
    return Optional.class; 
} 

@Override 
public boolean equals(Object o, Object o2) throws HibernateException { 
    return ObjectUtils.equals(o, o2); 

} 

@Override 
public int hashCode(Object o) throws HibernateException { 
    assert (o != null); 
    return o.hashCode(); 
} 

@Override 
public Optional<? extends Object> nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException { 
    return Optional.fromNullable(rs.getObject(names[0])); 
} 

@VisibleForTesting 
void handleDate(PreparedStatement st, Date value, int index) throws SQLException { 
    st.setDate(index, value); 
} 

@VisibleForTesting 
void handleNumber(PreparedStatement st, String stringValue, int index) throws SQLException { 
    Double doubleValue = Double.valueOf(stringValue); 
    st.setDouble(index, doubleValue); 
} 

@Override 
public void nullSafeSet(PreparedStatement st, Object value, int index) throws SQLException { 

    if (value != null) { 
     if (value instanceof Optional) { 
      Optional optionalValue = (Optional) value; 
      if (optionalValue.isPresent()) { 
       String stringValue = String.valueOf(optionalValue.get()); 


       if (StringUtils.isNotBlank(stringValue)) { 

        if (PredicateHelper.IS_DATE_PREDICATE.apply(stringValue)) { 
         handleDate(st, new Date(DateTime.parse(stringValue).getMillis()), index); 
        } else if (StringUtils.isNumeric(stringValue)) { 
         handleNumber(st, stringValue, index); 
        } else { 
         st.setString(index, optionalValue.get().toString()); 
        } 
       } else { 
        st.setString(index, null); 
       } 


      } else { 
       System.out.println("else Some"); 
      } 

     } else { 
      //TODO replace with Preconditions guava 
      throw new IllegalArgumentException(value + " is not implemented"); 

     } 
    } else { 
     st.setString(index, null); 

    } 


} 

@Override 
public Object deepCopy(Object o) throws HibernateException { 
    return o; 
} 

@Override 
public boolean isMutable() { 
    return false; 
} 

@Override 
public Serializable disassemble(Object o) throws HibernateException { 
    return (Serializable) o; 
} 

@Override 
public Object assemble(Serializable serializable, Object o) throws HibernateException { 
    return serializable; 
} 

@Override 
public Object replace(Object original, Object target, Object owner) throws HibernateException { 
    return original; 
} 
} 
関連する問題