diff --git a/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/META-INF/persistence.xml b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/META-INF/persistence.xml new file mode 100644 index 0000000000000000000000000000000000000000..98008b00ab1bb2f3eecc5b18831954d92ce7f619 --- /dev/null +++ b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/META-INF/persistence.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd" + version="2.2"> + + <persistence-unit name="NewPersistenceUnit"> + <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> + <properties> + <property name="hibernate.connection.url" value=""/> + <property name="hibernate.connection.driver_class" value=""/> + <property name="hibernate.connection.username" value=""/> + <property name="hibernate.connection.password" value=""/> + <property name="hibernate.archive.autodetection" value="class"/> + <property name="hibernate.show_sql" value="true"/> + <property name="hibernate.format_sql" value="true"/> + <property name="hbm2ddl.auto" value="update"/> + </properties> + </persistence-unit> +</persistence> diff --git a/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/JqlTypeViolation.java b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/JqlTypeViolation.java new file mode 100644 index 0000000000000000000000000000000000000000..281370f09019bbe43be717c2a75344530cceb560 --- /dev/null +++ b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/JqlTypeViolation.java @@ -0,0 +1,34 @@ +package de.hdm_stuttgart.mi.sda1; + +import de.hdm_stuttgart.mi.sda1.model.StudyCourse; + +import javax.persistence.*; +import java.util.List; + +/** + * Datbase / OO Model type violation. + */ +public class JqlTypeViolation { + /** + * @param args unused + */ + public static void main( String[] args ) { + + final EntityManagerFactory factory = Persistence.createEntityManagerFactory( + "strategy_none"); + + final EntityManager em = factory.createEntityManager(); + + final Query query = em.createQuery("SELECT S.shortName FROM StudyCourse AS S"); + + final List<StudyCourse> studyCourses = query.getResultList(); + + try { + for (final StudyCourse studyCourse : studyCourses) { + System.out.println("Read + '" + studyCourse + "'"); + } + } finally { + factory.close(); + } + } +} \ No newline at end of file diff --git a/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/ReadAllStudyCourses.java b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/ReadAllStudyCourses.java index a8ee77b7e7bac1a9cabebc14f55a372c140fd5c8..77cef47ecfbf4085e2ec34eeac44ecb0dc1c7a0b 100644 --- a/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/ReadAllStudyCourses.java +++ b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/ReadAllStudyCourses.java @@ -18,17 +18,12 @@ public class ReadAllStudyCourses { "strategy_none"); final EntityManager em = factory.createEntityManager(); - final EntityTransaction tx = em.getTransaction(); - final Query query = em.createQuery("SELECT s FROM StudyCourse s"); - final List<StudyCourse> studyCourses; - tx.begin(); - studyCourses = query.getResultList(); - tx.commit(); + final List<StudyCourse> studyCourses = query.getResultList(); for (final StudyCourse studyCourse: studyCourses) { - System.out.println("Read + '" + studyCourse + "'"); + System.out.println("Read '" + studyCourse + "'"); } // See http://stackoverflow.com/questions/21645516/program-using-hibernate-does-not-terminate diff --git a/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/ReadStudyCourseById.java b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/ReadStudyCourseById.java index 7b78907d71a5e4d8d4436f79df531b4ec684456a..252be89770ad8599b208599d01bce56703a60184 100644 --- a/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/ReadStudyCourseById.java +++ b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/ReadStudyCourseById.java @@ -20,14 +20,9 @@ public class ReadStudyCourseById { "strategy_none"); final EntityManager em = factory.createEntityManager(); - final EntityTransaction tx = em.getTransaction(); + final StudyCourse studyCourse = em.find(StudyCourse.class, "CSM"); - final StudyCourse studyCourse; - tx.begin(); - studyCourse = em.find(StudyCourse.class, "CSM"); - tx.commit(); - - System.out.println("Read + '" + studyCourse + "'"); + System.out.println("Read '" + studyCourse + "'"); // See http://stackoverflow.com/questions/21645516/program-using-hibernate-does-not-terminate factory.close(); diff --git a/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/ReadStudyCourseShortName.java b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/ReadStudyCourseShortName.java new file mode 100644 index 0000000000000000000000000000000000000000..60e00494683d401452b5eee6b239bffb60eb8443 --- /dev/null +++ b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/ReadStudyCourseShortName.java @@ -0,0 +1,36 @@ +package de.hdm_stuttgart.mi.sda1; + +import de.hdm_stuttgart.mi.sda1.model.StudyCourse; + +import javax.persistence.*; +import java.util.List; + +/** + * Datbase / OO Model type violation. + */ +public class ReadStudyCourseShortName { + /** + * @param args unused + */ + public static void main( String[] args ) { + + final EntityManagerFactory factory = Persistence.createEntityManagerFactory( + "strategy_none"); + final EntityManager em = factory.createEntityManager(); + + final EntityTransaction tx = em.getTransaction(); + + final Query query = em.createQuery("SELECT S.shortName FROM StudyCourse AS S"); + final List<String> shortNames; + tx.begin(); + shortNames = query.getResultList(); + tx.commit(); + try { + for (final String shortName : shortNames) { + System.out.println("Read '" + shortName + "'"); + } + } finally { + factory.close(); + } + } +} \ No newline at end of file diff --git a/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/UpdateStudyCourseById.java b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/UpdateStudyCourseById.java new file mode 100644 index 0000000000000000000000000000000000000000..90fff92de98cfd4c373a6a3e3d1f8b0578a35954 --- /dev/null +++ b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/UpdateStudyCourseById.java @@ -0,0 +1,36 @@ +package de.hdm_stuttgart.mi.sda1; + +import de.hdm_stuttgart.mi.sda1.model.StudyCourse; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; +import javax.persistence.Persistence; + +/** + * Read a {@link StudyCourse} by its primary key value. + */ +public class UpdateStudyCourseById { + /** + * @param args unused + */ + public static void main( String[] args ) { + + final EntityManagerFactory factory = Persistence.createEntityManagerFactory( + "strategy_none"); + final EntityManager em = factory.createEntityManager(); + + + final StudyCourse csm = em.find(StudyCourse.class, "CSM"); + + final EntityTransaction tx = em.getTransaction(); + tx.begin(); + csm.setFullName("Computerwissenschaft und Medien"); + tx.commit(); + + System.out.println("After renaming: '" + csm + "'"); + + // See http://stackoverflow.com/questions/21645516/program-using-hibernate-does-not-terminate + factory.close(); + } +} \ No newline at end of file diff --git a/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/model/StudyCourse.java b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/model/StudyCourse.java index 5d513ac73941104281351055ea2b0928807dc312..f8e560bf051ce037ddc7818ae060e7c32544197a 100644 --- a/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/model/StudyCourse.java +++ b/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/model/StudyCourse.java @@ -21,6 +21,9 @@ public class StudyCourse { this.fullName = fullName; } + public void setFullName(final String fullName) { + this.fullName = fullName; + } @Override public String toString() { return fullName + "(" + shortName + ")"; diff --git a/Doc/Sda1/Ref/JpaIntro/ideaAddFrameworkSupportHibernate.png b/Doc/Sda1/Ref/JpaIntro/ideaAddFrameworkSupportHibernate.png new file mode 100644 index 0000000000000000000000000000000000000000..6d0e4c0201fcc483c385e07230cd1c83af2c263e Binary files /dev/null and b/Doc/Sda1/Ref/JpaIntro/ideaAddFrameworkSupportHibernate.png differ diff --git a/Doc/Sda1/Ref/JpaIntro/ideaAddFrameworkSupportJ2EEpersistence.png b/Doc/Sda1/Ref/JpaIntro/ideaAddFrameworkSupportJ2EEpersistence.png new file mode 100644 index 0000000000000000000000000000000000000000..2ed24e0d041425b6a6e09807b88511a2e049c608 Binary files /dev/null and b/Doc/Sda1/Ref/JpaIntro/ideaAddFrameworkSupportJ2EEpersistence.png differ diff --git a/Doc/Sda1/Ref/JpaIntro/ideaConfigFacets.png b/Doc/Sda1/Ref/JpaIntro/ideaConfigFacets.png new file mode 100644 index 0000000000000000000000000000000000000000..c90c2deaca41d9275242b30bc01e97f92b15f508 Binary files /dev/null and b/Doc/Sda1/Ref/JpaIntro/ideaConfigFacets.png differ diff --git a/Doc/Sda1/jpaintro.xml b/Doc/Sda1/jpaintro.xml index b1ae7f9fc5d94fd967de195ab3e678faca08786f..cc68e972457760a50880b2729e9c43522c5a811a 100644 --- a/Doc/Sda1/jpaintro.xml +++ b/Doc/Sda1/jpaintro.xml @@ -228,11 +228,46 @@ </glosslist> </figure> + <section xml:id="sda1_jpaintro_sect_Tooling"> + <title>Notes on tooling</title> + + <figure xml:id="sda1_jpaintro_fig_ideaConfigPersist"> + <title>Right click »Add Framework Support«</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/JpaIntro/ideaAddFrameworkSupportJ2EEpersistence.png"/> + </imageobject> + </mediaobject> + </figure> + + <figure xml:id="sda1_jpaintro_fig_ideaConfigHibernate"> + <title>Enable Hibernate support</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/JpaIntro/ideaAddFrameworkSupportHibernate.png"/> + </imageobject> + </mediaobject> + </figure> + + <figure xml:id="sda1_jpaintro_fig_ideaConfigFacets"> + <title>»File« --> »Project Structure«</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/JpaIntro/ideaConfigFacets.png"/> + </imageobject> + </mediaobject> + </figure> + </section> + <section xml:id="sda1_jpaintro_sect_mappingObjectsRoundTrip"> - <title>A round trip mapping objects</title> + <title>A round trip working with objects</title> <section xml:id="sda1_jpaintro_sect_createSchema"> - <title>Mapping object- an database model</title> + <title>Mapping <xref linkend="glo_OO"/> domain model to database + model</title> <figure xml:id="sda1_jpaintro_figClassStudyCourse"> <title>Class <classname>StudyCourse</classname></title> @@ -254,7 +289,7 @@ <figure xml:id="sda1_jpaintro_fig_jreCreateStudyCourse"> <title>Transient instance</title> - <programlisting language="java">final StudyCourse csm = new StudyCourse("CSM", "Computer Science and Media"); + <programlisting language="java">final StudyCourse csm = new StudyCourse("CSM", "Computer Science and Media"); System.out.println(csm);</programlisting> <para>Result:</para> @@ -316,8 +351,8 @@ public class StudyCourse { CREATE TABLE StudyCourse( PRIMARY KEY <coref linkend="sda1_jpaintro_fig_studyCourseEntity-2-co"/> (shortName), - shortName varchar(3 <coref - linkend="sda1_jpaintro_fig_studyCourseEntity-4-co"/>) NOT NULL, + shortName varchar(3) <coref + linkend="sda1_jpaintro_fig_studyCourseEntity-4-co"/> NOT NULL, @@ -594,23 +629,20 @@ insert into <coref linkend="sda1_jpaintro_fig_inserByTransaction-7-co"/> "<emphasis role="red">strategy_none</emphasis>"<co linkends="sda1_jpaintro_fig_readStudyCourseById-1" xml:id="sda1_jpaintro_fig_readStudyCourseById-1-co"/> ); - ... -final StudyCourse studyCourse; - -tx.begin(); - studyCourse = em.<link xlink:href="???">find</link> <co +final StudyCourse studyCourse = em.<link xlink:href="???">find</link> <co linkends="sda1_jpaintro_fig_readStudyCourseById-2" xml:id="sda1_jpaintro_fig_readStudyCourseById-2-co"/>(StudyCourse.class, "<emphasis role="red">CSM</emphasis>" <co linkends="sda1_jpaintro_fig_readStudyCourseById-3" xml:id="sda1_jpaintro_fig_readStudyCourseById-3-co"/>); -tx.commit(); -System.out.println("Read + '" + studyCourse + "'"); <co +System.out.println("Read '" + studyCourse + "'"); <co linkends="sda1_jpaintro_fig_readStudyCourseById-4" xml:id="sda1_jpaintro_fig_readStudyCourseById-4-co"/></programlisting> + + <screen>Read 'Computer Science and Media(CSM)'</screen> </figure> <calloutlist> @@ -653,12 +685,185 @@ System.out.println("Read + '" + studyCourse + "'"); <co <para>Print study course's value.</para> <note> - <para>Since the transactional has been committed changes to <code - language="java">studyCourse</code> won't be propagated to the - database.</para> + <para>Since the transaction has been committed changes to <code + language="java">studyCourse</code> are transient and won't be + propagated to the database until being attached to another + transaction.</para> </note> </callout> </calloutlist> + + <figure xml:id="sda1_jpaintro_fig_readStudyCourseAll"> + <title>Retrieving all instances</title> + + <programlisting language="java">... +final Query query = em.createQuery("SELECT s FROM StudyCourse s"); + +final List<StudyCourse><co + linkends="sda1_jpaintro_fig_readStudyCourseAll-1" + xml:id="sda1_jpaintro_fig_readStudyCourseAll-1-co"/> studyCourses =<co + linkends="sda1_jpaintro_fig_readStudyCourseAll-2" + xml:id="sda1_jpaintro_fig_readStudyCourseAll-2-co"/> query.getResultList(); + +for (final StudyCourse studyCourse: studyCourses) { + System.out.println("Read '" + studyCourse + "'"); }</programlisting> + + <calloutlist> + <callout arearefs="sda1_jpaintro_fig_readStudyCourseAll-1-co" + xml:id="sda1_jpaintro_fig_readStudyCourseAll-1"> + <para>Notice: <classname + xlink:href="https://docs.oracle.com/javase/9/docs/api/java/util/List.html">List</classname> + in favour of <classname + xlink:href="https://docs.oracle.com/javase/9/docs/api/java/util/Set.html">Set</classname> + respecting database ordering.</para> + </callout> + + <callout arearefs="sda1_jpaintro_fig_readStudyCourseAll-2-co" + xml:id="sda1_jpaintro_fig_readStudyCourseAll-2"> + <para>Unchecked assignment <classname + xlink:href="https://docs.oracle.com/javase/9/docs/api/java/util/List.html">java.util.List</classname> + to <classname + xlink:href="https://docs.oracle.com/javase/9/docs/api/java/util/List.html">java.util.List</classname><<classname + xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sda1/Ref/JpaIntro/P/StudyCourse_basic/src/main/java/de/hdm_stuttgart/mi/sda1/model/StudyCourse.java">StudyCourse</classname>>.</para> + </callout> + </calloutlist> + </figure> + + <figure xml:id="sda1_jpaintro_fig_readTypeViolate"> + <title>Type conversion problems</title> + + <programlisting language="java" linenumbering="numbered" + startinglinenumber="21">... +final Query query = em.createQuery("SELECT S.shortName FROM StudyCourse AS S"); + +final List<StudyCourse> studyCourses = query.getResultList(); + +try { <co linkends="sda1_jpaintro_fig_readTypeViolate-1" + xml:id="sda1_jpaintro_fig_readTypeViolate-1-co"/> + for (final StudyCourse studyCourse : studyCourses)<co + linkends="sda1_jpaintro_fig_readTypeViolate-2" + xml:id="sda1_jpaintro_fig_readTypeViolate-2-co"/> { + System.out.println("Read '" + studyCourse + "'"); + } +} finally <co linkends="sda1_jpaintro_fig_readTypeViolate-3" + xml:id="sda1_jpaintro_fig_readTypeViolate-3-co"/>{ + factory.close(); +}</programlisting> + + <screen>Exception in thread "main" java.lang.ClassCastException: +java.lang.String cannot be cast to de.hdm_stuttgart.mi.sda1.model.StudyCourse + at de.hdm_stuttgart.mi.sda1.JqlTypeViolation.main(JqlTypeViolation.java:27)</screen> + </figure> + + <calloutlist> + <callout arearefs="sda1_jpaintro_fig_readTypeViolate-1-co" + xml:id="sda1_jpaintro_fig_readTypeViolate-1"> + <para><code language="java">try</code> block required for later + cleanup.</para> + </callout> + + <callout arearefs="sda1_jpaintro_fig_readTypeViolate-2-co" + xml:id="sda1_jpaintro_fig_readTypeViolate-2"> + <para>The culprit causing the <classname + xlink:href="https://docs.oracle.com/javase/9/docs/api/java/lang/ClassCastException.html">ClassCastException</classname>.</para> + </callout> + + <callout arearefs="sda1_jpaintro_fig_readTypeViolate-3-co" + xml:id="sda1_jpaintro_fig_readTypeViolate-3"> + <para>Cleaning up persistence context.</para> + </callout> + </calloutlist> + + <figure xml:id="sda1_jpaintro_fig_readShortNames"> + <title>Reading <code language="java">shortName</code> values</title> + + <programlisting language="java">... +final Query query = em.createQuery("SELECT S.shortName FROM StudyCourse AS S"); +final List<StudyCourse> studyCourses = query.getResultList(); + +try { + for (final StudyCourse studyCourse : studyCourses) { + System.out.println("Read '" + studyCourse + "'"); + } +} finally { + factory.close(); +}</programlisting> + + <screen>Read 'CSM'</screen> + </figure> + </section> + + <section xml:id="sda1_jpaintro_sect_UpdateStudyCourse"> + <title>Updating objects</title> + + <figure xml:id="sda1_jpaintro_fig_addStudyCourseFullNameSetter"> + <title> Adding a setter</title> + + <programlisting language="java">@Entity +public class StudyCourse { + @Id @Column(length = 3) private String shortName; + + @Column(length = 150, nullable = false, unique = true) + private String fullName; + + public void setFullName(final String fullName) { + this.fullName = fullName; + } + ... +}</programlisting> + </figure> + + <figure xml:id="sda1_jpaintro_fig_updateStudyCourse"> + <title>Update language</title> + + <informaltable border="0"> + <tr> + <td valign="top"><programlisting language="java">final StudyCourse csm <co + linkends="sda1_jpaintro_fig_updateStudyCourse-1" + xml:id="sda1_jpaintro_fig_updateStudyCourse-1-co"/>= + em.find(StudyCourse.class, "CSM"); + +final EntityTransaction tx = + em.getTransaction(); +tx.begin(); + csm.setFullName( <co linkends="sda1_jpaintro_fig_updateStudyCourse-2" + xml:id="sda1_jpaintro_fig_updateStudyCourse-2-co"/> + "Computerwissenschaft und Medien"); +tx.commit(); <co linkends="sda1_jpaintro_fig_updateStudyCourse-3" + xml:id="sda1_jpaintro_fig_updateStudyCourse-3-co"/></programlisting></td> + + <td valign="top"><screen>MariaDB [hdm]> + select * from StudyCourse; ++-----------+----------------------+ +| shortName | fullName | ++-----------+----------------------+ +| CSM | Computerwissenschaft | +| | und Medien | ++-----------+----------------------+</screen></td> + </tr> + </informaltable> + </figure> + + <calloutlist> + <callout arearefs="sda1_jpaintro_fig_updateStudyCourse-1-co" + xml:id="sda1_jpaintro_fig_updateStudyCourse-1"> + <para>Retrieving instance from database. Variable <code + language="java">csm</code> is bound to the persistence + context.</para> + </callout> + + <callout arearefs="sda1_jpaintro_fig_updateStudyCourse-2-co" + xml:id="sda1_jpaintro_fig_updateStudyCourse-2"> + <para>Changing instance's <code language="java">fullName</code> + property's value.</para> + </callout> + + <callout arearefs="sda1_jpaintro_fig_updateStudyCourse-3-co" + xml:id="sda1_jpaintro_fig_updateStudyCourse-3"> + <para>Committing transaction will automatically commit all + persistence context related changes.</para> + </callout> + </calloutlist> </section> </section> @@ -690,7 +895,8 @@ System.out.println("Read + '" + studyCourse + "'"); <co <orderedlist> <listitem> - <para>Execute + <para>Get used to <xref linkend="glo_JPA"/> using the existing + data model first. Execute <classname>jpaintro.university.CreateAirline</classname> and watch the generated <xref linkend="glo_SQL"/> statements.</para>