假设这些都是我的父母和我的子对象:Hibernate的级联删除不工作
家长:
@Entity
@Table(name = "import_table")
public class ImportTable {
@Cascade({ CascadeType.ALL, CascadeType.DELETE_ORPHAN })
@OneToMany(
mappedBy = "table",
fetch = FetchType.EAGER
)
public List<ImportTableColumn> getColumns()
{
return columns;
}
... setter is defined but I don't think it's important for the example
}
儿童:
@Entity
@Table(name = "import_table_column")
public class ImportTableColumn {
@ManyToOne
@JoinColumn(
name = "import_table_name",
nullable = false
)
public ImportTable getTable()
{
return table;
}
}
以下伪代码将起作用
- 创建ImportTable实例,添加2列,创建会话,保存它,关闭会话;
- 在不同的会话中读取保存的实例,删除一列;
- 将它保存在另一个会话中;
- 检查列数等于1。
但下面的不会起作用:
- 创建ImportTable的情况下,增加2列,创建一个会话,保存,关闭会话;
- 在不同的会话中读取保存的实例;
- 手动重新创建保存的对象;
- 删除列;
- 将它保存在另一个会话中;
- 检查列数等于1。
原因是我们有一个Java服务器/ Flex客户端应用程序,我们需要加载对象,将它发送到客户端,让客户端做它必须做的任何事情,将对象发回到服务器,然后保存它。
我认为当我重新创建对象时,Hibernate正在迷失。据我所知,当从数据库中检索到对象时,Hibernate确实在对象中注入了一些东西。当我重新创建对象时,我不会复制对象类中不是已声明字段的任何内容。这是重新创建对象的代码(用于我的单元测试):
private ImportTable recreate(ImportTable original) throws IOException
{
final ImportTable copy = new ImportTable();
copy.setDatabaseTableName(original.getDatabaseTableName());
copy.setDisplayTableName(original.getDisplayTableName());
if(original.getColumns() != null) {
copy.setColumns(new ArrayList<ImportTableColumn>(original.getColumns().size()));
for(ImportTableColumn originalColumn : original.getColumns()) {
final ImportTableColumn copyColumn = new ImportTableColumn();
copyColumn.setTable(copy);
copyColumn.setDatabaseColumnName(originalColumn.getDatabaseColumnName());
copyColumn.setDatatype(originalColumn.getDatatype());
copyColumn.setExcelColumnName(originalColumn.getExcelColumnName());
copyColumn.setId(originalColumn.getId());
copyColumn.setLength(originalColumn.getLength());
copyColumn.setPk(originalColumn.isPk());
copyColumn.setRequired(originalColumn.isRequired());
copyColumn.setPrecision(originalColumn.getPrecision());
copy.getColumns().add(copyColumn);
}
}
return copy;
}
我相信当我重新创建对象时,hibernate会丢失。我想让hibernate做的是将数据库中的内容与对象中的内容进行比较,并仅保存差异。有没有办法做到这一点?
flex引擎(flex.messaging)不会序列化对象,我相信引擎使用反射来读取字段,然后它使用自己的与flex客户端兼容的序列化引擎。我只是检查源代码,当列表从客户端返回时,引擎创建一个ArrayList来保存其内容。 我想我必须自己实施解决方案。我可以使用反射(通过commons-bean)读取所有对象获取器,找出是否有任何列表,然后读取数据库并使用其中的hibernate注释比较列表id。 – 2009-12-15 04:19:55
通过阅读@Id注释。我将评估这种情况是否会经常发生,足以证明额外的编码,否则我可能会在对象本身手动执行此操作。 – 2009-12-15 04:22:04