Add cayenne-java-modules example
diff --git a/cayenne-java-modules/.gitignore b/cayenne-java-modules/.gitignore
new file mode 100644
index 0000000..bb172de
--- /dev/null
+++ b/cayenne-java-modules/.gitignore
@@ -0,0 +1,15 @@
+target
+out
+.classpath
+.project
+.settings/
+.externalToolBuilders
+.DS_Store
+derby.log
+.metadata
+bin/
+.idea
+*.iml
+.factorypath
+build
+.gradle
\ No newline at end of file
diff --git a/cayenne-java-modules/README.md b/cayenne-java-modules/README.md
new file mode 100644
index 0000000..d9bdfde
--- /dev/null
+++ b/cayenne-java-modules/README.md
@@ -0,0 +1,22 @@
+Apache Cayenne example with java modules
+=============
+
+Example shows how to use Apache Cayenne in application with java modules.
+
+- Clone:
+```bash
+git clone https://github.com/apache/cayenne-examples
+cd cayenne-java-modules
+```
+
+- Run instance of mysql database and change url, username and password in cayenne-project.xml.
+
+- Build:
+```bash
+mvn clean install
+```
+
+- Run:
+```bash
+java --module-path target/cayenne-java-modules-1.0-SNAPSHOT.jar:target/lib/cayenne-server-4.1.B2.jar:target/lib/cayenne-di-4.1.B2.jar:target/lib/slf4j-api-1.7.25.jar:target/lib/mysql-connector-java-8.0.17.jar:target/lib/protobuf-java-3.6.1.jar:target/lib/slf4j-simple-1.7.25.jar --module cayenne.java.module/org.apache.cayenne.example.Main
+```
\ No newline at end of file
diff --git a/cayenne-java-modules/pom.xml b/cayenne-java-modules/pom.xml
new file mode 100644
index 0000000..421f286
--- /dev/null
+++ b/cayenne-java-modules/pom.xml
@@ -0,0 +1,81 @@
+<?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">
+ <modelVersion>4.0.0</modelVersion>
+
+ <packaging>jar</packaging>
+
+ <groupId>org.apache.cayenne.example</groupId>
+ <artifactId>cayenne-java-modules</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <properties>
+ <cayenne.version>4.1.B2</cayenne.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cayenne</groupId>
+ <artifactId>cayenne-server</artifactId>
+ <version>${cayenne.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>1.7.25</version>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>8.0.17</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.1</version>
+ <configuration>
+ <source>11</source>
+ <target>11</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/lib</outputDirectory>
+ <overWriteReleases>false</overWriteReleases>
+ <overWriteSnapshots>false</overWriteSnapshots>
+ <overWriteIfNewer>true</overWriteIfNewer>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <!-- Build an executable JAR -->
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>3.1.0</version>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>org.apache.cayenne.example.Main</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/cayenne-java-modules/src/main/java/module-info.java b/cayenne-java-modules/src/main/java/module-info.java
new file mode 100644
index 0000000..f063342
--- /dev/null
+++ b/cayenne-java-modules/src/main/java/module-info.java
@@ -0,0 +1,5 @@
+module cayenne.java.module {
+ requires java.sql;
+ requires cayenne.server;
+ exports org.apache.cayenne.example.persistent;
+}
\ No newline at end of file
diff --git a/cayenne-java-modules/src/main/java/org/apache/cayenne/example/Main.java b/cayenne-java-modules/src/main/java/org/apache/cayenne/example/Main.java
new file mode 100644
index 0000000..5a8a7cd
--- /dev/null
+++ b/cayenne-java-modules/src/main/java/org/apache/cayenne/example/Main.java
@@ -0,0 +1,34 @@
+package org.apache.cayenne.example;
+
+import java.util.List;
+
+import org.apache.cayenne.example.persistent.Artist;
+import org.apache.cayenne.example.persistent.Painting;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.query.ObjectSelect;
+
+public class Main {
+ public static void main(String[] args) {
+ ServerRuntime cayenneRuntime = ServerRuntime.builder()
+ .addConfig("cayenne-project.xml")
+ .build();
+ ObjectContext context = cayenneRuntime.newContext();
+ Artist artist = context.newObject(Artist.class);
+ artist.setArtistName("Pablo Picasso");
+
+ Painting painting = context.newObject(Painting.class);
+ painting.setPaintingTitle("Girl Reading at a Table");
+
+ artist.addToPaintings(painting);
+
+ context.commitChanges();
+
+ List<Artist> artists = ObjectSelect.query(Artist.class)
+ .prefetch(Artist.PAINTINGS.disjoint())
+ .select(context);
+
+ System.out.println(artists.get(0).getArtistName());
+ System.out.println(artists.get(0).getPaintings().get(0).getPaintingTitle());
+ }
+}
diff --git a/cayenne-java-modules/src/main/java/org/apache/cayenne/example/persistent/Artist.java b/cayenne-java-modules/src/main/java/org/apache/cayenne/example/persistent/Artist.java
new file mode 100644
index 0000000..900b2c5
--- /dev/null
+++ b/cayenne-java-modules/src/main/java/org/apache/cayenne/example/persistent/Artist.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.example.persistent;
+
+import org.apache.cayenne.example.persistent.auto._Artist;
+
+public class Artist extends _Artist {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/cayenne-java-modules/src/main/java/org/apache/cayenne/example/persistent/Painting.java b/cayenne-java-modules/src/main/java/org/apache/cayenne/example/persistent/Painting.java
new file mode 100644
index 0000000..0cc90de
--- /dev/null
+++ b/cayenne-java-modules/src/main/java/org/apache/cayenne/example/persistent/Painting.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.example.persistent;
+
+import org.apache.cayenne.example.persistent.auto._Painting;
+
+public class Painting extends _Painting {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/cayenne-java-modules/src/main/java/org/apache/cayenne/example/persistent/auto/_Artist.java b/cayenne-java-modules/src/main/java/org/apache/cayenne/example/persistent/auto/_Artist.java
new file mode 100644
index 0000000..20648ab
--- /dev/null
+++ b/cayenne-java-modules/src/main/java/org/apache/cayenne/example/persistent/auto/_Artist.java
@@ -0,0 +1,110 @@
+package org.apache.cayenne.example.persistent.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.List;
+
+import org.apache.cayenne.BaseDataObject;
+import org.apache.cayenne.example.persistent.Painting;
+import org.apache.cayenne.exp.Property;
+
+/**
+ * Class _Artist was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _Artist extends BaseDataObject {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String ID_PK_COLUMN = "ID";
+
+ public static final Property<String> ARTIST_NAME = Property.create("artistName", String.class);
+ public static final Property<List<Painting>> PAINTINGS = Property.create("paintings", List.class);
+
+ protected String artistName;
+
+ protected Object paintings;
+
+ public void setArtistName(String artistName) {
+ beforePropertyWrite("artistName", this.artistName, artistName);
+ this.artistName = artistName;
+ }
+
+ public String getArtistName() {
+ beforePropertyRead("artistName");
+ return this.artistName;
+ }
+
+ public void addToPaintings(Painting obj) {
+ addToManyTarget("paintings", obj, true);
+ }
+
+ public void removeFromPaintings(Painting obj) {
+ removeToManyTarget("paintings", obj, true);
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<Painting> getPaintings() {
+ return (List<Painting>)readProperty("paintings");
+ }
+
+ @Override
+ public Object readPropertyDirectly(String propName) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch(propName) {
+ case "artistName":
+ return this.artistName;
+ case "paintings":
+ return this.paintings;
+ default:
+ return super.readPropertyDirectly(propName);
+ }
+ }
+
+ @Override
+ public void writePropertyDirectly(String propName, Object val) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (propName) {
+ case "artistName":
+ this.artistName = (String)val;
+ break;
+ case "paintings":
+ this.paintings = val;
+ break;
+ default:
+ super.writePropertyDirectly(propName, val);
+ }
+ }
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ writeSerialized(out);
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ readSerialized(in);
+ }
+
+ @Override
+ protected void writeState(ObjectOutputStream out) throws IOException {
+ super.writeState(out);
+ out.writeObject(this.artistName);
+ out.writeObject(this.paintings);
+ }
+
+ @Override
+ protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ super.readState(in);
+ this.artistName = (String)in.readObject();
+ this.paintings = in.readObject();
+ }
+
+}
diff --git a/cayenne-java-modules/src/main/java/org/apache/cayenne/example/persistent/auto/_Painting.java b/cayenne-java-modules/src/main/java/org/apache/cayenne/example/persistent/auto/_Painting.java
new file mode 100644
index 0000000..c3961d0
--- /dev/null
+++ b/cayenne-java-modules/src/main/java/org/apache/cayenne/example/persistent/auto/_Painting.java
@@ -0,0 +1,104 @@
+package org.apache.cayenne.example.persistent.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.cayenne.BaseDataObject;
+import org.apache.cayenne.example.persistent.Artist;
+import org.apache.cayenne.exp.Property;
+
+/**
+ * Class _Painting was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _Painting extends BaseDataObject {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String ID_PK_COLUMN = "ID";
+
+ public static final Property<String> PAINTING_TITLE = Property.create("paintingTitle", String.class);
+ public static final Property<Artist> TO_ARTIST = Property.create("toArtist", Artist.class);
+
+ protected String paintingTitle;
+
+ protected Object toArtist;
+
+ public void setPaintingTitle(String paintingTitle) {
+ beforePropertyWrite("paintingTitle", this.paintingTitle, paintingTitle);
+ this.paintingTitle = paintingTitle;
+ }
+
+ public String getPaintingTitle() {
+ beforePropertyRead("paintingTitle");
+ return this.paintingTitle;
+ }
+
+ public void setToArtist(Artist toArtist) {
+ setToOneTarget("toArtist", toArtist, true);
+ }
+
+ public Artist getToArtist() {
+ return (Artist)readProperty("toArtist");
+ }
+
+ @Override
+ public Object readPropertyDirectly(String propName) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch(propName) {
+ case "paintingTitle":
+ return this.paintingTitle;
+ case "toArtist":
+ return this.toArtist;
+ default:
+ return super.readPropertyDirectly(propName);
+ }
+ }
+
+ @Override
+ public void writePropertyDirectly(String propName, Object val) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (propName) {
+ case "paintingTitle":
+ this.paintingTitle = (String)val;
+ break;
+ case "toArtist":
+ this.toArtist = val;
+ break;
+ default:
+ super.writePropertyDirectly(propName, val);
+ }
+ }
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ writeSerialized(out);
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ readSerialized(in);
+ }
+
+ @Override
+ protected void writeState(ObjectOutputStream out) throws IOException {
+ super.writeState(out);
+ out.writeObject(this.paintingTitle);
+ out.writeObject(this.toArtist);
+ }
+
+ @Override
+ protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ super.readState(in);
+ this.paintingTitle = (String)in.readObject();
+ this.toArtist = in.readObject();
+ }
+
+}
diff --git a/cayenne-java-modules/src/main/resources/cayenne-project.xml b/cayenne-java-modules/src/main/resources/cayenne-project.xml
new file mode 100644
index 0000000..ff1373b
--- /dev/null
+++ b/cayenne-java-modules/src/main/resources/cayenne-project.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<domain xmlns="http://cayenne.apache.org/schema/10/domain"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://cayenne.apache.org/schema/10/domain http://cayenne.apache.org/schema/10/domain.xsd"
+ project-version="10">
+ <map name="datamap"/>
+ <node name="datanode"
+ factory="org.apache.cayenne.configuration.server.XMLPoolingDataSourceFactory"
+ schema-update-strategy="org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy">
+ <map-ref name="datamap"/>
+ <data-source>
+ <driver value="com.mysql.cj.jdbc.Driver"/>
+ <url value="jdbc:mysql://localhost:3306/test"/>
+ <connectionPool min="1" max="1"/>
+ <login userName="root" password="root"/>
+ </data-source>
+ </node>
+</domain>
diff --git a/cayenne-java-modules/src/main/resources/datamap.map.xml b/cayenne-java-modules/src/main/resources/datamap.map.xml
new file mode 100644
index 0000000..c869081
--- /dev/null
+++ b/cayenne-java-modules/src/main/resources/datamap.map.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap http://cayenne.apache.org/schema/10/modelMap.xsd"
+ project-version="10">
+ <property name="defaultPackage" value="com.bulackiy.persistent"/>
+ <db-entity name="ARTIST" catalog="test">
+ <db-attribute name="ARTIST_NAME" type="VARCHAR" length="100"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+ </db-entity>
+ <db-entity name="PAINTING">
+ <db-attribute name="ARTIST_ID" type="INTEGER"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="PAINTING_TITLE" type="VARCHAR" length="255"/>
+ </db-entity>
+ <obj-entity name="Artist" className="org.apache.cayenne.example.persistent.Artist" dbEntityName="ARTIST">
+ <obj-attribute name="artistName" type="java.lang.String" db-attribute-path="ARTIST_NAME"/>
+ </obj-entity>
+ <obj-entity name="Painting" className="org.apache.cayenne.example.persistent.Painting" dbEntityName="PAINTING">
+ <obj-attribute name="paintingTitle" type="java.lang.String" db-attribute-path="PAINTING_TITLE"/>
+ </obj-entity>
+ <db-relationship name="paintings" source="ARTIST" target="PAINTING" toMany="true">
+ <db-attribute-pair source="ID" target="ARTIST_ID"/>
+ </db-relationship>
+ <db-relationship name="toArtist" source="PAINTING" target="ARTIST">
+ <db-attribute-pair source="ARTIST_ID" target="ID"/>
+ </db-relationship>
+ <obj-relationship name="paintings" source="Artist" target="Painting" deleteRule="Deny" db-relationship-path="paintings"/>
+ <obj-relationship name="toArtist" source="Painting" target="Artist" deleteRule="Nullify" db-relationship-path="toArtist"/>
+</data-map>