Hibernate:将子级添加到父级集合

时间:2014-09-25 14:32:47

标签: mysql hibernate


我在一个Web项目上使用Hibernate,它有两个不同的类(Node,Interface)

节点

@Entity
@Table(name="NODES")
public class Node {
    //...

    @OneToMany(mappedBy="node", cascade={CascadeType.ALL, CascadeType.MERGE, CascadeType.PERSIST}, orphanRemoval=true)
    private Set<Interface> interfaces = new HashSet<>();

    //...

}

接口

@Entity
@Table(name="INTERFACES")
public class Interface {
    //...

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="REF_NODE")
    private Node node;

    //...
}

一切都很好,
我的问题是如何将一个接口(chlid)添加到已经存在的Node(Parent)?意味着如果我已经在数据库中有一些Node有2个Interfaces例如我想添加第三个,我该怎么做?

我的第一个快速解决方案是在Hibernate中使用本机sql,如下所示:

public void addInteface(Interface i, Long idNode) {
    //OpenSession..
    Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction tx = null;

    try {
        //Start transaction
        tx = session.beginTransaction();

        //Native SQL in Hibernate
        SQLQuery query = session.createSQLQuery("INSERT INTO INTERFACES (ID_INTERFACE, ALIAS, ID_NODE) VALUES (NULL, :Alias, :idNode)");

        query.setParameter("ifAlias", i.getAlias());
        query.setParameter("refNode", idNode);
        //Some other parameters...

        //Execute and Commit
        query.executeUpdate();
        tx.commit();

    } catch (Exception e) {
        if (tx != null) tx.rollback();
        throw e;

    } finally {
        session.close();
    }
}

它有效,但它不是我认为的最佳解决方案。

注意:我在stackoverflow中找到了一些标题几乎相同的主题,但没有回答我的问题。

2 个答案:

答案 0 :(得分:3)

可以通过两种方式完成。

第一个选项:

node.getInterfaces().add(new Interface(....)); // you have orphan removal to true, this will work
session.saveOrUpdate(node);
tx.commit();
session.close();

或者

第二次选择

newInterface.setNode(nodeObject);
session.saveOrUpdate(newInterface);
tx.commit();
session.close();

在上述两种方法中,第二种方法与第一种方法相比效果很好。当你调用getInterfaces()时,第一个将拉出所有的孩子,这样做效果不佳。

答案 1 :(得分:1)

//语法可能不在点,也可能是一些伪代码

假设您要为Node添加一个ID为1的接口:

Query query = session.createQuery("Select n from Node n where n.id = '1'");//JPQL
Node n = query.getSingleResult();

然后你将创建一个新的界面

Interface i = new Interface();

然后将变量设置为您想要的但也设置节点

i.setVariables(..);
i.setNode(n);

然后更新

session.merge(i);

现在所有这一切都假设生成器ID是正确的等等。