Monday, June 30, 2014

JPA2.1 and LockModeType

Below is a self-explained test case.
    @Rollback(true)
    @Test
    public void testLock() {
        /**
         * Find by primary key. Search for an entity of the specified class and
         * primary key. If the entity instance is contained in the persistence
         * context, it is returned from there...Note that only the find(...)
         * method of entity manager will try to retrieve entity from persistence
         * context first.
         */
        Merchant retailer = this.getMerchantDao().findById(Merchant.class, 111l);
        System.out.println(retailer.getName());
        Map hints = new HashMap();
        /**
         * Regarding what standard hints properties are supported, refer to
         * "#3.4.4.3 Lock Mode Properties and Use" of JPA2.1 specification
         * document.
         *
         * If no hint 'javax.persistence.lock.timeout' supplied, the underlying
         * SQL will be:
         *
         * select MERCHANT_ID from MERCHANT where MERCHANT_ID =111 for update
         *
         * If provide this hint and set value to 0, the SQL will be:
         *
         * select MERCHANT_ID from MERCHANT where MERCHANT_ID =111 for update
         * nowait
         *
         * If provide this hint and set a value which is greater than 0(the
         * measurement unit for hint is millisecond, however it is second in
         * SQL, that says if your provide hint with value 10 milliseconds, the
         * SQL will tell you wait 0 seconds ), the SQL will be:
         *
         * select MERCHANT_ID from MERCHANT where MERCHANT_ID =111 for update
         * wait XXX
         *
         */
        hints.put("javax.persistence.lock.timeout", 10000);
        /**
         * Entity manager won't query all fields of entity in this case, and
         * simply perform SQL: select MERCHANT_ID from MERCHANT where
         * MERCHANT_ID =111 for update...so it won't reload entity
         *
         * The OPTIMISTIC lock must work with version checking.
         */
        this.entityManager.lock(retailer, LockModeType.PESSIMISTIC_READ, hints);
        // must call refresh() to reload entity
        this.getEntityManager().refresh(retailer, LockModeType.PESSIMISTIC_READ);
        // retailer = this.getMerchantDao().findById(Merchant.class, 111l);
        System.out.println(retailer.getName());
    }

No comments: