Skip Headers
Oracle® Coherence Tutorial for Oracle Coherence
Release 3.6

Part Number E15831-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

9 Interacting with the Cache and the Database

In this chapter, you create and configure an Oracle Coherence cache in Oracle JDeveloper using all the concepts presented in this tutorial. In this exercise you will:

This chapter has the following sections:

9.1 Introduction

A Coherence cache is a collection of data objects that serves as an intermediary between the database and the client applications. Database data may be loaded into a cache and made available to different applications. Thus, Coherence caches reduce load on the database and provide faster access to database data.

Coherence caches provide higher availability through database isolation and data replication. Modifications made to a cache may be synchronized with the database whenever the database is available. Even if the database or an application server node is not available, database updates are still reliable due to the lazy load and lazy write mechanism used by a Coherence cache and due to the failover and fail back provided by Oracle Coherence.

Coherence caches provide distributed processing not only across a cluster of application server nodes but also across the data objects in the cache, because data modification operations may be performed on the data objects.

Oracle Coherence also provides event-based processing. The state of data objects in a cache may be monitored and actions invoked on other processes such as the start of a business process execution language (BPEL) process.

Oracle Coherence supports different types of caches.

Oracle Coherence is implemented by using services such as the cluster service, the distributed cache service, and the replicated cache service. Whichever type of cache is used, an application uses the same API to access and store data.

The cache configuration deployment descriptor is used to configure a cache. The root element of the cache configuration file is cache-config. Cache names and name patterns are mapped to cache types in the caching-scheme-mapping element using the subelement cache-mapping. Cache types are defined in the caching-schemes element. Some of the commonly used cache types are described in Table 9-1.

Table 9-1 Descriptions of Cache Types

Cache Type Description

distributed scheme

Defines a distributed cache in which data is stored across a cluster of nodes

replicated scheme

Defines a cache in which cache entries are replicated across all the cluster nodes

read-write-backing-map scheme

Defines a map, which provides a cache of a persistent store such as a relational database

external scheme

Defines an external cache such as a disk

class scheme

Defines a custom cache implementation, which is required to implement the java.util.Map interface


9.2 Creating a Cache Application

This section describes how to create and run an application that puts and gets cache data.

  1. Create an Application which Creates a Cache

  2. Create a Cache Configuration File

  3. Configure the Project Properties

  4. Edit the Cache Server Start-Up File

  5. Run the Cache Creation Application

9.2.1 Create an Application which Creates a Cache

Follow these steps to create a Java class which creates a Coherence cache:

  1. Create a project in Oracle JDeveloper.

    1. Create a project called Interact in Oracle JDeveloper. See "Creating a New Project in an Existing Application" if you need detailed information.

    2. Add the Coherence JAR file coherence.jar and C:\home\oracle\labs to the project classpath. Also add the Oracle JDBC library, which is required for database access to the project libraries.

      Figure 9-1 Adding Coherence Jar, Labs Directory, and JDBC Libraries to the Classpath

      Adding the Oracle JDBC Libraries to the Classpath
  2. Create a Java class, CoherenceCache, that will be used to create a Coherence cache. See "Creating a Java Class" if you need detailed information on creating a class.

    1. Create a cache in the CoherenceCache Java class. Import the CacheFactory class and the NamedCache interface.

      import com.tangosol.net.CacheFactory; 
      import com.tangosol.net.NamedCache;
      
    2. An instance of a cache is created from the CacheFactory class. Create a NamedCache using the getCache() method of the CacheFactory class. Use the cache name VirtualCache, which is mapped to a distributed caching scheme.

      NamedCache cache = CacheFactory.getCache ( "VirtualCache");
      
    3. A NamedCache is a java.util.Map that holds resources that are shared across nodes in a cluster. Add a cache entry using the put() method.

      cache.put (key, "Hello Cache");
      
    4. A cache entry can be retrieved using the get() method.

      System.out.println((String)cache.get("hello"));
      

      Example 9-1 illustrates a possible solution. You can copy the code to the CoherenceCache application in Oracle JDeveloper.

      Example 9-1 Implementation of a Coherence Cache

      package com.oracle.handson;
      
      import com.tangosol.net.CacheFactory; 
      import com.tangosol.net.NamedCache;
      
      public class CoherenceCache {
          NamedCache cache;
          public CoherenceCache() {
          }
          public void putCache(){
                  cache = CacheFactory.getCache ( "VirtualCache"); 
                 String key = "hello"; 
                 cache.put (key, "Hello Cache"); 
             
             }
             
             public void retrieveCache(){
             
                 System.out.println((String)cache.get("hello"));
      
             }
             
              public static void main (String [] args) {
              CoherenceCache cache = new CoherenceCache(); 
              cache.putCache();
              cache.retrieveCache();
              }
      }
      

9.2.2 Create a Cache Configuration File

Create an XML document, cache-config.xml, as the cache configuration deployment descriptor.

To add the XML document, right-click the project and choose New. In the New Gallery window, select XML under General categories. Select XML Document and click OK. Change the File Name to cache-config.xml. Change the directory to C:\home\oracle\labs\.

In the cache configuration file:

  • Define mapping for cache names and naming patterns with the cache-mapping elements in the caching-scheme-mapping element.

  • Map the cache name VirtualCache to cache type default-distributed.

  • Define the distributed caching scheme with the distributed-scheme element using the DistributedCache service.

The cache configuration file is listed in Example 9-2. Copy the contents of this example to the cache-config.xml file in Oracle JDeveloper.

Example 9-2 Cache Configuration File

<?xml version="1.0"?>
<!DOCTYPE cache-config SYSTEM "cache-config.dtd">
<cache-config>
    <caching-scheme-mapping>
        
        <cache-mapping>
            <cache-name>VirtualCache</cache-name>
            <scheme-name>default-distributed</scheme-name>
        </cache-mapping>
    </caching-scheme-mapping>
    <caching-schemes>
        <!--
        Default Distributed caching scheme.
        -->
        <distributed-scheme>
            <scheme-name>default-distributed</scheme-name>
            <service-name>DistributedCache</service-name>
            <backing-map-scheme>
                <class-scheme>
                    <scheme-ref>default-backing-map</scheme-ref>
                </class-scheme>
            </backing-map-scheme>
        </distributed-scheme>
         <class-scheme>
            <scheme-name>default-backing-map</scheme-name>
            <class-name>com.tangosol.util.SafeHashMap</class-name>
         </class-scheme>
  <autostart>true</autostart>
 </caching-schemes>
</cache-config>

9.2.3 Configure the Project Properties

Modify the Run configuration for the application to add the cache configuration file as a run-time Java option.

  1. Select the project node and select Tools then Project Properties. In the Project Properties window, select Run/Debug/Profile. The Default configuration is selected by default. Click Edit for the Default configuration.

  2. In the Edit Run Configuration window, select Launch Settings. In the Java Options field, specify the cache configuration file (cache-config.xml) with -Dtangosol.coherence.cacheconfig.

    For example, for the Oracle Coherence application that you created, specify the following (your path to cache-config.xml may vary) in the Java Options field and click OK.

    -Dtangosol.coherence.cacheconfig=/home/oracle/labs/cache-config.xml
    

    Figure 9-2 Setting the Runtime Options

    Setting the Cache Configuration File for Runtime Options

    Click OK in the Run/Debug/Profile window. The cache configuration file will be added as a run-time Java option to the Coherence Java application.

9.2.4 Edit the Cache Server Start-Up File

Edit the JPA cache server (jpa-cache-server.cmd) start-up file that you created in Chapter 8, "Using JPA with Coherence".

Replace the name of the cache configuration file, "jpa-cache-config.xml", with "cache-config.xml".

-Dtangosol.coherence.cacheconfig=\home\oracle\labs\cache-config.xml

In the classpath, replace the path to the JPA\classes directory with the path to the Interact\classes directory.

C:\home\oracle\labs\Interact\classes; 

9.2.5 Run the Cache Creation Application

Follow these steps to run the cache creation application CoherenceCache.java.

  1. Stop any running cache servers. Run jpa-cache-server.cmd to start the cache server.

  2. Right-click the Oracle Coherence application CoherenceCache.java and click Run. The JDeveloper Log window displays the output:

    • the operational configuration is loaded from tangosol-coherence.xml. This file specifies the operational and run-time settings used by Coherence for its clustering, communication, and data management services.

    • the cache configuration is loaded from cache-config.xml.

    • a new cluster is created and the DistributedCache service joins the cluster.

    • the output of the CoherenceCache.java program, Hello Cache is displayed.

    Example 9-3 Output of the Coherence Cache Application

    2010-06-02 17:11:36.197/0.313 Oracle Coherence 3.6.0.0 DPR3 <Info> (thread=main, member=n/a): Loaded operational configuration from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence.xml"
    2010-06-02 17:11:36.213/0.329 Oracle Coherence 3.6.0.0 DPR3 <Info> (thread=main, member=n/a): Loaded operational overrides from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence-override-dev.xml"
    2010-06-02 17:11:36.213/0.329 Oracle Coherence 3.6.0.0 DPR3 <D5> (thread=main, member=n/a): Optional configuration override "/tangosol-coherence-override.xml" is not specified
    2010-06-02 17:11:36.213/0.329 Oracle Coherence 3.6.0.0 DPR3 <D5> (thread=main, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified
    
    Oracle Coherence Version 3.6.0.0 DPR3 Build 16141
     Grid Edition: Development mode
    Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
    
    2010-06-02 17:11:36.431/0.547 Oracle Coherence GE 3.6.0.0 DPR3 <Info> (thread=main, member=n/a): Loaded cache configuration from "file:/C:/home/oracle/labs/cache-config.xml"
    2010-06-02 17:11:36.853/0.969 Oracle Coherence GE 3.6.0.0 DPR3 <D4> (thread=main, member=n/a): SystemSocketProvider bound to port 8088
    2010-06-02 17:11:40.353/4.469 Oracle Coherence GE 3.6.0.0 DPR3 <Info> (thread=Cluster, member=n/a): Created a new cluster "cluster:0xC4DB" with Member(Id=1, Timestamp=2010-06-02 17:11:36.869, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:4884, Role=OracleHandsonCoherenceCache, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1) UID=0x822363D500000128FB261625C2D51F98
    2010-06-02 17:11:40.353/4.469 Oracle Coherence GE 3.6.0.0 DPR3 <Info> (thread=main, member=n/a): Started cluster Name=cluster:0xC4DB
    
    Group{Address=224.3.6.0, Port=36000, TTL=4}
    
    MasterMemberSet
      (
      ThisMember=Member(Id=1, Timestamp=2010-06-02 17:11:36.869, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:4884, Role=OracleHandsonCoherenceCache)
      OldestMember=Member(Id=1, Timestamp=2010-06-02 17:11:36.869, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:4884, Role=OracleHandsonCoherenceCache)
      ActualMemberSet=MemberSet(Size=1, BitSetCount=2
        Member(Id=1, Timestamp=2010-06-02 17:11:36.869, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:4884, Role=OracleHandsonCoherenceCache)
        )
      RecycleMillis=1200000
      RecycleSet=MemberSet(Size=0, BitSetCount=0
        )
      )
    
    TcpRing{Connections=[]}
    IpMonitor{AddressListSize=0}
    
    2010-06-02 17:11:40.431/4.547 Oracle Coherence GE 3.6.0.0 DPR3 <D5> (thread=Invocation:Management, member=1): Service Management joined the cluster with senior service member 1
    2010-06-02 17:11:40.697/4.813 Oracle Coherence GE 3.6.0.0 DPR3 <D5> (thread=DistributedCache, member=1): Service DistributedCache joined the cluster with senior service member 1
    Hello Cache
    2010-06-02 17:11:40.775/4.891 Oracle Coherence GE 3.6.0.0 DPR3 <D4> (thread=ShutdownHook, member=1): ShutdownHook: stopping cluster node
    2010-06-02 17:11:40.775/4.891 Oracle Coherence GE 3.6.0.0 DPR3 <D5> (thread=Cluster, member=1): Service Cluster left the cluster
    Process exited with exit code 0.
    

9.3 Creating a Database Cache

In this section, create a cache backed by the Oracle database. This is also referred to as an "Oracle database cache".

  1. Create an Oracle Database Cache

  2. Create a Class to Define a Custom CacheStore

  3. Modify the Cache Configuration File

  4. Create a Class to Create the Database Cache

  5. Run the Database Cache Application

9.3.1 Create an Oracle Database Cache

Follow these steps to use SQL*Plus and the Oracle Database 10g Express Edition (XE) to create an Oracle database cache. This section assumes that the database is installed on your system.

  1. Invoke SQL*Plus.

    Navigate to Start then All Programs then Oracle Database 10g Express Edition then Run SQL Command Line.

  2. Connect as hr user with hr as the password.

    connect hr/hr;
     
    
  3. Create an Oracle Database table.

    Open a text editor and copy the following SQL code. Save the file as dbscript.sql in the /home/oracle/labs/ folder.

    Example 9-4 SQL Script for Creating a Database Table

    CREATE TABLE HR.CATALOG(id VARCHAR(25) PRIMARY KEY, value VARCHAR(96)); 
    INSERT INTO HR.CATALOG VALUES('catalog1', 'Tuning Undo Tablespace');
    INSERT INTO HR.CATALOG VALUES('catalog2', 'Tuning Your View Objects');
    
  4. Run the SQL script.

    Example 9-5 illustrates the output from the script.

    Example 9-5 Running the SQL Script for Creating a Database Table

    SQL*Plus: Release 10.2.0.1.0 - Production on Wed Jun 2 16:30:15 2010
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    SQL> connect hr/hr;
    Connected.
    SQL> @/home/oracle/labs/dbscript.sql
    
    Table created
    
    1 row created
    
    1 row created
    

9.3.2 Create a Class to Define a Custom CacheStore

Follow these steps to create a Java class that connects to the database and retrieves table data.

  1. Create a Java class DBCacheStore in Oracle JDeveloper. See "Creating a Java Class" if you need detailed information.

  2. Create the code to connect to the database and get table data.

    Example 9-6 illustrates a possible solution. Copy the code to the DBCacheStore application in Oracle JDeveloper. The DBCacheStore application uses Java Database Connectivity (JDBC) to access Oracle Database, but you could use another mechanism, such as Hibernate or Java Data Objects (JDO), instead.

    Example 9-6 Database CacheStore Implementation

    package com.oracle.handson;
    
    import com.tangosol.net.cache.CacheStore;import com.tangosol.util.Base;
    
    import java.sql.DriverManager;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Collection;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    
    public class DBCacheStore
    
            extends Base
            implements CacheStore {
        
            protected Connection m_con;
            protected String m_sTableName;
            private static final String DB_DRIVER   = "oracle.jdbc.OracleDriver";
    
                
                private static final String DB_URL      = "jdbc:oracle:thin:@localhost:1521:XE";
                private static final String DB_USERNAME = "hr";
                private static final String DB_PASSWORD = "hr";
        
        public DBCacheStore(String sTableName)
            {
            m_sTableName = sTableName;
    
            configureConnection();        }
        protected void configureConnection()
            {
            try
                {
                Class.forName("oracle.jdbc.OracleDriver");
                m_con = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD);
                m_con.setAutoCommit(true);
                }
            catch (Exception e)
                {
                throw ensureRuntimeException(e, "Connection failed");
                }
            }
    
        public String getTableName()        {
            return m_sTableName;
            }
    
        public Connection getConnection()
            {
            return m_con;
            }
    
        public Object load(Object oKey)
            {
            Object     oValue = null;
            Connection con    = getConnection();
            String     sSQL   = "SELECT id, value FROM " + getTableName()
                        + " WHERE id = ?";
            try
                {
                PreparedStatement stmt = con.prepareStatement(sSQL);
    
                stmt.setString(1, String.valueOf(oKey));
                ResultSet rslt = stmt.executeQuery();
                if (rslt.next())
                    {
                    oValue = rslt.getString(2);
                    if (rslt.next())
                        {
                        throw new SQLException("Not a unique key: " + oKey);
                        }                }
                stmt.close();
                }
            catch (SQLException e)
                {
                throw ensureRuntimeException(e, "Load failed: key=" + oKey);
                }
            return oValue;
            }
    
          public void store(Object oKey, Object oValue)
            {
            Connection con     = getConnection();
            String     sTable  = getTableName();
            String     sSQL;
            
            if (load(oKey) != null)
                {
                
                sSQL = "UPDATE " + sTable + " SET value = ? where id = ?";
                }
            else
                {
                
                sSQL = "INSERT INTO " + sTable + " (value, id) VALUES (?,?)";
                }
            try
                {
                PreparedStatement stmt = con.prepareStatement(sSQL);
                int i = 0;
                stmt.setString(++i, String.valueOf(oValue));
                stmt.setString(++i, String.valueOf(oKey));
                stmt.executeUpdate();
                stmt.close();
                }
            catch (SQLException e)
                {
                throw ensureRuntimeException(e, "Store failed: key=" + oKey);
                }
            }
        public void erase(Object oKey)
            {
            Connection con  = getConnection();
            String     sSQL = "DELETE FROM " + getTableName() + " WHERE id=?";
            try
                {
                PreparedStatement stmt = con.prepareStatement(sSQL);
    
                stmt.setString(1, String.valueOf(oKey));
                stmt.executeUpdate();
                stmt.close();
                }
            catch (SQLException e)
                {
                throw ensureRuntimeException(e, "Erase failed: key=" + oKey);
                }
            }
        public void eraseAll(Collection colKeys)
            {
            throw new UnsupportedOperationException();
            }
    
        
    
        public Map loadAll(Collection colKeys)        {
            throw new UnsupportedOperationException();
            }
    
        public void storeAll(Map mapEntries)
            {
            throw new UnsupportedOperationException();
            }
       
        public Iterator keys()
            {
            Connection con  = getConnection();
            String     sSQL = "SELECT id FROM " + getTableName();
            List       list = new LinkedList();
            
            try
                {
                PreparedStatement stmt = con.prepareStatement(sSQL);
                ResultSet         rslt = stmt.executeQuery();
                while (rslt.next())
                    {
                    Object oKey = rslt.getString(1);
                    list.add(oKey);
                    }
                stmt.close();
                }
            catch (SQLException e)
                {
                throw ensureRuntimeException(e, "Iterator failed");
                }
    
            return list.iterator();
            }
        
        }
    

9.3.3 Modify the Cache Configuration File

Modify the cache configuration file (cache-config.xml) that you created earlier for the database cache.

To connect a cache to a back-end database, a cache configuration file (cache-config.xml) element cachestore-scheme is required. The cachestore-scheme element must be configured with a custom class that implements either the com.tangosol.net.cache.CacheLoader or com.tangosol.net.cache.CacheStore interface.

Copy the cache configuration file for the database cache in Example 9-7 and replace the existing code in the cache-config.xml file in Oracle JDeveloper.

Example 9-7 Database Cache Configuration File

<?xml version="1.0" encoding="UTF-8" ?>
<cache-config>
    <caching-scheme-mapping>
        
  <!-- 
    Caches with names that start with 'DBBacked' will be created 
    as distributed-db-backed.   
    -->
  <cache-mapping>
   <cache-name>DBBacked*</cache-name>
   <scheme-name>distributed-db-backed</scheme-name>
  </cache-mapping>
 </caching-scheme-mapping>
 <caching-schemes>
  <!-- 
    DB Backed Distributed caching scheme.
    -->
  <distributed-scheme>
   <scheme-name>distributed-db-backed</scheme-name>
   <service-name>DistributedCache</service-name>
   <backing-map-scheme>
    <read-write-backing-map-scheme>
     <internal-cache-scheme>
      <class-scheme>
       <class-name>com.tangosol.util.ObservableHashMap</class-name>
      </class-scheme>
     </internal-cache-scheme>
     <cachestore-scheme>  
      <class-scheme> 
       <class-name>com.oracle.handson.DBCacheStore</class-name> 
       <init-params>   
        <init-param> 
         <param-type>java.lang.String</param-type> 
         <param-value>CATALOG</param-value> 
        </init-param> 
       </init-params> 
      </class-scheme> 
     </cachestore-scheme>   
     <read-only>false</read-only>
     <!--
        To make this a write-through cache just change the value below to 0 (zero)
        -->
     <write-delay-seconds>0</write-delay-seconds>
    </read-write-backing-map-scheme>
   </backing-map-scheme>
   <listener/>
   <autostart>true</autostart>
  </distributed-scheme>
 </caching-schemes>
</cache-config>

In the cache configuration file, you have taken care of the following:

  • Define a cache name pattern DBBacked*, which is mapped to a distributed caching scheme distributed-db-backed.

  • Specify the CacheStore scheme in the distributed scheme using the class coherence.DBCacheStore, which implements the CacheStore interface.

  • An init parameter for the database table that is at the back end of the cache is specified for the DBCacheStore class. The table name is specified in the init-param element. The DBCacheStore class performs database operations such as reading and writing cache entries.

  • Coherence supports read/write caching of a data source for which the read-write-backing-map scheme is used. The read-write-backing-map scheme defines a backing map, which provides a size-limited cache of a persistent store. Here, you use the Write-Through mechanism. Oracle Coherence supports the types of read/write caching described in Table 9-2:

Table 9-2 Types of Read-Write Caching Supported by Coherence

Types of Read-Write Caching Action

Read-Through

A cache entry is read into a cache from the database when required and made available to an application.

Write-Through

Updates to cache entries are synchronized with the database without delay.

Refresh-Ahead

Cache entries are refreshed periodically.

Write-Behind

Updates to cache entries are asynchronously written to a database after a delay specified in the write-delay-seconds element in the cache configuration file.


9.3.4 Create a Class to Create the Database Cache

Create a Java class DatabaseCache for the database cache in Oracle JDeveloper. The class must contain a main method. See "Creating a Java Class" if you need detailed information.

In the class file, add code to add a cache entry, query a database cache, and retrieve a cache entry. Add the following methods: createCache(), addEntry(), retrieveEntry(), eraseEntry(), and queryCache(). You can copy the code that is listed in Example 9-8.

Example 9-8 Implementation for the Database Cache Class File

package com.oracle.handson;

import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
import com.tangosol.net.cache.ContinuousQueryCache;
import com.tangosol.util.Filter;
import com.tangosol.util.extractor.IdentityExtractor;
import com.tangosol.util.filter.LikeFilter;

import java.util.HashSet;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class DatabaseCache {
    NamedCache cache;
    public DatabaseCache() {
    }

    public void createCache() {
         cache = CacheFactory.getCache("DBBackedCache");
        //cache.put(new String("catalog3"), new String("Evolving Grid Management"));
           // System.out.println((String) cache.get( "catalog3"));
        
    }

    public void addEntry() {
    
        cache.put(new String("catalog3"), new String("Tuning Grid Management"));
        cache.put(new String("catalog4"), new String("Tuning Coherence"));
        cache.put(new String("catalog5"), new String("Tuning Database"));
        //System.out.println((String) cache.get( "catalog3"));
   
    }

    public void retrieveEntry() {
    System.out.println((String) cache.get( "catalog3"));
    }

    public void eraseEntry() {
    cache.remove(new String("catalog3"));
    }

    public void queryCache() {
        Filter filter = new LikeFilter(IdentityExtractor.INSTANCE, "Tuning%", '\\', true);
        HashSet hashSet=new HashSet();
        hashSet.add(new String("catalog3"));
        hashSet.add(new String("catalog4"));
        hashSet.add(new String("catalog5"));

        Map map=cache.getAll(hashSet);
        //ContinuousQueryCache queryCache = new ContinuousQueryCache(cache, filter);
        //Set results = queryCache.entrySet(filter);
        Set results = cache.entrySet(filter);
       /* Set results = cache.entrySet(filter);*/
        
        

       // if(results.isEmpty())
       // System.out.println("Result Set Empty");
            for (Iterator i = results.iterator(); i.hasNext();)
                {
                Map.Entry e = (Map.Entry) i.next();
                System.out.println("Catalog ID: "+e.getKey() + ", Title: "+e.getValue());
                }
    }
    

    public static void main(String[] args) {
        DatabaseCache databaseCache = new DatabaseCache();
        databaseCache.createCache();
       databaseCache.addEntry();
       //databaseCache.retrieveEntry();
        //databaseCache.eraseEntry();
       databaseCache.queryCache();
    }
}

Note the following features of the code:

  • A NamedCache object is created using the getCache() method of the CacheFactory class in the createCache() method.

    NamedCache cache = CacheFactory.getCache("DBBackedCache");
    
  • The DBBackedCache matches the cache pattern DBBacked* and is, therefore, mapped to a distributed caching scheme distributed-db-backed in the cache-config.xml file. Add a cache entry using the put() method of the NamedCache object.

    cache.put(new String("catalog3"), new String("Tuning Grid Management"));
    
  • Because the Write-Through mechanism is used, the new cache entry also gets synchronized with the database; a new row is added to the CATALOG table. Comment out all the methods except the createCache() and addEntry() methods.

  • When the put() method is invoked, the store() method, which maps the new cache entry to the database table CATALOG using JDBC, gets invoked in the DBCacheStore class. The output from the Oracle Coherence application is displayed in the Log window and a new cache entry is added. The output shows that the operational configuration deployment descriptor is loaded, the cache configuration is loaded, a new cluster is created, and the DistributedCache service has joined the cluster.

  • The new cache entry may be removed with the remove() method of the NamedCache object.

    cache.remove(new String("catalog3"));
    
  • Bulk uploading of cache entries is performed using the putAll() method.

  • A cache entry is retrieved using the get() method of the NamedCache object. For example, retrieving the cache entry for ID catalog1:

    System.out.println((String) cache.get("catalog1"));
    
  • When the get() method is invoked, the load() method, which retrieves database table data using JDBC, gets invoked in the DBCacheStore class.

  • Bulk retrieval is performed using the getAll() method of the NamedCache object.

  • Oracle Coherence supports searching for cache entries based on a search criteria using filters. Coherence filters are available in the com.tangosol.util.filter package. In Oracle Coherence Enterprise Edition and Grid Edition, indexes may be added to the Coherence cache to improve performance. You query the database cache using a LikeFilter filter, which matches cache entries with a specified pattern. To query a database cache, the cache entries must be created before querying, and the cache entries must be retrieved into the cache using the get() or getAll() method before a query using a filter may be performed. Therefore, you can retrieve database data and create a collection of cache entries using the getAll() method.

    HashSet hashSet=new HashSet(); 
    hashSet.add(new String("catalog1")); 
    hashSet.add(new String("catalog2")); 
    hashSet.add(new String("catalog3")); 
    Map map=cache.getAll(hashSet);
    
  • A LikeFilter filter is created to search for cache entries starting with Tuning.

    Filter filter = new LikeFilter(IdentityExtractor.INSTANCE, "Tuning%", '\\', true);
    
  • The database cache is queried using the entrySet() method with the LikeFilter filter.

    Set results = cache.entrySet(filter);
    
  • Iterate over the results of the query to output the cache entries retrieved.

    for (Iterator i = results.iterator(); i.hasNext();) {
       Map.Entry e = (Map.Entry) i.next();
       System.out.println("Catalog ID: "+e.getKey() + ", Title: "+e.getValue());
    }
    
  • Oracle Coherence supports continuous query using the com.tangosol.net.cache.ContinuousQueryCache class. A continuous query is a query that is kept up-to-date using a continuous query cache. In a ContinuousQueryCache, the results of a query are updated using event listeners on events that could change the results of the query. Create a ContinuousQueryCache object using the NamedCache object and the LikeFilter object.

    ContinuousQueryCache queryCache = new ContinuousQueryCache(cache, filter );
    
  • A result set is created using the entrySet() method.

    Set results = queryCache.entrySet(filter);
    

9.3.5 Run the Database Cache Application

Follow these steps to run the Oracle database cache application.

  1. Modify the Run configuration for the Interact application to turn off local storage with -Dtangosol.coherence.distributed.localstorage=false.

    Figure 9-3 Turning Off Local Storage

    Turning Off Local Storage
  2. Stop any running cache servers. Start the cache server (jpa-cache-server.cmd).

  3. Right-click the DatabaseCache application in Oracle JDeveloper and select Run. Figure 9-4 illustrates the expected results.

    Figure 9-4 Results from Running the DatabaseCache Application

    Results from Running the DatabaseCache Application

    If you receive any exceptions, such as the following:

    java.lang.IllegalArgumentException: No scheme for cache: "cachename, 
    

    You may be able to remove them by editing the cache-config.xml file and replacing DBBacked* in the <cache-name> element with *. Save the file. Re-run the DatabaseCache application in Oracle JDeveloper. You should not see any exceptions now.

  4. Note that because you are using a Write-Through cache, the database table also gets updated. From the SQL prompt, enter the following code:

    select * from hr.catalog;
    

    Example 9-9 illustrates the results.

    Example 9-9 Output from the select Command

    ....
    SQL> select * from hr.catalog;
    
    -------------------------
    VALUE
    -------------------------------------------------------------------
    catalog3
    Tuning Grid Management
    catalog4
    Tuning Coherence
    
    catalog5
    Tuning Database
    
    
    ID
    -------------------------
    VALUE
    -------------------------------------------------------------------
    catalog1
    Tuning Undo Tablespace
    
    catalog2
    Tuning Your View Objects