I am new to hibernate. Would like some clarification on Dirty Checking for Blob type. More specifically I would like to know if calling "free" on a Blob after saving it is enough to release the bytes in memory or if Hibernate keeps a copy of the object internally for Dirty Checking.

More details: I am using spring JPA and Partitioning a large list of files before calling "save" method. Every N number of files I get the bytes contents for these files, check if entity exist in DB and update or create a new one(s). I then release the files entity bytes by calling Free on the Blob (hopefully this actually releases it!) and associate the file to some parent entity (the parent does not have cascade operations allowed to files). These operation keeps repeating until all files have been update/created. All of these updates need to happen within a single transaction.

When I call Free on Blob, is this enough to release memory or does Hibernate makes a copy of the Blob internally for Dirty Checking purposes?

In the case I have, a transaction encompasses several saves for many files and I would like the Blob.free() to release bytes during the transaction and not wait for the end of it.

More details below if necessary:

I am manually calling "Free" on the Blob every time I save a couple of these files. I am concerned Hibernate keeps a copy (another instance of Blob or of the byte[] that backs the blob) internally and when I call free it only release the bytes in the instance I have access. (Haven't verified this, just concerned)

I am not seeing issues with the flow yet -but there hasn't been much usage of system yet.

I am concerned Hibernate keeps a copy (another instance of Blob or of the byte[] that backs the blob) internally and when I call free it only release the bytes in the instance I have access. (Haven't verified this, just concerned)

Usually, for every field, a copy is taken for dirty checking. However, for Blob, I'm not sure that's true for Blobs as well. Try to debug it and see if Hibernate can update it after you call free().

Looks like hibernate treat Blobs as immutable - which means it doesn't have to keep copies of it

That's not for the hydratedState. The mutability plan specifies if the object internal state can be manipulated. For instance, that's not the case for String, Integer, BigInteger, which are immutable. However, for Calendar, which is mutable, you can alter the internal state.

I added the breakpoint to two phase load. Not sure exactly how this step has implications on freeing the blob bytes. Can you provide some explanation on that?

Here is what I found out:In select phase Hibernate returns a proxy to ibm Blob type

Later I replace this blob with a new SerialBlob(byte[] newContent). Upon calling save hibernate returns a proxy in place of the SerailBlob from before. The proxy returned is of type hibernate.engine.jdbc.BlobProxy~StreamBackedBinaryStream and the Stream it holds internally seems to be a ByteArrayInputStream.

Calling Blob.free seems to only call .close() on the ByteArrayInputStream which does nothing. All the bytes are still in the internal ByteArrayInputStream buffer.

So as far as the Blob goes it doesn't seem like I can get rid of those bytes :(

However the code I have does map the returned entity to a non-managed bean after blob is saved (i.e. I just care about the id to append to parent). So at this point I think the entity should be a candidate for Garbage Collection. Would detaching using EntityManager.detach() allow hibernate remove its internal references to it and make it a candidate for GC?

That is, assuming my code has no more references to this entity - what is necessary to make it so that hibernate also removes all references to it (at this point changes can be flushed but the transaction cannot be terminated)?