16

MongoDB に Spring-Data を使用しています。

バージョン情報 - org.mongodb.mongo-java-driver バージョン 2.10.1、org.springframework.data.spring-data-mongodb バージョン 1.2.1.RELEASE。

hereで定義されているものに似たケースがあります(フォーマットが申し訳ありません...):

spring-data-mongodb を使用して Java でアプリの開発を開始したところ、解決できない問題に遭遇しました。

次のようなドキュメント Bean がいくつかあります。

@Document(collection="myBeanBar")
public class BarImpl implements Bar {
    String id;
    Foo foo;
    // More fields and methods ... 
}

@Document
public class FooImpl implements Foo {
    String id;
    String someField;
    // some more fields and methods ...
} 

そして、次のような検索を呼び出すだけのメソッドを持つリポジトリ クラスがあります。

public List<? extends Bar> findByFooField(final String fieldValue) {
    Query query = Query.query(Criteria.where("foo.someField").is(fieldValue));
    return getMongoOperations().find(query, BarImpl.class);
} 

Bar の保存は問題なく機能します。Foo と Bar の両方の「_class」属性とともに mongo に保存されます。ただし、Foo の属性で検索すると、次のような例外がスローされます。

Exception in thread "main" java.lang.IllegalArgumentException: No
property someField found on test.Foo!
    at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:225)
    at org.springframework.data.mongodb.core.convert.QueryMapper.getPath(QueryMapper.java:202)
    at org.springframework.data.mongodb.core.convert.QueryMapper.getTargetProperty(QueryMapper.java:190)
    at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedObject(QueryMapper.java:86)
    at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1336)
    at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1322)
    at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:495)
    at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:486)

与えられた解決策は、抽象クラスで @TypeAlias アノテーションを使用することでした。これにより、フレームワークに特定の実装 (この場合はFooImpl ) を使用するように指示されました。

私の場合、抽象メンバーの代わりにインターフェイスメンバーがあります。

@Document(collection="myBeanBar")
public class BarImpl implements Bar {
    String id;
    IFoo foo;
    // More fields and methods ...
}

デフォルトの実装を提供するインターフェイスIFooに注釈を付けることには非常に消極的です。代わりに、@JsonTypeInfoのように、実装するBarImplクラスのコンテキストでこのフィールドのデフォルトの実装をフレームワークに伝えたいと思います。

@Document(collection="myBeanBar") 
public class BarImpl implements Bar {
    String id;    

    @JsonTypeInfo(use = Id.CLASS, defaultImpl = FooImpl.class)
    IFoo foo; 

    // More fields and methods ... 
}

this answerを見つけました。多かれ少なかれ、インターフェースの使用を避けるように言っています。しかし、より良い選択肢がないかどうかを教えていただければ幸いです。

何か案は?

ありがとう!

4

3 に答える 3

0

インターフェイスをデータ オブジェクトのフィールドとして定義するのは、非常に悪い考えです。

インターフェイスとは、何らかのオブジェクトが何かを実行できる可能性を意味しますが、フィールドに関する情報は提供しません。本当にインターフェイスを使用する必要がありますか? これを回避できますか?抽象クラス定義を使用しても、より良いアイデアになります。

PSもちろん、私の答えはいずれにしても正解としてマークすることはできません。

于 2014-08-01T16:15:10.293 に答える