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:21:02 UTC

svn commit: r932929 - in /openjpa/trunk: openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java openjpa-project/src/doc/manual/migration_considerations.xml openjpa-project/src/doc/manual/ref_guide_caching.xml

Author: dwoods
Date: Sun Apr 11 16:21:01 2010
New Revision: 932929

URL: http://svn.apache.org/viewvc?rev=932929&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/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java   (with props)
Modified:
    openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml
    openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java?rev=932929&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java Sun Apr 11 16:21:01 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/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestQuerySQLCache.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml?rev=932929&r1=932928&r2=932929&view=diff
==============================================================================
--- openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml (original)
+++ openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml Sun Apr 11 16:21:01 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/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml?rev=932929&r1=932928&r2=932929&view=diff
==============================================================================
--- openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml (original)
+++ openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml Sun Apr 11 16:21:01 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>