openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fa...@apache.org
Subject svn commit: r706481 - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/
Date Tue, 21 Oct 2008 00:23:30 GMT
Author: fancy
Date: Mon Oct 20 17:23:29 2008
New Revision: 706481

URL: http://svn.apache.org/viewvc?rev=706481&view=rev
Log:
OPENJPA-738 QueryCache Improvement
Committing patch provided by Sandhya Sturaga

Added:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Part.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartBase.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartComposite.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Supplier.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/TestQueryTimestampEviction.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Usage.java
Modified:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractQueryCache.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ConcurrentQueryCache.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryResult.java

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractQueryCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractQueryCache.java?rev=706481&r1=706480&r2=706481&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractQueryCache.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractQueryCache.java
Mon Oct 20 17:23:29 2008
@@ -18,12 +18,16 @@
  */
 package org.apache.openjpa.datacache;
 
+import java.security.AccessController;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.event.RemoteCommitEvent;
@@ -31,6 +35,7 @@
 import org.apache.openjpa.lib.conf.Configurable;
 import org.apache.openjpa.lib.conf.Configuration;
 import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
 import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashSet;
@@ -63,34 +68,65 @@
      */
     protected Log log;
 
+    protected ConcurrentHashMap<String,Long> entityTimestampMap = null;
     private boolean _closed = false;
 
+    protected String evictPolicy = "default";
+
     public void initialize(DataCacheManager manager) {
+        if(evictPolicy.equalsIgnoreCase("timestamp")) {
+            entityTimestampMap = new ConcurrentHashMap<String,Long>();
+        
+            // Get all persistence types to pre-load the entityTimestamp Map
+            Collection perTypes = conf.getMetaDataRepositoryInstance().
+            getPersistentTypeNames(false,
+                (ClassLoader) AccessController.doPrivileged(
+                J2DoPrivHelper.getContextClassLoaderAction()));
+            
+            // Pre-load all the entity types into the HashMap to handle 
+            // synchronization on the map efficiently
+            for (Object o : perTypes)
+                entityTimestampMap.put((String)o, new Long(0));
+        }
     }
 
     public void onTypesChanged(TypesChangedEvent ev) {
         writeLock();
         Collection keys = null;
-        try {
-            if (hasListeners())
-                fireEvent(ev);
-            keys = keySet();
-        } finally {
-            writeUnlock();
-        }
-
-        QueryKey qk;
-        List removes = null;
-        for (Iterator iter = keys.iterator(); iter.hasNext();) {
-            qk = (QueryKey) iter.next();
-            if (qk.changeInvalidatesQuery(ev.getTypes())) {
-                if (removes == null)
-                    removes = new ArrayList();
-                removes.add(qk);
+        if (!evictPolicy.equalsIgnoreCase("timestamp")) {
+            try {
+                if (hasListeners())
+                    fireEvent(ev);
+                keys = keySet();
+            } finally {
+                writeUnlock();
+            }
+    
+            QueryKey qk;
+                List<QueryKey> removes = null;
+                for (Object o: keys) {
+                    qk = (QueryKey) o;
+                if (qk.changeInvalidatesQuery(ev.getTypes())) {
+                    if (removes == null)
+                        removes = new ArrayList<QueryKey>();
+                    removes.add(qk);
+                }
             }
+            if (removes != null)
+                removeAllInternal(removes);
+        } else {
+            Collection changedTypes = ev.getTypes();
+            HashMap<String,Long> changedClasses = 
+                new HashMap<String,Long>(); 
+            for (Object o: changedTypes) {
+                String name = ((Class) o).getName();
+                if(!changedClasses.containsKey(name))
+                    changedClasses.put(name, 
+                        new Long(System.currentTimeMillis()));
+            }           
+            // Now update entity timestamp map
+            updateEntityTimestampMap(changedClasses);
         }
-        if (removes != null)
-            removeAllInternal(removes);
     }
 
     public QueryResult get(QueryKey key) {
@@ -319,4 +355,50 @@
     protected Collection newListenerCollection() {
         return new ConcurrentReferenceHashSet (ConcurrentReferenceHashSet.WEAK);
 	}
+
+    /**
+     * Sets the eviction policy for the query cache
+     * @param evictPolicy -- String value that specifies the eviction policy
+     */
+    public void setEvictPolicy(String evictPolicy) {
+        this.evictPolicy = evictPolicy;
+    }
+
+    /**
+     * Returns the evictionPolicy for QueryCache
+     * @return -- returns a String value of evictPolicy attribute
+     */
+    public String getEvictPolicy() {
+        return null;
+    }
+
+    /**
+     * Updates the entity timestamp map with the current time in milliseconds
+     * @param timestampMap -- a map that contains entityname and its last updated timestamp
+     */
+    protected void updateEntityTimestampMap(Map<String,Long> timestampMap) {
+        if (entityTimestampMap != null)
+            entityTimestampMap.putAll(timestampMap);
+     }
+
+    /**
+     * Returns a list of timestamps in the form of Long objects
+     * which are the last updated time stamps for the given entities in the
+     * keylist.
+     * @param keyList -- List of entity names 
+     * @return -- Returns a list that has the timestamp for the given entities
+     */
+    public List<Long> getAllEntityTimestampFromMap(List<String> keyList) { 
+        ArrayList<Long> tmval = null;
+        if (entityTimestampMap != null) {
+            for (String s: keyList) {
+                if (entityTimestampMap.containsKey(s)) {
+                    if(tmval == null)
+                        tmval = new ArrayList<Long>();
+                    tmval.add(entityTimestampMap.get(s));
+                }
+            }
+        }
+        return tmval;
+    }
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ConcurrentQueryCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ConcurrentQueryCache.java?rev=706481&r1=706480&r2=706481&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ConcurrentQueryCache.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ConcurrentQueryCache.java
Mon Oct 20 17:23:29 2008
@@ -137,4 +137,11 @@
     protected Collection keySet() {
         return _cache.keySet ();
 	}
+
+    /**
+     * Returns the eviction policy of the query cache
+     */
+    public String getEvictPolicy() {
+        return super.evictPolicy;
+    }
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java?rev=706481&r1=706480&r2=706481&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryCacheStoreQuery.java
Mon Oct 20 17:23:29 2008
@@ -28,6 +28,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 import java.util.TreeMap;
 
 import org.apache.commons.collections.map.LinkedMap;
@@ -119,10 +120,34 @@
         // get the cached data
         QueryResult res = _cache.get(qk);
         if (res == null)
-            return null;
+            return null;        
         if (res.isEmpty())
             return Collections.EMPTY_LIST;
 
+        // this if block is invoked if the evictOnTimestamp is set to true
+        if (_cache instanceof AbstractQueryCache) {
+            AbstractQueryCache qcache = (AbstractQueryCache) _cache;
+            if (qcache.getEvictPolicy().equalsIgnoreCase("timestamp")) {
+                Set<String> classNames = qk.getAcessPathClassNames();
+                List<String> keyList = new ArrayList<String>();      
+                keyList.addAll(classNames);
+
+                List<Long> timestamps = 
+                    qcache.getAllEntityTimestampFromMap(keyList);
+                long queryTS = res.getTimestamp();
+                if (timestamps != null) {
+                    for (Long ts: timestamps) {
+                        // if this is true we have to evict the query 
+                        // from cache
+                        if (queryTS < ts) { 
+                            qcache.remove(qk);
+                            return null;
+                        }
+                    }
+                }
+            }
+        }
+
         int projs = getContext().getProjectionAliases().length;
         if (projs == 0) {
             // make sure the data cache contains the oids for the query result;
@@ -572,6 +597,7 @@
                         QueryResult res = null;
                         synchronized (this) {
                             res = new QueryResult(_qk, _data.values());
+                            res.setTimestamp(System.currentTimeMillis());
                         }
                         _cache.put(_qk, res);
                         abortCaching();

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java?rev=706481&r1=706480&r2=706481&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryKey.java
Mon Oct 20 17:23:29 2008
@@ -200,6 +200,8 @@
             // since the class change framework deals with least-derived types,
             // record the least-derived access path types
             meta = metas[i];
+            if (meta.getDataCache() != null)
+                accessPathClassNames.add(meta.getDescribedType().getName());
             while (meta.getPCSuperclass() != null)
                 meta = meta.getPCSuperclassMetaData();
 
@@ -232,6 +234,7 @@
                 if (metas[i].getDataCache() == null)
                     return null;
 
+                accessPathClassNames.add(metas[i].getDescribedType().getName());
                 subTimeout = metas[i].getDataCacheTimeout();
                 if (subTimeout != -1 && subTimeout < timeout)
                     timeout = subTimeout;
@@ -466,4 +469,12 @@
         _rangeEnd = in.readLong ();
 		_timeout = in.readInt ();
 	}
+    
+    /**
+     * Returns the set of the accessPathClassnames that exists in the query
+     * @return -- Returns a set of accesspath classnames.
+     */
+    public Set<String> getAcessPathClassNames() {
+        return this._accessPathClassNames;
+    }
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryResult.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryResult.java?rev=706481&r1=706480&r2=706481&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryResult.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/QueryResult.java
Mon Oct 20 17:23:29 2008
@@ -31,6 +31,7 @@
 
     private final long _ex;
 
+    private long _timestamp = 0L;
     /**
      * Constructor; supply corresponding query key and result data.
      */
@@ -64,4 +65,20 @@
     public boolean isTimedOut() {
         return _ex != -1 && _ex < System.currentTimeMillis();
 	}
+
+    /**
+     * Sets the timestamp of the query result.
+     * @param ts  -- Timestamp value in long
+     */
+    public void setTimestamp(long ts) {
+        this._timestamp = ts;
+    }
+
+    /**
+     * Returns the timestamp of the query result.
+     * @return -- the timestamp value in long
+     */
+    public long getTimestamp() {
+        return this._timestamp;
+    }
 }

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Part.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Part.java?rev=706481&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Part.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Part.java
Mon Oct 20 17:23:29 2008
@@ -0,0 +1,81 @@
+/*
+ * 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.jdbc.query.cache;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToMany;
+import javax.persistence.Version;
+
+import org.apache.openjpa.persistence.DataCache;
+
+@Entity
+//@MappedSuperclass
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name="PARTTYPE")
+
+@DataCache
+abstract public class Part {
+	
+	@Id  int partno;
+	@Column(length=20)
+	String name;
+	int inventory;
+	
+	@OneToMany(mappedBy="child",cascade=CascadeType.PERSIST)
+	protected Collection<Usage> usedIn = new ArrayList<Usage>();
+	
+	@Version
+	long version;
+	
+	
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public int getPartno() {
+		return partno;
+	}
+	public void setPartno(int partno) {
+		this.partno = partno;
+	}
+	public Collection<Usage> getUsedIn() {
+		return usedIn;
+	}
+	public void setUsedIn(Collection<Usage> usedIn) {
+		this.usedIn = usedIn;
+	}
+	public int getInventory() {
+		return inventory;
+	}
+	public void setInventory(int inventory) {
+		this.inventory = inventory;
+	}
+
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartBase.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartBase.java?rev=706481&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartBase.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartBase.java
Mon Oct 20 17:23:29 2008
@@ -0,0 +1,93 @@
+/*
+ * 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.jdbc.query.cache;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToMany;
+
+import org.apache.openjpa.persistence.DataCache;
+
+
+@Entity
+@DataCache
+public class PartBase extends Part  {
+	
+	 double cost;
+	 double mass;
+	 int backOrder;
+	
+	@ManyToMany(mappedBy="supplies")
+	protected List<Supplier> suppliers = new ArrayList<Supplier>();
+	
+	public PartBase() {}
+	
+  public PartBase(int partno, String name, double cost, double mass){
+  	this.partno=partno;
+  	this.name = name;
+  	this.cost = cost;
+  	this.mass= mass;
+  	this.backOrder=0;
+  	this.inventory=0;
+  }
+
+	public double getCost() {
+		return cost;
+	}
+
+	public void setCost(double cost) {
+		this.cost = cost;
+	}
+
+	public double getMass() {
+		return mass;
+	}
+
+	public void setMass(double mass) {
+		this.mass = mass;
+	}
+
+	public Collection<Supplier> getSuppliers() {
+		return suppliers;
+	}
+
+	public void setSuppliers(List<Supplier> suppliers) {
+		this.suppliers = suppliers;
+	}
+	
+	public String toString() {
+		String sup= "";
+		if (getSuppliers()!=null)
+			for (Supplier s : getSuppliers()){
+				sup= sup+s.sid+",";
+			}
+		return "PartBase:"+partno+" name:+"+name+" cost:"+cost+" mass:"+mass+" supplies=["+sup+"]";
+	}
+
+	public int getBackOrder() {
+		return backOrder;
+	}
+
+	public void setBackOrder(int backOrder) {
+		this.backOrder = backOrder;
+	}
+
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartComposite.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartComposite.java?rev=706481&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartComposite.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/PartComposite.java
Mon Oct 20 17:23:29 2008
@@ -0,0 +1,96 @@
+/*
+ * 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.jdbc.query.cache;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.persistence.Entity;
+import javax.persistence.EntityManager;
+import javax.persistence.OneToMany;
+
+import org.apache.openjpa.persistence.DataCache;
+
+
+@Entity
+@DataCache
+public class PartComposite extends  Part  {
+
+	 double assemblyCost;
+	 double assemblyTime;
+	 double massIncrement;
+	 
+	 @OneToMany( mappedBy="parent")
+	 Collection<Usage> partsUsed = new ArrayList<Usage>();
+	
+	public PartComposite() {}
+	
+	public PartComposite(int partno, String name, double asmCost, double massInc) {
+		this.partno=partno;
+		this.name=name;
+		assemblyCost=asmCost;
+		massIncrement=massInc;
+		inventory=0;
+	}
+	
+	public PartComposite addSubPart(EntityManager em,  int quantity, Part subpart) {
+		Usage use = new Usage( this, quantity, subpart);
+		em.persist(use);
+		return this;
+	}
+
+	public double getAssemblyCost() {
+		return assemblyCost;
+	}
+
+	public void setAssemblyCost(double assemblyCost) {
+		this.assemblyCost = assemblyCost;
+	}
+
+
+	public double getMassIncrement() {
+		return massIncrement;
+	}
+
+	public void setMassIncrement(double massIncrement) {
+		this.massIncrement = massIncrement;
+	}
+	
+	public String toString() {
+	
+		return "PartComposite:"+partno+" name:+"+name+" assemblyCost:"+assemblyCost+" massIncrement:"+massIncrement;
+	}
+
+	public Collection<Usage> getPartsUsed() {
+		return partsUsed;
+	}
+
+	public void setPartsUsed(Collection<Usage> partsUsed) {
+		this.partsUsed = partsUsed;
+	}
+
+	public double getAssemblyTime() {
+		return assemblyTime;
+	}
+
+	public void setAssemblyTime(double assemblyTime) {
+		this.assemblyTime = assemblyTime;
+	}
+
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Supplier.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Supplier.java?rev=706481&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Supplier.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Supplier.java
Mon Oct 20 17:23:29 2008
@@ -0,0 +1,87 @@
+/*
+ * 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.jdbc.query.cache;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.DataCache;
+
+@Entity
+@DataCache
+
+public class Supplier {
+	
+	@Id  int sid;
+	@Column(length=20)
+	 String name;
+	
+	@ManyToMany
+	List<PartBase> supplies = new ArrayList<PartBase>();
+	
+	@Version 
+	long version;
+	
+	public Supplier(){}
+	
+	public Supplier(int sid, String name){
+		this.sid=sid;
+		this.name=name;
+	}
+	
+	public Supplier addPart( PartBase p ) {
+		supplies.add(p);
+		p.getSuppliers().add(this);
+		return this;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public int getSid() {
+		return sid;
+	}
+
+	public void setSid(int sid) {
+		this.sid = sid;
+	}
+
+	public Collection<PartBase> getSupplies() {
+		return supplies;
+	}
+
+	public void setSupplies(List<PartBase> supplies) {
+		this.supplies = supplies;
+	}
+	
+	public String toString() {
+
+		return "Supplier:"+sid+" name:+"+name;
+	}
+
+	
+
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/TestQueryTimestampEviction.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/TestQueryTimestampEviction.java?rev=706481&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/TestQueryTimestampEviction.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/TestQueryTimestampEviction.java
Mon Oct 20 17:23:29 2008
@@ -0,0 +1,207 @@
+/*
+ * 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.jdbc.query.cache;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.datacache.ConcurrentQueryCache;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.QueryResultCacheImpl;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.util.CacheMap;
+
+public class TestQueryTimestampEviction extends SingleEMFTestCase {
+    public void setUp() throws Exception {
+        super.setUp(Part.class, PartBase.class, PartComposite.class,
+            Supplier.class, Usage.class,
+            "openjpa.DataCache", "true",
+            "openjpa.QueryCache",
+            "CacheSize=1000, evictPolicy='timestamp'",
+            "openjpa.RemoteCommitProvider", "sjvm");
+
+        if (recreateData) {
+            // deletes any data leftover data in the database due to the failed
+            // last run of this testcase
+            deleteAllData(); 
+            reCreateData();
+        }
+    }
+
+    private  boolean deleteData = false;
+    private  boolean recreateData = true;
+
+    public void testLoadQueries() {
+
+        loadQueryCache();
+        int cacheSizeBeforeUpdate = queryCacheGet();
+        updateAnEntity();
+        int cacheSizeAfterUpdate = queryCacheGet();
+
+        // If evictPolicy is timestamp the querycache size should be equal to
+        // cacheSizeBeforeUpdate value.
+        String evictPolicy = getQueryCache().getEvictPolicy();
+
+        if(evictPolicy.equalsIgnoreCase("timestamp")) 
+            assertEquals(cacheSizeBeforeUpdate, cacheSizeAfterUpdate);
+
+        this.recreateData = false;
+    }
+
+    public void testEviction() {
+        loadQueryCache();
+        try {
+            Thread.sleep(20);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        updateAnEntity();
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        String insert1 = "insert into part(partno,parttype,name,cost,mass)" +
+            " values(13,'PartBase','breakes',1000.0,100.0)";
+        em.createNativeQuery(insert1).executeUpdate();
+        String insert2 = "insert into supplier_part(suppliers_sid," +
+            "supplies_partno) values(1,13)";
+        em.createNativeQuery(insert2).executeUpdate();
+
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        String sql = "select partno from part where cost > 120 ";
+        Query nativeq = em.createNativeQuery(sql);
+        List nativelist = nativeq.getResultList();
+
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        Query q = em.createQuery("select p from PartBase p where p.cost>?1");
+        q.setParameter(1, new Double(120));
+        List jpalist = q.getResultList();
+
+        em.getTransaction().commit();
+        em.close();
+
+        // The resultlist of nativelist and jpalist should be the same 
+        // in both eviction policies(dafault/timestamp)
+        assertEquals(nativelist.size(),jpalist.size());
+
+        this.deleteData = true;
+        this.recreateData = true;
+    }
+
+    private void loadQueryCache() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        String qry = "select p from PartBase p where p.cost > ?1";
+        for (int i=120; i<155; i++) {
+            Query q = em.createQuery(qry);
+            q.setParameter(1, new Double(i));
+            q.getResultList();
+        }
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    private void updateAnEntity() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        //Update entity
+        PartBase p = em.find(PartBase.class,11);
+        double oldcost = p.getCost();
+        if (p != null) 
+            p.setCost((oldcost + 10.0));
+
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    private ConcurrentQueryCache getQueryCache() {
+        OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf);
+        QueryResultCacheImpl scache = (QueryResultCacheImpl) oemf.
+            getQueryResultCache();
+
+        return (ConcurrentQueryCache ) scache.getDelegate();
+    }
+
+    private int  queryCacheGet() {
+        ConcurrentQueryCache dcache = getQueryCache();
+        CacheMap map = dcache.getCacheMap();
+        return map.size();
+    }
+
+    public void tearDown() throws Exception {
+        if (deleteData)
+            deleteAllData();
+    }
+
+    private void reCreateData() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        Supplier s1 = new Supplier(1, "S1");
+        em.persist(s1);
+        Supplier s2 = new Supplier(2, "S2");
+        em.persist(s2);
+        Supplier s3 = new Supplier(3, "S3");
+        em.persist(s3);
+
+        PartBase p1 = new PartBase(10, "Wheel", 150, 15.00);
+        em.persist(p1);
+        PartBase p2 = new PartBase(11, "Frame", 550.00, 25.00);
+        em.persist(p2);
+        PartBase p3 = new PartBase(12, "HandleBar", 125.00, 80.00);
+        em.persist(p3);
+
+        s1.addPart(p1).addPart(p2).addPart(p3);
+        s2.addPart(p1).addPart(p3);
+
+        PartComposite p4 = new PartComposite(20, "Bike", 180, 1.0);
+        em.persist(p4);
+        p4.addSubPart(em, 2, p1).addSubPart(em, 1, p2).addSubPart(em, 1, p3);
+
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    private void deleteAllData() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        em.createNativeQuery("delete from supplier_part").executeUpdate();
+        em.createQuery("delete from PartBase s").executeUpdate();
+        em.createQuery("delete from Supplier s").executeUpdate();
+        em.createQuery("delete from Usage u").executeUpdate();
+        em.createQuery("delete from Part p").executeUpdate();
+
+        em.getTransaction().commit();
+        em.close();
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Usage.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Usage.java?rev=706481&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Usage.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/cache/Usage.java
Mon Oct 20 17:23:29 2008
@@ -0,0 +1,95 @@
+/*
+ * 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.jdbc.query.cache;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.DataCache;
+
+@Entity
+@DataCache(timeout=100000)
+
+public class Usage {
+	@Id  
+	@GeneratedValue(strategy=GenerationType.IDENTITY)
+	 int id;
+	 int quantity;
+	 
+	@ManyToOne
+	 Part child;
+	@ManyToOne
+	 PartComposite parent ;
+	
+	@Version
+	long version;
+	
+	
+	public Usage(PartComposite p, int quantity, Part subpart) {
+		parent=p;
+		this.quantity=quantity;
+		parent.getPartsUsed().add(this);
+		setChild(subpart);
+		subpart.getUsedIn().add(this);
+	}
+	
+	// JPA entity needs a public no-arg constructor ! 
+	public Usage() {}
+
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public Part getParent() {
+		return parent;
+	}
+
+	public void setParent(PartComposite parent) {
+		this.parent = parent;
+	}
+
+	public int getQuantity() {
+		return quantity;
+	}
+
+	public void setQuantity(int quantity) {
+		this.quantity = quantity;
+	}
+
+	public Part getChild() {
+		return child;
+	}
+
+	public void setChild(Part child) {
+		this.child = child;
+	}
+
+	public String toString() {
+		return "Usage:"+id+" quantity:"+quantity+" child:"+child.getPartno()+" parent"+parent.getPartno();
+	}
+
+	
+	
+	
+
+}



Mime
View raw message