OPENJPA-1477: Do not use cached PreparedQuery unless it is initialized

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@901845 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Pinaki Poddar 2010-01-21 20:17:50 +00:00
parent 08cf015207
commit ec8dba1465
2 changed files with 60 additions and 2 deletions

View File

@ -41,6 +41,7 @@ import org.apache.openjpa.kernel.jpql.JPQLParser;
import org.apache.openjpa.lib.jdbc.AbstractJDBCListener;
import org.apache.openjpa.lib.jdbc.JDBCEvent;
import org.apache.openjpa.lib.jdbc.JDBCListener;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
import org.apache.openjpa.persistence.OpenJPAPersistence;
@ -780,6 +781,32 @@ public class TestPreparedQueryCache extends TestCase {
em.getTransaction().rollback();
}
public void testMultithreadedAccess() {
OpenJPAEntityManager em1 = emf.createEntityManager();
String jpql = "select p from Author p where p.name=:name";
int N = 5;
Thread[] threads = new Thread[N];
QueryThread[] qts = new QueryThread[N];
for (int i = 0; i < N; i++) {
OpenJPAEntityManager emt = emf.createEntityManager();
qts[i] = new QueryThread(emt, jpql);
threads[i] = new Thread(qts[i]);
threads[i].setDaemon(true);
}
for (Thread t : threads) {
t.start();
}
for (int i = 0; i < N; i++) {
try {
threads[i].join();
assertFalse(qts[i].isFailed());
} catch (InterruptedException e) {
e.printStackTrace();
fail();
}
}
}
PreparedQueryCache getPreparedQueryCache() {
return emf.getConfiguration().getQuerySQLCacheInstance();
@ -967,5 +994,36 @@ public class TestPreparedQueryCache extends TestCase {
return new ArrayList<String>(sqls);
}
}
public static class QueryThread implements Runnable {
private final OpenJPAEntityManager em;
private final String jpql;
private boolean failed = false;
public QueryThread(OpenJPAEntityManager em, String jpql) {
super();
this.em = em;
this.jpql = jpql;
}
public void run() {
try {
for (int i = 0; i < 10 && !failed; i++) {
OpenJPAQuery q = em.createQuery(jpql);
q.setParameter("name", "Author-"+i);
q.getResultList();
if (i > 1)
assertEquals(QueryLanguages.LANG_PREPARED_SQL, q.getLanguage());
}
} catch (Exception e) {
e.printStackTrace();
failed = true;
}
}
public boolean isFailed() {
return failed;
}
}
}

View File

@ -963,7 +963,7 @@ public class EntityManagerImpl
String qid = query;
PreparedQuery pq = JPQLParser.LANG_JPQL.equals(language)
? getPreparedQuery(qid) : null;
org.apache.openjpa.kernel.Query q = (pq == null)
org.apache.openjpa.kernel.Query q = (pq == null || !pq.isInitialized())
? _broker.newQuery(language, query)
: _broker.newQuery(pq.getLanguage(), pq);
// have to validate JPQL according to spec
@ -1003,7 +1003,7 @@ public class EntityManagerImpl
PreparedQuery pq = JPQLParser.LANG_JPQL.equals(meta.getLanguage())
? getPreparedQuery(qid) : null;
org.apache.openjpa.kernel.Query del = (pq == null)
org.apache.openjpa.kernel.Query del = (pq == null || !pq.isInitialized())
? _broker.newQuery(meta.getLanguage(), meta.getQueryString())
: _broker.newQuery(pq.getLanguage(), pq);