This is generally a database related problem, so I shall move your question to the
JDBC forum.
This isn't anything Hibernate specific. The same logic implemented using pure JDBC would do the same. It has to do with concurrency model in MySQL, which is based on locks. You're using some of the higher isolation levels (I'd say at least
TRANSACTION_REPEATABLE_READ), and this means that the database is obliged to return the same unmodified row if you read it again in the same transaction. MySQL and other lock-based concurrency databases generally ensure this by locking rows which have been read by an active transaction. So the locks are obtained at the time a row is read (or modified), and released upon commit or rollback.
You might avoid locking row read by a transaction by using a lower isolation level, for example
TRANSACTION_READ_COMMITTED, but it might impact your business logic, so you need to make sure that your code will still work as expected in multi-user environment with the relaxed isolation level.