开发者

Hibernate cascade delete not working when removing element of recreated bean

Supposing these are my parent and my child objects:

Parent:

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

The following pseudo-code will work

  • Create instance of ImportTable, add 2 columns, create a session, save it, close the session;
  • Read saved instance in a different session, remove one column;
  • Save it in another session;
  • Check number of columns and is equal to one.

But the following won't work:

  • Create instance of ImportTable, add 2 columns, create a session, save it, close the session;
  • Read saved instance in a different session;
  • Recreate saved object manually;
  • Remove the column;
  • Save it in another session;
  • Check number of columns and is equal to one.

The reason for this is that we have a Java server/ Flex client application, and we need to load the object, send it to the client, let the client do whatever it has to do, send the object back to the server, and then save it.

I think Hibernate is getting lost when I recreate the object. As far as I know, Hibernate does inject something in the object when it's retrieved from the database. When I recreate the object, I am not copying anything that is not a declared field in the object class. This is the code to recreate the object (for my unit test):

private ImportTable recreate( ImportTable original ) throws IOException
{
    final ImportTable copy = new ImportTable();
    copy.setDatab开发者_开发技巧aseTableName( 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;
}

I believe hibernate is getting lost when I recreate the object. What I want hibernate to do is to compare what is in the database with what is in the object and save the differences only. Is there any way to do that?


Hibernate wraps collection instances into appropriate subclasses of AbstractPersistentCollection when the owner entity is first attached to session.

That PersistentCollection is then tracking deleted collection elements; without it Hibernate will only be able to perform inserts / updates on them (in most cases; for some id generator classes even that is not possible).

You're basically out of luck there; the only thing you can do is to load an existing entity (ImportTable) from the database and modify it (e.g. delete collection elements that are present in loaded copy but not in your clone) then save it.

That said, I don't quite follow why you need to clone your entity in the first place (I don't know Flex ... are you marshalling your entity to XML / JSON / etc?) All PersistentCollection implementations are Serializable and thus can be sent over the wire and back. There are ways to marshall them to XML and back as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜