2017-06-05 70 views
2

我是新來的JPA,並試圖找出設計爲以下類。所有類都有equals和hashcode重寫,getter和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; 
} 

有3班從BaseEntity繼承。第一個是House。房子可以容納一個家庭。

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; 
} 

包括

public class Family extends LivingEntity { 
    private House house; 
    private List<Minion> members; 
} 

public class Member extends LivingEntity { 
    private Family family; 
    private String name; 
} 

所以層次圖是

BaseEntity 
     | 
     /|\ 
    /| \ 
    /| \ 
House Tree LivingEntity 
       | 
      /\ 
     Family Member 

和組成grap h是

House <---> Family ---> {Member, Member, Member, ...} 
      ^   |  |  | 
       |---------------------------- 

除了他們繼承的東西。


房子和樹是由它們的位置確定(在equals方法),所以我想我可以使用它作爲@Id。我可以給他們一個具體id場,但它是多餘的。

這意味着我需要讓一個實體也有一個實體,它的x和y也有一個合成ID。我不知道這是否會導致同一點在數據庫中多次保存。我將有不同的組保存BaseEntities的,所以如果2是在同一地點將它複製點進入或指所有在一個地方?

家庭和會員是由他們的身份證定義的,因爲他們可以從一個家到另一個家。所以我想用id在LivingEntity爲@Id,但我會造成與@Id從BaseEntities衝突。

這裏是我的註解:

@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; 
} 

@Entity 
public class Tree extends BaseEntity { 
    private String name; 
} 

@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; 
} 

除2個@MappedSuperclass如果我正確使用說明我不知道的衝突,一個聰明的辦法。這種情況下什麼是一個好的設計?

+0

什麼是@OneToOne保護字符串名稱;?!關係是另一個實體。一個字符串不是「另一個實體」。主JPA提供商的所有文檔都解釋了 –

+0

@NeilStockton複製粘貼錯誤。固定。 – Mark

+0

需要更多的分解。正如你提到的Point,你需要首先弄清楚這是一個實體,它有自己的身份,還是僅僅是擁有類的數據封裝(一個可嵌入的)。最重要的是你的商業規則。我不明白爲什麼Tree和Family和'member'會有相同的基類。人們沒有紮根,所以可能與地址相關聯,但沒有定義它。 – Chris

回答

0

我不知道你的商業原因(我覺得奇怪,有一個「活」或「死亡」的整個家庭,而不是僅僅個人會員身份),但給出的例子,似乎更現實碰到這樣的:那麼

BaseFixedObject -> Point 
     | 
     /| 
    /| 
    /| 
House Tree 

LivingEntity -> many Properties 
     | 
     /| 
    /| 
    /| 
Member | 
    Family -> many Members 


Property -> many BaseFixedObjects 

物業將主要資產上的屬性集合 - 與可能有很多樹木院子的房子。我不知道它是否會引用該點,或者每棵樹/房子都有自己的觀點 - 這取決於您的需要。或者你可以放棄Property,直接使用LivingEntity引用BaseFixedObjects。

的關係可能是雙向的,因此一個屬性可能會引用它是聯繫在一起的LivingEntity,這將是一個單獨的「構件」或家庭。我不知道,如果共同所有權,需要在這個模型中的家庭之外 - 如果是,屬性可能需要允許一個以上的所有者,使其成爲一個多對多的關係。

這樣,你的家庭(可能)有一個房子,有一個固定點。它不需要引用點本身,因爲您可以通過關聯的屬性訪問它。