【发布时间】:2014-11-07 12:55:40
【问题描述】:
考虑图表:
我与 JPA 合作了很短的时间,到目前为止,我从来没有需要持久化扩展类...正如您在示例中看到的那样,SNMPNode、IPNode 等是所有来自Node 的扩展类也从GeoLocation 扩展。
我知道我可以用@MappedSuperclass 和IPNode 注释主类,SNMPNode 将继承它们的属性以进行持久化...但是在这种情况下,我最终会得到几乎相同的表,并且据我了解,而不是这样做,我可以将 Node 中的所有信息分组并使用单个表。
这是JPA工作中扩展类的持久化方式还是我的概念有误?
与恢复的代码相同:
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;
}
[[在此点回答后编辑]]
为了做出贡献,以下是我最终所做的示例:
INode:
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);
}
节点:
@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 ...)
}
IP节点:
@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 ...)
}
SNMP节点:
@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> { }
所以现在我可以做这样的事情了:
@ContextConfiguration("classpath:/spring/application-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class NodeRepositoryTest {
@Autowired
NodeRepository repo;
private INode node;
@Before
@Transactional
@Rollback(false)
public void setup() {
node = new IPNode();
node.setName("ipNode");
node.setIpAddress("1.1.1.1");
repo.save((IPNode)node);
node = new SNMPNode();
node.setName("snmpNode");
node.setIpAddress("2.2.2.2");
node.setCommunity("some text");
repo.save((SNMPNode)node);
}
@Test
@Transactional
public void Test() throws Exception {
INode testNode = repo.findOne(1L);
assertNotNull(testNode);
}
}
两种节点类型都保存在同一张表上,因此它们的键不能重复...我的 REST URL 可以通过 /nodes/1 或 /nodes/2 获取它们,这毕竟是我的主要目标...
谢谢:)
【问题讨论】:
-
简单查google(“jpa继承”):你会得到en.wikibooks.org/wiki/Java_Persistence/Inheritance
-
非常好的文档。示例表使其非常容易理解。谢谢。
标签: java spring hibernate jpa spring-data-jpa