http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheAsyncApiExample.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheAsyncApiExample.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheAsyncApiExample.scala
new file mode 100644
index 0000000..1059c5b
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheAsyncApiExample.scala
@@ -0,0 +1,75 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid
+
+import org.apache.ignite.examples.ExampleNodeStartup
+import org.apache.ignite.internal.util.scala.impl
+import org.apache.ignite.lang.{IgniteFuture, IgniteInClosure}
+import org.apache.ignite.scalar.scalar
+import org.apache.ignite.scalar.scalar._
+
+/**
+ * This example demonstrates some of the cache rich API capabilities.
+ * <p>
+ * Remote nodes should always be started with special configuration file which
+ * enables P2P class loading: `'ignite.{sh|bat} 
examples/config/example-ignite.xml'`.
+ * <p>
+ * Alternatively you can run [[ExampleNodeStartup]] in another JVM which will
+ * start node with `examples/config/example-ignite.xml` configuration.
+ */
+object ScalarCacheAsyncApiExample extends App {
+    /** Configuration file name. */
+    private val CONFIG = "examples/config/example-ignite.xml"
+    
+    /** Cache name. */
+    private val CACHE_NAME = ScalarCacheAsyncApiExample.getClass.getSimpleName
+    
+    scalar(CONFIG) {
+        println()
+        println(">>> Cache asynchronous API example started.")
+
+        val cache = createCache$[Integer, String](CACHE_NAME)
+
+        try {
+            // Enable asynchronous mode.
+            val asyncCache = cache.withAsync()
+
+            // Execute several puts asynchronously.
+            val t = (0 until 10).map(i => {
+                asyncCache.put(i, String.valueOf(i))
+
+                asyncCache.future().asInstanceOf[IgniteFuture[_]]
+            }).foreach(_.get())
+
+            // Execute get operation asynchronously.
+            asyncCache.get(1)
+
+            // Asynchronously wait for result.
+            asyncCache.future[String].listen(new 
IgniteInClosure[IgniteFuture[String]] {
+                @impl def apply(fut: IgniteFuture[String]) {
+                    println("Get operation completed [value=" + fut.get + ']')
+                }
+            })
+        }
+        finally {
+            cache.close()
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheContinuousQueryExample.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheContinuousQueryExample.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheContinuousQueryExample.scala
new file mode 100644
index 0000000..637c13c
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheContinuousQueryExample.scala
@@ -0,0 +1,108 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid
+
+import org.apache.ignite.IgniteDataStreamer
+import org.apache.ignite.cache.CacheEntryEventSerializableFilter
+import org.apache.ignite.cache.query.{ContinuousQuery, ScanQuery}
+import org.apache.ignite.examples.ExampleNodeStartup
+import org.apache.ignite.internal.util.scala.impl
+import org.apache.ignite.lang.IgniteBiPredicate
+import org.apache.ignite.scalar.scalar
+import org.apache.ignite.scalar.scalar._
+
+import javax.cache.event.{CacheEntryEvent, CacheEntryUpdatedListener}
+import java.lang.{Iterable => JavaIterable}
+
+import scala.collection.JavaConversions._
+
+/**
+ * Demonstrates how cache can be populated with data utilizing 
[[IgniteDataStreamer]] API.
+ * [[IgniteDataStreamer]] is a lot more efficient to use than standard
+ * `put(...)` operation as it properly buffers cache requests
+ * together and properly manages load on remote nodes.
+ * <p>
+ * Remote nodes should always be started with special configuration file which
+ * enables P2P class loading: `'ignite.{sh|bat} 
examples/config/example-ignite.xml'`.
+ * <p>
+ * Alternatively you can run [[ExampleNodeStartup]] in another JVM which will
+ * start node with `examples/config/example-ignite.xml` configuration.
+ */
+object ScalarCacheContinuousQueryExample extends App {
+    /** Configuration file name. */
+    private val CONFIG = "examples/config/example-ignite.xml"
+    
+    /** Cache name. */
+    private val CACHE_NAME = 
ScalarCacheContinuousQueryExample.getClass.getSimpleName
+
+    scalar(CONFIG) {
+        println()
+        println(">>> Cache continuous query example started.")
+
+        val cache = createCache$[Integer, String](CACHE_NAME)
+
+        try {
+            val keyCnt = 20
+
+            for (i <- 0 until keyCnt)
+                cache.put(i, Integer.toString(i))
+
+            val qry = new ContinuousQuery[Integer, String]
+
+            qry.setInitialQuery(new ScanQuery[Integer, String](new 
IgniteBiPredicate[Integer, String] {
+                @impl def apply(key: Integer, value: String): Boolean = {
+                    key > 10
+                }
+            }))
+
+            qry.setLocalListener(new CacheEntryUpdatedListener[Integer, 
String] {
+                @impl def onUpdated(events: JavaIterable[CacheEntryEvent[_ <: 
Integer, _ <: String]]) {
+                    for (e <- events)
+                        println("Updated entry [key=" + e.getKey + ", val=" + 
e.getValue + ']')
+                }
+            })
+
+            qry.setRemoteFilter(new CacheEntryEventSerializableFilter[Integer, 
String] {
+                @impl def evaluate(e: CacheEntryEvent[_ <: Integer, _ <: 
String]): Boolean = {
+                    e.getKey > 10
+                }
+            })
+
+            val cur = cache.query(qry)
+
+            try {
+                for (e <- cur)
+                    println("Queried existing entry [key=" + e.getKey + ", 
val=" + e.getValue + ']')
+
+                for (i <- keyCnt until (keyCnt + 10))
+                    cache.put(i, Integer.toString(i))
+
+                Thread.sleep(2000)
+            }
+            finally {
+                if (cur != null)
+                    cur.close()
+            }
+        }
+        finally {
+            cache.close()
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheDataStreamerExample.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheDataStreamerExample.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheDataStreamerExample.scala
new file mode 100644
index 0000000..b6bac1b
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheDataStreamerExample.scala
@@ -0,0 +1,88 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid
+
+import org.apache.ignite.IgniteDataStreamer
+import org.apache.ignite.examples.{ExampleNodeStartup, ExamplesUtils}
+import org.apache.ignite.scalar.scalar
+import org.apache.ignite.scalar.scalar._
+
+/**
+ * Demonstrates how cache can be populated with data utilizing 
[[IgniteDataStreamer]] API.
+ * [[IgniteDataStreamer]] is a lot more efficient to use than standard
+ * `put(...)` operation as it properly buffers cache requests
+ * together and properly manages load on remote nodes.
+ * <p>
+ * Remote nodes should always be started with special configuration file which
+ * enables P2P class loading: `'ignite.{sh|bat} 
examples/config/example-ignite.xml'`.
+ * <p>
+ * Alternatively you can run [[ExampleNodeStartup]] in another JVM which will
+ * start node with `examples/config/example-ignite.xml` configuration.
+ */
+object ScalarCacheDataStreamerExample extends App {
+    /** Configuration file name. */
+    private val CONFIG = "examples/config/example-ignite.xml"
+    
+    /** Cache name. */
+    private val CACHE_NAME = 
ScalarCacheDataStreamerExample.getClass.getSimpleName
+
+    /** Number of entries to load. */
+    private val ENTRY_COUNT = 500000
+
+    /** Heap size required to run this example. */
+    val MIN_MEMORY = 512 * 1024 * 1024
+
+    ExamplesUtils.checkMinMemory(MIN_MEMORY)
+
+    scalar(CONFIG) {
+        println()
+        println(">>> Cache data streamer example started.")
+
+        val cache = createCache$(CACHE_NAME)
+
+        try {
+            val start = System.currentTimeMillis
+
+            val stmr = dataStreamer$[Integer, String](CACHE_NAME)
+
+            try {
+                stmr.perNodeBufferSize(1024)
+                stmr.perNodeParallelOperations(8)
+
+                for (i <- 0 until ENTRY_COUNT) {
+                    stmr.addData(i, Integer.toString(i))
+
+                    if (i > 0 && i % 10000 == 0)
+                        println("Loaded " + i + " keys.")
+                }
+            }
+            finally {
+                stmr.close()
+            }
+
+            val end = System.currentTimeMillis
+
+            println(">>> Loaded " + ENTRY_COUNT + " keys in " + (end - start) 
+ "ms.")
+        }
+        finally {
+            cache.close()
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheEventsExample.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheEventsExample.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheEventsExample.scala
new file mode 100644
index 0000000..cd93776
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheEventsExample.scala
@@ -0,0 +1,89 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid
+
+import org.apache.ignite.events.CacheEvent
+import org.apache.ignite.events.EventType._
+import org.apache.ignite.examples.ExampleNodeStartup
+import org.apache.ignite.internal.util.scala.impl
+import org.apache.ignite.lang.{IgniteBiPredicate, IgnitePredicate}
+import org.apache.ignite.scalar.scalar
+import org.apache.ignite.scalar.scalar._
+
+import java.util.UUID
+
+/**
+ * This examples demonstrates events API. Note that ignite events are disabled 
by default and
+ * must be specifically enabled, just like in 
`examples/config/example-ignite.xml` file.
+ * <p>
+ * Remote nodes should always be started with special configuration file which
+ * enables P2P class loading: `'ignite.{sh|bat} 
examples/config/example-ignite.xml'`.
+ * <p>
+ * Alternatively you can run [[ExampleNodeStartup]] in another JVM which will
+ * start node with `examples/config/example-ignite.xml` configuration.
+ */
+object ScalarCacheEventsExample extends App {
+    /** Configuration file name. */
+    private val CONFIG = "examples/config/example-ignite.xml"
+    
+    /** Cache name. */
+    private val CACHE_NAME = ScalarCacheEventsExample.getClass.getSimpleName
+
+    scalar(CONFIG) {
+        println()
+        println(">>> Cache events example started.")
+
+        val cache = createCache$[Integer, String](CACHE_NAME)
+
+        val cluster = cluster$
+
+        try {
+            val locLsnr = new IgniteBiPredicate[UUID, CacheEvent] {
+                @impl def apply(uuid: UUID, evt: CacheEvent): Boolean = {
+                    println("Received event [evt=" + evt.name + ", key=" + 
evt.key +
+                        ", oldVal=" + evt.oldValue + ", newVal=" + 
evt.newValue)
+
+                    true
+                }
+            }
+
+            val rmtLsnr = new IgnitePredicate[CacheEvent] {
+                @impl def apply(evt: CacheEvent): Boolean = {
+                    println("Cache event [name=" + evt.name + ", key=" + 
evt.key + ']')
+
+                    val key = evt.key.asInstanceOf[Int]
+
+                    key >= 10 && 
ignite$.affinity(CACHE_NAME).isPrimary(cluster.localNode, key)
+                }
+            }
+
+            
ignite$.events(cluster.forCacheNodes(CACHE_NAME)).remoteListen(locLsnr, rmtLsnr,
+                EVT_CACHE_OBJECT_PUT, EVT_CACHE_OBJECT_READ, 
EVT_CACHE_OBJECT_REMOVED)
+
+            for (i <- 0 until 20)
+                cache.put(i, Integer.toString(i))
+
+            Thread.sleep(2000)
+        }
+        finally {
+            if (cache != null) cache.close()
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCachePutGetExample.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCachePutGetExample.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCachePutGetExample.scala
new file mode 100644
index 0000000..bf1c375
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCachePutGetExample.scala
@@ -0,0 +1,106 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid
+
+import org.apache.ignite.examples.ExampleNodeStartup
+import org.apache.ignite.scalar.scalar
+import org.apache.ignite.scalar.scalar._
+import org.apache.ignite.{IgniteCache, IgniteException}
+
+import java.util.{HashMap => JavaMap}
+
+import scala.collection.JavaConversions._
+
+/**
+ * This example demonstrates very basic operations on cache, such as 'put' and 
'get'.
+ * <p>
+ * Remote nodes should always be started with special configuration file which
+ * enables P2P class loading: `'ignite.{sh|bat} 
examples/config/example-ignite.xml'`.
+ * <p>
+ * Alternatively you can run [[ExampleNodeStartup]] in another JVM which will
+ * start node with `examples/config/example-ignite.xml` configuration.
+ */
+object ScalarCachePutGetExample extends App {
+    /** Configuration file name. */
+    private val CONFIG = "examples/config/example-ignite.xml"
+
+    /** Cache name. */
+    private val CACHE_NAME = ScalarCachePutGetExample.getClass.getSimpleName
+
+    scalar(CONFIG) {
+        val cache = createCache$[Integer, String](CACHE_NAME)
+
+        try {
+            putGet(cache)
+            putAllGetAll(cache)
+        }
+        finally {
+            if (cache != null) cache.close()
+        }
+    }
+    
+    /**
+     * Execute individual puts and gets.
+     *
+     * @throws IgniteException If failed.
+     */
+    @throws(classOf[IgniteException])
+    private def putGet(cache: IgniteCache[Integer, String]) {
+        println()
+        println(">>> Cache put-get example started.")
+
+        val keyCnt = 20
+
+        for (i <- 0 until keyCnt)
+            cache.put(i, Integer.toString(i))
+
+        println(">>> Stored values in cache.")
+
+        for (i <- 0 until keyCnt)
+            println("Got [key=" + i + ", val=" + cache.get(i) + ']')
+    }
+
+    /**
+     * Execute bulk `putAll(...)` and `getAll(...)` operations.
+     *
+     * @throws IgniteException If failed.
+     */
+    @throws(classOf[IgniteException])
+    private def putAllGetAll(cache: IgniteCache[Integer, String]) {
+        println()
+        println(">>> Starting putAll-getAll example.")
+
+        val keyCnt = 20
+
+        val batch = new JavaMap[Integer, String]
+
+        for (i <- 0 until keyCnt)
+            batch.put(i, "bulk-" + Integer.toString(i))
+
+        cache.putAll(batch)
+
+        println(">>> Bulk-stored values in cache.")
+
+        val vals = cache.getAll(batch.keySet)
+
+        for (e <- vals.entrySet)
+            println("Got entry [key=" + e.getKey + ", val=" + e.getValue + ']')
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheQueryExample.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheQueryExample.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheQueryExample.scala
new file mode 100644
index 0000000..1876515
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheQueryExample.scala
@@ -0,0 +1,305 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid
+
+import org.apache.ignite.IgniteCache
+import org.apache.ignite.cache.CacheMode._
+import org.apache.ignite.cache.affinity.AffinityKey
+import org.apache.ignite.cache.query._
+import org.apache.ignite.internal.util.scala.impl
+import org.apache.ignite.lang.IgniteBiPredicate
+import org.apache.ignite.scalar.scalar
+import org.apache.ignite.scalar.scalar._
+
+import javax.cache.Cache
+import java.lang.{Iterable => JavaIterable}
+import java.util.UUID
+
+import scala.collection.JavaConversions._
+
+/**
+ * Demonstrates cache ad-hoc queries with Scalar.
+ * <p/>
+ * Remote nodes should be started using `ExampleNodeStartup` which will
+ * start node with `examples/config/example-ignite.xml` configuration.
+ */
+object ScalarCacheQueryExample {
+    /** Configuration file name. */
+    private val CONFIG = "examples/config/example-ignite.xml"
+
+    /** Organizations cache name. */
+    private val ORG_CACHE = ScalarCacheQueryExample.getClass.getSimpleName + 
"Organizations"
+
+    /** Persons cache name. */
+    private val PERSON_CACHE = ScalarCacheQueryExample.getClass.getSimpleName 
+ "Persons"
+
+    /**
+     * Example entry point. No arguments required.
+     *
+     * @param args Command line arguments. None required.
+     */
+    def main(args: Array[String]) {
+        scalar(CONFIG) {
+            val orgCache = createCache$(ORG_CACHE, PARTITIONED, 
Seq(classOf[UUID], classOf[Organization]))
+
+            try {
+                val personCache = createCache$(PERSON_CACHE, PARTITIONED, 
Seq(classOf[AffinityKey[_]], classOf[Person]))
+
+                try {
+                    initialize()
+
+                    scanQuery()
+
+                    sqlQuery()
+
+                    sqlQueryWithJoin()
+
+                    textQuery()
+
+                    sqlQueryWithAggregation()
+
+                    sqlFieldsQuery()
+
+                    sqlFieldsQueryWithJoin()
+
+                    print("Cache query example finished.")
+                }
+                finally {
+                    if (personCache != null)
+                        personCache.close()
+                }
+            }
+            finally {
+                if (orgCache != null)
+                    orgCache.close()
+            }
+        }
+    }
+
+    /**
+     * Gets instance of typed cache view to use.
+     *
+     * @return Cache to use.
+     */
+    private def mkCache[K, V](cacheName: String): IgniteCache[K, V] = 
cache$[K, V](cacheName).get
+
+    /**
+     * Example for scan query based on a predicate.
+     */
+    private def scanQuery() {
+        val cache = mkCache[AffinityKey[UUID], Person](PERSON_CACHE)
+
+        val scan = new ScanQuery[AffinityKey[UUID], Person](
+            new IgniteBiPredicate[AffinityKey[UUID], Person] {
+                @impl def apply(key: AffinityKey[UUID], person: Person): 
Boolean = {
+                    person.salary <= 1000
+                }
+        })
+
+        print("People with salaries between 0 and 1000 (queried with SCAN 
query): ", cache.query(scan).getAll)
+    }
+
+    /**
+     * Example for SQL queries based on salary ranges.
+     */
+    private def sqlQuery() {
+        val cache = mkCache[AffinityKey[UUID], Person](PERSON_CACHE)
+
+        val sql = "salary > ? and salary <= ?"
+
+        print("People with salaries between 0 and 1000 (queried with SQL 
query): ",
+            cache.query(new SqlQuery[AffinityKey[UUID], 
Person](classOf[Person], sql)
+                .setArgs(0.asInstanceOf[Object], 
1000.asInstanceOf[Object])).getAll)
+
+        print("People with salaries between 1000 and 2000 (queried with SQL 
query): ",
+            cache.query(new SqlQuery[AffinityKey[UUID], 
Person](classOf[Person], sql)
+                .setArgs(1000.asInstanceOf[Object], 
2000.asInstanceOf[Object])).getAll)
+    }
+
+    /**
+     * Example for SQL queries based on all employees working for a specific 
organization.
+     */
+    private def sqlQueryWithJoin() {
+        val cache = mkCache[AffinityKey[UUID], Person](PERSON_CACHE)
+
+        val joinSql = "from Person, \"" + ORG_CACHE + "\".Organization as org 
" +
+            "where Person.orgId = org.id " +
+            "and lower(org.name) = lower(?)"
+
+        print("Following people are 'ApacheIgnite' employees: ",
+            cache.query(new SqlQuery[AffinityKey[UUID], 
Person](classOf[Person], joinSql).setArgs("ApacheIgnite")).getAll)
+        print("Following people are 'Other' employees: ",
+            cache.query(new SqlQuery[AffinityKey[UUID], 
Person](classOf[Person], joinSql).setArgs("Other")).getAll)
+    }
+
+    /**
+     * Example for TEXT queries using LUCENE-based indexing of people's 
resumes.
+     */
+    private def textQuery() {
+        val cache = mkCache[AffinityKey[UUID], Person](PERSON_CACHE)
+
+        val masters: QueryCursor[Cache.Entry[AffinityKey[UUID], Person]] =
+            cache.query(new TextQuery[AffinityKey[UUID], 
Person](classOf[Person], "Master"))
+
+        val bachelors: QueryCursor[Cache.Entry[AffinityKey[UUID], Person]] =
+            cache.query(new TextQuery[AffinityKey[UUID], 
Person](classOf[Person], "Bachelor"))
+
+        print("Following people have 'Master Degree' in their resumes: ", 
masters.getAll)
+
+        print("Following people have 'Bachelor Degree' in their resumes: ", 
bachelors.getAll)
+    }
+
+    /**
+     * Example for SQL queries to calculate average salary for a specific 
organization.
+     */
+    private def sqlQueryWithAggregation() {
+        val cache = mkCache[AffinityKey[UUID], Person](PERSON_CACHE)
+
+        val sql = "select avg(salary) " +
+            "from Person, \"" + ORG_CACHE + "\".Organization as org " +
+            "where Person.orgId = org.id " +
+            "and lower(org.name) = lower(?)"
+
+        val cursor = cache.query(new 
SqlFieldsQuery(sql).setArgs("ApacheIgnite"))
+
+        print("Average salary for 'ApacheIgnite' employees: ", cursor.getAll)
+    }
+
+    /**
+     * Example for SQL-based fields queries that return only required
+     * fields instead of whole key-value pairs.
+     */
+    private def sqlFieldsQuery() {
+        val cache = ignite$.cache[AffinityKey[UUID], Person](PERSON_CACHE)
+
+        // Execute query to get names of all employees.
+        val cursor = cache.query(new SqlFieldsQuery("select concat(firstName, 
' ', lastName) from Person"))
+
+        val res = cursor.getAll
+
+        print("Names of all employees:", res)
+    }
+
+    /**
+     * Example for SQL-based fields queries that return only required
+     * fields instead of whole key-value pairs.
+     */
+    private def sqlFieldsQueryWithJoin() {
+        val cache = ignite$.cache[AffinityKey[UUID], Person](PERSON_CACHE)
+
+        val sql = "select concat(firstName, ' ', lastName), org.name " + "from 
Person, \"" +
+            ORG_CACHE + "\".Organization as org " + "where Person.orgId = 
org.id"
+
+        val cursor = cache.query(new SqlFieldsQuery(sql))
+
+        val res = cursor.getAll
+
+        print("Names of all employees and organizations they belong to:", res)
+    }
+
+    /**
+     * Populate cache with test data.
+     */
+    private def initialize() {
+        val orgCache = mkCache[UUID, Organization](ORG_CACHE)
+
+        val org1 = new Organization("ApacheIgnite")
+        val org2 = new Organization("Other")
+
+        orgCache += (org1.id -> org1)
+        orgCache += (org2.id -> org2)
+
+        val personCache = mkCache[AffinityKey[UUID], Person](PERSON_CACHE)
+
+        val p1 = new Person(org1, "John", "Doe", 2000, "John Doe has Master 
Degree.")
+        val p2 = new Person(org1, "Jane", "Doe", 1000, "Jane Doe has Bachelor 
Degree.")
+        val p3 = new Person(org2, "John", "Smith", 1000, "John Smith has 
Bachelor Degree.")
+        val p4 = new Person(org2, "Jane", "Smith", 2000, "Jane Smith has 
Master Degree.")
+
+        personCache += (p1.key -> p1)
+        personCache += (p2.key -> p2)
+        personCache += (p3.key -> p3)
+        personCache += (p4.key -> p4)
+    }
+
+    /**
+     * Prints message.
+     *
+     * @param msg Message to print before all objects are printed.
+     */
+    private def print(msg: String) {
+        assert(msg != null)
+
+        println()
+        println(">>> " + msg)
+    }
+
+    /**
+     * Prints object or collection of objects to standard out.
+     *
+     * @param msg Message to print before object is printed.
+     * @param res Collection of result object to print.
+     */
+    private def print(msg: String, res: JavaIterable[_]) {
+        assert(msg != null)
+        assert(res != null)
+
+        print(msg)
+
+        res.foreach(e => println(">>>     " + e.toString))
+    }
+
+    /**
+     * Organization class.
+     */
+    private case class Organization(
+        @ScalarCacheQuerySqlField
+        name: String) {
+        /** Organization ID. */
+        @ScalarCacheQuerySqlField
+        val id = UUID.randomUUID
+    }
+
+    /**
+     * Person class.
+     */
+    private case class Person(org: Organization,
+        @ScalarCacheQuerySqlField firstName: String,
+        @ScalarCacheQuerySqlField lastName: String,
+        @ScalarCacheQuerySqlField salary: Double,
+        @ScalarCacheQueryTextField resume: String) {
+        /** Person ID. */
+        val id = UUID.randomUUID
+
+        /** Organization ID. */
+        @ScalarCacheQuerySqlField
+        val orgId = org.id
+
+        /** Affinity key for this person. */
+        val key = new AffinityKey[UUID](id, org.id)
+
+        /**
+         * `toString` implementation.
+         */
+        override def toString: String = {
+            firstName + " " + lastName + " [salary: " + salary + ", resume: " 
+ resume + "]"
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheTransactionExample.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheTransactionExample.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheTransactionExample.scala
new file mode 100644
index 0000000..a9c0b4c
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/ScalarCacheTransactionExample.scala
@@ -0,0 +1,127 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid
+
+import org.apache.ignite.cache.CacheAtomicityMode
+import org.apache.ignite.examples.ExampleNodeStartup
+import org.apache.ignite.scalar.scalar
+import org.apache.ignite.scalar.scalar._
+import org.apache.ignite.transactions.TransactionConcurrency._
+import org.apache.ignite.transactions.TransactionIsolation._
+import org.apache.ignite.{IgniteCache, IgniteException}
+
+import java.io.Serializable
+
+/**
+ * Demonstrates how to use cache transactions.
+ * <p>
+ * Remote nodes should always be started with special configuration file which
+ * enables P2P class loading: `'ignite.{sh|bat} 
examples/config/example-ignite.xml'`.
+ * <p>
+ * Alternatively you can run [[ExampleNodeStartup]] in another JVM which will
+ * start node with `examples/config/example-ignite.xml` configuration.
+ */
+object ScalarCacheTransactionExample extends App {
+    /** Configuration file name. */
+    private val CONFIG = "examples/config/example-ignite.xml"
+
+    /** Cache name. */
+    private val CACHE_NAME = 
ScalarCacheTransactionExample.getClass.getSimpleName
+
+    scalar(CONFIG) {
+        println()
+        println(">>> Cache transaction example started.")
+
+        val cache = createCache$[Integer, Account](CACHE_NAME, atomicityMode = 
CacheAtomicityMode.TRANSACTIONAL)
+
+        try {
+            cache.put(1, new Account(1, 100))
+            cache.put(2, new Account(1, 200))
+
+            println()
+            println(">>> Accounts before deposit: ")
+            println(">>> " + cache.get(1))
+            println(">>> " + cache.get(2))
+
+            deposit(cache, 1, 100)
+            deposit(cache, 2, 200)
+
+            println()
+            println(">>> Accounts after transfer: ")
+            println(">>> " + cache.get(1))
+            println(">>> " + cache.get(2))
+            println(">>> Cache transaction example finished.")
+        }
+        finally {
+            cache.close()
+        }
+    }
+
+    /**
+     * Make deposit into specified account.
+     *
+     * @param acctId Account ID.
+     * @param amount Amount to deposit.
+     * @throws IgniteException If failed.
+     */
+    @throws(classOf[IgniteException])
+    private def deposit(cache: IgniteCache[Integer, Account], acctId: Int, 
amount: Double) {
+        val tx = transaction$(PESSIMISTIC, REPEATABLE_READ)
+
+        try {
+            val acct = cache.get(acctId)
+
+            assert(acct != null)
+
+            acct.update(amount)
+
+            cache.put(acctId, acct)
+
+            tx.commit()
+        }
+        finally {
+            tx.close()
+        }
+
+        println()
+        println(">>> Transferred amount: $" + amount)
+    }
+
+    /**
+     * Account.
+     *
+     * @param id Account ID.
+     * @param balance Balance.
+     */
+    private class Account(id: Int, var balance: Double) extends Serializable {
+        /**
+         * Change balance by specified amount.
+         *
+         * @param amount Amount to add to balance (may be negative).
+         */
+        private[datagrid] def update(amount: Double) {
+            balance += amount
+        }
+
+        override def toString: String = {
+            "Account [id=" + id + ", balance=$" + balance + ']'
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/hibernate/Post.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/hibernate/Post.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/hibernate/Post.scala
new file mode 100644
index 0000000..ee44eb4
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/hibernate/Post.scala
@@ -0,0 +1,115 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid.hibernate
+
+import javax.persistence._
+import java.util.Date
+
+/**
+ * An entity class representing a post, that a
+ * [[User]] has made on some public service.
+ */
+@Entity class Post {
+    /** ID. */
+    @Id @GeneratedValue(strategy = GenerationType.AUTO) private var id = 0L
+
+    /** Author. */
+    @ManyToOne private var author: User = null
+
+    /** Text. */
+    private var text: String = null
+
+    /** Created timestamp. */
+    private var created: Date = null
+
+    /**
+     * Constructor.
+     *
+     * @param author Author.
+     * @param text Text.
+     */
+    private[hibernate] def this(author: User, text: String) {
+        this()
+
+        this.author = author
+        this.text = text
+        created = new Date
+    }
+
+    /**
+     * @return ID.
+     */
+    def getId: Long = {
+        id
+    }
+
+    /**
+     * @param id New ID.
+     */
+    def setId(id: Long) {
+        this.id = id
+    }
+
+    /**
+     * @return Author.
+     */
+    def getAuthor: User = {
+        author
+    }
+
+    /**
+     * @param author New author.
+     */
+    def setAuthor(author: User) {
+        this.author = author
+    }
+
+    /**
+     * @return Text.
+     */
+    def getText: String = {
+        text
+    }
+
+    /**
+     * @param text New text.
+     */
+    def setText(text: String) {
+        this.text = text
+    }
+
+    /**
+     * @return Created timestamp.
+     */
+    def getCreated: Date = {
+        created.clone.asInstanceOf[Date]
+    }
+
+    /**
+     * @param created New created timestamp.
+     */
+    def setCreated(created: Date) {
+        this.created = created.clone.asInstanceOf[Date]
+    }
+
+    override def toString: String = {
+        "Post [id=" + id + ", text=" + text + ", created=" + created + ']'
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/hibernate/ScalarHibernateL2CacheExample.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/hibernate/ScalarHibernateL2CacheExample.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/hibernate/ScalarHibernateL2CacheExample.scala
new file mode 100644
index 0000000..05e5def
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/hibernate/ScalarHibernateL2CacheExample.scala
@@ -0,0 +1,242 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid.hibernate
+
+import org.apache.ignite.IgniteCache
+import org.apache.ignite.cache.CacheAtomicityMode
+import org.apache.ignite.cache.CacheAtomicityMode._
+import org.apache.ignite.cache.CacheWriteSynchronizationMode._
+import org.apache.ignite.configuration.CacheConfiguration
+import org.apache.ignite.examples.{ExampleNodeStartup, ExamplesUtils}
+import org.apache.ignite.scalar.scalar
+import org.apache.ignite.scalar.scalar._
+
+import org.hibernate.cfg.Configuration
+import org.hibernate.service.ServiceRegistryBuilder
+import org.hibernate.{Session, SessionFactory}
+
+import javax.persistence._
+import java.net.URL
+import java.util.{Arrays, HashSet => JavaHashSet, List => JavaList, Set => 
JavaSet}
+
+import scala.collection.JavaConversions._
+
+/**
+ * This example demonstrates the use of Ignite In-Memory Data Ignite cluster 
as a Hibernate
+ * Second-Level cache provider.
+ * <p>
+ * The Hibernate Second-Level cache (or "L2 cache" shortly) lets you 
significantly
+ * reduce the number of requests to the underlying SQL database. Because 
database
+ * access is known to be an expansive operation, using L2 cache may improve
+ * performance dramatically.
+ * <p>
+ * This example defines 2 entity classes: [[User]] and [[Post]], with
+ * 1 <-> N relation, and marks them with appropriate annotations for Hibernate
+ * object-relational mapping to SQL tables of an underlying H2 in-memory 
database.
+ * The example launches node in the same JVM and registers it in
+ * Hibernate configuration as an L2 cache implementation. It then stores and
+ * queries instances of the entity classes to and from the database, having
+ * Hibernate SQL output, L2 cache statistics output, and Ignite cache metrics
+ * output enabled.
+ * <p>
+ * When running example, it's easy to notice that when an object is first
+ * put into a database, the L2 cache is not used and it's contents is empty.
+ * However, when an object is first read from the database, it is immediately
+ * stored in L2 cache (which is Ignite In-Memory Data Ignite cluster in fact), 
which can
+ * be seen in stats output. Further requests of the same object only read the 
data
+ * from L2 cache and do not hit the database.
+ * <p>
+ * In this example, the Hibernate query cache is also enabled. Query cache 
lets you
+ * avoid hitting the database in case of repetitive queries with the same 
parameter
+ * values. You may notice that when the example runs the same query repeatedly 
in
+ * loop, only the first query hits the database and the successive requests 
take the
+ * data from L2 cache.
+ * <p>
+ * Note: this example uses [[AccessType#READ_ONLY]] L2 cache access type, but 
you
+ * can experiment with other access types by modifying the Hibernate 
configuration file
+ * `IGNITE_HOME/examples/config/hibernate/example-hibernate-L2-cache.xml`, 
used by the example.
+ * <p>
+ * Remote nodes should always be started with special configuration file which
+ * enables P2P class loading: `'ignite.{sh|bat} 
examples/config/example-ignite.xml'`.
+ * <p>
+ * Alternatively you can run [[ExampleNodeStartup]] in another JVM which will
+ * start node with `examples/config/example-ignite.xml` configuration.
+ */
+object ScalarHibernateL2CacheExample extends App {
+    /** Configuration file name. */
+    private val CONFIG = "examples/config/example-ignite.xml"
+
+    /** JDBC URL for backing database (an H2 in-memory database is used). */
+    private val JDBC_URL = "jdbc:h2:mem:example;DB_CLOSE_DELAY=-1"
+    
+    /** Path to hibernate configuration file (will be resolved from 
application `CLASSPATH`). */
+    private val HIBERNATE_CFG = 
"hibernate/example-scalar-hibernate-L2-cache.xml"
+    
+    /** Entity names for stats output. */
+    private val ENTITY_NAMES: JavaList[String] = 
+        Arrays.asList(classOf[User].getName, classOf[Post].getName, 
classOf[User].getName + ".posts")
+    // We use a single session factory, but create a dedicated session
+    // for each transaction or query. This way we ensure that L1 cache
+    // is not used (L1 cache has per-session scope only).
+    
+    scalar(CONFIG) {
+        println()
+        println(">>> Hibernate L2 cache example started.")
+
+        val c1 = createCache("org.hibernate.cache.spi.UpdateTimestampsCache", 
ATOMIC)
+        val c2 = 
createCache("org.hibernate.cache.internal.StandardQueryCache", ATOMIC)
+        val c3 = 
createCache("org.apache.ignite.scalar.examples.datagrid.hibernate.User", 
TRANSACTIONAL)
+        val c4 = 
createCache("org.apache.ignite.scalar.examples.datagrid.hibernate.User.posts", 
TRANSACTIONAL)
+        val c5 = 
createCache("org.apache.ignite.scalar.examples.datagrid.hibernate.Post", 
TRANSACTIONAL)
+
+        try {
+            val hibernateCfg: URL = ExamplesUtils.url(HIBERNATE_CFG)
+
+            val sesFactory: SessionFactory = 
createHibernateSessionFactory(hibernateCfg)
+
+            println()
+            println(">>> Creating objects.")
+
+            var userId = 0L
+
+            var ses: Session = sesFactory.openSession
+
+            try {
+                val tx = ses.beginTransaction
+
+                val user = new User("jedi", "Luke", "Skywalker")
+
+                user.getPosts.add(new Post(user, "Let the Force be with you."))
+
+                ses.save(user)
+
+                tx.commit()
+
+                userId = user.getId
+            }
+            finally {
+                ses.close
+            }
+
+            printStats(sesFactory)
+
+            println()
+            println(">>> Querying object by ID.")
+
+            for (i <- 0 until 3) {
+                ses = sesFactory.openSession
+
+                try {
+                    val tx = ses.beginTransaction
+
+                    val user = ses.get(classOf[User], 
userId).asInstanceOf[User]
+
+                    println("User: " + user)
+
+                    for (post <- user.getPosts)
+                        println("\tPost: " + post)
+
+                    tx.commit()
+                }
+                finally {
+                    ses.close
+                }
+            }
+
+            printStats(sesFactory)
+        }
+        finally {
+            if (c1 != null)
+                c1.close()
+
+            if (c2 != null)
+                c2.close()
+
+            if (c3 != null)
+                c3.close()
+
+            if (c4 != null)
+                c4.close()
+
+            if (c5 != null)
+                c5.close()
+        }
+    }
+
+    /**
+     * Creates cache.
+     *
+     * @param name Cache name.
+     * @param atomicityMode Atomicity mode.
+     * @return Cache configuration.
+     */
+    private def createCache(name: String, atomicityMode: CacheAtomicityMode): 
IgniteCache[_, _] = {
+        val ccfg = new CacheConfiguration[AnyRef, AnyRef](name)
+
+        ccfg.setAtomicityMode(atomicityMode)
+
+        ccfg.setWriteSynchronizationMode(FULL_SYNC)
+
+        createCache$(ccfg)
+    }
+
+    /**
+     * Creates a new Hibernate [[SessionFactory]] using a programmatic
+     * configuration.
+     *
+     * @param hibernateCfg Hibernate configuration file.
+     * @return New Hibernate { @link SessionFactory}.
+     */
+    private def createHibernateSessionFactory(hibernateCfg: URL): 
SessionFactory = {
+        val builder = new ServiceRegistryBuilder
+
+        builder.applySetting("hibernate.connection.url", JDBC_URL)
+
+        builder.applySetting("hibernate.show_sql", true)
+
+        new 
Configuration().configure(hibernateCfg).buildSessionFactory(builder.buildServiceRegistry)
+    }
+
+    /**
+     * Prints Hibernate L2 cache statistics to standard output.
+     *
+     * @param sesFactory Hibernate { @link SessionFactory}, for which to print
+     *                                     statistics.
+     */
+    private def printStats(sesFactory: SessionFactory) {
+        println("=== Hibernate L2 cache statistics ===")
+
+        for (entityName <- ENTITY_NAMES) {
+            println("\tEntity: " + entityName)
+
+            val stats = 
sesFactory.getStatistics.getSecondLevelCacheStatistics(entityName)
+
+            println("\t\tL2 cache entries: " + stats.getEntries)
+            println("\t\tHits: " + stats.getHitCount)
+            println("\t\tMisses: " + stats.getMissCount)
+        }
+
+        println("=====================================")
+    }
+}
+
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/hibernate/User.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/hibernate/User.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/hibernate/User.scala
new file mode 100644
index 0000000..dccc1c5
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/hibernate/User.scala
@@ -0,0 +1,136 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid.hibernate
+
+import org.hibernate.annotations.NaturalId
+
+import javax.persistence._
+import java.util.{HashSet => JavaHashSet, Set => JavaSet}
+
+/**
+ * A user entity class. Represents a user of some public service,
+ * having a number of personal information fields as well as a
+ * number of posts written.
+ */
+@Entity private[hibernate] class User {
+    /** ID. */
+    @Id @GeneratedValue(strategy = GenerationType.AUTO) private var id = 0L
+
+    /** Login. */
+    @NaturalId private var login: String = null
+
+    /** First name. */
+    private var firstName: String = null
+
+    /** Last name. */
+    private var lastName: String = null
+
+    /** Posts. */
+    @OneToMany(mappedBy = "author", cascade = Array(CascadeType.ALL))
+    private var posts: JavaSet[Post] = new JavaHashSet[Post]
+
+    /**
+     * Constructor.
+     *
+     * @param login Login.
+     * @param firstName First name.
+     * @param lastName Last name.
+     */
+    private[hibernate] def this(login: String, firstName: String, lastName: 
String) {
+        this()
+        this.login = login
+        this.firstName = firstName
+        this.lastName = lastName
+    }
+
+    /**
+     * @return ID.
+     */
+    def getId: Long = {
+        id
+    }
+
+    /**
+     * @param id New ID.
+     */
+    def setId(id: Long) {
+        this.id = id
+    }
+
+    /**
+     * @return Login.
+     */
+    def getLogin: String = {
+        login
+    }
+
+    /**
+     * @param login New login.
+     */
+    def setLogin(login: String) {
+        this.login = login
+    }
+
+    /**
+     * @return First name.
+     */
+    def getFirstName: String = {
+        firstName
+    }
+
+    /**
+     * @param firstName New first name.
+     */
+    def setFirstName(firstName: String) {
+        this.firstName = firstName
+    }
+
+    /**
+     * @return Last name.
+     */
+    def getLastName: String = {
+        lastName
+    }
+
+    /**
+     * @param lastName New last name.
+     */
+    def setLastName(lastName: String) {
+        this.lastName = lastName
+    }
+
+    /**
+     * @return Posts.
+     */
+    def getPosts: JavaSet[Post] = {
+        posts
+    }
+
+    /**
+     * @param posts New posts.
+     */
+    def setPosts(posts: JavaSet[Post]) {
+        this.posts = posts
+    }
+
+    override def toString: String = {
+        "User [id=" + id + ", login=" + login + ", firstName=" + firstName + 
", lastName=" + lastName + ']'
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/starschema/ScalarStarSchemaExample.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/starschema/ScalarStarSchemaExample.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/starschema/ScalarStarSchemaExample.scala
new file mode 100644
index 0000000..870addf
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/starschema/ScalarStarSchemaExample.scala
@@ -0,0 +1,314 @@
+/*
+ * 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.ignite.scalar.examples.datagrid.starschema
+
+import org.apache.ignite.IgniteCache
+import org.apache.ignite.cache.CacheMode
+import org.apache.ignite.scalar.scalar
+import org.apache.ignite.scalar.scalar._
+
+import org.jsr166.ThreadLocalRandom8
+
+import javax.cache.Cache
+import java.lang.{Integer => JavaInt}
+import java.util.ConcurrentModificationException
+
+import scala.collection.JavaConversions._
+
+/**
+ * <a href="http://en.wikipedia.org/wiki/Snowflake_schema";>Snowflake 
Schema</a> is a logical
+ * arrangement of data in which data is split into `dimensions`  and `facts`
+ * <i>Dimensions</i> can be referenced or joined by other <i>dimensions</i> or 
<i>facts</i>,
+ * however, <i>facts</i> are generally not referenced by other facts. You can 
view <i>dimensions</i>
+ * as your master or reference data, while <i>facts</i> are usually large data 
sets of events or
+ * other objects that continuously come into the system and may change 
frequently. In Ignite
+ * such architecture is supported via cross-cache queries. By storing 
<i>dimensions</i> in
+ * `CacheMode#REPLICATED REPLICATED` caches and <i>facts</i> in much larger
+ * `CacheMode#PARTITIONED PARTITIONED` caches you can freely execute 
distributed joins across
+ * your whole in-memory data ignite cluster, thus querying your in memory data 
without any limitations.
+ * <p/>
+ * In this example we have two <i>dimensions</i>, `DimProduct` and `DimStore` 
and
+ * one <i>fact</i> - `FactPurchase`. Queries are executed by joining 
dimensions and facts
+ * in various ways.
+ * <p/>
+ * Remote nodes should be started using `ExampleNodeStartup` which will
+ * start node with `examples/config/example-ignite.xml` configuration.
+ */
+object ScalarStarSchemaExample {
+    /** Configuration file name. */
+    private val CONFIG = "examples/config/example-ignite.xml"
+
+    /** Name of replicated cache specified in spring configuration. */
+    private val REPL_NAME = "ScalarSnowflakeSchemaExampleReplicated"
+
+    /** Name of partitioned cache specified in spring configuration. */
+    private val PART_NAME = "ScalarSnowflakeSchemaExamplePartitioned"
+
+    /** ID generator. */
+    private[this] val idGen = 
Stream.from(System.currentTimeMillis.toInt).iterator
+
+    /** DimStore data. */
+    private[this] val dataStore = scala.collection.mutable.Map[JavaInt, 
DimStore]()
+
+    /** DimProduct data. */
+    private[this] val dataProduct = scala.collection.mutable.Map[JavaInt, 
DimProduct]()
+
+    /**
+     * Example entry point. No arguments required.
+     */
+    def main(args: Array[String]) {
+        scalar(CONFIG) {
+            val dimCache = createCache$[JavaInt, AnyRef](REPL_NAME, 
CacheMode.REPLICATED,
+                Seq(classOf[JavaInt], classOf[DimStore], classOf[JavaInt], 
classOf[DimProduct]))
+
+            try {
+                val factCache = createCache$[JavaInt, FactPurchase](PART_NAME,
+                    indexedTypes = Seq(classOf[JavaInt], 
classOf[FactPurchase]))
+
+                try {
+                    populateDimensions(dimCache)
+                    populateFacts(factCache)
+
+                    queryStorePurchases()
+                    queryProductPurchases()
+                }
+                finally {
+                    factCache.close()
+                }
+            }
+            finally {
+                dimCache.close()
+            }
+        }
+    }
+
+    /**
+     * Populate cache with `dimensions` which in our case are
+     * `DimStore` and `DimProduct` instances.
+     */
+    def populateDimensions(dimCache: IgniteCache[JavaInt, AnyRef]) {
+        val store1 = new DimStore(idGen.next(), "Store1", "12345", "321 Chilly 
Dr, NY")
+        val store2 = new DimStore(idGen.next(), "Store2", "54321", "123 Windy 
Dr, San Francisco")
+
+        // Populate stores.
+        dimCache.put(store1.id, store1)
+        dimCache.put(store2.id, store2)
+
+        dataStore.put(store1.id, store1)
+        dataStore.put(store2.id, store2)
+
+        for (i <- 1 to 20) {
+            val product = new DimProduct(idGen.next(), "Product" + i, i + 1, 
(i + 1) * 10)
+
+            dimCache.put(product.id, product)
+
+            dataProduct.put(product.id, product)
+        }
+    }
+
+    /**
+     * Populate cache with `facts`, which in our case are `FactPurchase` 
objects.
+     */
+    def populateFacts(factCache: IgniteCache[JavaInt, FactPurchase]) {
+        for (i <- 1 to 100) {
+            val store: DimStore = rand(dataStore.values)
+            val prod: DimProduct = rand(dataProduct.values)
+            val purchase = new FactPurchase(idGen.next(), prod.id, store.id, i 
+ 1)
+
+            factCache.put(purchase.id, purchase)
+        }
+    }
+
+    /**
+     * Query all purchases made at a specific store. This query uses 
cross-cache joins
+     * between `DimStore` objects stored in `replicated` cache and
+     * `FactPurchase` objects stored in `partitioned` cache.
+     */
+    def queryStorePurchases() {
+        val factCache = ignite$.cache[JavaInt, FactPurchase](PART_NAME)
+
+        val storePurchases = factCache.sql(
+            "from \"" + REPL_NAME + "\".DimStore, \"" + PART_NAME + 
"\".FactPurchase " +
+            "where DimStore.id=FactPurchase.storeId and DimStore.name=?", 
"Store1")
+
+        printQueryResults("All purchases made at store1:", 
storePurchases.getAll)
+    }
+
+    /**
+     * Query all purchases made at a specific store for 3 specific products.
+     * This query uses cross-cache joins between `DimStore`, `DimProduct`
+     * objects stored in `replicated` cache and `FactPurchase` objects
+     * stored in `partitioned` cache.
+     */
+    private def queryProductPurchases() {
+        val factCache = ignite$.cache[JavaInt, FactPurchase](PART_NAME)
+
+        // All purchases for certain product made at store2.
+        // =================================================
+        val p1: DimProduct = rand(dataProduct.values)
+        val p2: DimProduct = rand(dataProduct.values)
+        val p3: DimProduct = rand(dataProduct.values)
+
+        println("IDs of products [p1=" + p1.id + ", p2=" + p2.id + ", p3=" + 
p3.id + ']')
+
+        val prodPurchases = factCache.sql(
+            "from \"" + REPL_NAME + "\".DimStore, \"" + REPL_NAME + 
"\".DimProduct, \"" +
+                PART_NAME + "\".FactPurchase " +
+            "where DimStore.id=FactPurchase.storeId and " +
+                "DimProduct.id=FactPurchase.productId and " +
+                "DimStore.name=? and DimProduct.id in(?, ?, ?)",
+            "Store2", p1.id, p2.id, p3.id)
+
+        printQueryResults("All purchases made at store2 for 3 specific 
products:", prodPurchases.getAll)
+    }
+
+    /**
+     * Print query results.
+     *
+     * @param msg Initial message.
+     * @param res Results to print.
+     */
+    private def printQueryResults[V](msg: String, res: 
Iterable[Cache.Entry[JavaInt, V]]) {
+        println(msg)
+
+        for (e <- res)
+            println("    " + e.getValue.toString)
+    }
+
+    /**
+     * Gets random value from given collection.
+     *
+     * @param c Input collection (no `null` and not emtpy).
+     * @return Random value from the input collection.
+     */
+    def rand[T](c: Iterable[_ <: T]): T = {
+        val n = ThreadLocalRandom8.current.nextInt(c.size)
+
+        var i = 0
+
+        for (t <- c) {
+            if (i < n)
+                i += 1
+            else
+                return t
+        }
+
+        throw new ConcurrentModificationException
+    }
+}
+
+/**
+ * Represents a product available for purchase. In our `snowflake` schema a 
`product`
+ * is a `dimension` and will be cached in `CacheMode#REPLICATED` cache.
+ *
+ * @param id Product ID.
+ * @param name Product name.
+ * @param price Product list price.
+ * @param qty Available product quantity.
+ */
+class DimProduct(
+    @ScalarCacheQuerySqlField
+    val id: Int,
+    val name: String,
+    @ScalarCacheQuerySqlField
+    val price: Float,
+    val qty: Int) {
+    /**
+     * `toString` implementation.
+     */
+    override def toString: String = {
+        val sb = new StringBuilder
+
+        sb.append("DimProduct ")
+        sb.append("[id=").append(id)
+        sb.append(", name=").append(name)
+        sb.append(", price=").append(price)
+        sb.append(", qty=").append(qty)
+        sb.append(']')
+
+        sb.toString()
+    }
+}
+
+/**
+ * Represents a physical store location. In our `snowflake` schema a `store`
+ * is a `dimension` and will be cached in `CacheMode#REPLICATED` cache.
+ *
+ * @param id Primary key.
+ * @param name Store name.
+ * @param zip Zip code.
+ * @param addr Address.
+ */
+class DimStore(
+    @ScalarCacheQuerySqlField
+    val id: Int,
+    @ScalarCacheQuerySqlField
+    val name: String,
+    val zip: String,
+    val addr: String) {
+    /**
+     * `toString` implementation.
+     */
+    override def toString: String = {
+        val sb = new StringBuilder
+
+        sb.append("DimStore ")
+        sb.append("[id=").append(id)
+        sb.append(", name=").append(name)
+        sb.append(", zip=").append(zip)
+        sb.append(", addr=").append(addr)
+        sb.append(']')
+
+        sb.toString()
+    }
+}
+
+/**
+ * Represents a purchase record. In our `snowflake` schema purchase
+ * is a `fact` and will be cached in larger `CacheMode#PARTITIONED` cache.
+ *
+ * @param id Purchase ID.
+ * @param productId Purchased product ID.
+ * @param storeId Store ID.
+ * @param purchasePrice Purchase price.
+ */
+class FactPurchase(
+    @ScalarCacheQuerySqlField
+    val id: Int,
+    @ScalarCacheQuerySqlField
+    val productId: Int,
+    @ScalarCacheQuerySqlField
+    val storeId: Int,
+    @ScalarCacheQuerySqlField
+    val purchasePrice: Float) {
+    /**
+     * `toString` implementation.
+     */
+    override def toString: String = {
+        val sb = new StringBuilder
+
+        sb.append("FactPurchase ")
+        sb.append("[id=").append(id)
+        sb.append(", productId=").append(productId)
+        sb.append(", storeId=").append(storeId)
+        sb.append(", purchasePrice=").append(purchasePrice)
+        sb.append(']')
+
+        sb.toString()
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/Person.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/Person.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/Person.scala
new file mode 100644
index 0000000..10a8f1b
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/Person.scala
@@ -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.ignite.scalar.examples.datagrid.store
+
+import java.lang.Long
+
+/**
+ * Person class.
+ */
+@SerialVersionUID(0L)
+class Person() {
+    /** ID field */
+    private[this] var id = 0L
+
+    /** First name field */
+    private[this] var firstName: String = null
+
+    /** Last name field */
+    private[this] var lastName: String = null
+
+    def this(id: Long, firstName: String, lastName: String) = {
+        this()
+
+        this.id = id
+        this.firstName = firstName
+        this.lastName = lastName
+    }
+
+    /**
+     * @return ID field.
+     */
+    def getId = id
+
+    /**
+     * Update ID field.
+     *
+     * @param id New ID field.
+     */
+    def setId(id: Long) {
+        this.id = id
+    }
+
+    /**
+     * @return First name field.
+     */
+    def getFirstName = firstName
+
+    /**
+     * Update first name field.
+     *
+     * @param firstName New first name field.
+     */
+    def setFirstName(firstName: String) {
+        this.firstName = firstName
+    }
+
+    /**
+     * @return Last name field.
+     */
+    def getLastName = lastName
+
+    /**
+     * Update last name field.
+     *
+     * @param lastName New last name field.
+     */
+    def setLastName(lastName: String) {
+        this.lastName = lastName
+    }
+
+    /**
+     * `toString` implementation.
+     */
+    override def toString: String =
+        "Person [id=" + id + ", firstName=" + firstName + ", lastName=" + 
lastName + "]"
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/auto/CacheConfig.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/auto/CacheConfig.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/auto/CacheConfig.scala
new file mode 100644
index 0000000..1118098
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/auto/CacheConfig.scala
@@ -0,0 +1,77 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid.store.auto
+
+import org.apache.ignite.cache.CacheAtomicityMode._
+import org.apache.ignite.cache.store.CacheStore
+import org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStore
+import org.apache.ignite.cache.{CacheTypeFieldMetadata, CacheTypeMetadata}
+import org.apache.ignite.configuration.CacheConfiguration
+import org.apache.ignite.internal.util.scala.impl
+import org.apache.ignite.scalar.examples.datagrid.store.Person
+
+import org.h2.jdbcx.JdbcConnectionPool
+
+import javax.cache.configuration.Factory
+import java.lang.{Long => JavaLong}
+import java.sql.Types
+import java.util.{Arrays, Collections}
+
+/**
+ * Predefined configuration for examples with [[CacheJdbcPojoStore]].
+ */
+private[auto] object CacheConfig {
+    /**
+     * Configure cache with store.
+     */
+    def jdbcPojoStoreCache(name: String): CacheConfiguration[JavaLong, Person] 
= {
+        val cfg = new CacheConfiguration[JavaLong, Person](name)
+
+        cfg.setAtomicityMode(TRANSACTIONAL)
+
+        cfg.setCacheStoreFactory(new Factory[CacheStore[_ >: JavaLong, _ >: 
Person]] {
+            @impl def create: CacheStore[_ >: JavaLong, _ >: Person] = {
+                val store = new CacheJdbcPojoStore[JavaLong, Person]
+
+                
store.setDataSource(JdbcConnectionPool.create("jdbc:h2:tcp://localhost/mem:ExampleDb",
 "sa", ""))
+
+                store
+            }
+        })
+
+        val meta = new CacheTypeMetadata
+
+        meta.setDatabaseTable("PERSON")
+        meta.setKeyType("java.lang.Long")
+        
meta.setValueType("org.apache.ignite.scalar.examples.datagrid.store.Person")
+        meta.setKeyFields(Collections.singletonList(new 
CacheTypeFieldMetadata("ID", Types.BIGINT, "id", classOf[JavaLong])))
+        meta.setValueFields(Arrays.asList(new CacheTypeFieldMetadata("ID", 
Types.BIGINT, "id", classOf[JavaLong]),
+            new CacheTypeFieldMetadata("FIRST_NAME", Types.VARCHAR, 
"firstName", classOf[String]),
+            new CacheTypeFieldMetadata("LAST_NAME", Types.VARCHAR, "lastName", 
classOf[String])))
+
+        cfg.setTypeMetadata(Collections.singletonList(meta))
+        cfg.setWriteBehindEnabled(true)
+        cfg.setReadThrough(true)
+        cfg.setWriteThrough(true)
+
+        cfg
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/auto/ScalarCacheAutoStoreExample.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/auto/ScalarCacheAutoStoreExample.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/auto/ScalarCacheAutoStoreExample.scala
new file mode 100644
index 0000000..60aaac8
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/auto/ScalarCacheAutoStoreExample.scala
@@ -0,0 +1,94 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid.store.auto
+
+import org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStore
+import org.apache.ignite.examples.ExampleNodeStartup
+import org.apache.ignite.examples.datagrid.store.auto.DbH2ServerStartup
+import org.apache.ignite.scalar.examples.datagrid.store.Person
+import org.apache.ignite.scalar.scalar
+import org.apache.ignite.scalar.scalar._
+
+import java.lang.{Long => JavaLong}
+import java.util.UUID
+
+/**
+ * Demonstrates usage of cache with underlying persistent store configured.
+ * <p>
+ * This example uses [[CacheJdbcPojoStore]] as a persistent store.
+ * <p>
+ * To start the example, you should:
+ * <ul>
+ *  <li>Start H2 database TCP server using [[DbH2ServerStartup]].</li>
+ *  <li>Start a few nodes using [[ExampleNodeStartup]] or by starting remote 
nodes as specified below.</li>
+ *  <li>Start example using [[ScalarCacheAutoStoreExample]].</li>
+ * </ul>
+ * <p>
+ * Remote nodes should always be started with special configuration file which
+ * enables P2P class loading: `'ignite.{sh|bat} 
examples/config/example-ignite.xml'`.
+ * <p>
+ * Alternatively you can run [[ExampleNodeStartup]] in another JVM which will
+ * start node with `examples/config/example-ignite.xml` configuration.
+ */
+object ScalarCacheAutoStoreExample extends App {
+    /** Configuration file name. */
+    private val CONFIG = "examples/config/example-ignite.xml"
+
+    /** Cache name. */
+    private val CACHE_NAME = ScalarCacheAutoStoreExample.getClass.getSimpleName
+
+    /** Global person ID to use across entire example. */
+    private val id = Math.abs(UUID.randomUUID.getLeastSignificantBits)
+
+    scalar(CONFIG) {
+        println()
+        println(">>> Cache auto store example started.")
+
+        val cache = createCache$[JavaLong, 
Person](CacheConfig.jdbcPojoStoreCache(CACHE_NAME))
+
+        try {
+            val tx = transaction$()
+
+            try {
+                var value = cache.get(id)
+
+                println("Read value: " + value)
+
+                value = cache.getAndPut(id, new Person(id, "Isaac", "Newton"))
+
+                println("Overwrote old value: " + value)
+
+                value = cache.get(id)
+
+                println("Read value: " + value)
+
+                tx.commit()
+            }
+            finally {
+                if (tx != null) tx.close()
+            }
+
+            println("Read value after commit: " + cache.get(id))
+        }
+        finally {
+            if (cache != null) cache.close()
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/auto/ScalarCacheAutoStoreLoadDataExample.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/auto/ScalarCacheAutoStoreLoadDataExample.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/auto/ScalarCacheAutoStoreLoadDataExample.scala
new file mode 100644
index 0000000..38d34d6
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/auto/ScalarCacheAutoStoreLoadDataExample.scala
@@ -0,0 +1,84 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid.store.auto
+
+import org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStore
+import org.apache.ignite.examples.datagrid.store.auto.DbH2ServerStartup
+import org.apache.ignite.examples.{ExampleNodeStartup, ExamplesUtils}
+import org.apache.ignite.scalar.scalar
+import org.apache.ignite.scalar.scalar._
+
+import java.lang.{Long => JavaLong}
+
+/**
+ * Demonstrates how to load data from database.
+ * <p>
+ * This example uses [[CacheJdbcPojoStore]] as a persistent store.
+ * <p>
+ * To start the example, you should:
+ * <ul>
+ *  <li>Start H2 database TCP server using [[DbH2ServerStartup]].</li>
+ *  <li>Start a few nodes using [[ExampleNodeStartup]] or by starting remote 
nodes as specified below.</li>
+ *  <li>Start example using [[ScalarCacheAutoStoreLoadDataExample]].</li>
+ * </ul>
+ * <p>
+ * Remote nodes should always be started with special configuration file which
+ * enables P2P class loading: `'ignite.{sh|bat} 
examples/config/example-ignite.xml'`.
+ * <p>
+ * Alternatively you can run [[ExampleNodeStartup]] in another JVM which will
+ * start node with `examples/config/example-ignite.xml` configuration.
+ */
+object ScalarCacheAutoStoreLoadDataExample extends App {
+    /** Configuration file name. */
+    private val CONFIG = "examples/config/example-ignite.xml"
+
+    /** Cache name. */
+    private val CACHE_NAME = 
ScalarCacheAutoStoreLoadDataExample.getClass.getSimpleName
+    
+    /** Heap size required to run this example. */
+    val MIN_MEMORY = 1024 * 1024 * 1024
+    
+    ExamplesUtils.checkMinMemory(MIN_MEMORY)
+    
+    scalar(CONFIG) {
+        println()
+        println(">>> Cache auto store load data example started.")
+
+        val cacheCfg = CacheConfig.jdbcPojoStoreCache(CACHE_NAME)
+
+        val cache = createCache$(cacheCfg)
+
+        try {
+            cache.loadCache(null, "java.lang.Long", "select * from PERSON 
where id <= 3")
+
+            println("Loaded cache entries: " + cache.size())
+
+            cache.clear()
+
+            cache.loadCache(null)
+
+            println("Loaded cache entries: " + cache.size())
+        }
+        finally {
+            if (cache != null)
+                cache.close()
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/dummy/ScalarCacheDummyPersonStore.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/dummy/ScalarCacheDummyPersonStore.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/dummy/ScalarCacheDummyPersonStore.scala
new file mode 100644
index 0000000..d12cb27
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/dummy/ScalarCacheDummyPersonStore.scala
@@ -0,0 +1,101 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid.store.dummy
+
+import org.apache.ignite.Ignite
+import org.apache.ignite.cache.store.{CacheStoreAdapter, CacheStoreSession}
+import org.apache.ignite.examples.datagrid.store.Person
+import org.apache.ignite.lang.IgniteBiInClosure
+import org.apache.ignite.resources.{CacheNameResource, 
CacheStoreSessionResource, IgniteInstanceResource}
+import org.apache.ignite.transactions.Transaction
+
+import org.jetbrains.annotations.Nullable
+
+import javax.cache.Cache
+import java.lang.{Long => JavaLong}
+import java.util.concurrent.ConcurrentHashMap
+
+/**
+ * Dummy cache store implementation.
+ */
+class ScalarCacheDummyPersonStore extends CacheStoreAdapter[JavaLong, Person] {
+    /** Auto-inject ignite instance. */
+    @IgniteInstanceResource private var ignite: Ignite = null
+
+    /** Auto-inject cache name. */
+    @CacheNameResource private var cacheName: String = null
+
+    /** */
+    @CacheStoreSessionResource private var ses: CacheStoreSession = null
+
+    /** Dummy database. */
+    private val dummyDB = new ConcurrentHashMap[JavaLong, Person]
+
+    def load(key: JavaLong): Person = {
+        val tx = transaction
+
+        println(">>> Store load [key=" + key + ", xid=" + (if (tx == null) 
null else tx.xid) + ']')
+
+        dummyDB.get(key)
+    }
+
+    def write(entry: Cache.Entry[_ <: JavaLong, _ <: Person]) {
+        val tx = transaction
+
+        val key = entry.getKey
+
+        val value = entry.getValue
+
+        println(">>> Store put [key=" + key + ", val=" + value + ", xid=" + 
(if (tx == null) null else tx.xid) + ']')
+
+        dummyDB.put(key, value)
+    }
+
+    def delete(key: AnyRef) {
+        val tx = transaction
+
+        println(">>> Store remove [key=" + key + ", xid=" + (if (tx == null) 
null else tx.xid) + ']')
+
+        dummyDB.remove(key)
+    }
+
+    override def loadCache(clo: IgniteBiInClosure[JavaLong, Person], args: 
AnyRef*) {
+        val cnt = args(0).asInstanceOf[Integer]
+
+        println(">>> Store loadCache for entry count: " + cnt)
+
+        for (i <- 0 until cnt) {
+            val p = new Person(i, "first-" + i, "last-" + 1)
+
+            if 
(ignite.affinity(cacheName).isPrimaryOrBackup(ignite.cluster.localNode, 
p.getId)) {
+                dummyDB.put(p.getId, p)
+
+                clo.apply(p.getId, p)
+            }
+        }
+    }
+
+    /**
+     * @return Current transaction.
+     */
+    @Nullable private def transaction: Transaction = {
+        if (ses != null) ses.transaction else null
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/41a5bf67/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/dummy/ScalarCacheDummyStoreExample.scala
----------------------------------------------------------------------
diff --git 
a/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/dummy/ScalarCacheDummyStoreExample.scala
 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/dummy/ScalarCacheDummyStoreExample.scala
new file mode 100644
index 0000000..260497b
--- /dev/null
+++ 
b/examples/src/main/scala/org/apache/ignite/scalar/examples/datagrid/store/dummy/ScalarCacheDummyStoreExample.scala
@@ -0,0 +1,133 @@
+/*
+ *
+ *  * 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.ignite.scalar.examples.datagrid.store.dummy
+
+import org.apache.ignite.IgniteCache
+import org.apache.ignite.cache.CacheAtomicityMode._
+import org.apache.ignite.configuration.CacheConfiguration
+import org.apache.ignite.examples.datagrid.store.Person
+import org.apache.ignite.examples.{ExampleNodeStartup, ExamplesUtils}
+import org.apache.ignite.scalar.scalar
+import org.apache.ignite.scalar.scalar._
+
+import javax.cache.configuration.FactoryBuilder
+import java.lang.{Long => JavaLong}
+import java.util.UUID
+
+/**
+ * Demonstrates usage of cache with underlying persistent store configured.
+ * <p>
+ * This example uses [[ScalarCacheDummyPersonStore]] as a persistent store.
+ * <p>
+ * Remote nodes can be started with [[ExampleNodeStartup]] in another JVM 
which will
+ * start node with `examples/config/example-ignite.xml` configuration.
+ */
+object ScalarCacheDummyStoreExample extends App {
+    /** Configuration file name. */
+    private val CONFIG = "examples/config/example-ignite.xml"
+
+    /** Cache name. */
+    private val CACHE_NAME = 
ScalarCacheDummyStoreExample.getClass.getSimpleName
+    
+    /** Heap size required to run this example. */
+    val MIN_MEMORY = 1024 * 1024 * 1024
+    
+    /** Number of entries to load. */
+    private val ENTRY_COUNT = 100000
+    
+    /** Global person ID to use across entire example. */
+    private val id = Math.abs(UUID.randomUUID.getLeastSignificantBits)
+
+    ExamplesUtils.checkMinMemory(MIN_MEMORY)
+
+    scalar(CONFIG) {
+        println()
+        println(">>> Cache store example started.")
+
+        val cacheCfg = new CacheConfiguration[JavaLong, Person](CACHE_NAME)
+
+        // Set atomicity as transaction, since we are showing transactions in 
example.
+        cacheCfg.setAtomicityMode(TRANSACTIONAL)
+
+        // Configure Dummy store.
+        
cacheCfg.setCacheStoreFactory(FactoryBuilder.factoryOf(classOf[ScalarCacheDummyPersonStore]))
+
+        cacheCfg.setReadThrough(true)
+        cacheCfg.setWriteThrough(true)
+
+        val cache = createCache$[JavaLong, Person](cacheCfg)
+
+        try {
+            loadCache(cache)
+
+            executeTransaction(cache)
+        }
+        finally {
+            if (cache != null)
+                cache.close()
+        }
+    }
+
+    /**
+     * Makes initial cache loading.
+     *
+     * @param cache Cache to load.
+     */
+    private def loadCache(cache: IgniteCache[JavaLong, Person]) {
+        val start = System.currentTimeMillis
+
+        cache.loadCache(null, Integer.valueOf(ENTRY_COUNT))
+
+        val end = System.currentTimeMillis
+
+        println(">>> Loaded " + cache.size() + " keys with backups in " + (end 
- start) + "ms.")
+    }
+
+    /**
+     * Executes transaction with read/write-through to persistent store.
+     *
+     * @param cache Cache to execute transaction on.
+     */
+    private def executeTransaction(cache: IgniteCache[JavaLong, Person]) {
+        val tx = transaction$()
+
+        try {
+            var value = cache.get(id)
+
+            println("Read value: " + value)
+
+            value = cache.getAndPut(id, new Person(id, "Isaac", "Newton"))
+
+            println("Overwrote old value: " + value)
+
+            value = cache.get(id)
+
+            println("Read value: " + value)
+
+            tx.commit()
+        }
+        finally {
+            if (tx != null)
+                tx.close()
+        }
+
+        println("Read value after commit: " + cache.get(id))
+    }
+}


Reply via email to