LockModeType specifies the optimistic or pessimistic locking behavior requested for a JPA query or entity operation. Set it on a Query, or pass it to EntityManager.find(), lock(), or refresh(). A pessimistic lock timeout hint is also standardized. section 11.0 section 11.2.4
For an entity with @Version, Hibernate checks versions automatically when flushing a changed entity; no explicit lock mode is needed for that case. An UPDATE includes the version previously read, so a conflicting change can raise OptimisticLockException. Use an explicit optimistic mode when a unit of work must also check entities it reads without changing. section 11.2.2
Check query results without changing them
Within a transaction, `em.createQuery("select i from Item i where i.category.id = :catId", Item.class).setLockMode(LockModeType.OPTIMISTIC).setParameter("catId", categoryId).getResultList()` requests a version check for the returned items. The example sums their prices and commits without modifying them. section 11.2.2
Listing 11.4 Requesting a version check at flush time to ensure repeatable reads
Path: /Ch11/transactions/src/test/java/com/manning/javapersistence/ch11 /concurrency/Versioning.java – manualVersionChecking() EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); BigDecimal totalPrice = BigDecimal.ZERO; for (Long categoryId : CATEGORIES) { List<Item> items = #1 em.createQuery("select i from Item i where i.category.id = :catId", Item.class) .setLockMode(LockModeType.OPTIMISTIC) .setParameter("catId", categoryId) .getResultList(); for (Item item : items) totalPrice = totalPrice.add(item.getBuyNowPrice()); } em.getTransaction().commit(); #2 em.close(); assertEquals("108.00", totalPrice.toString()); #1 For each <kbd>Category</kbd>, query all <kbd>Item</kbd> instances with an <kbd>OPTIMISTIC</kbd> lock mode. Hibernate now knows it has to check each <kbd>Item</kbd> at flush time. #2 For each <kbd>Item</kbd> loaded earlier with the locking query, Hibernate executes a <kbd>SELECT</kbd> during flushing. It checks whether the database version of each <kbd>ITEM</kbd> row is still the same as when it was loaded. If any <kbd>ITEM</kbd> row has a different version or the row no longer exists, an <kbd>OptimisticLockException</kbd> is thrown.
The transaction shows where the query lock mode is set and why the version check matters even though the retrieved entities are only read. section 11.2.2
`LockModeType.OPTIMISTIC_FORCE_INCREMENT` requests a forced version increment; it can be passed to `find()`. For an already-loaded persistent entity, `lock()` applies the requested mode without loading it again. When locking a versioned entity pessimistically, `lock()` immediately checks its database version and may throw OptimisticLockException. Database locking behavior also matters when assessing deadlocks. section 11.2.2 section 11.2.4
