我在使用Hibernate 3.6.10.Final时遇到了问题。
我使用类似的东西映射了OneToMany关系:
public class Master implements Serializable {
@Id
@GeneratedValue(strategy = IDENTITY)
Long masterId;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "master")
private List<Row> rows = new ArrayList<Attribute>(0);
// Getter and setters and other properties
}
public class Row implements Serializable {
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(
name = "masterId",
column = @Column(name = "masterId", nullable = false)),
// Index is calculated
@AttributeOverride(
name = "index",
column = @Column(name = "index", nullable = false, length = 18))
})
@NotNull
private RowId id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "masterId", nullable = false, insertable = false, updatable = false)
@XmlTransient
private Master master;
// Some other properties, getters and setters
}
我实现了一个saveAll REST方法,并且从请求json序列化的对象是@OneToMany关系的完整表示。
我无法使用hibernate自动行为,因为Row.RowId.index是使用传统算法计算的。
所以,为此,我在create:
上执行此操作@Transactional
public void createAll(Master master) throws Exception {
// Save in a variable the row list
List<Row> rows = master.getRows();
// Nullify the rows
master.setRows(null);
// Persists the Master using an helper
masterService.persist(master);
for (Row row : rows) {
// the row helper method has the legacy index algorithm
rowService.persist(row);
}
}
这样做很好,插入操作没有问题。
问题出现在更新时,我需要在插入之前删除每一行。 代码与insert完全相同,但是调用了执行HQL更新查询的deleteAll。
@Transactional
public void updateAll(Master master) throws Exception {
// Save in a variable the row list
List<Row> rows = master.getRows();
// Nullify the rows
master.setRows(null);
// Persists the Master using an helper
masterService.merge(master);
// Delete Everything before to save
rowService.deleteAll(master);
for (Row row : rows) {
rowService.persist(row);
}
}
这仅适用于此更新前没有行的情况。 当有行时,hibernate会删除所有内容,插入新行而不会出错,但不会将它们持久存储到数据库中。
结果是清除所有当前的主行。
有没有办法以明确的方式避免这个问题? 我不知道如何使用SQL我不想把它们混合......
非常感谢,Davide。
答案 0 :(得分:0)
@OneToMany关系的级联类型设置为any。这告诉Hibernate将更改同步到child。
删除cascadeType,一切正常。
public class Master implements Serializable {
@Id
@GeneratedValue(strategy = IDENTITY)
Long masterId;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "master")
private List<Row> rows = new ArrayList<Attribute>(0);
// Getter and setters and other properties
}
非常感谢,Davide。