2016-03-25 13 views
1

私は次のようになりますクラスがありますので、一方のエンティティが参照する、他にアソシエーションのエンティティの代わりにIDのみを取得するにはどうすればよいですか?

@Entity 
public class NodeInnovation { 
    @Id 
    public long id; 
    @OneToOne 
    public EdgeInnovation replacedEdge; 
} 

ので、各テーブルマップ:

@Entity 
public class EdgeInnovation { 
    @Id 
    public long id; 
    @ManyToOne 
    public NodeInnovation destination; 
    @ManyToOne 
    public NodeInnovation origin; 
} 

とこのようになります別のものをより多くのエンティティを参照する他のエンティティなど、最終的にデータベースからフェッチされる多くのエンティティが存在するようになります。キーの値(整数/ロング)のみを取得する方法はありますか、それが参照するエンティティは取得できませんか?このような何か:

@ManyToOne(referToThisTable="NodeInnovation") 
@Entity 
public class EdgeInnovation { 
    @Id 
    public long id; 
    @ManyToOne(referToTable="NodeInnovation") 
    public Long destination; 
    @ManyToOne(referToTable="NodeInnovation") 
    public Long origin; 
} 

@Entity 
public class NodeInnovation { 
    @Id 
    public long id; 
    @OneToOne(referToTable="EdgeInnovation") 
    public Long replacedEdge; 
} 

Here's an example.

は、ここでの例です。私は緑のものを欲しい、私はそれと一緒に赤ですべてのものを取得します。これは、メモリとディスクからの読み取り時間を無駄にします。

@Entity 
    public class NodeInnovation { 
     @Id 
     public long id; 
     @OneToMany(mappedBy="origin") 
     public List<EdgeInnovation> replacedEdges; 
    } 

私は状況を取得していた場合:

答えて

3

あなただけではなく、人間関係の基本的なマッピングなどの外部キーマッピングします:

@Entity 
public class EdgeInnovation { 
    @Id 
    public long id; 
    @Column(name="DESTINATION_ID") 
    public Long destination; 
    @Column(name="ORIGIN_ID") 
    public Long origin; 
} 

それとも、IDとEdgeInnovation内の参照先エンティティの両方にアクセスすることができますが、あなたはどれを決定する必要がありますがマッピングを設定するために使用する:

@Entity 
public class EdgeInnovation { 
    @Id 
    public long id; 
    @Column(name="DESTINATION_ID", updatable=false, insertable=false) 
    public Long destination_id; 
    @ManyToOne 
    public NodeInnovation destination; 
    @Column(name="ORIGIN_ID", updatable=false, insertable=false) 
    public Long origin_id; 
    @ManyToOne 
    public NodeInnovation origin; 
} 

上記の例では、origin_idは読み取り専用で原点基準をテーブルの外部キーを設定するために使用されます。両方のフィールドに変更を加えて、オブジェクトのマッピングを互いに同期させておく必要があります。

もう1つの方法は、プロバイダのネイティブコードを使用して参照が遅延し、トリガされていないかどうかを調べ、外部キー値を取得する方法です。トリガされている場合は、ID値を取得するために参照を使用することができます。なぜなら、クエリで何かを取得することはないからです。これは、EclipseLinkのソースコードを調べなければならないものです。

+0

私はあなたの2番目のオプションを働かせることができませんでしたので、私はちょうど最初の使用を終了しました。また、エンティティの更新に伴う問題も解決しました。 –

1

申し訳ありませんが、私はので、私は、私はそれが

@Entity 
public class EdgeInnovation { 
    @Id 
    public long id; 
    @ManyToOne 
    public NodeInnovation destination; 
    @ManyToOne 
    public NodeInnovation origin; 
} 

そして、他のクラスであるようにすべきだと思い、ここに をそれを置くコメントカント間違って申し訳ありません、(あなたが関係であなたのクラスを描くことができますので、私はそれをまっすぐにできますか?)

+0

いいえ、NodeInnovationのフィールド "replacedEdge"は、EdgeInnovationのフィールド "destination"と "origin"とは関係ありません。新しい行がNodeInnovationに挿入されると、 "replacesEdge"は古いEdgeInnovationを参照し、新しい行がEdgeInnovationに挿入されると、 "origin"と "destination"の両方が古いNodeInnovation行を参照します。 –

+0

[ERダイアグラム、接続の終わりにある看板で100%正しいとは思わないかもしれませんが、オプションの場合は必須です](https://drive.google.com/file/d/0B3jy9wMk6GxmM0huTmJYUmhkMHc/view?usp=sharing )eta:起点と目的地から目的地までの2つが間違った方向です。 –

+0

私はより明確にするために質問を編集しました。面倒な処方とダイアグラムをお詫び申し上げます。私はそれが現在午前3時であるという言い訳をするつもりだから、私は明日戻ってきます。 –

0

JPAでカスタムのコンストラクタiをnew construction n NodeInnovation

@Entity 
public class NodeInnovation { 
    @Id @GeneratedValue private Long id; 
    private Integer type; 
    @OneToOne 
    private EdgeInnovation replacedEdge; 
    @Transient 
    private Long replacedEdgeId; 
    public NodeInnovation() {} 
    public NodeInnovation(Long id, Integer type, Long replacedEdgeId) { 
     this.id = id; 
     this.type = type; 
     this.replacedEdgeId = replacedEdgeId; 
    } 
    ... 
} 

がそうのようにそれを使用してください:あなたは、直接か、NodeInnovationを選択したか

NodeInnovation n = em.createQuery("select new NodeInnovation(n.id, n.type, n.replacedEdge.id) from NodeInnovation n where n.id = 20", NodeInnovation.class).getSingleResult(); 

を言わなかっただけEdgeInnovation IDが必要な場合、基本的に使用するためにNodeInnovationで過渡特性を作成しますJPQLまたはCriteriaBuilderクエリのnew NodeInnovationです。

+0

これは私が欲しいもののように見える、私は私が追加した場合、私は、オブジェクトの魔女が理想的ではないが、仕事をしていませんアクセスするまで、彼らは「次のレベル」をロードしませんキーに「= FetchType.LAZYをフェッチする」ことが分かりました。そして、私は他の問題に移りましたが、今日や明日に戻ってきて、それがうまくいっているかどうかを伝え、そうであれば正しい答えを記入します。 –

+0

いいですね。 'replacedEdge'プロパティに' replacedEdge'を格納するには、 'new EdgeInnovation()'を実行してidを設定します。これはこのカスタムコンストラクタで行われます。これは、後続のクエリでこの 'NodeInnovation'を使用できるという利点があります。 –

関連する問題