这个实体层次结构的良好持久性设计是什么?

时间:2017-06-05 06:14:31

标签: java jpa entity

我是JPA的新手并尝试为以下课程设计。所有类都有equals和hashcode overriden,getters和setter以及空构造函数。

我有一个所有实体的基类:

public abstract class BaseEntity {
    protected Point loc;
    protected List<Property> properties = new ArrayList<>();
}

Point类只是标准的x-y持有者

public class Point {
    private int x, y;
}

Property类包含一个名称和一个id:

public class Property {
    private int id;
    private String name;
}

有3个类继承自BaseEntity。第一个是House。 A 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

,组成图是

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

除了他们继承的内容。

House和Tree由它们的位置(在equals方法中)标识,所以我想我可以将它用作@Id。我可以给他们一个特定的id字段,但这是多余的。

这意味着我需要使Point的实体也使用x和y的复合ID。我不知道这是否会导致在数据库中多次保存相同的点。我会保存不同的BaseEntities集,所以如果2位于同一个点,它会复制点条目还是全部引用一个地方?

家庭和会员由他们的身份定义,因为他们可以挨家挨户。所以我想在LivingEntity中使用id作为@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;
}
@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;
}

除了@MappedSuperclass的冲突之外,我不知道我是否正确且以智能方式使用注释。对于这种情况,什么是好的设计?

1 个答案:

答案 0 :(得分:0)

我不知道你的商业原因(对于一个整个家庭而不仅仅是个别成员来说,拥有一个“活着的”或“已故的”状态似乎很奇怪),但是对于给出的例子,看起来更像是现实:

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

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


Property -> many BaseFixedObjects 

物业将主要是物业上的资产集合 - 一个有可能有许多树木的院子的房子。我不知道它是否会引用Point,或者每棵树/房子都有自己的观点 - 这取决于你的需要。或者你可以取消Property并直接使用LivingEntity引用BaseFixedObjects。

这种关系可能是双向的,因此一个属性可以引用它所依赖的LivingEntity,这将是一个单一的成员&#39;或家庭。我不确定此模型中的家庭以外是否需要共同所有权 -  如果是,则属性可能需要允许多个所有者,使其成为ManyToMany关系。

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

相关问题