Code for video tutorial
diff --git a/.gitignore b/.gitignore
index e69de29..c3484a1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.idea
+*.iml
+target
+.DS_Store
diff --git a/cayenne-video-tutorial-01/cayenne-demo.sql b/cayenne-video-tutorial-01/cayenne-demo.sql
new file mode 100644
index 0000000..e433fa5
--- /dev/null
+++ b/cayenne-video-tutorial-01/cayenne-demo.sql
@@ -0,0 +1,12 @@
+create table cayenne.gallery (gallery_id int not null auto_increment, gallery_name varchar(100) not null, primary key (gallery_id)) engine=innodb;
+create table cayenne.artist (artist_id bigint not null auto_increment, artist_name char(254) not null, date_of_birth date null, primary key (artist_id)) engine=innodb;
+create table cayenne.exhibit (closing_date datetime not null, exhibit_id int not null auto_increment, gallery_id int not null, opening_date datetime not null, primary key (exhibit_id)) engine=innodb;
+create table cayenne.painting (artist_id bigint null, estimated_price decimal(16, 2) null, painting_description varchar(255) null, painting_id int not null auto_increment, painting_title varchar(255) not null, primary key (painting_id)) engine=innodb;
+create table cayenne.painting_info (image_blob longblob null, painting_id int not null, review longtext null, primary key (painting_id)) engine=innodb;
+create table cayenne.painting_exhibit (exhibit_id int not null, painting_id int not null, primary key (exhibit_id, painting_id)) engine=innodb;
+
+alter table cayenne.exhibit add foreign key (gallery_id) references cayenne.gallery (gallery_id);
+alter table cayenne.painting add foreign key (artist_id) references cayenne.artist (artist_id);
+alter table cayenne.painting_info add foreign key (painting_id) references cayenne.painting (painting_id);
+alter table cayenne.painting_exhibit add foreign key (exhibit_id) references cayenne.exhibit (exhibit_id);
+alter table cayenne.painting_exhibit add foreign key (painting_id) references cayenne.painting (painting_id);
diff --git a/cayenne-video-tutorial-01/pom.xml b/cayenne-video-tutorial-01/pom.xml
new file mode 100644
index 0000000..ff1d5c9
--- /dev/null
+++ b/cayenne-video-tutorial-01/pom.xml
@@ -0,0 +1,34 @@
+<?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>
+
+ <groupId>org.apache.cayenne.demo</groupId>
+ <artifactId>cayenne-demo</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <properties>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cayenne</groupId>
+ <artifactId>cayenne-server</artifactId>
+ <version>4.1.B1</version>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>8.0.13</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>1.7.25</version>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/Application.java b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/Application.java
new file mode 100644
index 0000000..33c2a03
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/Application.java
@@ -0,0 +1,86 @@
+package org.apache.cayenne.demo;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.datasource.DataSourceBuilder;
+import org.apache.cayenne.demo.model.Artist;
+import org.apache.cayenne.demo.model.Painting;
+import org.apache.cayenne.query.ObjectSelect;
+import org.apache.cayenne.query.SelectById;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.util.List;
+
+public class Application {
+
+ private final ServerRuntime cayenneRuntime;
+
+ public static void main(String[] args) {
+ Application app = new Application();
+// app.insertArtist();
+// app.updateArtist();
+// app.insertPaintings();
+ app.selectPaintings();
+ }
+
+ private Application() {
+ cayenneRuntime = ServerRuntime.builder()
+ .addConfig("cayenne-project.xml")
+ .dataSource(DataSourceBuilder.url("jdbc:mysql://localhost/cayenne")
+ .driver(com.mysql.cj.jdbc.Driver.class.getName())
+ .userName("root")
+ .password("cayenne")
+ .pool(1, 3).build())
+ .build();
+ }
+
+ private void selectPaintings() {
+ ObjectContext context = cayenneRuntime.newContext();
+
+ List<Painting> paintingList = ObjectSelect.query(Painting.class)
+ .where(Painting.ESTIMATED_PRICE.gt(BigDecimal.valueOf(100_000_000)))
+ .and(Painting.ARTIST.dot(Artist.DATE_OF_BIRTH).gt(LocalDate.of(1800, 1, 1)))
+ .prefetch(Painting.ARTIST.joint())
+ .orderBy(Painting.TITLE.asc())
+ .select(context);
+
+ paintingList.forEach(System.out::println);
+ }
+
+ private void insertPaintings() {
+ ObjectContext context = cayenneRuntime.newContext();
+
+ Artist picasso = ObjectSelect.query(Artist.class, Artist.NAME.eq("Pablo Picasso")).selectOne(context);
+
+ Painting boy = context.newObject(Painting.class);
+ boy.setTitle("Boy with a Pipe");
+ boy.setEstimatedPrice(BigDecimal.valueOf(104_168_000));
+ boy.setArtist(picasso);
+
+ Painting drinker = context.newObject(Painting.class);
+ drinker.setArtist(picasso);
+ drinker.setTitle("Absinthe Drinker");
+
+ context.commitChanges();
+ }
+
+ private void updateArtist() {
+ ObjectContext context = cayenneRuntime.newContext();
+
+ Artist picasso = SelectById.query(Artist.class, 1).selectOne(context);
+ picasso.setDateOfBirth(LocalDate.of(1881, 10, 25));
+
+ context.commitChanges();
+ }
+
+ private void insertArtist() {
+ ObjectContext context = cayenneRuntime.newContext();
+
+ Artist picasso = context.newObject(Artist.class);
+ picasso.setName("Pablo Picasso");
+
+ context.commitChanges();
+ }
+
+}
diff --git a/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/Artist.java b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/Artist.java
new file mode 100644
index 0000000..5706605
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/Artist.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.demo.model;
+
+import org.apache.cayenne.demo.model.auto._Artist;
+
+public class Artist extends _Artist {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/Exhibit.java b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/Exhibit.java
new file mode 100644
index 0000000..28dd8d2
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/Exhibit.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.demo.model;
+
+import org.apache.cayenne.demo.model.auto._Exhibit;
+
+public class Exhibit extends _Exhibit {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/Gallery.java b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/Gallery.java
new file mode 100644
index 0000000..6ae45a4
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/Gallery.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.demo.model;
+
+import org.apache.cayenne.demo.model.auto._Gallery;
+
+public class Gallery extends _Gallery {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/Painting.java b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/Painting.java
new file mode 100644
index 0000000..51a3d43
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/Painting.java
@@ -0,0 +1,17 @@
+package org.apache.cayenne.demo.model;
+
+import org.apache.cayenne.demo.model.auto._Painting;
+
+public class Painting extends _Painting {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public String toString() {
+ return "Painting{" +
+ "title='" + title + '\'' +
+ ", objectId=" + objectId +
+ ", artist=" + getArtist().getName() +
+ '}';
+ }
+}
diff --git a/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/PaintingInfo.java b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/PaintingInfo.java
new file mode 100644
index 0000000..aa49c4b
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/PaintingInfo.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.demo.model;
+
+import org.apache.cayenne.demo.model.auto._PaintingInfo;
+
+public class PaintingInfo extends _PaintingInfo {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_Artist.java b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_Artist.java
new file mode 100644
index 0000000..7081428
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_Artist.java
@@ -0,0 +1,130 @@
+package org.apache.cayenne.demo.model.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.time.LocalDate;
+import java.util.List;
+
+import org.apache.cayenne.BaseDataObject;
+import org.apache.cayenne.demo.model.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 ARTIST_ID_PK_COLUMN = "artist_id";
+
+ public static final Property<LocalDate> DATE_OF_BIRTH = Property.create("dateOfBirth", LocalDate.class);
+ public static final Property<String> NAME = Property.create("name", String.class);
+ public static final Property<List<Painting>> PAINTINGS = Property.create("paintings", List.class);
+
+ protected LocalDate dateOfBirth;
+ protected String name;
+
+ protected Object paintings;
+
+ public void setDateOfBirth(LocalDate dateOfBirth) {
+ beforePropertyWrite("dateOfBirth", this.dateOfBirth, dateOfBirth);
+ this.dateOfBirth = dateOfBirth;
+ }
+
+ public LocalDate getDateOfBirth() {
+ beforePropertyRead("dateOfBirth");
+ return this.dateOfBirth;
+ }
+
+ public void setName(String name) {
+ beforePropertyWrite("name", this.name, name);
+ this.name = name;
+ }
+
+ public String getName() {
+ beforePropertyRead("name");
+ return this.name;
+ }
+
+ 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 "dateOfBirth":
+ return this.dateOfBirth;
+ case "name":
+ return this.name;
+ 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 "dateOfBirth":
+ this.dateOfBirth = (LocalDate)val;
+ break;
+ case "name":
+ this.name = (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.dateOfBirth);
+ out.writeObject(this.name);
+ out.writeObject(this.paintings);
+ }
+
+ @Override
+ protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ super.readState(in);
+ this.dateOfBirth = (LocalDate)in.readObject();
+ this.name = (String)in.readObject();
+ this.paintings = in.readObject();
+ }
+
+}
diff --git a/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_Exhibit.java b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_Exhibit.java
new file mode 100644
index 0000000..c87e122
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_Exhibit.java
@@ -0,0 +1,148 @@
+package org.apache.cayenne.demo.model.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.time.LocalDateTime;
+import java.util.List;
+
+import org.apache.cayenne.BaseDataObject;
+import org.apache.cayenne.demo.model.Gallery;
+import org.apache.cayenne.demo.model.Painting;
+import org.apache.cayenne.exp.Property;
+
+/**
+ * Class _Exhibit 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 _Exhibit extends BaseDataObject {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String EXHIBIT_ID_PK_COLUMN = "exhibit_id";
+
+ public static final Property<LocalDateTime> CLOSING_DATE = Property.create("closingDate", LocalDateTime.class);
+ public static final Property<LocalDateTime> OPENING_DATE = Property.create("openingDate", LocalDateTime.class);
+ public static final Property<Gallery> GALLERY = Property.create("gallery", Gallery.class);
+ public static final Property<List<Painting>> PAINTINGS = Property.create("paintings", List.class);
+
+ protected LocalDateTime closingDate;
+ protected LocalDateTime openingDate;
+
+ protected Object gallery;
+ protected Object paintings;
+
+ public void setClosingDate(LocalDateTime closingDate) {
+ beforePropertyWrite("closingDate", this.closingDate, closingDate);
+ this.closingDate = closingDate;
+ }
+
+ public LocalDateTime getClosingDate() {
+ beforePropertyRead("closingDate");
+ return this.closingDate;
+ }
+
+ public void setOpeningDate(LocalDateTime openingDate) {
+ beforePropertyWrite("openingDate", this.openingDate, openingDate);
+ this.openingDate = openingDate;
+ }
+
+ public LocalDateTime getOpeningDate() {
+ beforePropertyRead("openingDate");
+ return this.openingDate;
+ }
+
+ public void setGallery(Gallery gallery) {
+ setToOneTarget("gallery", gallery, true);
+ }
+
+ public Gallery getGallery() {
+ return (Gallery)readProperty("gallery");
+ }
+
+ 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 "closingDate":
+ return this.closingDate;
+ case "openingDate":
+ return this.openingDate;
+ case "gallery":
+ return this.gallery;
+ 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 "closingDate":
+ this.closingDate = (LocalDateTime)val;
+ break;
+ case "openingDate":
+ this.openingDate = (LocalDateTime)val;
+ break;
+ case "gallery":
+ this.gallery = 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.closingDate);
+ out.writeObject(this.openingDate);
+ out.writeObject(this.gallery);
+ out.writeObject(this.paintings);
+ }
+
+ @Override
+ protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ super.readState(in);
+ this.closingDate = (LocalDateTime)in.readObject();
+ this.openingDate = (LocalDateTime)in.readObject();
+ this.gallery = in.readObject();
+ this.paintings = in.readObject();
+ }
+
+}
diff --git a/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_Gallery.java b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_Gallery.java
new file mode 100644
index 0000000..39cf6c4
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_Gallery.java
@@ -0,0 +1,110 @@
+package org.apache.cayenne.demo.model.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.demo.model.Exhibit;
+import org.apache.cayenne.exp.Property;
+
+/**
+ * Class _Gallery 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 _Gallery extends BaseDataObject {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String GALLERY_ID_PK_COLUMN = "gallery_id";
+
+ public static final Property<String> NAME = Property.create("name", String.class);
+ public static final Property<List<Exhibit>> EXHIBITS = Property.create("exhibits", List.class);
+
+ protected String name;
+
+ protected Object exhibits;
+
+ public void setName(String name) {
+ beforePropertyWrite("name", this.name, name);
+ this.name = name;
+ }
+
+ public String getName() {
+ beforePropertyRead("name");
+ return this.name;
+ }
+
+ public void addToExhibits(Exhibit obj) {
+ addToManyTarget("exhibits", obj, true);
+ }
+
+ public void removeFromExhibits(Exhibit obj) {
+ removeToManyTarget("exhibits", obj, true);
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<Exhibit> getExhibits() {
+ return (List<Exhibit>)readProperty("exhibits");
+ }
+
+ @Override
+ public Object readPropertyDirectly(String propName) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch(propName) {
+ case "name":
+ return this.name;
+ case "exhibits":
+ return this.exhibits;
+ default:
+ return super.readPropertyDirectly(propName);
+ }
+ }
+
+ @Override
+ public void writePropertyDirectly(String propName, Object val) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (propName) {
+ case "name":
+ this.name = (String)val;
+ break;
+ case "exhibits":
+ this.exhibits = 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.name);
+ out.writeObject(this.exhibits);
+ }
+
+ @Override
+ protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ super.readState(in);
+ this.name = (String)in.readObject();
+ this.exhibits = in.readObject();
+ }
+
+}
diff --git a/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_Painting.java b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_Painting.java
new file mode 100644
index 0000000..ca90620
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_Painting.java
@@ -0,0 +1,185 @@
+package org.apache.cayenne.demo.model.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigDecimal;
+import java.util.List;
+
+import org.apache.cayenne.BaseDataObject;
+import org.apache.cayenne.demo.model.Artist;
+import org.apache.cayenne.demo.model.Exhibit;
+import org.apache.cayenne.demo.model.PaintingInfo;
+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 PAINTING_ID_PK_COLUMN = "painting_id";
+
+ public static final Property<BigDecimal> ESTIMATED_PRICE = Property.create("estimatedPrice", BigDecimal.class);
+ public static final Property<String> DESCRIPTION = Property.create("description", String.class);
+ public static final Property<String> TITLE = Property.create("title", String.class);
+ public static final Property<PaintingInfo> PAINTING = Property.create("painting", PaintingInfo.class);
+ public static final Property<Artist> ARTIST = Property.create("artist", Artist.class);
+ public static final Property<List<Exhibit>> EXHIBITS = Property.create("exhibits", List.class);
+
+ protected BigDecimal estimatedPrice;
+ protected String description;
+ protected String title;
+
+ protected Object painting;
+ protected Object artist;
+ protected Object exhibits;
+
+ public void setEstimatedPrice(BigDecimal estimatedPrice) {
+ beforePropertyWrite("estimatedPrice", this.estimatedPrice, estimatedPrice);
+ this.estimatedPrice = estimatedPrice;
+ }
+
+ public BigDecimal getEstimatedPrice() {
+ beforePropertyRead("estimatedPrice");
+ return this.estimatedPrice;
+ }
+
+ public void setDescription(String description) {
+ beforePropertyWrite("description", this.description, description);
+ this.description = description;
+ }
+
+ public String getDescription() {
+ beforePropertyRead("description");
+ return this.description;
+ }
+
+ public void setTitle(String title) {
+ beforePropertyWrite("title", this.title, title);
+ this.title = title;
+ }
+
+ public String getTitle() {
+ beforePropertyRead("title");
+ return this.title;
+ }
+
+ public void setPainting(PaintingInfo painting) {
+ setToOneTarget("painting", painting, true);
+ }
+
+ public PaintingInfo getPainting() {
+ return (PaintingInfo)readProperty("painting");
+ }
+
+ public void setArtist(Artist artist) {
+ setToOneTarget("artist", artist, true);
+ }
+
+ public Artist getArtist() {
+ return (Artist)readProperty("artist");
+ }
+
+ public void addToExhibits(Exhibit obj) {
+ addToManyTarget("exhibits", obj, true);
+ }
+
+ public void removeFromExhibits(Exhibit obj) {
+ removeToManyTarget("exhibits", obj, true);
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<Exhibit> getExhibits() {
+ return (List<Exhibit>)readProperty("exhibits");
+ }
+
+ @Override
+ public Object readPropertyDirectly(String propName) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch(propName) {
+ case "estimatedPrice":
+ return this.estimatedPrice;
+ case "description":
+ return this.description;
+ case "title":
+ return this.title;
+ case "painting":
+ return this.painting;
+ case "artist":
+ return this.artist;
+ case "exhibits":
+ return this.exhibits;
+ default:
+ return super.readPropertyDirectly(propName);
+ }
+ }
+
+ @Override
+ public void writePropertyDirectly(String propName, Object val) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (propName) {
+ case "estimatedPrice":
+ this.estimatedPrice = (BigDecimal)val;
+ break;
+ case "description":
+ this.description = (String)val;
+ break;
+ case "title":
+ this.title = (String)val;
+ break;
+ case "painting":
+ this.painting = val;
+ break;
+ case "artist":
+ this.artist = val;
+ break;
+ case "exhibits":
+ this.exhibits = 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.estimatedPrice);
+ out.writeObject(this.description);
+ out.writeObject(this.title);
+ out.writeObject(this.painting);
+ out.writeObject(this.artist);
+ out.writeObject(this.exhibits);
+ }
+
+ @Override
+ protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ super.readState(in);
+ this.estimatedPrice = (BigDecimal)in.readObject();
+ this.description = (String)in.readObject();
+ this.title = (String)in.readObject();
+ this.painting = in.readObject();
+ this.artist = in.readObject();
+ this.exhibits = in.readObject();
+ }
+
+}
diff --git a/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_PaintingInfo.java b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_PaintingInfo.java
new file mode 100644
index 0000000..b236489
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/java/org/apache/cayenne/demo/model/auto/_PaintingInfo.java
@@ -0,0 +1,123 @@
+package org.apache.cayenne.demo.model.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.cayenne.BaseDataObject;
+import org.apache.cayenne.demo.model.Painting;
+import org.apache.cayenne.exp.Property;
+
+/**
+ * Class _PaintingInfo 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 _PaintingInfo extends BaseDataObject {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String PAINTING_ID_PK_COLUMN = "painting_id";
+
+ public static final Property<String> REVIEW = Property.create("review", String.class);
+ public static final Property<byte[]> IMAGE = Property.create("image", byte[].class);
+ public static final Property<Painting> PAINTING = Property.create("painting", Painting.class);
+
+ protected String review;
+ protected byte[] image;
+
+ protected Object painting;
+
+ public void setReview(String review) {
+ beforePropertyWrite("review", this.review, review);
+ this.review = review;
+ }
+
+ public String getReview() {
+ beforePropertyRead("review");
+ return this.review;
+ }
+
+ public void setImage(byte[] image) {
+ beforePropertyWrite("image", this.image, image);
+ this.image = image;
+ }
+
+ public byte[] getImage() {
+ beforePropertyRead("image");
+ return this.image;
+ }
+
+ public void setPainting(Painting painting) {
+ setToOneTarget("painting", painting, true);
+ }
+
+ public Painting getPainting() {
+ return (Painting)readProperty("painting");
+ }
+
+ @Override
+ public Object readPropertyDirectly(String propName) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch(propName) {
+ case "review":
+ return this.review;
+ case "image":
+ return this.image;
+ case "painting":
+ return this.painting;
+ default:
+ return super.readPropertyDirectly(propName);
+ }
+ }
+
+ @Override
+ public void writePropertyDirectly(String propName, Object val) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (propName) {
+ case "review":
+ this.review = (String)val;
+ break;
+ case "image":
+ this.image = (byte[])val;
+ break;
+ case "painting":
+ this.painting = 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.review);
+ out.writeObject(this.image);
+ out.writeObject(this.painting);
+ }
+
+ @Override
+ protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ super.readState(in);
+ this.review = (String)in.readObject();
+ this.image = (byte[])in.readObject();
+ this.painting = in.readObject();
+ }
+
+}
diff --git a/cayenne-video-tutorial-01/src/main/resources/cayenne-project.xml b/cayenne-video-tutorial-01/src/main/resources/cayenne-project.xml
new file mode 100644
index 0000000..9f629d3
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/resources/cayenne-project.xml
@@ -0,0 +1,7 @@
+<?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 https://cayenne.apache.org/schema/10/domain.xsd"
+ project-version="10">
+ <map name="datamap"/>
+</domain>
diff --git a/cayenne-video-tutorial-01/src/main/resources/datamap.map.xml b/cayenne-video-tutorial-01/src/main/resources/datamap.map.xml
new file mode 100644
index 0000000..fb4354e
--- /dev/null
+++ b/cayenne-video-tutorial-01/src/main/resources/datamap.map.xml
@@ -0,0 +1,121 @@
+<?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 https://cayenne.apache.org/schema/10/modelMap.xsd"
+ project-version="10">
+ <property name="defaultPackage" value="org.apache.cayenne.demo.model"/>
+ <db-entity name="artist" catalog="cayenne">
+ <db-attribute name="artist_id" type="BIGINT" isPrimaryKey="true" isGenerated="true" isMandatory="true" length="19"/>
+ <db-attribute name="artist_name" type="CHAR" isMandatory="true" length="254"/>
+ <db-attribute name="date_of_birth" type="DATE" length="10"/>
+ </db-entity>
+ <db-entity name="exhibit" catalog="cayenne">
+ <db-attribute name="closing_date" type="TIMESTAMP" isMandatory="true" length="26"/>
+ <db-attribute name="exhibit_id" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true" length="10"/>
+ <db-attribute name="gallery_id" type="INTEGER" isMandatory="true" length="10"/>
+ <db-attribute name="opening_date" type="TIMESTAMP" isMandatory="true" length="26"/>
+ </db-entity>
+ <db-entity name="gallery" catalog="cayenne">
+ <db-attribute name="gallery_id" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true" length="10"/>
+ <db-attribute name="gallery_name" type="VARCHAR" isMandatory="true" length="100"/>
+ </db-entity>
+ <db-entity name="painting" catalog="cayenne">
+ <db-attribute name="artist_id" type="BIGINT" length="19"/>
+ <db-attribute name="estimated_price" type="DECIMAL" length="16" scale="2"/>
+ <db-attribute name="painting_description" type="VARCHAR" length="255"/>
+ <db-attribute name="painting_id" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true" length="10"/>
+ <db-attribute name="painting_title" type="VARCHAR" isMandatory="true" length="255"/>
+ </db-entity>
+ <db-entity name="painting_exhibit" catalog="cayenne">
+ <db-attribute name="exhibit_id" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+ <db-attribute name="painting_id" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+ </db-entity>
+ <db-entity name="painting_info" catalog="cayenne">
+ <db-attribute name="image_blob" type="LONGVARBINARY" length="2147483647"/>
+ <db-attribute name="painting_id" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+ <db-attribute name="review" type="LONGVARCHAR" length="2147483647"/>
+ </db-entity>
+ <obj-entity name="Artist" className="org.apache.cayenne.demo.model.Artist" dbEntityName="artist">
+ <obj-attribute name="dateOfBirth" type="java.time.LocalDate" db-attribute-path="date_of_birth"/>
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="artist_name"/>
+ </obj-entity>
+ <obj-entity name="Exhibit" className="org.apache.cayenne.demo.model.Exhibit" dbEntityName="exhibit">
+ <obj-attribute name="closingDate" type="java.time.LocalDateTime" db-attribute-path="closing_date"/>
+ <obj-attribute name="openingDate" type="java.time.LocalDateTime" db-attribute-path="opening_date"/>
+ </obj-entity>
+ <obj-entity name="Gallery" className="org.apache.cayenne.demo.model.Gallery" dbEntityName="gallery">
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="gallery_name"/>
+ </obj-entity>
+ <obj-entity name="Painting" className="org.apache.cayenne.demo.model.Painting" dbEntityName="painting">
+ <obj-attribute name="estimatedPrice" type="java.math.BigDecimal" db-attribute-path="estimated_price"/>
+ <obj-attribute name="description" type="java.lang.String" db-attribute-path="painting_description"/>
+ <obj-attribute name="title" type="java.lang.String" db-attribute-path="painting_title"/>
+ </obj-entity>
+ <obj-entity name="PaintingInfo" className="org.apache.cayenne.demo.model.PaintingInfo" dbEntityName="painting_info">
+ <obj-attribute name="review" type="java.lang.String" db-attribute-path="review"/>
+ <obj-attribute name="image" type="byte[]" db-attribute-path="image_blob"/>
+ </obj-entity>
+ <db-relationship name="paintings" source="artist" target="painting" toMany="true">
+ <db-attribute-pair source="artist_id" target="artist_id"/>
+ </db-relationship>
+ <db-relationship name="gallery" source="exhibit" target="gallery">
+ <db-attribute-pair source="gallery_id" target="gallery_id"/>
+ </db-relationship>
+ <db-relationship name="paintingExhibits" source="exhibit" target="painting_exhibit" toDependentPK="true" toMany="true">
+ <db-attribute-pair source="exhibit_id" target="exhibit_id"/>
+ </db-relationship>
+ <db-relationship name="exhibits" source="gallery" target="exhibit" toMany="true">
+ <db-attribute-pair source="gallery_id" target="gallery_id"/>
+ </db-relationship>
+ <db-relationship name="paintingExhibits" source="painting" target="painting_exhibit" toDependentPK="true" toMany="true">
+ <db-attribute-pair source="painting_id" target="painting_id"/>
+ </db-relationship>
+ <db-relationship name="painting" source="painting" target="painting_info" toDependentPK="true">
+ <db-attribute-pair source="painting_id" target="painting_id"/>
+ </db-relationship>
+ <db-relationship name="artist" source="painting" target="artist">
+ <db-attribute-pair source="artist_id" target="artist_id"/>
+ </db-relationship>
+ <db-relationship name="painting" source="painting_exhibit" target="painting">
+ <db-attribute-pair source="painting_id" target="painting_id"/>
+ </db-relationship>
+ <db-relationship name="exhibit" source="painting_exhibit" target="exhibit">
+ <db-attribute-pair source="exhibit_id" target="exhibit_id"/>
+ </db-relationship>
+ <db-relationship name="painting" source="painting_info" target="painting">
+ <db-attribute-pair source="painting_id" target="painting_id"/>
+ </db-relationship>
+ <obj-relationship name="paintings" source="Artist" target="Painting" deleteRule="Deny" db-relationship-path="paintings"/>
+ <obj-relationship name="gallery" source="Exhibit" target="Gallery" deleteRule="Nullify" db-relationship-path="gallery"/>
+ <obj-relationship name="paintings" source="Exhibit" target="Painting" db-relationship-path="paintingExhibits.painting"/>
+ <obj-relationship name="exhibits" source="Gallery" target="Exhibit" deleteRule="Deny" db-relationship-path="exhibits"/>
+ <obj-relationship name="painting" source="Painting" target="PaintingInfo" deleteRule="Nullify" db-relationship-path="painting"/>
+ <obj-relationship name="artist" source="Painting" target="Artist" deleteRule="Nullify" db-relationship-path="artist"/>
+ <obj-relationship name="exhibits" source="Painting" target="Exhibit" db-relationship-path="paintingExhibits.exhibit"/>
+ <obj-relationship name="painting" source="PaintingInfo" target="Painting" deleteRule="Nullify" db-relationship-path="painting"/>
+ <dbImport xmlns="http://cayenne.apache.org/schema/10/dbimport">
+ <catalog>
+ <name>cayenne</name>
+ </catalog>
+ <forceDataMapCatalog>false</forceDataMapCatalog>
+ <forceDataMapSchema>false</forceDataMapSchema>
+ <namingStrategy>org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator</namingStrategy>
+ <skipPrimaryKeyLoading>false</skipPrimaryKeyLoading>
+ <skipRelationshipsLoading>false</skipRelationshipsLoading>
+ <useJava7Types>false</useJava7Types>
+ <usePrimitives>true</usePrimitives>
+ </dbImport>
+ <cgen xmlns="http://cayenne.apache.org/schema/10/cgen">
+ <destDir>../java</destDir>
+ <mode>entity</mode>
+ <template>templates/v4_1/subclass.vm</template>
+ <superTemplate>templates/v4_1/superclass.vm</superTemplate>
+ <outputPattern>*.java</outputPattern>
+ <makePairs>true</makePairs>
+ <usePkgPath>true</usePkgPath>
+ <overwrite>false</overwrite>
+ <createPropertyNames>false</createPropertyNames>
+ <createPKProperties>false</createPKProperties>
+ <client>false</client>
+ </cgen>
+</data-map>