mirror of https://github.com/apache/openjpa.git
OPENJPA-1179 openjpa.jdbc.QuerySQLCache plugin no longer accepts value=all, so doc it in the Migration section. Testcase contributed by Tim McConnell.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/branches/2.0.x@932934 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5b1132136d
commit
8f30b053b0
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.compat;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
import org.apache.openjpa.persistence.EntityManagerImpl;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
|
||||
import org.apache.openjpa.persistence.OpenJPAPersistence;
|
||||
import org.apache.openjpa.persistence.relations.TblChild;
|
||||
import org.apache.openjpa.persistence.relations.TblGrandChild;
|
||||
import org.apache.openjpa.persistence.relations.TblParent;
|
||||
import org.apache.openjpa.persistence.simple.Person;
|
||||
import org.apache.openjpa.persistence.test.AllowFailure;
|
||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||
|
||||
/**
|
||||
* <b>TestQuerySQLCache</b> is used to verify multiple permutations of openjpa.jdbc.QuerySQLCache settings that were
|
||||
* valid in JPA 1.2 but may not be valid in JPA 2.0
|
||||
*/
|
||||
public class TestQuerySQLCache extends SingleEMFTestCase {
|
||||
|
||||
final int nThreads = 5;
|
||||
final int nPeople = 100;
|
||||
final int nIterations = 10;
|
||||
|
||||
@Override
|
||||
public void setUp() {
|
||||
// need this to cleanup existing tables as some entity names are reused
|
||||
setUp(DROP_TABLES, Person.class, TblChild.class, TblGrandChild.class, TblParent.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify an exception is thrown if a bad cache implementation class is specified
|
||||
*/
|
||||
public void testBadCustomCacheSetting() {
|
||||
Map props = new HashMap(System.getProperties());
|
||||
props.put("openjpa.MetaDataFactory", "jpa(Types=" + Person.class.getName() + ")");
|
||||
props.put("openjpa.jdbc.QuerySQLCache",
|
||||
"org.apache.openjpa.persistence.compatible.TestQuerySQLCache.BadCacheMap");
|
||||
|
||||
try {
|
||||
OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)OpenJPAPersistence.
|
||||
cast(Persistence.createEntityManagerFactory("test", props));
|
||||
//
|
||||
// EMF creation must throw an exception because the cache implementation class will not be found
|
||||
//
|
||||
assertFalse(false);
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Verify multi-threaded multi-entity manager finder works with the QuerySQLCache set to "all"
|
||||
*/
|
||||
@AllowFailure(message="OPENJPA-1179 2.0 doesn't allow 'all' as in previous releases")
|
||||
public void testMultiEMCachingAll() {
|
||||
Map props = new HashMap(System.getProperties());
|
||||
props.put("openjpa.MetaDataFactory", "jpa(Types=" + Person.class.getName() + ")");
|
||||
props.put("openjpa.jdbc.QuerySQLCache", "all");
|
||||
runMultiEMCaching(props);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Verify multi-threaded multi-entity manager finder works with the QuerySQLCache set to "true"
|
||||
*/
|
||||
public void testMultiEMCachingTrue() {
|
||||
Map props = new HashMap(System.getProperties());
|
||||
props.put("openjpa.MetaDataFactory", "jpa(Types=" + Person.class.getName() + ")");
|
||||
props.put("openjpa.jdbc.QuerySQLCache", "true");
|
||||
runMultiEMCaching(props);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Verify QuerySQLCacheValue setting "true" uses the expected cache implementation and is caching
|
||||
*/
|
||||
@AllowFailure(message="Fails after first run with duplicate key value in a unique PK constraint or index")
|
||||
public void testEagerFetch() {
|
||||
Map props = new HashMap(System.getProperties());
|
||||
props.put("openjpa.MetaDataFactory", "jpa(Types=" + TblChild.class.getName() + ";"
|
||||
+ TblGrandChild.class.getName() + ";"
|
||||
+ TblParent.class.getName() + ")");
|
||||
props.put("openjpa.jdbc.QuerySQLCache", "true");
|
||||
|
||||
OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.
|
||||
cast(Persistence.createEntityManagerFactory("test", props));
|
||||
EntityManagerImpl em = (EntityManagerImpl)emf.createEntityManager();
|
||||
|
||||
em.getTransaction().begin();
|
||||
|
||||
for (int i = 1; i < 3; i++) {
|
||||
TblParent p = new TblParent();
|
||||
p.setParentId(i);
|
||||
TblChild c = new TblChild();
|
||||
c.setChildId(i);
|
||||
c.setTblParent(p);
|
||||
p.addTblChild(c);
|
||||
em.persist(p);
|
||||
em.persist(c);
|
||||
|
||||
TblGrandChild gc = new TblGrandChild();
|
||||
gc.setGrandChildId(i);
|
||||
gc.setTblChild(c);
|
||||
c.addTblGrandChild(gc);
|
||||
|
||||
em.persist(p);
|
||||
em.persist(c);
|
||||
em.persist(gc);
|
||||
}
|
||||
em.flush();
|
||||
em.getTransaction().commit();
|
||||
em.clear();
|
||||
|
||||
for (int i = 1; i < 3; i++) {
|
||||
TblParent p = em.find(TblParent.class, i);
|
||||
int pid = p.getParentId();
|
||||
assertEquals(pid, i);
|
||||
Collection<TblChild> children = p.getTblChildren();
|
||||
boolean hasChild = false;
|
||||
for (TblChild c : children) {
|
||||
hasChild = true;
|
||||
Collection<TblGrandChild> gchildren = c.getTblGrandChildren();
|
||||
int cid = c.getChildId();
|
||||
assertEquals(cid, i);
|
||||
boolean hasGrandChild = false;
|
||||
for (TblGrandChild gc : gchildren) {
|
||||
hasGrandChild = true;
|
||||
int gcId = gc.getGrandChildId();
|
||||
assertEquals(gcId, i);
|
||||
}
|
||||
assertTrue(hasGrandChild);
|
||||
}
|
||||
assertTrue(hasChild);
|
||||
}
|
||||
em.close();
|
||||
emf.close();
|
||||
}
|
||||
|
||||
|
||||
private void runMultiEMCaching(Map props) {
|
||||
EntityManagerFactory emfac = Persistence.createEntityManagerFactory("test", props);
|
||||
EntityManager em = emfac.createEntityManager();
|
||||
|
||||
//
|
||||
// Create some entities
|
||||
//
|
||||
em.getTransaction().begin();
|
||||
for (int i = 0; i < nPeople; i++) {
|
||||
Person p = new Person();
|
||||
p.setId(i);
|
||||
em.persist(p);
|
||||
}
|
||||
em.flush();
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
|
||||
Thread[] newThreads = new Thread[nThreads];
|
||||
FindPeople[] customer = new FindPeople[nThreads];
|
||||
for (int i=0; i < nThreads; i++) {
|
||||
customer[i] = new FindPeople(emfac, 0, nPeople, nIterations, i);
|
||||
newThreads[i] = new Thread(customer[i]);
|
||||
newThreads[i].start();
|
||||
}
|
||||
|
||||
//
|
||||
// Wait for the worker threads to complete
|
||||
//
|
||||
for (int i = 0; i < nThreads; i++) {
|
||||
try {
|
||||
newThreads[i].join();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
this.fail("Caught Interrupted Exception: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Run through the state of all runnables to assert if any of them failed.
|
||||
//
|
||||
for (int i = 0; i < nThreads; i++) {
|
||||
assertFalse(customer[i].hadFailures());
|
||||
}
|
||||
|
||||
//
|
||||
// Clean up the entities used in this test
|
||||
//
|
||||
em = emfac.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
for (int i = 0; i < nPeople; i++) {
|
||||
Person p = em.find(Person.class, i);
|
||||
em.remove(p);
|
||||
}
|
||||
em.flush();
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Simple runnable to test finder in a tight loop. Multiple instances of this runnable will run simultaneously
|
||||
*/
|
||||
private class FindPeople implements Runnable {
|
||||
private int startId;
|
||||
private int endId;
|
||||
private int thread;
|
||||
private int iterations;
|
||||
private EntityManagerFactory emf;
|
||||
private boolean failures = false;
|
||||
|
||||
public FindPeople(EntityManagerFactory emf, int startId, int endId, int iterations, int thread) {
|
||||
super();
|
||||
this.startId = startId;
|
||||
this.endId = endId;
|
||||
this.thread = thread;
|
||||
this.iterations = iterations;
|
||||
this.emf = emf;
|
||||
}
|
||||
|
||||
public boolean hadFailures() {
|
||||
return failures;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
for (int j = 0; j < iterations; j++) {
|
||||
|
||||
for (int i = startId; i < endId; i++) {
|
||||
Person p1 = em.find(Person.class, i);
|
||||
if (p1.getId() != i) {
|
||||
System.out.println("Finder failed: " + i);
|
||||
failures = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
em.clear();
|
||||
}
|
||||
em.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
failures = true;
|
||||
System.out.println("Thread " + thread + " exception :" + e );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -204,6 +204,22 @@
|
|||
</simplelist>
|
||||
</para>
|
||||
</section>
|
||||
<section id="QuerySQLCache">
|
||||
<title>
|
||||
openjpa.jdbc.QuerySQLCache
|
||||
</title>
|
||||
<!-- See OPENJPA-1179 for details. -->
|
||||
<para>
|
||||
In prior 1.x.x releases, the openjpa.jdbc.QuerySQLCache
|
||||
configuration property for Prepared SQL Cache accepted
|
||||
value <literal>all</literal> to never drop items from the
|
||||
cache, but this option is no longer supported and will cause
|
||||
a PersistenceException with a root cause of a ParseException
|
||||
to be thrown. See
|
||||
<xref linkend="ref_guide_cache_querysql"/>
|
||||
for details on the available configuration values.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<section id="Disabling AutoOff Collection Tracking">
|
||||
<title>
|
||||
|
|
|
@ -1166,6 +1166,50 @@ property accepts a plugin string (see <xref linkend="ref_guide_conf_plugins"/>)
|
|||
with value of <literal>true</literal> or <literal>false</literal>. The default
|
||||
is <literal>true</literal>.
|
||||
</para>
|
||||
<table>
|
||||
<title>
|
||||
Pre-defined aliases
|
||||
</title>
|
||||
<tgroup cols="2" align="left" colsep="1" rowsep="1">
|
||||
<colspec colname="alias"/>
|
||||
<colspec colname="value"/>
|
||||
<colspec colname="notes"/>
|
||||
<thead>
|
||||
<row>
|
||||
<entry colname="alias">Alias</entry>
|
||||
<entry colname="value">Value</entry>
|
||||
<entry colname="notes">Notes</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry colname="alias">
|
||||
<literal>true</literal>
|
||||
</entry>
|
||||
<entry colname="value">
|
||||
<literal>org.apache.openjpa.util.CacheMap</literal>
|
||||
</entry>
|
||||
<entry colname="notes">
|
||||
The default option. Uses a
|
||||
<ulink url="../javadoc/org/apache/openjpa/util/CacheMap.html">
|
||||
<literal>CacheMap</literal></ulink> to store SQL string.
|
||||
<literal>CacheMap</literal> maintains a fixed number of cache entries, and an
|
||||
optional soft reference map for entries that are moved out of the LRU space.
|
||||
So, for applications that have a monotonically increasing number of distinct
|
||||
queries, this option can be used to ensure that a fixed amount of memory is
|
||||
used by the cache.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry colname="alias"><literal>false</literal></entry>
|
||||
<entry colname="value"><emphasis>none</emphasis></entry>
|
||||
<entry colname="notes">
|
||||
Disables the SQL cache.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<para>
|
||||
Following salient points to be noted regarding usage of Prepared Query Cache.
|
||||
<itemizedlist>
|
||||
|
|
Loading…
Reference in New Issue