So I'm working in Jboss EAP1, so the version of hibernate may be a little old. If this has been fixed subsequently, just let me know. I'm dealing with EJB3.1 mostly, but have slipped into hibernate specifics where necessary to get the extra performance necessary to get work done.
I'm working on a very large enterprise software which uses very very nested behaviour logic inside EJB's which run for several seconds. During this time, arbitrary sets of entites are fetched into the code from the DB. Over several permutations of performance work, I've attempted detaching, selective flushing with commit mode, etc.. to improve hibernate performance. For the most part, its been successful, but to avoid exceedingly long flush operations, I've recently defaulted basically all DB fetches as read-only.
Code:
/* In TX, read-only by default */
someMethod() {
myEntity = entityManager.createQuery(.....).getSingleResult(); /* Just for simplicity */
entityManager.detach(myEntity);
/* Here the entity is out of the live entity pool, but still resident in hibernate as a 'detached entity'. Oddly, it is still marked as read-only in its EntityEntry even though its already been detached from the live pool. */
myEntity.setSomeValue("DIFFERENT VALUE");
entityManager.merge(myEntity);
entityManager.flush();
}
Inside the flush code, it finds a EntityEntry for myEntry (since its detached but styill resident) but since it was flagged as read-only before being detached, the entity's change doesn't get persisted back to the DB because the flush listener doesn't think anything's changed (because it was flagged as read-only prior).