java - 删除重新创建的 bean 的元素时,Hibernate 级联删除不起作用

标签 java hibernate hibernate-annotations

假设这些是我的父对象和子对象:

父级:

@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
}

child :

@Entity
@Table( name = "import_table_column" )
public class ImportTableColumn {
    @ManyToOne
    @JoinColumn(
        name = "import_table_name",
        nullable = false
    )
    public ImportTable getTable()
    {
        return table;
    }
}

以下伪代码将起作用

  • 创建 ImportTable 实例,添加 2 列,创建 session ,保存,关闭 session ;
  • 在不同的 session 中读取已保存的实例,删除一列;
  • 将其保存在另一个 session 中;
  • 检查列数,是否等于 1。

但是以下内容不起作用:

  • 创建 ImportTable 实例,添加 2 列,创建 session ,保存,关闭 session ;
  • 在不同的 session 中读取已保存的实例;
  • 手动重新创建保存的对象;
  • 删除列;
  • 将其保存在另一个 session 中;
  • 检查列数,是否等于 1。

原因是我们有一个Java服务器/Flex客户端应用程序,我们需要加载对象,将其发送到客户端,让客户端做它必须做的任何事情,将对象发送回服务器,然后保存。

我认为当我重新创建对象时 Hibernate 会迷失方向。据我所知,当从数据库检索对象时,Hibernate 确实会在对象中注入(inject)一些内容。当我重新创建对象时,我不会复制对象类中未声明字段的任何内容。这是重新创建对象的代码(用于我的单元测试):

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 做的是将数据库中的内容与对象中的内容进行比较并仅保存差异。有什么办法可以做到吗?

最佳答案

当所有者实体首次附加到 session 时,Hibernate 将集合实例包装到 AbstractPersistentCollection 的适当子类中。

PersistentCollection 然后跟踪已删除的集合元素;如果没有它,Hibernate 将只能对它们执行插入/更新(在大多数情况下;对于某些 id 生成器类,甚至这是不可能的)。

你基本上运气不好;您唯一能做的就是从数据库加载现有实体 (ImportTable) 并修改它(例如,删除加载副本中存在但克隆中不存在的集合元素),然后保存它。

也就是说,我不太明白为什么你需要首先克隆你的实体(我不知道 Flex ...你是否将你的实体编码为 XML/JSON/等?) 所有 PersistentCollection 实现是可序列化 的,因此可以通过线路发送和返回。也有一些方法可以将它们编码为 XML 并返回。

关于java - 删除重新创建的 bean 的元素时,Hibernate 级联删除不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1904949/

相关文章:

java - 在 Struts 2、Hibernate 中使用数据库值填充下拉列表

java - 使用 JPA 通过一列连接并返回另一列

hibernate - 如果存在类似的行,如何避免创建新行?

java - 使用 Java 8 流的复杂聚合

java - 我如何知道 View 是否已绘制

java - 从sqlite数据库Android检索数据时捕获异常

java - 如何在JSP窗体中插入外键存入数据库?

java - hsqldb 不支持列的 columnDefinition 属性

java - 使用 @ManyToOne 和 @OneToMany 会导致 org.hibernate.exception.GenericJDBCException

java - 是否有不能作为方法引用的 lambda 函数