2017-10-20 16 views
2

この質問は私が公式化するのは非常に難しいです。明確化が必要な場合はお気軽にお問い合わせください。組込みクラスと双方向関係

状況:私はHibernateを使用してデータベース内の異なるエンティティクラスを保持するSpringアプリケーションを持っています。これらのクラスを呼び出す簡略化のためにE1, E2, .., E20。これらのクラスはすべて同じ抽象@MappedSuperclassに基づいていますが、実際の継承はありません(データベース側)。

今、私は新しいエンティティクラス(En1, En2, ...)を追加し、いくつかの既存のエンティティとの双方向関係を確立したいと思います。 En1E1,E2,E3とrealtionであると仮定すると、私のコードは次のようになります。

@Entity 
public class E1 extends SuperClass { 
    //other attributes 

    @OneToMany(mappedBy = "e1") 
    List<En1> newAttribut; 

    public En1 doMagic(En1 entity) { 
    //a long function which does somthing with the entity 
    } 

    //other attribute 
} 

//-----------------------------// 
// The same code for E2 and E3 // 
//-----------------------------// 

@Entity 
public class En1 { 
    //other attributes 

    @ManyToOne 
    E1 e1; 

    @ManyToOne 
    E2 e2; 

    @ManyToOne 
    E3 e3; 

    //other attributes 
} 

問題:このソリューションは十分ではないスケール。私は各関係のクラスEn1に属性を必要とし、それぞれの既存のエンティティにdoMagic()メソッドをコピーする必要があります。さらに、実際には、エンティティEn1は、一度に1つの他のエンティティとの関係でのみ使用されます。したがって、3つの属性のうち2つはnullです。

しようとしたソリューション:@Embeddableの使用はE1,..,E3

public class EmbeddedEn1 implements Serializable { 

    @OneToMany(mappedBy="parentEntity") 
    private List<En1> newAttribut; 

    public En1 doMagic(En1 entity) { 
    //a long function which does somthing with the new entity 
    } 
} 

で同じコードを再実装の問題を解決しかし"parentEntity"バイdiretionを確立することはできません。

継承が動作していない:もちろんを、私はE1,E2,E3から継承hasAttributEn1のようなクラスを使用することができますが、これは他の新しいエンティティクラスを拡張できません。 En2,..,En4は、次のエンティティとの関係であるべきで、新しいエンティティ以下の状況、と仮定すると、このような状況で

  • En2 <-> E1, E3
  • En3 <-> E2,E3
  • En4 <-> E1,E2

を、多重継承が必要とされるであろう。

コードを複製せずにこの問題を解決するにはどうすればよいですか?

答えて

0

E1、E2、...、E20のジェネリック型を定義して、Eクラスの単一のコレクションでEnクラスを定義するだけでよい場合があります。 Eの各実装は異なる場合がありますが、Eクラスのコレクションを保持するだけなので、Enクラスを変更する必要はありません。

Here's a link to a guide that may help.

+0

私はプロジェクトで汎用DAOを使用しています。しかし、この疑問は、モデル構造、すなわちエンティティの設計であり、私がそれらにアクセスできる方法ではない。 – Thanthla

1

私はあなたがhibernate inheritanceを使用することができ、より良いモデルを解決すると思います。エンティティEn1の場合の

+だから、E1,E2,E3...のための親クラスを作成します。

@Entity 
// TABLE_PER_CLASS will create a table for each subclass with all attributes 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
//.... 
//Abstract entity, so you won't need to create a table for it 
public abstract class E extends SuperClass { 

    // shared attributes & methods 
    @OneToMany(mappedBy = "e") 
    private List<En> newAttribut; 

    public En doMagic(En entity) { 
     //a long function which does something with the new entity 
    } 
    //... 

}

  • 彼らは親からそれらを継承するよう、あなたのE1,E2,E3からdoMagic(En1)newAttributeを削除します。クラスE

更新:あなたがあなたのコメントで述べたように

(と同様にあなたの質問に)、あなたは複数のEnクラスでEクラスを関連付ける必要があります。

@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public abstract class En{ 

    @ManyToOne 
    private E e; 

    // ... 

} 

したがって、各En1, En2,..., Enxは、このクラスから継承されます:それは、単純な私もEnのため休止継承を使用するようにするに 。例えば

、あなたがEn2 <-> E3 & En3 <->E3を保存する場合(この例では、説明のためのものであり、およびトランザクションなどの他の側面をカバーしていない):

En en2 = new En2();   
En en3 = new En3(); 
E e3 = new E3();  
en2.setE(e3); 
e3.getEn().add(en2); 

en3.setE(e3); 
e3.getEn().add(en3); 
session.save(e3) 
session.save(en2) 
session.save(en3) 

終わりに、あなたの制約を満足させる:

doMagin()方法の
  • 1つのコピー、

  • サブエンティティは、一度に1つの他のエンティティ(例えば、E1またはE3)との関連付けを有するだけである。(例えば、En1

+0

ありがとうございます。しかし、これは厳密には複数の 'En *'に対してはうまくいかない解決法です。私の質問では**継承は機能していません**理由を説明しようとしました。私はあなたのサンプルコードで示されているように 'class hasEn1'のような抽象クラスを作ることができますが、' En2'も 'E1'との関係でなければならないので' class E1 extends hasEn1、hasEn2 'は、Javaでは使用できません。 – Thanthla

+0

@Thanthla私は第2のケースをカバーする答えを更新しました。 –

関連する問題