持久扩展类的适当方法是什么?

时间:2014-11-07 12:55:41

标签: java spring hibernate jpa spring-data-jpa

考虑图表:

image

我一直在与JPA合作很短的时间,到目前为止,我从来没有必要坚持扩展课程...正如您在示例中看到的那样SNMPNode,{{ 1}}等等都是IPNode的扩展类,也是Node的扩展类。

我知道我可以使用GeoLocation@MappedSuperclass注释主类,IPNode将继承其属性以保持...但在这种情况下,我最终会得到几乎相同的表格,据我所知,我可以只在Node中对所有信息进行分组,并使用单个表格。

这是JPA工作上的扩展类的持久性还是我的概念错误的方式?

与恢复的代码相同:

SNMPNode

[[从这一点回复后被征求]]

为了做出贡献,以下是我最终做的一个示例:

INODE:

public class Node extends GeoLocation {
    private String name;
    private Group group;
    private Location location;
    private Type type;
    private Company company;
}

public class IPNode extends Node {
    private Long id;
    private String ipAddress;
}

public class SNMPNode extends Node {
    private Long id;
    private SNMPServer server;
}

节点:

public interface INode {
    public Long getId();
    public void setId(Long id);

    public String getName();
    public void setName(String name);

    public String getIpAddress();
    public void setIpAddress(String ipAddress);

    public String getCommunity();
    public void setCommunity(String community);
}

IPNode:

@Entity
@DiscriminatorValue("N")
@DiscriminatorColumn(name="NODE_TYPE",discriminatorType=DiscriminatorType.STRING, length=20)
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public abstract class Node extends GeoLocation implements INode {
    @Id
    @GeneratedValue
    private Long id;
    private String name;

    public Long getId() {return id;}
    public void setId(Long id) {this.id = id;}

    public String getName() {return name;}
    public void setName(String name) {this.name = name;}

    (... Overrides from INode ...)
}

SNMPNode:

@Entity
@DiscriminatorValue("I")
public class IPNode extends Node {
    private String ipAddress;

    public String getIpAddress() { return this.ipAddress;}
    public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; }

    (... Overrides from INode ...)
}

NodeRepository:

@Entity
@DiscriminatorValue("S")
public class SNMPNode extends Node {
    private String community;

    public String getCommunity() { return community;}
    public void setCommunity(String community) { this.community = community; }

    (... Overrides from INode ...)
}

所以现在我可以做这样的事情:

@Repository
public interface NodeRepository extends JpaRepository<Node, Long> { }

两种节点类型都保存在同一个表中,因此它们的键无法重复...我的REST URL可以通过/ nodes / 1或/ nodes / 2来获取它们,这毕竟是我的主要目标。 ..

谢谢:)

1 个答案:

答案 0 :(得分:5)

如果基类使用@MappedSuperclass注释,则继承仅与OOP上下文相关。 @MappedSuperclass属性只是复制到每个子类关联的数据库表中,您只能查询子类实体。

Single table inheritance产生最佳性能(不涉及连接或联合),代价是无法声明所有特定子类属性的不可空(因为所有基类和所有子类特定属性都去到一个数据库表)。

使用joined inheritance tables,您可以在基础数据库表中拥有基类属性,并且每个特定的子类都拥有它自己的关联表。子类表通过FK与基础数据库表链接,因此您需要连接这些表以获取子类实体。正如@MappedSuperclass所示,基类是可查询的,因为OOP上下文和数据库都反映了继承模型。