如果我与@Cascade(CascadeType.SAVE_UPDATE) 有@OneToMany 关系,如下所示
public class One {
private Integer id;
private List<Many> manyList = new ArrayList<Many>();
@Id
@GeneratedValue
public Integer getId() {
return this.id;
}
@OneToMany
@JoinColumn(name="ONE_ID", updateable=false, nullable=false)
@Cascade(CascadeType.SAVE_UPDATE)
public List<Many> getManyList() {
return this.manyList;
}
}
和许多类
public class Many {
private Integer id;
/**
* required no-arg constructor
*/
public Many() {}
public Many(Integer uniqueId) {
this.id = uniqueId
}
/**
* Without @GeneratedValue annotation
* Hibernate will use assigned Strategy
*/
@Id
public Integer getId() {
return this.id;
}
}
如果我有以下情况
One one = new One();
/**
* generateUniqueId method will Take care of assigning unique id for each Many instance
*/
one.getManyList().add(new Many(generateUniqueId()));
one.getManyList().add(new Many(generateUniqueId()));
one.getManyList().add(new Many(generateUniqueId()));
one.getManyList().add(new Many(generateUniqueId()));
我打电话给
sessionFactory.getCurrentSession().save(one);
在继续之前
根据Transitive persistence Hibernate参考文档,可以看到
如果将父级传递给 save()、 update() 或 saveOrUpdate(),则所有子级都传递给 saveOrUpdate()
好的。现在让我们看看 Java Persistence With Hibernate 这本书讲了 saveOrUpdate 方法
Hibernate查询给定 id 的 MANY 表,如果找到,Hibernate更新该行。如果未找到,则需要插入新行并完成。
可以根据哪个翻译
INSERT INTO ONE (ID) VALUES (?)
/**
* I have four Many instances added To One instance
* So four select-before-saving
*
* I DO NOT NEED select-before-saving
* Because i know i have a Fresh Transient instance
*/
SELECT * FROM MANY WHERE MANY.ID = ?
SELECT * FROM MANY WHERE MANY.ID = ?
SELECT * FROM MANY WHERE MANY.ID = ?
SELECT * FROM MANY WHERE MANY.ID = ?
INSERT INTO MANY (ID, ONE_ID) VALUES (?, ?)
INSERT INTO MANY (ID, ONE_ID) VALUES (?, ?)
INSERT INTO MANY (ID, ONE_ID) VALUES (?, ?)
INSERT INTO MANY (ID, ONE_ID) VALUES (?, ?)
任何解决方法以避免保存前选择???是的,您可以
- 添加 @Version 列(未应用)
- 实现 Hibernate 拦截器提供的 isTransient 方法(我有这个选项)
因此,作为一种在使用这种级联时避免选择前保存默认行为的方法,我通过将 Hibernate Interceptor 分配给其 Transaction 由 Spring 管理的 Hibernate Session 来改进我的代码。
这是我的存储库
之前(没有任何休眠拦截器):它工作正常!
@Repository
public class SomeEntityRepository extends AbstractRepository<SomeEntity, Integer> {
@Autowired
private SessionFactory sessionFactory;
@Override
public void add(SomeEntity instance) {
sessionFactory.getCurrentSession().save(instance);
}
}
之后(使用 Hibernate Inteceptor):出现问题(不执行 SQL 查询 - 既不插入也不选择-前保存)
@Repository
public class SomeEntityRepository extends AbstractRepository<SomeEntity, Integer> {
@Autowired
private SessionFactory sessionFactory;
@Override
public void add(SomeEntity instance) {
sessionFactory.openSession(new EmptyInterceptor() {
/**
* To avoid select-before-saving
*/
@Override
public Boolean isTransient(Object o) {
return true;
}
}).save(instance);
}
}
我的问题是:为什么 Spring 在使用 Hibernate Interceptor 时不保留我的实体及其关系,我应该怎么做才能正常工作?