1

我对 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;
}
4

0 回答 0