我对 JPA 有一些严重的问题。我们正在使用 Vaadin 和 JPA (EclipseLink 2.5.0)
在我的应用程序中,我有一个基于树的数据结构。我从休息接口获取新数据,将它们放入队列中,用另一个线程将它们从队列中取出,并使用新值更新树中已经存在的节点,新的节点将被添加到树中。然后我保存父树(称为系统)并使用级联将所有子节点保存到数据库中。工作正常。有时。
这是正在保存并添加到树的线程的一些代码片段:
public void updateDatastructure(System connectedSystem, System receivedSystem) {
if (connectedSystem != null) {
boolean needRMUpdate = false;
dao.createEntityManager();
dao.beginTransaction();
for (Node receivedNode : receivedSystem.getNodes().values()) {
Node nodeInTree = connectedSystem.getNode(receivedNode.getName());
if (nodeInTree == null) {
addStructure(receivedNode, connectedSystem);
needRMUpdate = true;
} else if (nodeInTree != null) {
updateStructure(nodeInTree, receivedNode);
}
}
dao.commitTransaction();
dao.closeEntityManager();
triggerChangesOfHistoryDatas(historysizedData);
historysizedData.clear();
// RuleManager: Update the RuleManager
if (needRMUpdate)
XXX_Initializer.ruleManager.addOrUpdateSystem(connectedSystem);
}
}
UpdateDatastructure 方法每 10 秒调用一次。
我的树的结构如下所示:
系统 - 节点 - 数据
System 节点上方是另一个节点,但目前这无关紧要。
系统确实有 0..* 节点 节点确实有 0..* 节点 节点确实有 0..* 数据 数据是叶子
@Entity
@Table(name = "node")
@NamedQuery(name = "node.findAll", query = "SELECT n FROM Node n")
public class Node implements TreeNodeBase, Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "NAME", nullable = false)
private String name;
private String path;
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.EAGER)
@MapKey(name = "name")
@JoinColumn(name = "PARENT_ID", referencedColumnName = "id")
private Map<String, Node> nodes = new HashMap<String, Node>();
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.EAGER)
@MapKey(name = "name")
@JoinColumn(name = "NODE_ID", referencedColumnName = "id")
private Map<String, Data> datas = new HashMap<String, Data>();
@ManyToOne
@JoinColumn(name = "SYSTEM_ID", referencedColumnName = "id")
private System system;
@ManyToOne
@JoinColumn(name = "PARENT_ID", referencedColumnName = "id")
private Node parentNode;
数据结构(树)始终在内存中,因为多个用户可以登录到应用程序并需要树中的数据。
我想这意味着我需要让整棵树管理好?
那么这样使用 entityManager 有错吗?
主要问题:为什么重复 JPA / EclipseLink 有时是“节点”有时是“数据”有时是“系统”,但 ID 不同。
以下是数据库表的一些屏幕截图:
编辑节点哈希和等于:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((parentNode == null) ? 0 : parentNode.hashCode());
result = prime * result + ((system == null) ? 0 : system.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (parentNode == null) {
if (other.parentNode != null)
return false;
} else if (!parentNode.equals(other.parentNode))
return false;
if (system == null) {
if (other.system != null)
return false;
} else if (!system.equals(other.system))
return false;
return true;
}