with handling-mode=allow, bulk HQL UPDATE rowsAffected=1 row after allowed bulk HQL update: ExchangeRate{id=1, pair=ZAR/USD, rate=1.0000} flush() over 4000 loaded MUTABLE rows (12 cols, no pending changes): 8.62815 ms flush() over 4000 loaded @Immutable rows (12 cols, no pending changes): 2.535115 ms ratio (mutable / immutable) = 3.403455070085578 CAVEAT: single-run, shared-container timing -- indicative only, not a benchmark result. in-memory field mutated to 999.9999, about to flush inside a transaction Statistics.getEntityUpdateCount() after mutate+flush = 0 reloaded from DB: ExchangeRate{id=3, pair=USD/EUR, rate=0.9200} Session.setReadOnly(entity,true) then mutate+flush -> entityUpdateCount = 0 native SQL UPDATE rows=1 row after native SQL update: ExchangeRate{id=4, pair=CHF/USD, rate=7.7000} bulk HQL 'update ExchangeRate set ...' on an @Immutable entity threw: org.hibernate.query.sqm.InterpretationException: Error interpreting query [The query attempts to update an immutable entity: [exchange_rate] (set 'hibernate.query.immutable_entity_update_query_handling_mode' to suppress)] [update ExchangeRate set rate = :r where id = :id] adding to an @Immutable collection and flushing threw: jakarta.persistence.RollbackException: Error while committing the transaction [Immutable collection was modified: [com.ankurm.hibernatedemo.immutable.RateWithAuditTrail.auditTrails with owner id '1']] root cause class: org.hibernate.HibernateException message: Immutable collection was modified: [com.ankurm.hibernatedemo.immutable.RateWithAuditTrail.auditTrails with owner id '1'] persisted @Immutable+@Version entity, version after insert = 0 after mutate+flush, version = 0, rate = 0.0950 after EntityManager.remove() on an @Immutable entity, find() returns: null after setDefaultReadOnly(true) + mutate + flush, rate = 6.9000