I upgraded from Hibernate 5 to Hibernate 6.2.2.Final. I’m now getting the HHH000444 warning, which I understand can be ignored, but I’ve noticed that the SQL being executed seems to be different. Its now executing three statements instead of just the one, and the locking is being applied to the two new statements.
So, the first select is retrieving records based on some criteria, and in the instance I’m seeing, it returns two records. But now, Hibernate 6 is then doing two separate select statements to lock the records, and I guess it’s doing each one separately.
Is there a way to get back to having the initial select lock all the found records? And then to avoid the extra 2 selects?
Also, I’m using version-less pessimistic_write locking.
As the warning message says, you are getting separate select statements to lock separate objects because Hibernate is using follow-on locking as that’s the preferred way according to the database dialect.
If you want, you can forcibly disable this behaviour using the org.hibernate.LockOptions#setFollowOnLocking method or the hibernate.query.followOnLocking query hint.
I don’t think it’s a bug. Just the log message appearing. If the Postgres dialect really favors follow-on locking, then who am I to disagree with it. I just have to squelch the log message since it will litter the logs.
I am curious as to maybe why follow-on locking is now the default. I haven’t switched DB versions or anything. If I’m selecting a list of records based on some special criteria, and I desire those records to be locked for update, I would think that doing the “for update” on that select would be, I don’t know, more “atomic” than doing a follow-on lock. Am I mistaken in that thinking? I want to avoid the situation where 2 or more of my instances try to update the same list of records at the same time. I feel like with the follow-on lock, each instance will get the same result set, then will try to lock them. One will succeed, the other will block until the first finishes. The second will then run and could have undesirable effects.
Right now, I’m only running once instance, so I’m safe, but we’re moving to a new setup where we could potentially run multiple instances.
The query is basically: select * from table where state=? and date <= ?;
The ensuing code will update the state via a state machine, which is why I’m still worried about multiple instances getting the same result set and trying to shove it through the state machine twice or more, thus throwing errors.
You were right, my gradle file wasn’t using the global version I had set up. Everything is at 6.2.3 and the warning seems to have gone away. Does this mean it’s not using follow-on locking, or is it that the message just doesn’t appear?