Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 347592

Summary: pessimistic lock can not generated into SQL in eclipselink-2.2.0.v20110202-r8913
Product: z_Archived Reporter: wu jie <yz.mathematica>
Component: EclipselinkAssignee: Nobody - feel free to take it <nobody>
Status: CLOSED FIXED QA Contact:
Severity: major    
Priority: P3 CC: eclipselink.foundation-inbox, mitesh.meswani, tom.ware, wujie, yz.mathematica
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: Windows XP   
Whiteboard: submitted_patch
Attachments:
Description Flags
fix the problem of QueryHints.PESSIMISTIC_LOCK tom.ware: iplog+

Description wu jie CLA 2011-05-29 22:51:53 EDT
Build Identifier: 

the app is following:
===
Query query = em.createQuery("select i from RowLockEntity i where i.id=:id");
query.setParameter("id", id);
query.setHint(QueryHints.PESSIMISTIC_LOCK,lockType);
entity = (RowLockPesEntity)query.getSingleResult();
===
The generated SQL of above app by eclipselink-2.2.0.v20110202-r8913 as following.

===
SELECT ID,ENT_TYPE, NAME, OPT_LOCK_VER FROM ROWLOCKENTITY WHERE (ID = ?)")
===

The generated SQL does not contain pessimistic lock.
This problem occurred not only in SQL Server 2008, but also in Oracle, Derby and so on.

Reproducible: Always
Comment 1 Tom Ware CLA 2011-05-31 10:17:02 EDT
What is the value of lockType in your code below?
Comment 2 Mitesh Meswani CLA 2011-05-31 14:39:56 EDT
Originally reported as http://java.net/jira/browse/GLASSFISH-16746


Tom, 

Following code snippet reproduces the issue. 

em.getTransaction().begin();
Query query = em.createQuery("select e from Employee e where e.id=:id");
query.setParameter("id", 1);
query.setHint(org.eclipse.persistence.config.QueryHints.PESSIMISTIC_LOCK,org.eclipse.persistence.config.PessimisticLock.Lock);
query.getSingleResult();
Comment 3 wu jie CLA 2011-06-01 00:48:31 EDT
Created attachment 197057 [details]
fix the problem of QueryHints.PESSIMISTIC_LOCK

I think this patch fixes the issue.
Could you please confirm it.
Comment 4 Tom Ware CLA 2011-06-02 10:50:13 EDT
Looking at patch
Comment 5 Tom Ware CLA 2011-06-02 11:17:30 EDT
Is this problem recreatable outside of GlassFish?  I am running a similar query and can see the FOR UPDATE string on both Oracle and MySql.

@NamedQuery(
	name="findAllEmployeesByFirstName",
	query="SELECT OBJECT(employee) FROM Employee employee WHERE employee.firstName = :firstname"
)


        Query query = em.createNamedQuery("findAllEmployeesByFirstName");
        query.setHint("eclipselink.pessimistic-lock", PessimisticLock.Lock);
        query.setParameter("firstname", "Sarah");
        List results = query.getResultList();

Note: Our DerbyPlatform has limited support for "FOR UPDATE"

It is possible that if we are not detecting the database platform properly we would not issue the FOR UPDATE.  Try explicitly specifying your database platform with the eclipselink.target-database persistence unit property.
Comment 6 Mitesh Meswani CLA 2011-06-02 14:07:41 EDT
This is repdroducible outside GlassFish. Here is code snippet that reproduces it running against Derby

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("em");
        EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		javax.persistence.Query query = em.createQuery("select e from Employee e where e.id=:id");
		query.setParameter("id", 1);
		query.setHint(org.eclipse.persistence.config.QueryHints.PESSIMISTIC_LOCK,org.eclipse.persistence.config.PessimisticLock.Lock);
		//--Comment setHint above and uncomment following line to see FOR UPDATE being generated
		//query.setLockMode(javax.persistence.LockModeType.PESSIMISTIC_READ);
		query.getSingleResult();
		em.getTransaction().commit();
    }
Comment 7 wu jie CLA 2011-06-06 22:06:52 EDT
This is repdroducible either inside GlassFish or outside Glassfish if meets
the conditions as folowing.
1) use the QueryHints.PESSIMISTIC_LOCK 
   ===
   query.setHint(QueryHints.PESSIMISTIC_LOCK,lockType);
   ===

2) Query with primary key
   ===
   SELECT ID,ENT_TYPE, NAME, OPT_LOCK_VER FROM ROWLOCKENTITY WHERE (ID = ?)")
   // Here ID is the primary key
   ===
Comment 8 Tom Ware CLA 2011-06-07 09:54:51 EDT
Thanks.  I can now reproduce.
Comment 9 wu jie CLA 2011-06-10 02:13:16 EDT
Addition:
In EclipseLink, 
when query by primary key use the ReadObjectQuery.
when query no by primary key use the ReportQuery.

In the other hand,
Toplink always use the ReportQuery no matter whether query by primary key or not.

the logic of ReadObjectQuery.checkForCustomQuery() is different from the logic of ReportQuery.checkForCustomQuery(). so cannot reproduce in toplink.
Comment 10 Tom Ware CLA 2011-06-10 12:46:30 EDT
Checked changes into 2.3

Reviewed - user submitted fix reviewed by Tom Ware

Testing: Added Test to JUnitJPQLComplexTestSuite

Tested with JPA and Core LRG

2.3.1 check in to come when stream opens
Comment 11 Tom Ware CLA 2011-06-10 12:46:45 EDT
correction: Checked changes into Trunk
Comment 12 Tom Ware CLA 2011-06-29 13:21:45 EDT
Checked into 2.3.1
Comment 13 Eclipse Webmaster CLA 2022-06-09 10:35:54 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink