Skip Headers
Oracle® Coherence Tutorial for Oracle Coherence
Release 3.7.1

E22622-03
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 will create and configure an Oracle Coherence cache in Eclipse. In this exercise you will create these items:

This chapter contains the following sections:

9.1 Introduction

A Coherence cache is a collection of data objects that acts as an intermediary between the database and the client applications. Database data can 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 can 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 can be performed on the data objects.

Oracle Coherence also provides event-based processing. The state of data objects in a cache can 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.

A 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. Table 9-1 describes some of the cache types commonly used by Coherence.

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 data into the cache and retrieves it.

  1. Create an Application that Constructs a Cache

  2. Create a Cache Configuration File

  3. Configure the Project Properties

  4. Create the Cache Server Start-Up Configuration

  5. Run the Cache Creation Application

9.2.1 Create an Application that Constructs a Cache

To create a Java class that constructs a Coherence cache:

  1. Create a project in Eclipse.

    1. Use the JPA perspective in Eclipse to create a JPA Project called Interact. Select the JPAConfiguration you created in the previous chapter.

    2. In the Coherence page, select Coherence37 and EclipseLink2.1.2 - Helios.

    3. In the JPA Facet page, ensure that EclipseLink 2.1.x appears in the Platform field. In the Connection field, select the connection you created in "Configure the Project for JPA" (XE_HR), from the Connection drop down list. Click the Connect link to connect to the Oracle XE Database. Click Finish. (Note, this assumes that the database connection that you created is still running.)

  2. Create a Java class, CoherenceCache, that will be used to create a Coherence cache. Include a main method in the class. See "Creating a Java Class" for 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. Create the cache (NamedCache) instance by using the CacheFactory.getCache method. 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 instance that holds resources that are shared across nodes in a cluster. Add a cache entry by using the put method.

      cache.put (key, "Hello Cache");
      
    4. Retrieve a cache entry by using the get method.

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

      Example 9-1 illustrates a possible implementation of CoherenceCache class. You can copy the code to the CoherenceCache application in Eclipse.

      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. Save the file to the C:\home\oracle\workspace folder.

In the cache configuration file:

  • Define mappings 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 illustrated in Example 9-2. Copy the contents of this example to the cache-config.xml.

Example 9-2 Cache Configuration File

<?xml version="1.0"?>
<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
              xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd">
    <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

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

  1. Right click CoherenceCache.java in the Project Explorer and choose Run As then Run Configurations. In the Run Configurations dialog box, click the New launch configuration icon.

  2. Enter CoherenceCache in the Name field. Ensure that Interact is in the Project field and com.oracle.handson.CoherenceCache is in the Main class field.

  3. In the Coherence tab, enter the path to the cache configuration file, C:\home\oracle\workspace\cache-config.xml. Select the Enabled (cache server) button. Enter a unique value, such as 3155, in the Cluster port field. Click Apply.

  4. In the Classpath tab, Use the Add External JARs button to add the coherence.jar file to User Entries. When you are finished, the Classpath tab should look similar to Figure 9-1.

    Figure 9-1 Classpath for the CoherenceCache Program

    Classpath for the CoherenceCache Program
    Description of "Figure 9-1 Classpath for the CoherenceCache Program"

9.2.4 Create the Cache Server Start-Up Configuration

To create a cache sever start-up configuration for the Interact project:

  1. Right click the Interact project and select Properties. In the Properties for Interact dialog box, select Java Build Path. In the Order and Export tab, the Interact project and the JRE, EAR, Coherence37, EclipseLink 2.1.2 - Helios, and the Oracle Database 10g Driver Default libraries should be present. Click Select All. The Order and Export tab should look similar to Figure 9-2.

    Figure 9-2 Order and Export Tab for Libraries for the Java Build Path

    Order and Export for Libraries for the Java Build Path
    Description of "Figure 9-2 Order and Export Tab for Libraries for the Java Build Path "

  2. Edit the JPA cache server start-up configuration (JPACacheServer) that you created in Chapter 8, "Using JPA with Coherence".

  3. Right click the Interact project and select Run As then Run Configurations. In the Main tab click Browse and select the Interact project from the Project Selection dialog box.

  4. In the General tab of the Coherence tab, replace the name and path of the configuration file with C:\home\oracle\workspace\cache-config.xml.

  5. In the Classpath tab, remove the JPA (default classpath) folder. Click Add Project to add the Interact project. The Classpath tab should look similar to Figure 9-3.

    Figure 9-3 Classpath for the Interact Project Cache Server

    The Classpath tab for the Interact Project Cache Server
    Description of "Figure 9-3 Classpath for the Interact Project Cache Server"

  6. In the Shared file field of the Common tab, click Browse to select the Interact project. Click Apply, then Close.

9.2.5 Run the Cache Creation Application

To run the cache creation application CoherenceCache.java:

  1. Stop any running cache servers. See "Stopping Cache Servers" for more information.

  2. Run the jpa-cache-server.cmd file to start the cache server.

  3. Right-click the Oracle Coherence application CoherenceCache.java and click Run As then Run Configurations. Select the CoherenceCache configuration and click Run. The Eclipse console window displays the output:

    • The operational configuration is loaded from the tangosol-coherence.xml file. 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 the cache-config.xml file.

    • 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

    2011-03-15 13:03:17.202/0.313 Oracle Coherence 3.7.0.0 <Info> (thread=main, member=n/a): Loaded operational configuration from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence.xml"
    2011-03-15 13:03:17.249/0.360 Oracle Coherence 3.7.0.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence-override-dev.xml"
    2011-03-15 13:03:17.280/0.391 Oracle Coherence 3.7.0.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "file:/C:/home/oracle/workspace/Interact/build/classes/tangosol-coherence-override.xml"
    2011-03-15 13:03:17.280/0.391 Oracle Coherence 3.7.0.0 <D5> (thread=main, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified
     
    Oracle Coherence Version 3.7.0.0 Build 22913
     Grid Edition: Development mode
    Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
     
    2011-03-15 13:03:17.436/0.547 Oracle Coherence GE 3.7.0.0 <Info> (thread=main, member=n/a): Loaded cache configuration from "file:/C:/home/oracle/workspace/cache-config.xml"
    2011-03-15 13:03:17.624/0.735 Oracle Coherence GE 3.7.0.0 <D4> (thread=main, member=n/a): TCMP bound to /130.35.99.213:8088 using SystemSocketProvider
    2011-03-15 13:03:21.202/4.313 Oracle Coherence GE 3.7.0.0 <Info> (thread=Cluster, member=n/a): Created a new cluster "cluster:0x96AB" with Member(Id=1, Timestamp=2011-03-15 13:03:17.639, Address=130.35.99.213:8088, MachineId=49877, Location=site:URL, machine_name,process:2084, Role=OracleHandsonCoherenceCache, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1) UID=0x822363D50000012E733B6C87C2D51F98
    2011-03-15 13:03:21.217/4.328 Oracle Coherence GE 3.7.0.0 <Info> (thread=main, member=n/a): Started cluster Name=cluster:0x96AB
     
    Group{Address=224.3.7.0, Port=3155, TTL=4}
     
    MasterMemberSet
      (
      ThisMember=Member(Id=1, Timestamp=2011-03-15 13:03:17.639, Address=130.35.99.213:8088, MachineId=49877, Location=site:URL, machine_name,process:2084, Role=OracleHandsonCoherenceCache)
      OldestMember=Member(Id=1, Timestamp=2011-03-15 13:03:17.639, Address=130.35.99.213:8088, MachineId=49877, Location=site:URL, machine_name,process:2084, Role=OracleHandsonCoherenceCache)
      ActualMemberSet=MemberSet(Size=1, BitSetCount=2
        Member(Id=1, Timestamp=2011-03-15 13:03:17.639, Address=130.35.99.213:8088, MachineId=49877, Location=site:URL, machine_name,process:2084, Role=OracleHandsonCoherenceCache)
        )
      RecycleMillis=1200000
      RecycleSet=MemberSet(Size=0, BitSetCount=0
        )
      )
     
    TcpRing{Connections=[]}
    IpMonitor{AddressListSize=0}
     
    2011-03-15 13:03:21.264/4.375 Oracle Coherence GE 3.7.0.0 <D5> (thread=Invocation:Management, member=1): Service Management joined the cluster with senior service member 1
    2011-03-15 13:03:21.405/4.516 Oracle Coherence GE 3.7.0.0 <D5> (thread=DistributedCache, member=1): Service DistributedCache joined the cluster with senior service member 1
    Hello Cache
    

9.3 Creating a Database Cache

In this section, create a cache backed by 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 Cache Store

  3. Modify the Cache Configuration File

  4. Create a Class to Construct the Database Cache

  5. Run the Database Cache Application

9.3.1 Create an Oracle Database Cache

To use SQL*Plus and the Oracle Database Express Edition (Oracle XE) to create an Oracle Database cache follow these steps. You must have the database installed on your system.

  1. Invoke SQL*Plus.

    Navigate to Start then All Programs then Oracle Database Express Edition and 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 it as a file named dbscript.sql in the /home/oracle/workspace/ 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 Tue March 1 13:38:59 2011
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    
    SQL> connect hr/hr;
    Connected.
    SQL> @/home/oracle/workspace/dbscript.sql
    
    Table created
    
    1 row created
    
    1 row created
    

9.3.2 Create a Class to Define a Custom Cache Store

To create a Java class that connects to the database and retrieves table data:

  1. Create a Java class DBCacheStore in Eclipse. See "Creating a Java Class" for detailed information.

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

    Example 9-6 illustrates a possible implementation of the DBCacheStore class. Copy the code to the DBCacheStore application in the Eclipse IDE. 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 Cache Store 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 database, you must configure the cachestore-scheme element with a custom class that implements either the com.tangosol.net.cache.CacheLoader or com.tangosol.net.cache.CacheStore interface.

Replace the code in the existing cache-config.xml file in Eclipse with the cache configuration code for the database cache in Example 9-7.

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 done the following:

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

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

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

  • Specified a read-write-backing-map-scheme as the backing map. This scheme defines a backing map, which provides a size-limited cache of a persistent store. Here, by setting the write-delay-seconds parameter to 0, you specify the write-through mechanism.

    Table 9-2 describes the types of read/write caching that you can use with Oracle Coherence.

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 a 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 Construct the Database Cache

Create a Java class DatabaseCache for the database cache in Eclipse. The class must contain a main method. See "Creating a Java Class" for detailed information.

In the class file, provide the 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(). Example 9-8 illustrates a possible implementation.

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");
         }

    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"));
        }

    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);
       Set results = cache.entrySet(filter);
        
           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.queryCache();
       }
}

Note the following features of the database cache class file:

  • 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 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 can 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 can 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 can 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);
    
  • Create a LikeFilter filter to search for cache entries starting with Tuning.

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

    Set results = cache.entrySet(filter);
    
  • Iterate over the results of the query. Display the key and value of the cache entries that are 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 );
    
  • Create a result set by using the entrySet() method.

    Set results = queryCache.entrySet(filter);
    

9.3.5 Run the Database Cache Application

To run the Oracle Database cache application:

  1. Stop any running cache servers. See "Stopping Cache Servers" for more information.

  2. Start the cache server (JPACacheServer). Right click the project and select Run As then Run Configurations. In the Run Configurations dialog box, select JPACacheServer to display its configuration. Click Run.

  3. Create a run configuration for the DatabaseCache program.

    1. In the Run Configurations dialog box, click the New launch configuration icon.

    2. Enter DatabaseCache in the Name field. Ensure that Interact is in the Project field and com.oracle.handson.DatabaseCache is in the Main class field.

    3. In the Coherence tab, enter the path to the cache configuration file in the Cache configuration descriptor field: C:\home\oracle\workspace\cache-config.xml. Select Local storage: Disabled (cache client). Enter a unique value, such as 3155, in the Cluster port field.

    4. In the Classpath tab, use the Add External JARs button to add the coherence.jar file to User Entries. The Classpath tab should look similar to Figure 9-4.

      Figure 9-4 Classpath for the DatabaseCache Program

      Classpath for the DatabaseCache Program
      Description of "Figure 9-4 Classpath for the DatabaseCache Program"

    5. Click Apply then Run.

      Example 9-9 illustrates the expected results.

      Example 9-9 Output of the DatabaseCache Program

      ...
      2011-03-15 13:47:59.374/0.329 Oracle Coherence 3.7.0.0 <Info> (thread=main, member=n/a): Loaded operational configuration from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence.xml"
      2011-03-15 13:47:59.420/0.375 Oracle Coherence 3.7.0.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence-override-dev.xml"
      2011-03-15 13:47:59.452/0.407 Oracle Coherence 3.7.0.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "file:/C:/home/oracle/workspace/Interact/build/classes/tangosol-coherence-override.xml"
      2011-03-15 13:47:59.467/0.422 Oracle Coherence 3.7.0.0 <D5> (thread=main, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified
       
      Oracle Coherence Version 3.7.0.0 Build 22913
       Grid Edition: Development mode
      Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
       
      2011-03-15 13:47:59.624/0.579 Oracle Coherence GE 3.7.0.0 <Info> (thread=main, member=n/a): Loaded cache configuration from "file:/C:/home/oracle/workspace/cache-config.xml"
      2011-03-15 13:47:59.811/0.766 Oracle Coherence GE 3.7.0.0 <D4> (thread=main, member=n/a): TCMP bound to /130.35.99.213:8090 using SystemSocketProvider
      2011-03-15 13:48:00.327/1.282 Oracle Coherence GE 3.7.0.0 <Info> (thread=Cluster, member=n/a): This Member(Id=2, Timestamp=2011-03-15 13:48:00.17, Address=130.35.99.213:8090, MachineId=49877, Location=site:URL, machine_name,process:5076, Role=OracleHandsonDatabaseCache, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1) joined cluster "cluster:0x96AB" with senior Member(Id=1, Timestamp=2011-03-15 13:33:58.514, Address=130.35.99.213:8088, MachineId=49877, Location=site:URL, machine_name,process:3524, Role=CoherenceServer, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1)
      2011-03-15 13:48:00.342/1.297 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=n/a): Member 1 joined Service Cluster with senior member 1
      2011-03-15 13:48:00.342/1.297 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=n/a): Member 1 joined Service Management with senior member 1
      2011-03-15 13:48:00.342/1.297 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=n/a): Member 1 joined Service DistributedCache with senior member 1
      2011-03-15 13:48:00.342/1.297 Oracle Coherence GE 3.7.0.0 <Info> (thread=main, member=n/a): Started cluster Name=cluster:0x96AB
       
      Group{Address=224.3.7.0, Port=3155, TTL=4}
       
      MasterMemberSet
        (
        ThisMember=Member(Id=2, Timestamp=2011-03-15 13:48:00.17, Address=130.35.99.213:8090, MachineId=49877, Location=site:URL, machine_name,process:5076, Role=OracleHandsonDatabaseCache)
        OldestMember=Member(Id=1, Timestamp=2011-03-15 13:33:58.514, Address=130.35.99.213:8088, MachineId=49877, Location=site:URL, machine_name,process:3524, Role=CoherenceServer)
        ActualMemberSet=MemberSet(Size=2, BitSetCount=2
          Member(Id=1, Timestamp=2011-03-15 13:33:58.514, Address=130.35.99.213:8088, MachineId=49877, Location=site:URL, machine_name,process:3524, Role=CoherenceServer)
          Member(Id=2, Timestamp=2011-03-15 13:48:00.17, Address=130.35.99.213:8090, MachineId=49877, Location=site:URL, machine_name,process:5076, Role=OracleHandsonDatabaseCache)
          )
        RecycleMillis=1200000
        RecycleSet=MemberSet(Size=0, BitSetCount=0
          )
        )
       
      TcpRing{Connections=[1]}
      IpMonitor{AddressListSize=0}
       
      2011-03-15 13:48:00.436/1.391 Oracle Coherence GE 3.7.0.0 <D5> (thread=Invocation:Management, member=2): Service Management joined the cluster with senior service member 1
      2011-03-15 13:48:00.514/1.469 Oracle Coherence GE 3.7.0.0 <D5> (thread=DistributedCache, member=2): Service DistributedCache joined the cluster with senior service member 1
      Catalog ID: catalog3, Title: Tuning Grid Management
      Catalog ID: catalog4, Title: Tuning Coherence
      Catalog ID: catalog5, Title: Tuning Database
      

      Example 9-10 illustrates the cache server response to the DatabaseCache program.

      Example 9-10 Cache Server Response to the DatabaseCache Program

      ...
      Started DefaultCacheServer...
       
      2011-03-15 13:48:00.327/843.922 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2011-03-15 13:48:00.17, Address=130.35.99.213:8090, MachineId=49877, Location=site:URL, machine_name,process:5076, Role=OracleHandsonDatabaseCache) joined Cluster with senior member 1
      2011-03-15 13:48:00.436/844.031 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member 2 joined Service Management with senior member 1
      2011-03-15 13:48:00.545/844.156 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member 2 joined Service DistributedCache with senior member 1
      2011-03-15 13:48:02.842/846.437 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): TcpRing disconnected from Member(Id=2, Timestamp=2011-03-15 13:48:00.17, Address=130.35.99.213:8090, MachineId=49877, Location=site:URL, machine_name,process:5076, Role=OracleHandsonDatabaseCache) due to a peer departure; removing the member.
      2011-03-15 13:48:02.842/846.437 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member 2 left service Management with senior member 1
      2011-03-15 13:48:02.842/846.437 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member 2 left service DistributedCache with senior member 1
      2011-03-15 13:48:02.842/846.437 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2011-03-15 13:48:02.842, Address=130.35.99.213:8090, MachineId=49877, Location=site:URL, machine_name,process:5076, Role=OracleHandsonDatabaseCache) left Cluster with senior member 1
      

      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 *. Re-run the DatabaseCache application in Eclipse. You should not see any exceptions.

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

    select * from hr.catalog;
    

    Example 9-11 illustrates the results.

    Example 9-11 Output from the SELECT Statement

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