私はJPAを初めて使い、次のクラスの設計を試してみることにしました。すべてのクラスは、equalsとhashcodeのオーバーライド、gettersとsetter、および空のコンストラクタを持ちます。このエンティティ階層の良いパーシスタンス設計とは何ですか?
私はすべてのエンティティのための基本クラスを持っている:
public abstract class BaseEntity {
protected Point loc;
protected List<Property> properties = new ArrayList<>();
}
Pointクラスがちょうど標準のxyホルダー
public class Point {
private int x, y;
}
あるとプロパティクラスは名前とIDを保持:
をpublic class Property {
private int id;
private String name;
}
BaseEntity
から継承するクラスは3つあります。最初はハウスです。家はの単一のファミリーを保持することができます。
public class House extends BaseEntity {
private Family family;
}
public class Tree extends BaseEntity {
private String name;
}
ファミリーはすぐに表示されます。
public abstract class LivingEntity extends BaseEntity {
public static enum Status { ALIVE, DECEASED }
int id;
Status status;
}
だから、階層グラフは
BaseEntity
|
/|\
/| \
/| \
House Tree LivingEntity
|
/\
Family Member
とある
public class Family extends LivingEntity {
private House house;
private List<Minion> members;
}
と
public class Member extends LivingEntity {
private Family family;
private String name;
}
が含まれています。もう一つはすべての生きているエンティティのスーパークラスですコンポジショングラップhは、継承するものに加えて、
House <---> Family ---> {Member, Member, Member, ...}
^ | | |
|----------------------------
です。
ハウスとツリー(equalsメソッドで)自分の位置によって識別されますので、私はその@Id
として使用することができると思います。私は彼らに特定のid
フィールドを与えることができますが、それは冗長です。
これは、xとyのコンポジットIDを持つエンティティもPointにする必要があることを意味します。私は、これが同じポイントをDBに複数回保存するかどうかはわかりません。私は異なるBaseEntitiesのセットを保存しますので、2つが同じPointにある場合、ポイントエントリを複製するか、すべてを1つの場所に参照しますか?
ファミリとメンバーは、家から家に移動できるため、IDで定義されます。ですので、@Id
としてLivingEntityにid
を使用しますが、BaseEntitiesの@Id
と競合します。ここで
は、私が持っている注釈です:
@MappedSuperclass
public abstract class BaseEntity {
@Id
protected Point loc;
@OneToMany
protected List<Property> effects = new ArrayList<>();
}
@Entity
@IdClass(value = PointID.class)
public class Point {
@Id
private int x, y;
}
class PointID {
int x, y;
}
@Entity
public class Property {
@Id
protected int id;
protected String name;
}
@Entity
public class House extends BaseEntity {
@OneToOne
private Family family;
}
私が正しく、スマートな方法で注釈を使用している場合、私は知らない2 @MappedSuperclassの紛争を除き
@MappedSuperclass
public abstract class LivingEntity extends BaseEntity {
public static enum Status { ALIVE, DECEASED }
@Id
int id;
@Enumerated(EnumType.STRING)
Status status;
}
@Entity
public class Family extends LivingEntity {
@OneToOne // bidirectional? specify mappedBy?
private House house;
@OneToMany
private List<Minion> members;
}
@Entity
public class Member extends LivingEntity {
@ManyToOne // bidirectional? specify mappedBy?
private Family family;
private String name;
}
。この場合、どのようなデザインが良いでしょうか?
'@OneToOne protected String name;とは何ですか?他のエンティティとの関係です。 Stringは「別のエンティティ」ではありません。メインのJPAプロバイダのすべてのドキュメントはこれを説明しています –
@NeilStocktonペーストの間違いをコピーしてください。一定。 – Mark
もう少し細分化する必要があります。 Pointで言及しているように、これがエンティティであるか、独自のアイデンティティーであるか、または所有クラス(埋め込み可能)のデータのカプセル化であるかを最初に把握する必要があります。あなたのビジネスルールは最も重要です。私は、ツリーとファミリーと 'メンバー'が同じ基本クラスを持つ理由を理解できません。人々は根ざしていないので、住所に関連付けられるかもしれませんが、住所によって定義されません。 – Chris