4.2.2. カスタムのブリッジ

Hibernate Search のビルトインブリッジが使用するプロパティタイプの一部に対応しなかったリ、 ブリッジにより使用される文字列表現が要件を満たさないことがります。以下のパラグラフはこの問題の複数のソリューションについて説明します。

4.2.2.1. StringBridge

もっともシンプルなカスタムのソリューションとして Hibernate Search に期待する Object String のブリッジの実装を提供します。これを行うには org.hibernate.search.bridge.StringBridge インターフェースを実装する必要があります。すべての実装は同時に使用されるためスレッドセーフである必要があります。

例4.14 独自の StringBridge の実装

/**
 * Padding Integer bridge.
 * All numbers will be padded with 0 to match 5 digits
 *
 * @author Emmanuel Bernard
 */
public class PaddedIntegerBridge implements StringBridge {

    private int PADDING = 5;

    public String objectToString(Object object) {
        String rawInteger = ( (Integer) object ).toString();
        if (rawInteger.length() > PADDING) 
            throw new IllegalArgumentException( "Try to pad on a number too big" );
        StringBuilder paddedInteger = new StringBuilder( );
        for ( int padIndex = rawInteger.length() ; padIndex < PADDING ; padIndex++ ) {
            paddedInteger.append('0');
        }
        return paddedInteger.append( rawInteger ).toString();
    }
}
すると、 いずれのプロパティまたはフィールドも @FieldBridge アノテーションによりこのブリッジを使用できるようになります。
@FieldBridge(impl = PaddedIntegerBridge.class)
private Integer length;
柔軟性を向上させるためにパラメータをそのブリッジ実装に渡すことができます。 ブリッジ実装は ParameterizedBridge インターフェースを実装し、 そのパラメータは @FieldBridge アノテーションで渡されます。

例4.15 ブリッジ実装にパラメータを渡す

public class PaddedIntegerBridge implements StringBridge, ParameterizedBridge {

    public static String PADDING_PROPERTY = "padding";
    private int padding = 5; //default

    public void setParameterValues(Map parameters) {
        Object padding = parameters.get( PADDING_PROPERTY );
        if (padding != null) this.padding = (Integer) padding;
    }

    public String objectToString(Object object) {
        String rawInteger = ( (Integer) object ).toString();
        if (rawInteger.length() > padding) 
            throw new IllegalArgumentException( "Try to pad on a number too big" );
        StringBuilder paddedInteger = new StringBuilder( );
        for ( int padIndex = rawInteger.length() ; padIndex < padding ; padIndex++ ) {
            paddedInteger.append('0');
        }
        return paddedInteger.append( rawInteger ).toString();
    }
}


//property
@FieldBridge(impl = PaddedIntegerBridge.class,
             params = @Parameter(name="padding", value="10")
            )
private Integer length;
ParameterizedBridge インターフェースは StringBridgeTwoWayStringBridgeFieldBridge の実装で実装可能です。
すべての実装はスレッドセーフである必要がありますが、パラメータは初期化時に設定されるため、この段階では特に気を付ける必要はありません。
id プロパティにブリッジ実装を使用する予定がある場合 (つまり @DocumentId アノテーションを付与)、 若干拡張した TwoWayStringBridge という名前の StringBridge バージョンを使用する必要があります。 Hibernate Search は識別子の文字列表現を読み取りそこからオブジェクトを生成する必要があります。 @FieldBridge アノテーションの使用方法に違いはありません。

例4.16 id プロパティなどに使用できる TwoWayStringBridge の実装

public class PaddedIntegerBridge implements TwoWayStringBridge, ParameterizedBridge {

    public static String PADDING_PROPERTY = "padding";
    private int padding = 5; //default

    public void setParameterValues(Map parameters) {
        Object padding = parameters.get( PADDING_PROPERTY );
        if (padding != null) this.padding = (Integer) padding;
    }

    public String objectToString(Object object) {
        String rawInteger = ( (Integer) object ).toString();
        if (rawInteger.length() > padding) 
            throw new IllegalArgumentException( "Try to pad on a number too big" );
        StringBuilder paddedInteger = new StringBuilder( );
        for ( int padIndex = rawInteger.length() ; padIndex < padding ; padIndex++ ) {
            paddedInteger.append('0');
        }
        return paddedInteger.append( rawInteger ).toString();
    }

    public Object stringToObject(String stringValue) {
        return new Integer(stringValue);
    }
}


//id property
@DocumentId
@FieldBridge(impl = PaddedIntegerBridge.class,
             params = @Parameter(name="padding", value="10") 
private Integer id;
2 方向プロセスがべき等となることが非常に重要です (つまり、 object = stringToObject( objectToString( object ) ) )。