Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is @PostRemove out of transaction?

Tags:

jpa

lifecycle

I found following information from the spec. But it's not clear enough for me who is not an english native.

The PostPersist and PostRemove callback methods are invoked for an entity after the entity has been made persistent or removed. These callbacks will also be invoked on all entities to which these operations are cascaded. The PostPersist and PostRemove methods will be invoked after the database insert and delete operations respectively. These database operations may occur directly after the persist, merge, or remove operations have been invoked or they may occur directly after a flush operation has occurred (which may be at the end of the transaction). Generated primary key values are available in the PostPersist method.

My question is any transaction related jobs can be rolled back after @PostRemove?

Let's say my entity deletes some offline files on @PostRemove

class MyEntity {

    @PostRemove
    private void onPostRemove() {
        // delete offline files related to this entity
        // not restorable!
    }
}

Is it possible that those offline files deleted from the storage and the entity still left in the database? (by rollback?)

like image 406
Jin Kwon Avatar asked Jul 25 '16 06:07

Jin Kwon


2 Answers

Yes, it is possible that your files are deleted and your entites are still left in db after a rollback. @PostRemove is in transaction.

If you want to be absolutely sure that your files are deleted if and only if the transaction is successfully completed then you should delete the files after the commit() succeeds not using the callback methods. But if you also need to be sure that the entity is removed if and only if the file is deleted, then you have a problem. You need a transactional way of accessing the file system.

For a simple solution move your files into a to_be_deleted-folder during the db-transaction. Therefore you can use the callback methods. The files are finally deleted when commit() succeeds and restored on failure.

If you want to elaborate it a bit more and your application is running in a java EE container, then you might want to look at CDI events or even at a jca adapter. If you are using Spring you can register a TransactionSynchronizationAdapter see this answer.

like image 142
frifle Avatar answered Oct 05 '22 20:10

frifle


It depends.

If you're using multiple flushes (EntityManager#flush()), the transaction could still be rolled back. Otherwise, any callbacks prefixed with Post are executed after the database transaction is complete.

like image 23
fny Avatar answered Oct 05 '22 19:10

fny