You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by dw...@apache.org on 2010/04/11 18:37:46 UTC
svn commit: r932934 - in /openjpa/branches/2.0.x:
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/
openjpa-project/src/doc/manual/
Author: dwoods
Date: Sun Apr 11 16:37:46 2010
New Revision: 932934
URL: http://svn.apache.org/viewvc?rev=932934&view=rev
Log:
OPENJPA-1179 openjpa.jdbc.QuerySQLCache plugin no longer accepts value=all, so doc it in the Migration section. Testcase contributed by Tim McConnell.
Added:
openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java (with props)
Modified:
openjpa/branches/2.0.x/openjpa-project/src/doc/manual/migration_considerations.xml
openjpa/branches/2.0.x/openjpa-project/src/doc/manual/ref_guide_caching.xml
Added: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java?rev=932934&view=auto
==============================================================================
--- openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java (added)
+++ openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java Sun Apr 11 16:37:46 2010
@@ -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 );
+ }
+ }
+ }
+}
Propchange: openjpa/branches/2.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: openjpa/branches/2.0.x/openjpa-project/src/doc/manual/migration_considerations.xml
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-project/src/doc/manual/migration_considerations.xml?rev=932934&r1=932933&r2=932934&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-project/src/doc/manual/migration_considerations.xml (original)
+++ openjpa/branches/2.0.x/openjpa-project/src/doc/manual/migration_considerations.xml Sun Apr 11 16:37:46 2010
@@ -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>
Modified: openjpa/branches/2.0.x/openjpa-project/src/doc/manual/ref_guide_caching.xml
URL: http://svn.apache.org/viewvc/openjpa/branches/2.0.x/openjpa-project/src/doc/manual/ref_guide_caching.xml?rev=932934&r1=932933&r2=932934&view=diff
==============================================================================
--- openjpa/branches/2.0.x/openjpa-project/src/doc/manual/ref_guide_caching.xml (original)
+++ openjpa/branches/2.0.x/openjpa-project/src/doc/manual/ref_guide_caching.xml Sun Apr 11 16:37:46 2010
@@ -1166,6 +1166,50 @@ property accepts a plugin string (see <x
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>