2017-06-05 68 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,这将是一个单独的“构件”或家庭。我不知道,如果共同所有权,需要在这个模型中的家庭之外 - 如果是,属性可能需要允许一个以上的所有者,使其成为一个多对多的关系。

这样,你的家庭(可能)有一个房子,有一个固定点。它不需要引用点本身,因为您可以通过关联的属性访问它。