我在一个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中找到了一些标题几乎相同的主题,但没有回答我的问题。
答案 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是正确的等等。