2017-01-24 6 views
4

CreditcardNumb.classに、クレジットカード番号が有効かどうかを確認するコンストラクタがあるとします。Criteria APIコール中にAttributeConverterを(ローカルで)バイパスまたは無効にする方法はありますか?

私は、データベース内の文字列にクレジットカード番号を変換するCreditcardNumbConverter.classを作成します。

public class CreditcardnumbConverter 
     implements AttributeConverter<CreditcardNumb, String> { 

    public String convertToDatabaseColumn(CreditcardNumb cn) { 
     if (cn== null) return null; 
     return cn.toString(); 
     } 

    public CreditcardNumb convertToEntityAttribute(String cn) { 
     if ((cn == null) || cn.trim().isEmpty()) return null; 
     return new CreditcardNumb(cn); 
     } 
    } 

これは[OK]を動作しますが、今私は(新しいか古いAPI HibernateのクライテリアAPIを使用したいです)「123」で始まるクレジットカード番号を検索するには:

CreditcardNumb cn = new CreditcardNumb("123"); 

createCriteria(Wallet.class) 
     .add(Restrictions.ilike("creditcard", cn, MatchMode.START)) 
     .list(); 

しかし、「123」は、有効なクレジットカード番号ではないので、オブジェクトのインスタンス化は失敗します。また、ilikeメソッドは、ではなく、Stringを受け付けるので、これはコンパイルされません。

私の質問:私はのような何かを行うことができるように

は、(ローカル)バイパスや変換を無効にするにはどの方法あります:

createCriteria(Wallet.class) 
     .disable(CreditcardnumbConverter.class)) 
     .add(Restrictions.ilike("creditcard", "123", MatchMode.START)) 
     .list(); 

するか、他の方法がありますCriteria API(HQLを使用しない)を使用して "123"で始まるクレジットカード番号を検索します。

@Entity 
public class Wallet { 

    private CreditcardNumb creditcard; 

    @Column(name = ..., insertable = false, updatable = false) 
    private String creditcardStr; 

    ... 
} 

キーポイントは、その値が(そうでない場合にHibernate永続化されないように、挿入可能でも更新可能でもないとして、この列をマップすることです:

+0

ない道を。あなたの検証について再考してください。個人的に私はコンストラクタ内部で検証を行うことを好まない。コンパイラは最初に何かをする前にコンストラクタを見ます。だからこそあなたは誤りを抱えている。 –

+1

コンストラクタの検証が嫌いですか?申し訳ありませんが、私は違法な状態で私のオブジェクトを持っているのが好きではありません。私は合法的なクレジットカード番号だけを持っていますが、Criteria APIを使って検索することができます。 – MarcG

答えて

2

あなたはStringタイプの別のプロパティでのクレジットカードの列をマップすることができcreditcardまたはcreditcardStrの値を使用して基になるデータベースの列を更新するかどうかはわかりません。

今、あなたのクエリは次のようになります。

createCriteria(Wallet.class) 
    .add(Restrictions.ilike("creditcardStr", "123", MatchMode.START)) 
    .list(); 
+0

うわー、非常に創造的な解決策。問題は、クラスに余分なフィールドがあり、他の過度の複雑さを加えて、AttributeConvertersの目的を破ってしまうことです。これが唯一の方法であれば、私はAttributeConvertersを使ってあきらめたり、Hibernateチームがこれを解決するのを待っている間、この答えを暫定的な解決策として使用します:https://hibernate.atlassian.net/browse/HHH-11415 – MarcG

+0

私はこの数日後に他に良いアイデアが現れなければこの回答を受け入れます。 – MarcG

+0

実際、トレードオフがあります。個人的には、属性コンバーターをまったく使用せずにStringとしてマップし、変換を行う 'CreditcardNumb'ゲッターとセッターを作成します。もちろん、すべてのクエリで文字列値をパラメータとして使用するように注意する必要があります。 –

関連する問題