You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2018/01/05 13:10:36 UTC

[09/13] cayenne git commit: CAY-2371 Switch documentation from Docbook to Asciidoctor format

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/object-relational-mapping.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/object-relational-mapping.adoc b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/object-relational-mapping.adoc
new file mode 100644
index 0000000..1851c6d
--- /dev/null
+++ b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/object-relational-mapping.adoc
@@ -0,0 +1,109 @@
+// 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.
+=== Getting started with Object Relational Mapping (ORM)
+The goal of this section is to learn how to create a simple Object-Relational model with
+CayenneModeler. We will create a complete ORM model for the following database
+schema:
+
+image::cayenne-tutorial-model.png[align="center"]
+
+NOTE: Very often you'd have an existing database already, and
+    it can be quickly imported in Cayenne via "Tools > Reengineer Database
+    Schema". This will save you lots of time compared to manual mapping. However
+    understanding how to create the mapping by hand is important, so we are showing
+    the "manual" approach below.
+
+==== Mapping Database Tables and Columns
+Lets go back to CayenneModeler where we have the newly created project open and start
+by adding the ARTIST table. Database tables are called *DbEntities*
+in Cayenne mapping (those can be actual tables or database views).
+
+Select "datamap" on the left-hand side project tree and click "Create DbEntity" button image:icon-dbentity.png[]
+(or use "Project > Create DbEntity" menu). A new DbEntity is created. In "DbEntity
+Name" field enter "ARTIST". Then click on "Create Attribute" button image:icon-attribute.png[]
+on the entity toolbar. This action changes the view to the "Attribute"
+tab and adds a new attribute (attribute means a "table column" in this case) called
+"untitledAttr". Let's rename it to ID, make it an `INTEGER` and make it a PK:
+
+image::modeler-artistid.png[align="center"]
+
+Similarly add NAME `VARCHAR(200)` and DATE_OF_BIRTH `DATE` attributes. After that repeat
+this procedure for PAINTING and GALLERY entities to match DB schema shown above.
+
+==== Mapping Database Relationships
+
+Now we need to specify relationships between ARTIST, PAINTING and GALLERY tables.
+Start by creating a one-to-many ARTIST/PAINTING relationship:
+
+- Select the ARTIST DbEntity on the left and click on the "Properties" tab.
+
+- Click on "Create Relationship" button on the entity toolbar image:icon-relationship.png[] - a relationship
+called "untitledRel" is created.
+
+- Choose the "Target" to be "Painting".
+
+- Click on the "Database Mapping" button image:icon-edit.png[] - relationship
+configuration dialog is presented. Here you can assign a name to the
+relationship and also its complimentary reverse relationship. This name can be
+anything (this is really a symbolic name of the database referential
+constraint), but it is recommended to use a valid Java identifier, as this will
+save some typing later. We'll call the relationship "paintings" and reverse
+relationship "artist".
+
+- Click on "Add" button on the right to add a join
+
+- Select "ID" column for the "Source" and "ARTIST_ID" column for the target.
+
+- Relationship information should now look like this:
+
+image::modeler-dbrelationship.png[align="center"]
+
+- Click "Done" to confirm the changes and close the dialog.
+
+- Two complimentary relationships have been created - from ARTIST to PAINTING
+and back. Still you may have noticed one thing is missing - "paintings"
+relationship should be to-many, but "To Many" checkbox is not checked. Let's
+change that - check the checkbox for "paintings" relationship, and then click on
+PAINTING DbEntity, and uncheck "artist" relationship "To Many" to make the
+reverse relationship "to-one" as it should be.
+
+- Repeat the steps above to create a many-to-one relationship from PAINTING to GALLERY, calling the relationships pair
+"gallery" and "paintings".
+
+==== Mapping Java Classes
+
+Now that the database schema mapping is complete, CayenneModeler can create mappings
+of Java classes (aka "ObjEntities") by deriving everything from DbEntities. At present
+there is no way to do it for the entire DataMap in one click, so we'll do it for each
+table individually.
+
+- Select "ARTIST" DbEntity and click on "Create ObjEntity" button image:icon-new_objentity.png[]
+either on the entity toolbar or on the main toolbar. An ObjEntity called
+"Artist" is created with a Java class field set to
+"org.example.cayenne.persistent.Artist". The modeler transformed the database
+names to the Java-friendly names (e.g., if you click on the "Attributes" tab,
+you'll see that "DATE_OF_BIRTH" column was converted to "dateOfBirth" Java class
+attribute).
+
+- Select "GALLERY" DbEntity and click on "Create ObjEntity" button again - you'll see a "Gallery" ObjEntity created.
+- Finally, do the same thing for "PAINTING".
+
+Now you need to synchronize relationships. Artist and Gallery entities were created
+when there was no related "Painting" entity, so their relationships were not set.
+
+- Click on the "Artist" ObjEntity. Now click on "Sync ObjEntity with DbEntity" button on
+the toolbar image:icon-sync.png[] - you will see the "paintings" relationship appear.
+- Do the same for the "Gallery" entity.
+
+Unless you want to customize the Java class and property names (which you can do easily) the mapping is complete.

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/part2.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/part2.adoc b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/part2.adoc
new file mode 100644
index 0000000..e12d0f0
--- /dev/null
+++ b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/part2.adoc
@@ -0,0 +1,20 @@
+// 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.
+== Learning mapping basics
+
+include::starting-project.adoc[]
+
+include::object-relational-mapping.adoc[]
+
+include::java-classes.adoc[]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/part3.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/part3.adoc b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/part3.adoc
new file mode 100644
index 0000000..cd31060
--- /dev/null
+++ b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/part3.adoc
@@ -0,0 +1,22 @@
+// 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.
+== Learning Cayenne API
+
+include::object-context.adoc[]
+
+include::persistent-objects.adoc[]
+
+include::select-query.adoc[]
+
+include::delete.adoc[]

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/persistent-objects.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/persistent-objects.adoc b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/persistent-objects.adoc
new file mode 100644
index 0000000..16d4f2a
--- /dev/null
+++ b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/persistent-objects.adoc
@@ -0,0 +1,111 @@
+// 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.
+=== Getting started with persistent objects
+In this chapter we'll learn about persistent objects, how to customize them and how to
+create and save them in DB.
+
+==== Inspecting and Customizing Persistent Objects
+Persistent classes in Cayenne implement a DataObject interface. If you inspect any of
+the classes generated earlier in this tutorial (e.g.
+`org.example.cayenne.persistent.Artist`), you'll see that it extends a class with the name
+that starts with underscore (`org.example.cayenne.persistent.auto._Artist`), which in turn
+extends from `org.apache.cayenne.CayenneDataObject`. Splitting each persistent class into
+user-customizable subclass (`Xyz`) and a generated superclass (`_Xyz`) is a useful technique
+to avoid overwriting the custom code when refreshing classes from the mapping
+model.
+
+Let's for instance add a utility method to the Artist class that sets Artist date of
+birth, taking a string argument for the date. It will be preserved even if the model
+changes later:
+
+[source,java]
+----
+include::{java-include-dir}/persistent/Artist.java[tag=content]
+----
+
+==== Create New Objects
+Now we'll create a bunch of objects and save them to the database. An object is
+created and registered with `ObjectContext` using "`newObject`" method. Objects *must* be registered
+with `DataContext` to be persisted and to allow setting relationships with other objects.
+Add this code to the "main" method of the Main class:
+
+[source,java,indent=0]
+----
+include::{java-include-dir}/Main.java[tag=new-artist]
+----
+
+Note that at this point "picasso" object is only stored in memory and is not saved in
+the database. Let's continue by adding a Metropolitan Museum "`Gallery`" object and a few
+Picasso "Paintings":
+
+[source,java,indent=0]
+----
+include::{java-include-dir}/Main.java[tag=new-painting]
+----
+
+Now we can link the objects together, establishing relationships. Note that in each
+case below relationships are automatically established in both directions (e.g.
+`picasso.addToPaintings(girl)` has exactly the same effect as
+`girl.setToArtist(picasso)`).
+
+[source, java, indent=0]
+----
+include::{java-include-dir}/Main.java[tag=link-objects]
+----
+
+Now lets save all five new objects, in a single method call:
+
+[source, java, indent=0]
+----
+include::{java-include-dir}/Main.java[tag=commit]
+----
+
+Now you can run the application again as described in the previous chapter. The new
+output will show a few actual DB operations:
+
+    ...
+    INFO: --- transaction started.
+    INFO: No schema detected, will create mapped tables
+    INFO: CREATE TABLE GALLERY (ID INTEGER NOT NULL, NAME VARCHAR (200), PRIMARY KEY (ID))
+    INFO: CREATE TABLE ARTIST (DATE_OF_BIRTH DATE, ID INTEGER NOT NULL, NAME VARCHAR (200), PRIMARY KEY (ID))
+    INFO: CREATE TABLE PAINTING (ARTIST_ID INTEGER, GALLERY_ID INTEGER, ID INTEGER NOT NULL,
+          NAME VARCHAR (200), PRIMARY KEY (ID))
+    INFO: ALTER TABLE PAINTING ADD FOREIGN KEY (ARTIST_ID) REFERENCES ARTIST (ID)
+    INFO: ALTER TABLE PAINTING ADD FOREIGN KEY (GALLERY_ID) REFERENCES GALLERY (ID)
+    INFO: CREATE TABLE AUTO_PK_SUPPORT (
+          TABLE_NAME CHAR(100) NOT NULL,  NEXT_ID BIGINT NOT NULL,  PRIMARY KEY(TABLE_NAME))
+    INFO: DELETE FROM AUTO_PK_SUPPORT WHERE TABLE_NAME IN ('ARTIST', 'GALLERY', 'PAINTING')
+    INFO: INSERT INTO AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('ARTIST', 200)
+    INFO: INSERT INTO AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('GALLERY', 200)
+    INFO: INSERT INTO AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('PAINTING', 200)
+    INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE [bind: 1:'ARTIST']
+    INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE [bind: 1:'GALLERY']
+    INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE [bind: 1:'PAINTING']
+    INFO: INSERT INTO GALLERY (ID, NAME) VALUES (?, ?)
+    INFO: [batch bind: 1->ID:200, 2->NAME:'Metropolitan Museum of Art']
+    INFO: === updated 1 row.
+    INFO: INSERT INTO ARTIST (DATE_OF_BIRTH, ID, NAME) VALUES (?, ?, ?)
+    INFO: [batch bind: 1->DATE_OF_BIRTH:'1881-10-25 00:00:00.0', 2->ID:200, 3->NAME:'Pablo Picasso']
+    INFO: === updated 1 row.
+    INFO: INSERT INTO PAINTING (ARTIST_ID, GALLERY_ID, ID, NAME) VALUES (?, ?, ?, ?)
+    INFO: [batch bind: 1->ARTIST_ID:200, 2->GALLERY_ID:200, 3->ID:200, 4->NAME:'Gertrude Stein']
+    INFO: [batch bind: 1->ARTIST_ID:200, 2->GALLERY_ID:200, 3->ID:201, 4->NAME:'Girl Reading at a Table']
+    INFO: === updated 2 rows.
+    INFO: +++ transaction committed.
+
+So first Cayenne creates the needed tables (remember, we used
+"`CreateIfNoSchemaStrategy`"). Then it runs a number of inserts, generating primary keys
+on the fly. Not bad for just a few lines of code.
+    
+

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/select-query.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/select-query.adoc b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/select-query.adoc
new file mode 100644
index 0000000..56c843d
--- /dev/null
+++ b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/select-query.adoc
@@ -0,0 +1,56 @@
+// 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.
+=== Selecting Objects
+This chapter shows how to select objects from the database using `ObjectSelect` query. 
+    
+==== Introducing ObjectSelect
+It was shown before how to persist new objects. Cayenne queries are used to access
+already saved objects. The primary query type used for selecting objects is `ObjectSelect`.
+It can be mapped in CayenneModeler or created
+via the API. We'll use the latter approach in this section. We don't have too much data
+in the database yet, but we can still demonstrate the main principles below.
+
+- Select all paintings (the code, and the log output it generates):
+
+[source,java]
+----
+List<Painting> paintings1 = ObjectSelect.query(Painting.class).select(context);
+----
+
+   INFO: SELECT t0.GALLERY_ID, t0.ARTIST_ID, t0.NAME, t0.ID FROM PAINTING t0
+   INFO: === returned 2 rows. - took 18 ms.
+
+- Select paintings that start with "`gi`", ignoring case:
+
+[source,java]
+----
+List<Painting> paintings2 = ObjectSelect.query(Painting.class)
+        .where(Painting.NAME.likeIgnoreCase("gi%")).select(context);
+----
+    INFO: SELECT t0.GALLERY_ID, t0.NAME, t0.ARTIST_ID, t0.ID FROM PAINTING t0 WHERE UPPER(t0.NAME) LIKE UPPER(?)
+      [bind: 1->NAME:'gi%'] - prepared in 6 ms.
+    INFO: === returned 1 row. - took 18 ms.
+
+- Select all paintings done by artists who were born more than a 100 years ago:
+
+[source,java]
+----
+List<Painting> paintings3 = ObjectSelect.query(Painting.class)
+        .where(Painting.ARTIST.dot(Artist.DATE_OF_BIRTH).lt(LocalDate.of(1900,1,1)))
+        .select(context);
+----
+
+    INFO: SELECT t0.GALLERY_ID, t0.NAME, t0.ARTIST_ID, t0.ID FROM PAINTING t0 JOIN ARTIST t1 ON (t0.ARTIST_ID = t1.ID)
+      WHERE t1.DATE_OF_BIRTH < ? [bind: 1->DATE_OF_BIRTH:'1911-01-01 00:00:00.493'] - prepared in 7 ms.
+    INFO: === returned 2 rows. - took 25 ms.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/setup.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/setup.adoc b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/setup.adoc
new file mode 100644
index 0000000..5a81104
--- /dev/null
+++ b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/setup.adoc
@@ -0,0 +1,26 @@
+// 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.
+== Setting up the environment
+
+The goal of this chapter of the tutorial is to install (or check that you already have
+installed) a minimally needed set of software to build a Cayenne application.
+
+=== Install Java
+
+Obviously, JDK has to be installed. Cayenne 4.0 requires JDK 1.7 or newer.
+
+=== Install IntelliJ IDEA
+
+Download and install IntelliJ IDEA Community Edition.
+This tutorial is based on version 2016.3, still it should work with any recent IntelliJ IDEA version.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/starting-project.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/starting-project.adoc b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/starting-project.adoc
new file mode 100644
index 0000000..1e041e4
--- /dev/null
+++ b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/starting-project.adoc
@@ -0,0 +1,111 @@
+// 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.
+=== Starting a project
+
+The goal of this chapter is to create a new Java project in IntelliJ IDEA
+containing a basic Cayenne mapping. It presents an introduction to
+CayenneModeler GUI tool, showing how to create the initial mapping
+objects: `DataDomain`, `DataNode`, `DataMap`.
+
+==== Create a new Project in IntelliJ IDEA
+
+In IntelliJ IDEA select `File > New > Project..` and then
+select `Maven` and click `Next`.
+In the dialog shown on the screenshot below, fill the `Group Id`
+and `Artifact Id` fields and click `Next`.
+
+image::tutorial-idea-project.png[align="center"]
+
+On next dialog screen you can customize directory for your project and click `Finish`.
+Now you should have a new empty project.
+
+==== Download and Start CayenneModeler
+
+Although later in this tutorial we'll be using Maven to include Cayenne
+runtime jars in the project, you'll still need to download Cayenne to
+get access to the CayenneModeler tool.
+
+NOTE: If you are really into Maven, you can start CayenneModeler from Maven too.
+      We'll do it in a more traditional way here.
+
+Download the http://cayenne.apache.org/download.html[latest release]. Unpack the distribution
+somewhere in the file system and start CayenneModeler, following platform-specific instructions.
+On most platforms it is done simply by doubleclicking the Modeler icon.
+The welcome screen of the Modeler looks like this:
+
+image::modeler-started.png[align="center"]
+
+==== Create a New Mapping Project in CayenneModeler
+
+Click on the `New Project` button on Welcome screen. A new mapping project will appear
+that contains a single *DataDomain*. The meaning of a
+DataDomain is explained elsewhere in the User Guide. For now it is sufficient to
+understand that DataDomain is the root of your mapping project.
+
+==== Create a DataNode
+
+The next project object you will create is a *DataNode*.
+DataNode is a descriptor of a single database your application
+will connect to. Cayenne mapping project can use more than one database, but for now,
+we'll only use one. With "project" selected on the left, click on `Create DataNode` button image:icon-node.png[]
+on the toolbar (or select `Project > Create DataNode` from the menu).
+
+A new DataNode is displayed. Now you need to specify JDBC connection parameters. For
+an in-memory Derby database you can enter the following settings:
+
+- JDBC Driver: org.apache.derby.jdbc.EmbeddedDriver
+- DB URL: jdbc:derby:memory:testdb;create=true
+
+NOTE: We are creating an in-memory database here. So when
+      you stop your application, all the data will be lost. In most real-life
+      cases you'll be connecting to a database that actually persists its data on
+      disk, but an in-memory DB will do for the simple tutorial.
+
+Also you will need to change "Schema Update Strategy". Select
+`org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy` from the dropdown, so that
+Cayenne creates a new schema on Derby based on the ORM mapping when the application
+starts.
+
+image::base-datanode.png[align="center"]
+
+==== Create a DataMap
+
+Now you will create a *DataMap*. DataMap is an object
+that holds all the mapping information. To create it, click on "Create DataMap" button
+image:icon-datamap.png[] (or select a corresponding menu item).
+Note that the newly created DataMap is automatically linked to the DataNode that you created in
+the previous step. If there is more than one DataNode, you may need to link a DataMap
+to the correct node manually. In other words a DataMap within DataDomain must point
+to a database described by the map.
+
+You can leave all the DataMap defaults unchanged except for one - "Java Package".
+Enter `org.example.cayenne.persistent`. This name will later be used for all persistent
+classes.
+
+image::base-datamap.png[align="center"]
+
+==== Save the Project
+
+image::idea-xmlfiles.png[float="right"]
+
+Before you proceed with the actual mapping, let's save the project. Click on "Save"
+button in the toolbar and navigate to the `tutorial` IDEA project folder that was
+created earlier in this section and its `src/main/resources` subfolder and save the
+project there. Now go back to IDEA and you will see two Cayenne XML files.
+
+Note that the location of the XML files is not coincidental. Cayenne runtime looks for
+`cayenne-*.xml` file in the application `CLASSPATH` and `src/main/resources` folder should
+already be a "class folder" in IDEA for our project (and is also a standard location
+that Maven would copy to a jar file, if we were using Maven from command-line).
+

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/webapp.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/webapp.adoc b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/webapp.adoc
new file mode 100644
index 0000000..2b7d930
--- /dev/null
+++ b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/webapp.adoc
@@ -0,0 +1,280 @@
+// 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.
+== Converting to Web Application
+This chapter shows how to work with Cayenne in a web application.
+
+=== Converting Tutorial to a Web Application
+The web part of the web application tutorial is done in JSP, which is the least common
+denominator of the Java web technologies, and is intentionally simplistic from the UI
+perspective, to concentrate on Cayenne integration aspect, rather than the interface. A
+typical Cayenne web application works like this:
+
+- Cayenne configuration is loaded when an application context is started, using a special servlet filter.
+- User requests are intercepted by the filter, and the DataContext is bound to
+the request thread, so the application can access it easily from anywhere.
+- The same DataContext instance is reused within a single user session;
+different sessions use different DataContexts (and therefore different sets of
+objects). _The context can be scoped differently
+depending on the app specifics. For the tutorial we'll be using a
+session-scoped context._
+
+So let's convert the tutorial that we created to a web application:
+
+- In IDEA under "tutorial" project folder create a new folder `src/main/webapp/WEB-INF`.
+- Under `WEB-INF` create a new file `web.xml` (a standard web app descriptor):
+
+.web.xml
+[source,xml]
+----
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE web-app
+   PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+  "http://java.sun.com/dtd/web-app_2_3.dtd">
+<web-app>
+    <display-name>Cayenne Tutorial</display-name>
+
+    <!-- This filter bootstraps ServerRuntime and then provides each request thread 
+         with a session-bound DataContext. Note that the name of the filter is important,
+         as it points it to the right named configuration file.
+    -->
+    <filter>
+        <filter-name>cayenne-project</filter-name>
+        <filter-class>org.apache.cayenne.configuration.web.CayenneFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>cayenne-project</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+    <welcome-file-list>
+        <welcome-file>index.jsp</welcome-file>
+    </welcome-file-list>
+</web-app>
+----
+
+- Create the artist browser page `src/main/webapp/index.jsp` file with the following contents:
+
+.webapp/index.jsp
+[source,jsp]
+----
+<%@ page language="java" contentType="text/html" %>
+<%@ page import="org.example.cayenne.persistent.*" %>
+<%@ page import="org.apache.cayenne.*" %>
+<%@ page import="org.apache.cayenne.query.*" %>
+<%@ page import="org.apache.cayenne.exp.*" %>
+<%@ page import="java.util.*" %>
+
+<%
+    ObjectContext context = BaseContext.getThreadObjectContext();
+    List<Artist> artists = ObjectSelect.query(Artist.class)
+                .orderBy(Artist.NAME.asc())
+                .select(context);
+%>
+
+<html>
+    <head>
+        <title>Main</title>
+    </head>
+    <body>
+        <h2>Artists:</h2>
+        
+        <% if(artists.isEmpty()) {%>
+        <p>No artists found</p>
+        <% } else {
+               for(Artist a : artists) {
+        %>
+        <p><a href="detail.jsp?id=<%=Cayenne.intPKForObject(a)%>"> <%=a.getName()%> </a></p>
+        <%
+               }
+           } %>
+        <hr>
+        <p><a href="detail.jsp">Create new artist...</a></p>
+    </body>
+</html>
+----
+
+- Create the artist editor page `src/main/webapp/detail.jsp` with the following content:
+
+.webapp/detail.jsp
+[source,jsp]
+----
+<%@ page language="java" contentType="text/html" %>
+<%@ page import="org.example.cayenne.persistent.*" %>
+<%@ page import="org.apache.cayenne.*" %>
+<%@ page import="org.apache.cayenne.query.*" %>
+<%@ page import="java.util.*" %>
+<%@ page import="java.text.*" %>
+<%@ page import="java.time.format.DateTimeFormatter" %>
+
+<% 
+    ObjectContext context = BaseContext.getThreadObjectContext();
+    String id = request.getParameter("id");
+
+    // find artist for id
+    Artist artist = null;
+    if(id != null &amp;&amp; id.trim().length() > 0) {
+        artist = SelectById.query(Artist.class, Integer.parseInt(id)).selectOne(context);
+    }
+
+    if("POST".equals(request.getMethod())) {
+        // if no id is saved in the hidden field, we are dealing with
+        // create new artist request
+        if(artist == null) {
+            artist = context.newObject(Artist.class);
+        }
+
+        // note that in a real application we would so dome validation ...
+        // here we just hope the input is correct
+        artist.setName(request.getParameter("name"));
+        artist.setDateOfBirthString(request.getParameter("dateOfBirth"));
+
+        context.commitChanges();
+
+        response.sendRedirect("index.jsp");
+    }
+
+    if(artist == null) {
+        // create transient artist for the form response rendering
+        artist = new Artist();
+    }
+
+    String name = artist.getName() == null ? "" : artist.getName();
+
+    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
+    String dob = artist.getDateOfBirth() == null
+                        ? "" :artist.getDateOfBirth().format(formatter);
+%>
+<html>
+    <head>
+        <title>Artist Details</title>
+    </head>
+    <body>
+        <h2>Artists Details</h2>
+        <form name="EditArtist" action="detail.jsp" method="POST">
+            <input type="hidden" name="id" value="<%= id != null ? id : "" %>" />
+            <table border="0">
+                <tr>
+                    <td>Name:</td>
+                    <td><input type="text" name="name" value="<%= name %>"/></td>
+                </tr>
+                <tr>
+                    <td>Date of Birth (yyyyMMdd):</td>
+                    <td><input type="text" name="dateOfBirth" value="<%= dob %>"/></td>
+                </tr>
+                <tr>
+                    <td></td>
+                    <td align="right"><input type="submit" value="Save" /></td>
+                </tr>  
+            </table>
+        </form>
+    </body>
+</html>
+----
+
+==== Running Web Application
+We need to provide javax servlet-api for our application.
+
+.pom.xml
+[source,xml]
+----
+<dependency>
+    <groupId>javax.servlet</groupId>
+    <artifactId>javax.servlet-api</artifactId>
+    <version>3.1.0</version>
+    <scope>provided</scope>
+</dependency>
+----
+
+Also to run the web application we'll use "maven-jetty-plugin". To activate it,
+let's add the following piece of code to the `pom.xml` file, following the "dependencies"
+section and save the POM:
+
+.pom.xml
+[source,xml]
+----
+<build>
+    <plugins>
+        <plugin>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-maven-plugin</artifactId>
+            <version>9.3.14.v20161028</version>
+        </plugin>
+    </plugins>
+</build>
+----
+
+- Go to "Select Run/Debug Configuration" menu, and then "Edit Configuration..."
+
+image::idea-edit-configurations.png[align="center"]
+
+
+- Click `+` button and select "Maven". Enter "Name" and "Command line" as shown on screenshot:
+
+image:idea-run-configuration.png[]
+
+- Click "Apply" and "Run". On the first execution it may take a few minutes for
+Jetty plugin to download all dependencies, but eventually you'll see the logs
+like this:
+
+    [INFO] ------------------------------------------------------------------------
+    [INFO] Building tutorial 0.0.1-SNAPSHOT
+    [INFO] ------------------------------------------------------------------------
+    ...
+    [INFO] Configuring Jetty for project: tutorial
+    [INFO] webAppSourceDirectory not set. Trying src/main/webapp
+    [INFO] Reload Mechanic: automatic
+    [INFO] Classes = /.../tutorial/target/classes
+    [INFO] Logging initialized @1617ms
+    [INFO] Context path = /
+    [INFO] Tmp directory = /.../tutorial/target/tmp
+    [INFO] Web defaults = org/eclipse/jetty/webapp/webdefault.xml
+    [INFO] Web overrides =  none
+    [INFO] web.xml file = file:/.../tutorial/src/main/webapp/WEB-INF/web.xml
+    [INFO] Webapp directory = /.../tutorial/src/main/webapp
+    [INFO] jetty-9.3.0.v20150612
+    [INFO] Started o.e.j.m.p.JettyWebAppContext@6872f9c8{/,file:/.../tutorial/src/main/webapp/,AVAILABLE}{file:/.../tutorial/src/main/webapp/}
+    [INFO] Started ServerConnector@723875bc{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
+    [INFO] Started @2367ms
+    [INFO] Started Jetty Server</screen>
+
+- So the Jetty container just started.
+
+- Now go to http://localhost:8080/ URL. You should see "No artists found message" in the web browser and
+the following output in the IDEA console:
+
+    INFO: Loading XML configuration resource from file:/.../tutorial/target/classes/cayenne-project.xml
+    INFO: loading user name and password.
+    INFO: Connecting to 'jdbc:derby:memory:testdb;create=true' as 'null'
+    INFO: +++ Connecting: SUCCESS.
+    INFO: setting DataNode 'datanode' as default, used by all unlinked DataMaps
+    INFO: Detected and installed adapter: org.apache.cayenne.dba.derby.DerbyAdapter
+    INFO: --- transaction started.
+    INFO: No schema detected, will create mapped tables
+    INFO: CREATE TABLE GALLERY (ID INTEGER NOT NULL, NAME VARCHAR (200), PRIMARY KEY (ID))
+    INFO: CREATE TABLE ARTIST (DATE_OF_BIRTH DATE, ID INTEGER NOT NULL, NAME VARCHAR (200), PRIMARY KEY (ID))
+    INFO: CREATE TABLE PAINTING (ARTIST_ID INTEGER, GALLERY_ID INTEGER, ID INTEGER NOT NULL,
+          NAME VARCHAR (200), PRIMARY KEY (ID))
+    INFO: ALTER TABLE PAINTING ADD FOREIGN KEY (ARTIST_ID) REFERENCES ARTIST (ID)
+    INFO: ALTER TABLE PAINTING ADD FOREIGN KEY (GALLERY_ID) REFERENCES GALLERY (ID)
+    INFO: CREATE TABLE AUTO_PK_SUPPORT (
+          TABLE_NAME CHAR(100) NOT NULL,  NEXT_ID BIGINT NOT NULL,  PRIMARY KEY(TABLE_NAME))
+    ...
+    INFO: SELECT t0.DATE_OF_BIRTH, t0.NAME, t0.ID FROM ARTIST t0 ORDER BY t0.NAME
+    INFO: === returned 0 rows. - took 17 ms.
+    INFO: +++ transaction committed.</screen>
+
+- You can click on "Create new artist" link to create artists. Existing artists can be edited by clicking on their name:
+
+image::chrome-webapp.png[align="center"]
+
+You are done with the tutorial!
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/getting-started-guide.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/getting-started-guide.adoc b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/getting-started-guide.adoc
new file mode 100644
index 0000000..dc0d2ea
--- /dev/null
+++ b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/getting-started-guide.adoc
@@ -0,0 +1,48 @@
+// 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.
+= Getting Started with Cayenne
+:revnumber: {project-major-version} ({project-version})
+// enable section numbering, limiting depth to 2
+:sectnums:
+:sectnumlevels: 2
+// use custom header
+:cayenne-header: _getting-started-guide/header.html
+:cayenne-header-position: body
+// customize final layout
+//:linkcss:
+// base path to java code include
+:cayenne-root: {basedir}/../../..
+:java-include-dir: {cayenne-root}/tutorials/tutorial/src/main/java/org/apache/cayenne/tutorial
+:web-include-dir: {cayenne-root}/tutorials/tutorial/src/main/java/org/apache/cayenne/tutorial
+
+[small]#Copyright © 2011-2017 Apache Software Foundation and individual authors#
+
+.License
+[small]#_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_#
+
+[small]#_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._#
+
+include::_getting-started-guide/setup.adoc[]
+
+include::_getting-started-guide/part2.adoc[]
+
+include::_getting-started-guide/part3.adoc[]
+
+include::_getting-started-guide/webapp.adoc[]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/base-datamap.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/base-datamap.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/base-datamap.png
new file mode 100644
index 0000000..a12bc01
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/base-datamap.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/base-datanode.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/base-datanode.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/base-datanode.png
new file mode 100644
index 0000000..69939bb
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/base-datanode.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/cayenne-tutorial-model.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/cayenne-tutorial-model.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/cayenne-tutorial-model.png
new file mode 100644
index 0000000..454d198
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/cayenne-tutorial-model.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/chrome-webapp.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/chrome-webapp.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/chrome-webapp.png
new file mode 100644
index 0000000..603e1df
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/chrome-webapp.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/database-schema.jpg
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/database-schema.jpg b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/database-schema.jpg
new file mode 100644
index 0000000..9d4ee21
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/database-schema.jpg differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-attribute.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-attribute.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-attribute.png
new file mode 100755
index 0000000..77a68eb
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-attribute.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-datamap.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-datamap.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-datamap.png
new file mode 100755
index 0000000..2ea96ca
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-datamap.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-dbentity.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-dbentity.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-dbentity.png
new file mode 100755
index 0000000..87d9d8a
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-dbentity.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-edit.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-edit.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-edit.png
new file mode 100755
index 0000000..027c482
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-edit.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-new_objentity.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-new_objentity.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-new_objentity.png
new file mode 100755
index 0000000..8735d7a
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-new_objentity.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-node.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-node.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-node.png
new file mode 100755
index 0000000..2ff4383
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-node.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-relationship.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-relationship.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-relationship.png
new file mode 100755
index 0000000..44ed7eb
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-relationship.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-sync.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-sync.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-sync.png
new file mode 100755
index 0000000..03e8623
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/icon-sync.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-edit-configurations.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-edit-configurations.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-edit-configurations.png
new file mode 100644
index 0000000..df1d524
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-edit-configurations.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-file-run-menu.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-file-run-menu.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-file-run-menu.png
new file mode 100644
index 0000000..30cf05e
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-file-run-menu.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-generated-classes.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-generated-classes.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-generated-classes.png
new file mode 100644
index 0000000..504dce5
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-generated-classes.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-run-configuration.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-run-configuration.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-run-configuration.png
new file mode 100644
index 0000000..3ebbb62
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-run-configuration.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-xmlfiles.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-xmlfiles.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-xmlfiles.png
new file mode 100644
index 0000000..1b4707d
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/idea-xmlfiles.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-artistid.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-artistid.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-artistid.png
new file mode 100644
index 0000000..fb8c1dd
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-artistid.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-dbrelationship.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-dbrelationship.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-dbrelationship.png
new file mode 100644
index 0000000..4b23eb5
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-dbrelationship.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-deleterule.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-deleterule.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-deleterule.png
new file mode 100644
index 0000000..86ada13
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-deleterule.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-started.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-started.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-started.png
new file mode 100644
index 0000000..dbf8324
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/modeler-started.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/tutorial-idea-project.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/tutorial-idea-project.png b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/tutorial-idea-project.png
new file mode 100644
index 0000000..058dc1d
Binary files /dev/null and b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/images/tutorial-idea-project.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/var.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/var.adoc b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/var.adoc
new file mode 100644
index 0000000..e575eda
--- /dev/null
+++ b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/var.adoc
@@ -0,0 +1 @@
+:version: {project-version}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-rop/pom.xml
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/pom.xml b/docs/asciidoc/getting-started-rop/pom.xml
new file mode 100644
index 0000000..fca4548
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/pom.xml
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>cayenne-asciidoc-parent</artifactId>
+        <groupId>org.apache.cayenne.docs</groupId>
+        <version>4.0.B3-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>getting-started-rop</artifactId>
+
+    <packaging>jar</packaging>
+    <name>getting-started-rop: AsciiDoc - Getting Started with Cayenne ROP (Remote Object Persistence)</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.asciidoctor</groupId>
+                <artifactId>asciidoctor-maven-plugin</artifactId>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.cayenne.docs</groupId>
+                        <artifactId>cayenne-asciidoc-extension</artifactId>
+                        <version>${project.version}</version>
+                    </dependency>
+                </dependencies>
+
+                <executions>
+                    <!-- generate "embeddable" html content with front matter and without header/footer/styles -->
+                    <execution>
+                        <id>asciidoctor-html-web</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>process-asciidoc</goal>
+                        </goals>
+                        <configuration>
+                            <backend>html5</backend>
+                            <headerFooter>false</headerFooter> <!-- do not generate header and footer -->
+                            <outputDirectory>${project.build.directory}/tmp/</outputDirectory>
+                            <extensions>
+                                <extension>
+                                    <className>org.apache.cayenne.asciidoc.CayennePostProcessor</className>
+                                </extension>
+                            </extensions>
+                            <attributes>
+                                <toc>auto</toc>
+                            </attributes>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <!-- Move images to proper path for site -->
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy docs for site</id>
+                        <phase>install</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/site/</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${project.build.directory}/tmp/</directory>
+                                    <includes>
+                                        <include>${project.artifactId}.html</include>
+                                        <include>${project.artifactId}.toc.html</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+
+                    <execution>
+                        <id>copy images for site</id>
+                        <phase>install</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/site/${project.artifactId}/images/</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${project.build.directory}/tmp/images/</directory>
+                                    <filtering>true</filtering>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>assembly</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.asciidoctor</groupId>
+                        <artifactId>asciidoctor-maven-plugin</artifactId>
+                        <executions>
+                            <!-- generate standalone html help -->
+                            <execution>
+                                <id>asciidoctor-html-standalone</id>
+                                <phase>generate-resources</phase>
+                                <goals>
+                                    <goal>process-asciidoc</goal>
+                                </goals>
+                                <configuration>
+                                    <backend>html5</backend>
+                                    <sourceHighlighter>coderay</sourceHighlighter>
+                                    <embedAssets>true</embedAssets>
+                                    <attributes>
+                                        <toc>left</toc>
+                                    </attributes>
+                                </configuration>
+                            </execution>
+
+                            <!-- generate PDF -->
+                            <execution>
+                                <id>generate-pdf-doc</id>
+                                <phase>generate-resources</phase>
+                                <goals>
+                                    <goal>process-asciidoc</goal>
+                                </goals>
+                                <configuration>
+                                    <backend>pdf</backend>
+                                    <sourceHighlighter>coderay</sourceHighlighter>
+                                    <attributes>
+                                        <pagenums/>
+                                        <toc/>
+                                    </attributes>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/header.html
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/header.html b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/header.html
new file mode 100644
index 0000000..516fe0b
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/header.html
@@ -0,0 +1,24 @@
+---
+#  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.
+
+title: "Cayenne Getting Started ROP"
+description: "Tutorial how to quick start new Cayenne ROP project"
+cayenneVersion: "4.0"
+docsMenuTitle: "Getting Started ROP"
+weight: 40
+---

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part1.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part1.adoc b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part1.adoc
new file mode 100644
index 0000000..384f927
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part1.adoc
@@ -0,0 +1,17 @@
+// 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.
+
+== Prerequisites
+
+include::part1/prerequisites.adoc[]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part1/prerequisites.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part1/prerequisites.adoc b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part1/prerequisites.adoc
new file mode 100644
index 0000000..22587e0
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part1/prerequisites.adoc
@@ -0,0 +1,25 @@
+// 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.
+
+=== Prerequisites
+
+This tutorial starts where "Getting Started with Cayenne" left off. If you have gone through the previous tutorial, and have the "tutorial" project open in Eclipse, you can go directly to the next step. If not, here are the compressed instructions to prepare you for work with ROP:
+
+* Step 1 - Eclipse Setup
+* Step 2 - Create a project
+* Step 3 - Create Cayenne OR Mapping
+* Step 4 - Create Java Classes
+* Step 5 - Convert the project to webapp.
+
+Note that at "Step 5" you can skip the JSP creation part. Just setup web.xml and maven-jetty-plugin in the POM.

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2.adoc b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2.adoc
new file mode 100644
index 0000000..0f2c23a
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2.adoc
@@ -0,0 +1,23 @@
+// 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.
+
+== Remote Object Persistence Quick Start
+
+include::part2/starting.adoc[]
+
+include::part2/hessianWebServ.adoc[]
+
+include::part2/connect.adoc[]
+
+include::part2/adding.adoc[]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/adding.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/adding.adoc b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/adding.adoc
new file mode 100644
index 0000000..c9a86a4
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/adding.adoc
@@ -0,0 +1,126 @@
+// 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.
+
+=== Adding BASIC Authentication
+
+You probably don't want everybody in the world to connect to your service and access (and update!) arbitrary data in the database. The first step in securing Cayenne service is implementing client authentication. The easiest way to do it is to delegate the authentication task to the web container that is running the service. HessianConnection used in the previous chapter supports BASIC authentication on the client side, so we'll demonstrate how to set it up here.
+
+==== Securing ROP Server Application
+
+Open web.xml file in the server project and setup security constraints with BASIC authentication for the ROP service:
+
+[source, XML]
+----
+<security-constraint>
+    <web-resource-collection>
+        <web-resource-name>CayenneService</web-resource-name>
+        <url-pattern>/cayenne-service</url-pattern>
+    </web-resource-collection>
+    <auth-constraint>
+        <role-name>cayenne-service-user</role-name>
+    </auth-constraint>
+</security-constraint>
+
+<login-config>
+    <auth-method>BASIC</auth-method>
+    <realm-name>Cayenne Realm</realm-name>
+</login-config>
+
+<security-role>
+    <role-name>cayenne-service-user</role-name>
+</security-role>
+----
+
+==== Configuring Jetty for BASIC Authentication
+
+NOTE: These instructions are specific to Jetty 6. Other containers (and versions of Jetty) will have different mechansims to achieve the same thing.
+
+Open pom.xml in the server project and configure a "userRealm" for the Jetty plugin:
+
+[source, XML]
+----
+<plugin>
+    <groupId>org.mortbay.jetty</groupId>
+        <artifactId>maven-jetty-plugin</artifactId>
+        <version>6.1.22</version>
+        <!-- adding configuration below: -->
+        <configuration>
+            <userRealms>
+                <userRealm implementation="org.mortbay.jetty.security.HashUserRealm">
+                    <!-- this name must match the realm-name in web.xml -->
+                    <name>Cayenne Realm</name>
+                    <config>realm.properties</config>
+                </userRealm>
+            </userRealms>
+        </configuration>
+    </plugin>
+</plugins>
+----
+
+Now create a new file called {["realm.properties"}} at the root of the server project and put user login/password in there:
+
+[source]
+----
+cayenne-user: secret,cayenne-service-user
+----
+
+Now let's stop the server and start it again. Everything should start as before, but if you go to http://localhost:8080/tutorial/cayenne-service, your browser should pop up authentication dialog. Enter "cayenne-user/secret" for user name / password, and you should see "Hessian Requires POST" message. So the server is now secured.
+
+==== Running Client with Basic Authentication
+
+If you run the client without any changes, you'll get the following error:
+
+[source]
+----
+Mar 01, 2016 7:25:50 PM org.apache.cayenne.rop.http.HttpROPConnector logConnect
+INFO: Connecting to [cayenne-user@http://localhost:8080/tutorial-rop-server/cayenne-service] - dedicated session.
+Mar 01, 2016 7:25:50 PM org.apache.cayenne.rop.HttpClientConnection connect
+INFO: Server returned HTTP response code: 401 for URL: http://localhost:8080/tutorial-rop-server/cayenne-service
+java.rmi.RemoteException: Server returned HTTP response code: 401 for URL: http://localhost:8080/tutorial-rop-server/cayenne-service
+	at org.apache.cayenne.rop.ProxyRemoteService.establishSession(ProxyRemoteService.java:45)
+	at org.apache.cayenne.rop.HttpClientConnection.connect(HttpClientConnection.java:85)
+	at org.apache.cayenne.rop.HttpClientConnection.getServerEventBridge(HttpClientConnection.java:68)
+	at org.apache.cayenne.remote.ClientChannel.setupRemoteChannelListener(ClientChannel.java:279)
+	at org.apache.cayenne.remote.ClientChannel.<init>(ClientChannel.java:71)
+	at org.apache.cayenne.configuration.rop.client.ClientChannelProvider.get(ClientChannelProvider.java:48)
+	at org.apache.cayenne.configuration.rop.client.ClientChannelProvider.get(ClientChannelProvider.java:31)
+	at org.apache.cayenne.di.spi.CustomProvidersProvider.get(CustomProvidersProvider.java:39)
+	at org.apache.cayenne.di.spi.FieldInjectingProvider.get(FieldInjectingProvider.java:43)
+	at org.apache.cayenne.di.spi.DefaultScopeProvider.get(DefaultScopeProvider.java:50)
+	at org.apache.cayenne.di.spi.DefaultInjector.getInstance(DefaultInjector.java:139)
+	at org.apache.cayenne.di.spi.FieldInjectingProvider.value(FieldInjectingProvider.java:105)
+	at org.apache.cayenne.di.spi.FieldInjectingProvider.injectMember(FieldInjectingProvider.java:68)
+	at org.apache.cayenne.di.spi.FieldInjectingProvider.injectMembers(FieldInjectingProvider.java:59)
+	at org.apache.cayenne.di.spi.FieldInjectingProvider.get(FieldInjectingProvider.java:44)
+	at org.apache.cayenne.di.spi.DefaultScopeProvider.get(DefaultScopeProvider.java:50)
+	at org.apache.cayenne.di.spi.DefaultInjector.getInstance(DefaultInjector.java:134)
+	at org.apache.cayenne.configuration.CayenneRuntime.newContext(CayenneRuntime.java:134)
+	at org.apache.cayenne.tutorial.persistent.client.Main.main(Main.java:44)
+----
+
+Which is exactly what you'd expect, as the client is not authenticating itself. So change the line in Main.java where we obtained an ROP connection to this:
+
+[source, java]
+----
+Map<String,String> properties = new HashMap<>();
+properties.put(Constants.ROP_SERVICE_URL_PROPERTY, "http://localhost:8080/tutorial/cayenne-service");
+properties.put(Constants.ROP_SERVICE_USERNAME_PROPERTY, "cayenne-user");
+properties.put(Constants.ROP_SERVICE_PASSWORD_PROPERTY, "secret");
+
+ClientRuntime runtime = new ClientRuntime(properties);
+----
+
+Try running again, and everything should work as before. Obviously in production environment, in addition to authentication you'll need to use HTTPS to access the server to prevent third-party eavesdropping on your password and data.
+
+Congratulations, you are done with the ROP tutorial!

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/connect.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/connect.adoc b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/connect.adoc
new file mode 100644
index 0000000..284c7c3
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/connect.adoc
@@ -0,0 +1,174 @@
+// 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.
+
+=== Porting Existing Code to Connect to a Web Service Instead of a Database
+
+==== Starting Command Line Client
+
+One of the benefits of ROP is that the client code is no different from the server code - it uses the same ObjectContext interface for access, same query and commit API. So the code below will be similar to the code presented in the first Cayenne Getting Started Guide, although with a few ROP-specific parts required to bootstrap the ObjectContext.
+
+Let's start by creating an empty Main class with the standard main() method in the client project:
+
+[source, java]
+----
+package org.example.cayenne.persistent.client;
+
+public class Main {
+
+    public static void main(String[] args) {
+
+    }
+}
+----
+
+Now the part that is actually different from regular Cayenne - establishing the server connection and obtaining the ObjectContext:
+
+[source, java]
+----
+Map<String, String> properties = new HashMap<>();
+properties.put(Constants.ROP_SERVICE_URL_PROPERTY, "http://localhost:8080/tutorial/cayenne-service");
+properties.put(Constants.ROP_SERVICE_USERNAME_PROPERTY, "cayenne-user");
+properties.put(Constants.ROP_SERVICE_PASSWORD_PROPERTY, "secret");
+
+ClientRuntime runtime = new ClientRuntime(properties);
+ObjectContext context = runtime.newContext();
+----
+
+Note that the "runtime" can be used to create as many peer ObjectContexts as needed over the same connection, while ObjectContext is a kind of isolated "persistence session", similar to the server-side context. A few more notes. Since we are using HTTP(S) to communicate with ROP server, there's no need to explicitly close the connection (or channel, or context).
+
+So now let's do the same persistent operaions that we did in the first tutorial "Main" class. Let's start by creating and saving some objects:
+
+[source, java]
+----
+// creating new Artist
+Artist picasso = context.newObject(Artist.class);
+picasso.setName("Pablo Picasso");
+
+// Creating other objects
+Gallery metropolitan = context.newObject(Gallery.class);
+metropolitan.setName("Metropolitan Museum of Art");
+
+Painting girl = context.newObject(Painting.class);
+girl.setName("Girl Reading at a Table");
+
+Painting stein = context.newObject(Painting.class);
+stein.setName("Gertrude Stein");
+
+// connecting objects together via relationships
+picasso.addToPaintings(girl);
+picasso.addToPaintings(stein);
+
+girl.setGallery(metropolitan);
+stein.setGallery(metropolitan);
+
+// saving all the changes above
+context.commitChanges();
+----
+
+Now let's select them back:
+
+[source, java]
+----
+// ObjectSelect examples
+List<Painting> paintings1 = ObjectSelect.query(Painting.class).select(context);
+
+List<Painting> paintings2 = ObjectSelect.query(Painting.class)
+        .where(Painting.NAME.likeIgnoreCase("gi%")).select(context);
+----
+
+Now, delete:
+
+[source, java]
+----
+// Delete object example
+Artist picasso = ObjectSelect.query(Artist.class).where(Artist.NAME.eq("Pablo Picasso")).selectOne(context);
+
+if (picasso != null) {
+    context.deleteObject(picasso);
+    context.commitChanges();
+}
+----
+
+This code is exactly the same as in the first tutorial. So now let's try running the client and see what happens. In Eclipse open main class and select "Run > Run As > Java Application" from the menu (assuming the ROP server started in the previous step is still running). You will some output in both server and client process consoles. Client:
+
+[source]
+----
+INFO: Connecting to [http://localhost:8080/tutorial/cayenne-service] - dedicated session.
+INFO: === Connected, session: org.apache.cayenne.remote.RemoteSession@26544ec1[sessionId=17uub1h34r9x1] - took 111 ms.
+INFO: --- Message 0: Bootstrap
+INFO: === Message 0: Bootstrap done - took 58 ms.
+INFO: --- Message 1: flush-cascade-sync
+INFO: === Message 1: flush-cascade-sync done - took 1119 ms.
+INFO: --- Message 2: Query
+INFO: === Message 2: Query done - took 48 ms.
+INFO: --- Message 3: Query
+INFO: === Message 3: Query done - took 63 ms.
+INFO: --- Message 4: Query
+INFO: === Message 4: Query done - took 19 ms.
+INFO: --- Message 5: Query
+INFO: === Message 5: Query done - took 7 ms.
+INFO: --- Message 6: Query
+INFO: === Message 6: Query done - took 5 ms.
+INFO: --- Message 7: Query
+INFO: === Message 7: Query done - took 2 ms.
+INFO: --- Message 8: Query
+INFO: === Message 8: Query done - took 4 ms.
+INFO: --- Message 9: flush-cascade-sync
+INFO: === Message 9: flush-cascade-sync done - took 34 ms.
+----
+
+As you see client prints no SQL statmenets, just a bunch of query and flush messages sent to the server. The server side is more verbose, showing the actual client queries executed against the database:
+
+[source]
+----
+...
+INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE [bind: 1:'ARTIST']
+INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE [bind: 1:'GALLERY']
+INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE [bind: 1:'PAINTING']
+INFO: INSERT INTO ARTIST (DATE_OF_BIRTH, ID, NAME) VALUES (?, ?, ?)
+INFO: [batch bind: 1->DATE_OF_BIRTH:NULL, 2->ID:200, 3->NAME:'Pablo Picasso']
+INFO: === updated 1 row.
+INFO: INSERT INTO GALLERY (ID, NAME) VALUES (?, ?)
+INFO: [batch bind: 1->ID:200, 2->NAME:'Metropolitan Museum of Art']
+INFO: === updated 1 row.
+INFO: INSERT INTO PAINTING (ARTIST_ID, GALLERY_ID, ID, NAME) VALUES (?, ?, ?, ?)
+INFO: [batch bind: 1->ARTIST_ID:200, 2->GALLERY_ID:200, 3->ID:200, 4->NAME:'Girl Reading at a Table']
+INFO: [batch bind: 1->ARTIST_ID:200, 2->GALLERY_ID:200, 3->ID:201, 4->NAME:'Gertrude Stein']
+INFO: === updated 2 rows.
+INFO: +++ transaction committed.
+INFO: --- transaction started.
+INFO: SELECT t0.GALLERY_ID, t0.NAME, t0.ARTIST_ID, t0.ID FROM PAINTING t0
+INFO: === returned 2 rows. - took 14 ms.
+INFO: +++ transaction committed.
+INFO: --- transaction started.
+INFO: SELECT t0.GALLERY_ID, t0.NAME, t0.ARTIST_ID, t0.ID FROM PAINTING t0
+      WHERE UPPER(t0.NAME) LIKE UPPER(?) [bind: 1->NAME:'gi%']
+INFO: === returned 1 row. - took 10 ms.
+INFO: +++ transaction committed.
+INFO: --- transaction started.
+INFO: SELECT t0.DATE_OF_BIRTH, t0.NAME, t0.ID FROM ARTIST t0 WHERE t0.NAME = ? [bind: 1->NAME:'Pablo Picasso']
+INFO: === returned 1 row. - took 8 ms.
+INFO: +++ transaction committed.
+INFO: --- transaction started.
+INFO: DELETE FROM PAINTING WHERE ID = ?
+INFO: [batch bind: 1->ID:200]
+INFO: [batch bind: 1->ID:201]
+INFO: === updated 2 rows.
+INFO: DELETE FROM ARTIST WHERE ID = ?
+INFO: [batch bind: 1->ID:200]
+INFO: === updated 1 row.
+INFO: +++ transaction committed.
+----
+
+You are done with the basic ROP client!
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/cde78f0b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/hessianWebServ.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/hessianWebServ.adoc b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/hessianWebServ.adoc
new file mode 100644
index 0000000..d2768e1
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/hessianWebServ.adoc
@@ -0,0 +1,113 @@
+// 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.
+
+===  Setting up Hessian Web Service
+
+==== Setting up Dependencies
+
+Now lets get back to the "tutorial" project that contains a web application and set up dependencies. The only extra one that we don't have yet is resin-hessian.jar, just like the client, so let's add it (and the caucho repo declaration) to the pom.xml.
+
+[source, XML]
+----
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    ...
+    <dependencies>
+        ...
+        <dependency>
+            <groupId>com.caucho</groupId>
+            <artifactId>hessian</artifactId>
+            <version>4.0.38</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+    ...
+    </build>
+
+    <repositories>
+        <repository>
+            <id>caucho</id>
+            <name>Caucho Repository</name>
+            <url>http://caucho.com/m2</url>
+            <layout>default</layout>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+        </repository>
+    </repositories>
+    </project>
+----
+
+NOTE: *Maven Optimization Hint* On a real project both server and client modules will likely share a common parent pom.xml where common repository delcaration can be placed, with child pom's "inheriting" it from parent. This would reduce build code duplication.
+
+==== Client Classes on the Server
+
+Since ROP web service requires both server and client persistent classes, we need to generate a second copy of the client classes inside the server project. This is a minor inconvenience that will hopefully go away in the future versions of Cayenne. Don't forget to refresh the project in Eclipse after class generation is done.
+
+==== Configuring web.xml
+
+Cayenne web service is declared in the web.xml. It is implemented as a servlet "org.apache.cayenne.rop.ROPServlet". Open tutorial/src/main/webapp/WEB-INF/web.xml in Eclipse and add a service declaration:
+
+[source, XML]
+----
+<?xml version="1.0" encoding="utf-8"?>
+ <!DOCTYPE web-app
+   PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+   "http://java.sun.com/dtd/web-app_2_3.dtd">
+<web-app>
+    <display-name>Cayenne Tutorial</display-name>
+    <servlet>
+        <servlet-name>cayenne-project</servlet-name>
+        <servlet-class>org.apache.cayenne.rop.ROPServlet</servlet-class>
+        <load-on-startup>0</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>cayenne-project</servlet-name>
+        <url-pattern>/cayenne-service</url-pattern>
+    </servlet-mapping>
+    </web-app>
+----
+
+NOTE: *Extending Server Behavior via Callbacks* While no custom Java code is required on the server, just a service declaration, it is possible to customizing server-side behavior via callbacks and listeners (not shown in the tutorial).
+
+==== Running ROP Server
+
+Use previosly created Eclipse Jetty run configuration available via "Run > Run Configurations..." (or create a new one if none exists yet). You should see output in the Eclipse console similar to the following:
+
+[source]
+----
+[INFO] Scanning for projects...
+[INFO]
+[INFO] ------------------------------------------------------------------------
+[INFO] Building tutorial 0.0.1-SNAPSHOT
+[INFO] ------------------------------------------------------------------------
+...
+[INFO] Starting jetty 6.1.22 ...
+INFO::jetty-6.1.22
+INFO::No Transaction manager found - if your webapp requires one, please configure one.
+INFO::Started SelectChannelConnector@0.0.0.0:8080
+[INFO] Started Jetty Server
+INFO: Loading XML configuration resource from file:cayenne-project.xml
+INFO: loading user name and password.
+INFO: Created connection pool: jdbc:derby:memory:testdb;create=true
+    Driver class: org.apache.derby.jdbc.EmbeddedDriver
+    Min. connections in the pool: 1
+    Max. connections in the pool: 1
+----
+
+Cayenne ROP service URL is http://localhost:8080/tutorial/cayenne-service. If you click on it, you will see "Hessian Requires POST" message, that means that the service is alive, but you need a client other than the web browser to access it.
\ No newline at end of file