2017-01-31 4 views
12

私は別のエンティティを所有するエンティティ持っている:私はにClassAのオブジェクトを取得する場合他のエンティティが所有するJPAエンティティのサブセットをどのように送り返しますか?

//psuedocode  
public class ClassA{ 
    private String name; 

    @OneToOne 
    private ClassB classb; 
} 

public class ClassB{ 
    private String thing1; 
    private String thing2; 
    private String thing3; 
} 

を、私はClassB.thing3を見たいと思っていませんが、私はthing1と実物2見たいん:

{ 
"name":"classa", 
"classb":{ 
     "thing1":"hi", 
     "thing2":"there" 
     } 
} 

しかし、私はClassBのために照会する場合、私はすべてを見たい:その後、私はセコにそれを無視しますので、だから私はただ、thing3上無視注釈を入れることができません

{"thing1":"hi", 
"thing2":"there", 
"thing3":"joseph"} 

をフェッチする。私はConverter<ClassB>を試しましたが、これはJSONオブジェクトをJava側に変換する際に(JSONの場合はコンバーターがStringを要求しますが、オブジェクトを取得します)、終了するようにtoString()fromString()を実装する必要があります。

可能であれば、jsonプロバイダが可能な限り仕事をすることを可能にするために、JSONオブジェクトの構築/解析を避けたいと考えています。私はジョンソンにいる。

+1

jsonプロバイダとは何ですか?ジャクソンはあなたが望むことができるが、その非標準的なことをすることができるJsonのビューをサポートしています。例:http://www.baeldung.com/jackson-json-view-annotation – Gimby

答えて

1

これは、あなたが@NamedEntityGraphを使用する必要があることが可能であり、

これは役立つはず、http://www.thoughts-on-java.org/jpa-21-entity-graph-part-1-named-entity/

+0

答えとして受け入れるためには、一般的なチュートリアルを指すだけでなく、OPケースの実装を少なくとも記述する必要があると思います。 – Deltharis

+0

ありがとうございます! @Deltharis – zillani

+0

[JPA 2.1](http://download.oracle.com/otndocs/jcp/persistence-2_1-fr-eval-spec/index)のため、@ NamedEntityGraphがここに行く方法であるかどうかは不明です。 html)Specを使用すると、プロバイダは適切なデータを取得できるため、ClassBの保証はありません。thing3はロードされません。エンティティグラフにないからです:_フェーズグラフまたはロードグラフで指定されたエンティティ状態を超えて、永続性プロバイダが追加のエンティティ状態をフェッチすることが許可されています。ただし、持続性プロバイダは、フェッチまたはロードグラフで指定されたすべての状態をフェッチする必要があります._ – tom

1

このような何かがSELECT NEWを使用して照会することによって可能なはずですが、あなたはいくつかの新しいクラスが必要になるだろうあなたのエンティティを直接JSONに渡すことはありません。

新しいクラス: (擬似コード)

class ResultB { 
    String thing1; 
    String thing2; 

    public ResultB(ClassB classB) { 
     this.thing1 = classB.thing1; 
     this.thing2 = classB.thing2; 
    } 
} 

class ResultA { 
    String name; 
    ResultB resultB; 

    public ResultA(ClassA classA) { 
     this.name=classA.name; 
     this.resultB=new ResultB(classA); 
    } 
} 

問合せ:

select new ResultA(a) from ClassA a fetch join a.classB; 

その後、あなたはJSONにResultAの代わりにClassAを渡すことができます。

PS:上記のコメントで述べたように、私はNamedEntityGraphsがここ

+0

これは一つの解決策かもしれませんが、私のJsonプロバイダにResultAを渡すのではなく、ClassAとClassBに変換して、私のチームのフロントエンドへのインターフェイスが同じになるようにしたいと思います。これは、不要なフィールドを取得するためのリソースを使う必要がないという利点がありますが、私たちのチームを走らなければならない "特殊なデータアクセスクラスが必要"ということがあります。データ転送およびアクセスクラスとしてのエンティティ。 – GuitarStrum

+0

ええ、はい、元のクラスに戻すことができますが、それらのクラスは、(nullable)フィールドを消去している可能性があるため、返されたときに「そのまま」永続化されないよう注意する必要があります(ifフィールドはNULL可能ではありません)。 – tom

1

を移動するための方法とは思わない、私は常にデータベースからすべてのデータをフェッチし、フィルタリングはJSONプロバイダによって行われるように聞かせとにかくそれを直列化したい場合。あなたはジャクソンを使用している場合、あなたは単にあなたのフィールドにビューを追加することができます。

public class ClassA { 

    @JsonView(Views.AlwaysInclude.class) 
    private String name; 

    @JsonView(Views.AlwaysInclude.class) 
    @OneToOne 
    private ClassB classb; 
} 

public class ClassB { 
    @JsonView(Views.AlwaysInclude.class) 
    private String thing1; 

    @JsonView(Views.AlwaysInclude.class) 
    private String thing2; 

    private String thing3; 
} 

public class Views { 
    public static class AlwaysInclude { 
    } 
} 

を後で、あなたは自分のビューを使用する必要があなたのオブジェクトをシリアル化するとき:あなたはあなただけClassBのをシリアル化したい

String result = mapper 
    .writerWithView(Views.AlwaysInclude.class) 
    .writeValueAsString(new ClassA()); 

ビューを使用すべきではありません。

String result = mapper.writeValueAsString(new ClassB()); 
+0

ジャクソンを使用していませんが、ありがとうございます。 "私はいつもデータベースからすべてのデータをフェッチして、JSONプロバイダがフィルタリングを行うようにします"というコメントについては、同様のルートに入り、ClassAをフェッチするときにClassBから不要なフィールドをnullにすることができます。そのアプローチの欠点は、私がまだ必要としないデータを取り込むリソースを費やしているということですが、裏側に私のプロバイダが正しいjsonを構築できるようにすることができます。 – GuitarStrum

関連する問題