{"id":36797,"date":"2015-02-16T18:05:58","date_gmt":"2015-02-16T16:05:58","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=36797"},"modified":"2023-12-05T16:32:17","modified_gmt":"2023-12-05T14:32:17","slug":"jpa-tutorial","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html","title":{"rendered":"JPA Tutorial &#8211; The ULTIMATE Guide (PDF Download)"},"content":{"rendered":"<p><em><strong>EDITORIAL NOTE:<\/strong> In this post, we feature a comprehensive JPA Tutorial. The Java Persistence API (JPA) is a Java programming language application programming interface specification that describes the management of relational data in applications using Java Platform, Standard Edition and Java Platform, Enterprise Edition.<\/em><\/p>\n<p><em>JPA has become the de-facto standard to write application code that interacts with Databases. For this reason we have provided an abundance of tutorials here at Java Code Geeks, most of which can be found <a href=\"http:\/\/www.javacodegeeks.com\/tutorials\/java-tutorials\/enterprise-java-tutorials\/#JPA\">here<\/a>. Additionally, we have created the JPA mini-book which will get you introduced to JPA and smoothly transition the reader to more advanced concepts (get it for free by <a href=\"http:\/\/eepurl.com\/xRlkj\">joining our newsletter<\/a>).<\/em><\/p>\n<p><em>Now, we wanted to create a standalone, reference post to provide a framework on how to work with JPA and help you quickly kick-start your JPA applications. Enjoy!<\/em><\/p>\n<div class=\"toc\">\n<h2>Table Of Contents<\/h2>\n<dl>\n<dt><a href=\"#introduction\">A. Introduction<\/a><\/dt>\n<dt><a href=\"#setup\">B. Project setup<\/a><\/dt>\n<dt><a href=\"#basics\">C. Basics<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#entitymanager\">C.1. EntityManager and Persistence Unit<\/a><\/dt>\n<dt><a href=\"#transactions\">C.2. Transactions<\/a><\/dt>\n<dt><a href=\"#tables\">C.3. Tables<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#intheritance\">D. Inheritance<\/a><\/dt>\n<dt><a href=\"#relationships\">E. Relationships<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#relationships_onetoone\">E.1. OneToOne<\/a><\/dt>\n<dt><a href=\"#relationships_onetomany\">E.2. OneToMany<\/a><\/dt>\n<dt><a href=\"#relationships_manytomany\">E.3. ManyToMany<\/a><\/dt>\n<dt><a href=\"#relationships_embedded\">E.4. Embedded \/ ElementCollection<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#dataTypes\">F. Data Types and Converters<\/a><\/dt>\n<dt><a href=\"#criteriaapi\">G. Criteria API<\/a><\/dt>\n<dt><a href=\"#sequences\">H. Sequences<\/a><\/dt>\n<dt><a href=\"#download\">I. Download<\/a><\/dt>\n<\/dl>\n<\/div>\n<h2><a name=\"introduction\"><\/a>A. Introduction<\/h2>\n<p>The Java Persistence API (JPA) is a vendor independent specification for mapping Java objects to the tables of relational databases. Implementations of this specification allow application developers to abstract from the specific database prodcut they are working with and allow them to implement CRUD (create, read, update and delete) operations such that the same code works on different database products. These frameworks do not only handle the code that interacts with the database (the JDBC code) but also map the data to object structures used by the application.<\/p>\n<p>The JPA consists of three different components:<\/p>\n<ul>\n<li><code>Entities<\/code>: In current versions of the JPA entities are plain old Java objects (POJOs). Older versions of the JPA required to subclass entities from classes provided by the JPA, but as these approaches are more difficult to test because of their hard dependecies to the framework, newer versions of the JPA do not require entities to subclass any framework class.<\/li>\n<li><code>Object-relational metadata<\/code>: The application developer has to provide the mapping between the Java classes and their attributes to the tables and columns of the database. This can be done either trough dedicated configuration files or in newer version of the framework also by annotations.<\/li>\n<li><code>Java Persistence Query Language (JPQL)<\/code>: As the JPA aims to abstract from the specific database product, the framework also provides a dedicated query langauge that can be used instead of SQL. This additional translation from JPQL to SQL allows the implementations of the framework to support different database dialects and allows the application developer to implement queries in a database independent way<\/li>\n<\/ul>\n<p>In this tutorial we are going through different aspects of the framework and will develop a simple Java SE application that stores and retrieves data in\/from a relational database. We will use the following libraries\/environments:<\/p>\n<ul>\n<li>maven &gt;= 3.0 as build environment<\/li>\n<li>JPA 2.1 as contained in the Java Enterprise Edition (JEE) 7.0<\/li>\n<li>Hibernate as an implementation of JPA (4.3.8.Final)<\/li>\n<li>H2 as relational database in version 1.3.176<\/li>\n<\/ul>\n<h2><a name=\"setup\"><\/a>B. Project setup<\/h2>\n<p>As a first step we will create a simple maven project on the command line:<\/p>\n<pre class=\"brush:bash\">mvn archetype:create -DgroupId=com.javacodegeeks.ultimate -DartifactId=jpa\n<\/pre>\n<p>This command will create the following structure in the file system:<\/p>\n<pre class=\"brush:java\">|-- src\n|   |-- main\n|   |   `-- java\n|   |       `-- com \n|   |           `-- javacodegeeks\n|   |\t\t\t     `-- ultimate\n|   `-- test\n|   |   `-- java\n|   |       `-- com \n|   |           `-- javacodegeeks\n|   |\t\t\t     `-- ultimate\n`-- pom.xml\n<\/pre>\n<p>The libraries our implementation depends on are added to the dependencies section of the pom.xml file in the following way:<\/p>\n<pre class=\"brush:xml\">&lt;properties&gt;\n\t&lt;jee.version&gt;7.0&lt;\/jee.version&gt;\n\t&lt;h2.version&gt;1.3.176&lt;\/h2.version&gt;\n\t&lt;hibernate.version&gt;4.3.8.Final&lt;\/hibernate.version&gt;\n&lt;\/properties&gt;\n\n&lt;dependencies&gt;\n\t&lt;dependency&gt;\n\t\t&lt;groupId&gt;javax&lt;\/groupId&gt;\n\t\t&lt;artifactId&gt;javaee-api&lt;\/artifactId&gt;\n\t\t&lt;version&gt;${jee.version}&lt;\/version&gt;\n\t\t&lt;scope&gt;provided&lt;\/scope&gt;\n\t&lt;\/dependency&gt;\n\t&lt;dependency&gt;\n\t\t&lt;groupId&gt;com.h2database&lt;\/groupId&gt;\n\t\t&lt;artifactId&gt;h2&lt;\/artifactId&gt;\n\t\t&lt;version&gt;${h2.version}&lt;\/version&gt;\n\t&lt;\/dependency&gt;\n\t&lt;dependency&gt;\n\t\t&lt;groupId&gt;org.hibernate&lt;\/groupId&gt;\n\t\t&lt;artifactId&gt;hibernate-entitymanager&lt;\/artifactId&gt;\n\t\t&lt;version&gt;${hibernate.version}&lt;\/version&gt;\n\t&lt;\/dependency&gt;\n&lt;\/dependencies&gt;\n<\/pre>\n<p>To get a better overview of the separate versions, we define each version as a maven property and reference it later on in the dependencies section.<\/p>\n<h2><a name=\"basics\"><\/a>C. Basics<\/h2>\n<h3><a name=\"entitymanager\"><\/a>C.1. EntityManager and Persistence Unit<\/h3>\n<p>Now we cat start to implement our first JPA functionality. Let&#8217;s start with a simple class that provides a <code>run()<\/code> method that is invoked in the application&#8217;s <code>main<\/code> method:<\/p>\n<pre class=\"brush:java\">public class Main {\n\tprivate static final Logger LOGGER = Logger.getLogger(\"JPA\");\n\n\tpublic static void main(String[] args) {\n\t\tMain main = new Main();\n\t\tmain.run();\n\t}\n\n\tpublic void run() {\n\t\tEntityManagerFactory factory = null;\n\t\tEntityManager entityManager = null;\n\t\ttry {\n\t\t\tfactory = Persistence.createEntityManagerFactory(\"PersistenceUnit\");\n\t\t\tentityManager = factory.createEntityManager();\n\t\t\tpersistPerson(entityManager);\n\t\t} catch (Exception e) {\n\t\t\tLOGGER.log(Level.SEVERE, e.getMessage(), e);\n\t\t\te.printStackTrace();\n\t\t} finally {\n\t\t\tif (entityManager != null) {\n\t\t\t\tentityManager.close();\n\t\t\t}\n\t\t\tif (factory != null) {\n\t\t\t\tfactory.close();\n\t\t\t}\n\t\t}\n\t}\n\t...\n<\/pre>\n<p>Nearly all interaction with the JPA is done through the <code>EntityManager<\/code>. To obtain an instance of an <code>EntityManager<\/code>, we have to create an instance of the <code>EntityManagerFactory<\/code>. Normally we only need one <code>EntityManagerFactory<\/code> for one &#8220;persistence unit&#8221; per application. A persistence unit is a set of JPA classes that is managed together with the database configuration in a file called <code>persistence.xml<\/code>:<\/p>\n<pre class=\"brush:xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?&gt;\n&lt;persistence xmlns=\"http:\/\/java.sun.com\/xml\/ns\/persistence\"\n             xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\n             xsi:schemaLocation=\"http:\/\/java.sun.com\/xml\/ns\/persistence\n http:\/\/java.sun.com\/xml\/ns\/persistence\/persistence_1_0.xsd\" version=\"1.0\"&gt;\n\n    &lt;persistence-unit name=\"PersistenceUnit\" transaction-type=\"RESOURCE_LOCAL\"&gt;\n        &lt;provider&gt;org.hibernate.ejb.HibernatePersistence&lt;\/provider&gt;\n        &lt;properties&gt;\n            &lt;property name=\"connection.driver_class\" value=\"org.h2.Driver\"\/&gt;\n            &lt;property name=\"hibernate.connection.url\" value=\"jdbc:h2:~\/jpa\"\/&gt;\n            &lt;property name=\"hibernate.dialect\" value=\"org.hibernate.dialect.H2Dialect\"\/&gt;\n            &lt;property name=\"hibernate.hbm2ddl.auto\" value=\"create\"\/&gt;\n            &lt;property name=\"hibernate.show_sql\" value=\"true\"\/&gt;\n\t\t\t&lt;property name=\"hibernate.format_sql\" value=\"true\"\/&gt;\n        &lt;\/properties&gt;\n    &lt;\/persistence-unit&gt;\n&lt;\/persistence&gt;\n<\/pre>\n<p>This file is created in the <code>src\/main\/resource\/META-INF<\/code> folder of the maven project. As you can see, we define one <code>persistence-unit<\/code> with the name <code>PersistenceUnit<\/code> that has the <code>transaction-type<\/code> <code>RESOURCE_LOCAL<\/code>. The transaction-type determines how transactions are handled in the application.<\/p>\n<p>In our sample application we want to handle them on our own, hence we specify here <code>RESOURCE_LOCAL<\/code>. When you use a JEE container then the container is responsible for setting up the <code>EntityManagerFactory<\/code> and only provides you he <code>EntityManager<\/code>. The container then also handles the begin and end of each transaction. In this case you would provide the value <code>JTA<\/code>.<\/p>\n<p>By setting the <code>provider<\/code> to <code>org.hibernate.ejb.HibernatePersistence<\/code> we select the JPA implementation we want to use. Because we have included Hibernate as JPA provider on the classpath by defining a dependency to it, we can reference the provider implementation here by class name.<\/p>\n<p>The next step in <code>persistence.xml<\/code> is to inform the JPA provider about the database we want to use. This is done by specifying the JDBC driver that Hibernate should use. As we want to use the H2 database (www.h2database.com), the property <code>connection.driver_class<\/code> is set to the value <code>org.h2.Driver<\/code>.<\/p>\n<p>In order to enable Hibernate to create connections to the database we also have to provide the connection URL. H2 provides the option to create the database within a single file which path is given in the JDBC URL. Hence the JDBC URL <code>jdbc:h2:~\/jpa<\/code> tells H2 to create in the user&#8217;s home directory a file called <code>jpa.h2.db<\/code>.<\/p>\n<p>H2 is a fast open source database that can be easily embedded in Java applications as it comes as a single jar file with a size of about 1.5 MB. This makes it suitable for our purpose of creating a simple sample application to demonstrate the usage of JPA. In projects that require solutions that scale better for huge amounts of data you would probably choose a different database product, but for small amount of data that have strong relations H2 is good choice.<\/p>\n<p>The next thing we have to tell Hibernate is the JDBC dialect that it should use. As Hibernate provides a dedicated dialect implementation for H2, we choose this one with the property <code>hibernate.dialect<\/code>. With this dialect Hibernate is capable of creating the appropriate SQL statements for the H2 database.<\/p>\n<p>Last but not least we provide three options that come handy when developing a new application, but that would not be used in production environments. The first of them is the property <code>hibernate.hbm2ddl.auto<\/code> that tells Hibernate to create all tables from scratch at startup. If the table already exists, it will be deleted. In our sample application this is a good feature as we can rely on the fact that the database is empty at the beginnig and that all changes we have made to the schema since our last start of the application are reflected in the schema.<\/p>\n<p>The second option is <code>hibernate.show_sql<\/code> that tells Hibernate to print every SQL statement that it issues to the database on the command line. With this option enabled we can easily trace all statements and have a look if everything works as expected. And finally we tell Hibernate to pretty print the SQL for better readability by setting the property <code>hibernate.format_sql<\/code> to <code>true<\/code>.<\/p>\n<p>Now that we have setup the <code>persistence.xml<\/code> file, we get back to our Java code above:<\/p>\n<pre class=\"brush:java\">EntityManagerFactory factory = null;\nEntityManager entityManager = null;\ntry {\n\tfactory = Persistence.createEntityManagerFactory(\"PersistenceUnit\");\n\tentityManager = factory.createEntityManager();\n\tpersistPerson(entityManager);\n} catch (Exception e) {\n\tLOGGER.log(Level.SEVERE, e.getMessage(), e);\n\te.printStackTrace();\n} finally {\n\tif (entityManager != null) {\n\t\tentityManager.close();\n\t}\n\tif (factory != null) {\n\t\tfactory.close();\n\t}\n}\n<\/pre>\n<p>After having obtained an instance of the <code>EntityManagerFactory<\/code> and from it an instance of <code>EntityManager<\/code> we can use them in the method <code>persistPerson<\/code> to save some data in the database. Please note that after we have done our work we have to close both the <code>EntityManager<\/code> as well as the <code>EntityManagerFactory<\/code>.<\/p>\n<h3><a name=\"transactions\"><\/a>C.2. Transactions<\/h3>\n<p>The <code>EntityManager<\/code> represents a persistence unit and therefore we will need in <code>RESOURCE_LOCAL<\/code> applications only one instance of the <code>EntityManager<\/code>. A persistence unit is a cache for the entities that represent parts of the state stored in the database as well as a connection to the database. In order to store data in the database we therefore have to pass it to the <code>EntityManager<\/code> and therewith to the underlying cache. In case you want to create a new row in the database, this is done by invoking the method <code>persist()<\/code> on the <code>EntityManager<\/code> as demonstrated in the following code:<\/p>\n<pre class=\"brush:java\">private void persistPerson(EntityManager entityManager) {\n\tEntityTransaction transaction = entityManager.getTransaction();\n\ttry {\n\t\ttransaction.begin();\n\t\tPerson person = new Person();\n\t\tperson.setFirstName(\"Homer\");\n\t\tperson.setLastName(\"Simpson\");\n\t\tentityManager.persist(person);\n\t\ttransaction.commit();\n\t} catch (Exception e) {\n\t\tif (transaction.isActive()) {\n\t\t\ttransaction.rollback();\n\t\t}\n\t}\n}\n<\/pre>\n<p>But before we can call <code>persist()<\/code> we have to open a new transaction by calling <code>transaction.begin()<\/code> on a new transaction object we have retrieved from the <code>EntityManager<\/code>. If we would omit this call, Hibernate would throw a <code>IllegalStateException<\/code> that tells us that we have forgotten to run the <code>persist()<\/code> within a transaction:<\/p>\n<pre class=\"brush:java\">java.lang.IllegalStateException: Transaction not active\n\tat org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:70)\n\tat jpa.Main.persistPerson(Main.java:87)\n<\/pre>\n<p>After calling <code>persist()<\/code> we have to commit the transaction, i.e. send the data to the database and store it there. In case an exception is thrown within the try block, we have to rollback the transaction we have begun before. But as we can only rollback active transactions, we have to check before if the current transaction is already running, as it may happen that the exception is thrown within the <code>transaction.begin()<\/code> call.<\/p>\n<h3><a name=\"tables\"><\/a>C.3. Tables<\/h3>\n<p>The class Person is mapped to the database table <code>T_PERSON<\/code> by adding the annotation <code>@Entity<\/code>:<\/p>\n<pre class=\"brush:java\">@Entity\n@Table(name = \"T_PERSON\")\npublic class Person {\n\tprivate Long id;\n\tprivate String firstName;\n\tprivate String lastName;\n\n\t@Id\n\t@GeneratedValue\n\tpublic Long getId() {\n\t\treturn id;\n\t}\n\n\tpublic void setId(Long id) {\n\t\tthis.id = id;\n\t}\n\n\t@Column(name = \"FIRST_NAME\")\n\tpublic String getFirstName() {\n\t\treturn firstName;\n\t}\n\n\tpublic void setFirstName(String firstName) {\n\t\tthis.firstName = firstName;\n\t}\n\n\t@Column(name = \"LAST_NAME\")\n\tpublic String getLastName() {\n\t\treturn lastName;\n\t}\n\n\tpublic void setLastName(String lastName) {\n\t\tthis.lastName = lastName;\n\t}\n}\n<\/pre>\n<p>The additional annotation <code>@Table<\/code> is optional, but you can use it to specify a specific table name. In our example we want that all tables have the prefix T_, hence we tell Hibernate to create the table <code>T_PERSON<\/code>. The table <code>T_PERSON<\/code> has three columns: <code>ID<\/code>, <code>FIRST_NAME<\/code>, <code>LAST_NAME<\/code>.<\/p>\n<p>This information is provided to the JPA provider with the annotations <code>@Column<\/code> and their attribute <code>name<\/code>. Even this annotation is optional. JPA will use all properties of the Java class that have a setter and getter method and create columns for them, as long as you do not exclude them by annotating them with <code>@Transient<\/code>. On the other hand you can specify more information for each column by using the other attributes that the <code>@Column<\/code> annotation provides:<\/p>\n<pre class=\"brush:java\">@Column(name = \"FIRST_NAME\", length = 100, nullable = false, unique = false)\n<\/pre>\n<p>The example above restricts the length of the string colum to 100 characters, states that the column must not contain null values and is not unique. Trying to insert null as first name into this table would provoke a constraint violation on the database and cause the current transaction to roll back.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>The two annotations <code>@Id<\/code> and <code>@GeneratedValue<\/code> tell JPA that this value is the primary key for this table and that it should be generated automatically.<\/p>\n<p>In the example code above we have added the JPA annotations to the getter methods for each field that should be mapped to a database column. Another way would be to annotate the field directly instead of the getter method:<\/p>\n<pre class=\"brush:java\">@Entity\n@Table(name = \"T_PERSON\")\npublic class Person {\n\t@Id\n\t@GeneratedValue\n\tprivate Long id;\n\t@Column(name = \"FIRST_NAME\")\n\tprivate String firstName;\n\t@Column(name = \"LAST_NAME\")\n\tprivate String lastName;\n\t...\n<\/pre>\n<p>The two ways are more or less equal, the only difference they have plays a role when you want to override annotations for fields in subclasses. As we will see in the further course of this tutorial, it is possible to extend an existing entity in order to inherit its fields. When we place the JPA annotations at the field level, we cannot override them as we can by overriding the corresponding getter method.<\/p>\n<p>One also has to pay attention to keep the way to annotate entities the same for one entity hierarchy. You can mix annotation of fields and methods within one JPA project, but within one entity and all its subclasses is must be consistent. If you need to change the way of annotatio within a subclass hierarchy, you can use the JPA annotation <code>Access<\/code> to specify that a certain subclass uses a different way to annotate fields and methods:<\/p>\n<pre class=\"brush:java\">@Entity\n@Table(name = \"T_GEEK\")\n@Access(AccessType.PROPERTY)\npublic class Geek extends Person {\n...\n<\/pre>\n<p>The code snippet above tells JPA that this class is going to use annotations on the method level, whereas the superclass may have used annotations on field level.<\/p>\n<p>When we run the code above, Hibernate will issue the following queries to our local H2 database:<\/p>\n<pre class=\"brush:bash\">Hibernate: drop table T_PERSON if exists\nHibernate: create table T_PERSON (id bigint generated by default as identity, FIRST_NAME varchar(255), LAST_NAME varchar(255), primary key (id))\nHibernate: insert into T_PERSON (id, FIRST_NAME, LAST_NAME) values (null, ?, ?)\n<\/pre>\n<p>As we can see, Hibernate first drops the table <code>T_PERSON<\/code> if it exists and re-creates it afterwards. If creates the table with two columns of the type <code>varchar(255)<\/code> (<code>FIRST_NAME<\/code>, <code>LAST_NAME<\/code>) and one column named <code>id<\/code> of type <code>bigint<\/code>. The latter column is defined as primary key and its values are automatically generated by the database when we insert a new value.<\/p>\n<p>We can check that everything is correct by using the Shell that ships with H2. In order to use this Shell we just need the jar archive <code>h2-1.3.176.jar<\/code>:<\/p>\n<pre class=\"brush:bash\">&gt;java -cp h2-1.3.176.jar org.h2.tools.Shell -url jdbc:h2:~\/jpa\n\n...\n\nsql&gt; select * from T_PERSON;\nID | FIRST_NAME | LAST_NAME\n1  | Homer      | Simpson\n(4 rows, 4 ms)\n<\/pre>\n<p>The query result above shows us that the table <code>T_PERSON<\/code> actually contains one row with id 1 and values for first name and last name.<\/p>\n<h2><a name=\"intheritance\"><\/a>D. Inheritance<\/h2>\n<p>After having accomplished the setup and this easy use case, we turn towards some more complex use cases. Let&#8217;s assume we want to store next to persons also information about geeks and about their favourite programming language. As geeks are also persons, we would model this in the Java world as subclass relation to Person:<\/p>\n<pre class=\"brush:java\">@Entity\n@Table(name = \"T_GEEK\")\npublic class Geek extends Person {\n\tprivate String favouriteProgrammingLanguage;\n\tprivate List&lt;Project&gt; projects = new ArrayList&lt;Project&gt;();\n\n\t@Column(name = \"FAV_PROG_LANG\")\n\tpublic String getFavouriteProgrammingLanguage() {\n\t\t\treturn favouriteProgrammingLanguage;\n\t}\n\n\tpublic void setFavouriteProgrammingLanguage(String favouriteProgrammingLanguage) {\n\t\tthis.favouriteProgrammingLanguage = favouriteProgrammingLanguage;\n\t}\n\t...\n}\n<\/pre>\n<p>Adding the annotations <code>@Entity<\/code> and <code>@Table<\/code> to the class lets Hibernate create the new table <code>T_GEEK<\/code>:<\/p>\n<pre class=\"brush:bash\">Hibernate: create table T_PERSON (DTYPE varchar(31) not null, id bigint generated by default as identity, FIRST_NAME varchar(255), LAST_NAME varchar(255), FAV_PROG_LANG varchar(255), primary key (id))\n<\/pre>\n<p>We can see that Hibernate creates one table for both entities and puts the information whether we have stored a <code>Person<\/code> or a <code>Geek<\/code> within a new column named <code>DTYPE<\/code>. Let&#8217;s persist some geeks in our database (for better readability I have omitted the block that catches any exception and rolls back the transaction):<\/p>\n<pre class=\"brush:java\">private void persistGeek(EntityManager entityManager) {\n\tEntityTransaction transaction = entityManager.getTransaction();\n\ttransaction.begin();\n\tGeek geek = new Geek();\n\tgeek.setFirstName(\"Gavin\");\n\tgeek.setLastName(\"Coffee\");\n\tgeek.setFavouriteProgrammingLanguage(\"Java\");\n\tentityManager.persist(geek);\n\tgeek = new Geek();\n\tgeek.setFirstName(\"Thomas\");\n\tgeek.setLastName(\"Micro\");\n\tgeek.setFavouriteProgrammingLanguage(\"C#\");\n\tentityManager.persist(geek);\n\tgeek = new Geek();\n\tgeek.setFirstName(\"Christian\");\n\tgeek.setLastName(\"Cup\");\n\tgeek.setFavouriteProgrammingLanguage(\"Java\");\n\tentityManager.persist(geek);\n\ttransaction.commit();\n}\n<\/pre>\n<p>After having executed this method, the database table <code>T_PERSON<\/code> contains the following rows (together with the person we have already inserted):<\/p>\n<pre class=\"brush:bash\">sql&gt; select * from t_person;\nDTYPE  | ID | FIRST_NAME | LAST_NAME | FAV_PROG_LANG\nPerson | 1  | Homer      | Simpson   | null\nGeek   | 2  | Gavin      | Coffee    | Java\nGeek   | 3  | Thomas     | Micro     | C#\nGeek   | 4  | Christian  | Cup       | Java\n<\/pre>\n<p>As expected the new column <code>DTYPE<\/code> determines which type of person we have. The column <code>FAV_PROG_LANG<\/code> has the value <code>null<\/code> for persons that are no geeks.<\/p>\n<p>If you do not like the name or type of the discriminator column, you can change it with the corresponding annotation. In the following we want that the column has the name <code>PERSON_TYPE<\/code> and is an integer column instead of a string column:<\/p>\n<pre class=\"brush:java\">@DiscriminatorColumn(name=\"PERSON_TYPE\", discriminatorType = DiscriminatorType.INTEGER)\n<\/pre>\n<p>This yields to the following result:<\/p>\n<pre class=\"brush:bash\">sql&gt; select * from t_person;\nPERSON_TYPE | ID | FIRST_NAME | LAST_NAME | FAV_PROG_LANG\n-1907849355 | 1  | Homer      | Simpson   | null\n2215460     | 2  | Gavin      | Coffee    | Java\n2215460     | 3  | Thomas     | Micro     | C#\n2215460     | 4  | Christian  | Cup       | Java\n<\/pre>\n<p>Not in every situation you want to have one table for all different types you want to store in your database. This is especially the case when the different types do not have nearly all columns in common. Therefore JPA lets you specify how to lay out the different columns. These three options are available:<\/p>\n<ul>\n<li><code>SINGLE_TABLE<\/code>: This strategy maps all classes to one single table. As a consequence that each row has all columns for all types the database needs additional storage for the empty columns. On the other hand this strategy brings the advantage that a query never has to use a join and therefore can be much faster.<\/li>\n<li><code>JOINED<\/code>: This strategy creates for each type a separate table. Each table therefore only contains the state of the mapped entity. To load one entity, the JPA provider has to load the data for one entity from all tables the entity is mapped to. This approach reduces storage space but on the other hand introduces join queries which can decrease query speed significantly.<\/li>\n<li><code>TABLE_PER_CLASS<\/code>: Like the <code>JOINED<\/code> strategy, this strategy creates a separate table for each entity type. But in contrast to the <code>JOINED<\/code> strategy these tables contain all information necessary to load this entity. Hence no join queries are necessary for loading the entities but it introduces in situations where the concrete subclass is not known additional SQL quries in order to determine it.<\/li>\n<\/ul>\n<p>To change our implementation to use the <code>JOINED<\/code> strategy, all we have to do is to add the following annotation to the base class:<\/p>\n<pre class=\"brush:java\">@Inheritance(strategy = InheritanceType.JOINED)\n<\/pre>\n<p>Now Hibernate creates two tables for persons and geeks:<\/p>\n<pre class=\"brush:bash\">Hibernate: create table T_GEEK (FAV_PROG_LANG varchar(255), id bigint not null, primary key (id))\nHibernate: create table T_PERSON (id bigint generated by default as identity, FIRST_NAME varchar(255), LAST_NAME varchar(255), primary key (id))\n<\/pre>\n<p>Having added the person and the geeks we get the following result:<\/p>\n<pre class=\"brush:bash\">sql&gt; select * from t_person;\nID | FIRST_NAME | LAST_NAME\n1  | Homer      | Simpson\n2  | Gavin      | Coffee\n3  | Thomas     | Micro\n4  | Christian  | Cup\n(4 rows, 12 ms)\nsql&gt; select * from t_geek;\nFAV_PROG_LANG | ID\nJava          | 2\nC#            | 3\nJava          | 4\n(3 rows, 7 ms)\n<\/pre>\n<p>As expected the data is distributed over the two tables. The base table <code>T_PERSON<\/code> contains all the common attributes whereas the table <code>T_GEEK<\/code> only contains rows for each geek. Each row references a person by the value of the column <code>ID<\/code>.<\/p>\n<p>When we issue a query for persons, the following SQL is send to the database:<\/p>\n<pre class=\"brush:sql\">select\n\tperson0_.id as id1_2_,\n\tperson0_.FIRST_NAME as FIRST_NA2_2_,\n\tperson0_.LAST_NAME as LAST_NAM3_2_,\n\tperson0_1_.FAV_PROG_LANG as FAV_PROG1_1_,\n\tcase \n\t\twhen person0_1_.id is not null then 1 \n\t\twhen person0_.id is not null then 0 \n\tend as clazz_ \nfrom\n\tT_PERSON person0_ \nleft outer join\n\tT_GEEK person0_1_ \n\t\ton person0_.id=person0_1_.id\n<\/pre>\n<p>We see that a join query is necessary to include the data from the table <code>T_GEEK<\/code> and that Hibernate encodes the information if one row is a geek or by returning an integer (see case statement).<\/p>\n<p>The Java code to issue such a query looks like the following:<\/p>\n<pre class=\"brush:java\">TypedQuery&lt;Person&gt; query = entityManager.createQuery(\"from Person\", Person.class);\nList&lt;Person&gt; resultList = query.getResultList();\nfor (Person person : resultList) {\n\tStringBuilder sb = new StringBuilder();\n\tsb.append(person.getFirstName()).append(\" \").append(person.getLastName());\n\tif (person instanceof Geek) {\n\t\tGeek geek = (Geek)person;\n\t\tsb.append(\" \").append(geek.getFavouriteProgrammingLanguage());\n\t}\n\tLOGGER.info(sb.toString());\n}\n<\/pre>\n<p>First of all we create a <code>Query<\/code> object by calling EntityManager&#8217;s <code>createQuery()<\/code> method. The query clause can omit the select keyword. The second parameter helps to parameterize the method such that the <code>Query<\/code> is of type <code>Person<\/code>. Issuing the query is simply done by calling <code>query.getResultList()<\/code>. The returned list is iterable, hence we can just iterate over the <code>Person<\/code> objects. If we want to know whether we have a <code>Person<\/code> or a <code>Geek<\/code>, we can just use Java&#8217;s <code>instanceof<\/code> operator.<\/p>\n<p>Running the above code leads to the following output:<\/p>\n<pre class=\"brush:bash\">Homer Simpson\nGavin Coffee Java\nThomas Micro C#\nChristian Cup Java\n<\/pre>\n<h2><a name=\"relationships\"><\/a>E. Relationships<\/h2>\n<p>Until now we have not modelled any relations between different entities except the <code>extends<\/code> relation between a subclass and its superclass. JPA offers different relations between entities\/tables that can be modelled:<\/p>\n<ul>\n<li><code>OneToOne<\/code>: In this relationship each entity has exactly one reference to the other entity and vice versa.<\/li>\n<li><code>OneToMany \/ ManyToOne<\/code>: In this relationship one entity can have multiple child entities and each child entity belongs to one parent entity.<\/li>\n<li><code>ManyToMany<\/code>: In this relationship multiple entites of one type can have multiple references to entities from the other type.<\/li>\n<li><code>Embedded<\/code>: In this relationship the other entity is stored in the same table as the parent entity (i.e. we have two entites for one table).<\/li>\n<li><code>ElementCollection<\/code>: This relationship is similar to the <code>OneToMany<\/code> relation but in contrast to it the referenced entity is an <code>Embedded<\/code> entity. This allows to define <code>OneToMany<\/code> relationships to simple objects that are stored in contrast to the &#8220;normal&#8221; <code>Embedded<\/code> relationship in another table.<\/li>\n<\/ul>\n<h3><a name=\"relationships_onetoone\"><\/a>E.1. OneToOne<\/h3>\n<p>Let&#8217;s start with an <code>OneToOne<\/code> relationship by adding a new entity <code>IdCard<\/code>:<\/p>\n<pre class=\"brush:java\">@Entity\n@Table(name = \"T_ID_CARD\")\npublic class IdCard {\n\tprivate Long id;\n\tprivate String idNumber;\n\tprivate Date issueDate;\n\n\t@Id\n\t@GeneratedValue\n\tpublic Long getId() {\n\t\treturn id;\n\t}\n\n\tpublic void setId(Long id) {\n\t\tthis.id = id;\n\t}\n\n\t@Column(name = \"ID_NUMBER\")\n\tpublic String getIdNumber() {\n\t\treturn idNumber;\n\t}\n\n\tpublic void setIdNumber(String idNumber) {\n\t\tthis.idNumber = idNumber;\n\t}\n\n\t@Column(name = \"ISSUE_DATE\")\n\t@Temporal(TemporalType.TIMESTAMP)\n\tpublic Date getIssueDate() {\n\t\treturn issueDate;\n\t}\n\n\tpublic void setIssueDate(Date issueDate) {\n\t\tthis.issueDate = issueDate;\n\t}\n}\n<\/pre>\n<p>Note that we have used a common <code>java.util.Date<\/code> to model the issue date of the ID card. We can use the annotation <code>@Temporal<\/code> to tell JPA how we want the <code>Date<\/code> to be serialized to the database. Depending on the underlying database product this column is mapped to an appropriate date\/timestamp type. Possible values for this annotation are next to <code>TIMESTAMP<\/code>: <code>TIME<\/code> and <code>DATE<\/code>.<\/p>\n<p>We tell JPA that each person has exactly one ID card:<\/p>\n<pre class=\"brush:java\">@Entity\n@Table(name = \"T_PERSON\")\npublic class Person {\n\t...\n\tprivate IdCard idCard;\n\t...\n\n\t@OneToOne\n\t@JoinColumn(name = \"ID_CARD_ID\")\n\tpublic IdCard getIdCard() {\n\t\treturn idCard;\n\t}\n<\/pre>\n<p>The column in the table <code>T_PERSON<\/code> that contains the foreign key to the table <code>T_ID_CARD<\/code> is stored in the additional column <code>ID_CARD_ID<\/code>. Now Hibernate generates these two tables in the following way:<\/p>\n<pre class=\"brush:sql\">    create table T_ID_CARD (\n        id bigint generated by default as identity,\n        ID_NUMBER varchar(255),\n        ISSUE_DATE timestamp,\n        primary key (id)\n    )\n\n    create table T_PERSON (\n        id bigint generated by default as identity,\n        FIRST_NAME varchar(255),\n        LAST_NAME varchar(255),\n        ID_CARD_ID bigint,\n        primary key (id)\n    )\n<\/pre>\n<p>An important fact is that we can configure when the ID card entity should be loaded. Therefore we can add the attribute <code>fetch<\/code> to the <code>@OneToOne<\/code> annotation:<\/p>\n<pre class=\"brush:java\">@OneToOne(fetch = FetchType.EAGER)\n<\/pre>\n<p>The value <code>FetchType.EAGER<\/code> is the default value and specifies that each time we load a person we also want to load the ID card. On the other hand we can specify that we only want to load the ID when we actually access it by calling <code>person.getIdCard()<\/code>:<\/p>\n<pre class=\"brush:java\">@OneToOne(fetch = FetchType.LAZY)\n<\/pre>\n<p>This result in the following SQL statements when loading all persons:<\/p>\n<pre class=\"brush:bash\">Hibernate: \n    select\n        person0_.id as id1_3_,\n        person0_.FIRST_NAME as FIRST_NA2_3_,\n        person0_.ID_CARD_ID as ID_CARD_4_3_,\n        person0_.LAST_NAME as LAST_NAM3_3_,\n        person0_1_.FAV_PROG_LANG as FAV_PROG1_1_,\n        case \n            when person0_1_.id is not null then 1 \n            when person0_.id is not null then 0 \n        end as clazz_ \n    from\n        T_PERSON person0_ \n    left outer join\n        T_GEEK person0_1_ \n            on person0_.id=person0_1_.id\nHibernate: \n    select\n        idcard0_.id as id1_2_0_,\n        idcard0_.ID_NUMBER as ID_NUMBE2_2_0_,\n        idcard0_.ISSUE_DATE as ISSUE_DA3_2_0_ \n    from\n        T_ID_CARD idcard0_ \n    where\n        idcard0_.id=?\n<\/pre>\n<p>We can see that we now have to load each ID card separately. Therefore this feature has to be used wisely, as it can cause hundreds of additional select queries in case you are loading a huge number of persons and you know that you are loading each time also the ID card.<\/p>\n<h3><a name=\"relationships_onetomany\"><\/a>E.2. OneToMany<\/h3>\n<p>Another important relationship is the <code>@OneToMany<\/code> relationship. In our example every <code>Person<\/code> should have one ore more phones:<\/p>\n<pre class=\"brush:java\">@Entity\n@Table(name = \"T_PHONE\")\npublic class Phone {\n\tprivate Long id;\n\tprivate String number;\n\tprivate Person person;\n\n\t@Id\n\t@GeneratedValue\n\tpublic Long getId() {\n\t\treturn id;\n\t}\n\n\tpublic void setId(Long id) {\n\t\tthis.id = id;\n\t}\n\n\t@Column(name = \"NUMBER\")\n\tpublic String getNumber() {\n\t\treturn number;\n\t}\n\n\tpublic void setNumber(String number) {\n\t\tthis.number = number;\n\t}\n\n\t@ManyToOne(fetch = FetchType.LAZY)\n\t@JoinColumn(name = \"PERSON_ID\")\n\tpublic Person getPerson() {\n\t\treturn person;\n\t}\n\n\tpublic void setPerson(Person person) {\n\t\tthis.person = person;\n\t}\n}\n<\/pre>\n<p>Each phone has an internal id as well as the number. Next to this we also have to specify the relation to the <code>Person<\/code> with the <code>@ManyToOne<\/code>, as we have &#8220;many&#8221; phones for &#8220;one&#8221; person. The annotation <code>@JoinColumn<\/code> specifies the column in the <code>T_PHONE<\/code> table that stores the foreign key to the person.<\/p>\n<p>On the other side of the relation we have to add a <code>List<\/code> of <code>Phone<\/code> objects to the person and annotate the corresponding getter method with <code>@OneToMany<\/code> as we have &#8220;one&#8221; person with &#8220;many&#8221; phones:<\/p>\n<pre class=\"brush:java\">private List&lt;Phone&gt; phones = new ArrayList&lt;&gt;();\n...\n@OneToMany(mappedBy = \"person\", fetch = FetchType.LAZY)\npublic List&lt;Phone&gt; getPhones() {\n\treturn phones;\n}\n<\/pre>\n<p>The value of the attribute <code>mappedBy<\/code> tells JPA which list on the other side of the relation (here <code>Phone.person<\/code>) this annotation references.<\/p>\n<p>As we do not want to load all phones every time we load the person, we set the relationship to be fetched lazy (although this is the default value and we would have to set it explicitly). Now we get an additional selecte statment each time we load the phones for one person:<\/p>\n<pre class=\"brush:sql\">select\n\tphones0_.PERSON_ID as PERSON_I3_3_0_,\n\tphones0_.id as id1_4_0_,\n\tphones0_.id as id1_4_1_,\n\tphones0_.NUMBER as NUMBER2_4_1_,\n\tphones0_.PERSON_ID as PERSON_I3_4_1_ \nfrom\n\tT_PHONE phones0_ \nwhere\n\tphones0_.PERSON_ID=?\n<\/pre>\n<p>As the value for the attribute <code>fetch<\/code> is set at compile time, we unfortunately cannot change it at runtime. But if we know that we want to load all phone numbers in this use case and in other use cases not, we can leave the relation to be loaded lazy and add the clause <code>left join fetch<\/code> to our JPQL query in order to tell the JPA provider to also load all phones in this specific query even if the relation is set to <code>FetchType.LAZY<\/code>. Such a query can look like the following one:<\/p>\n<pre class=\"brush:java\">TypedQuery&lt;Person&gt; query = entityManager.createQuery(\"from Person p left join fetch p.phones\", Person.class);\n<\/pre>\n<p>We give the <code>Person<\/code> the alias <code>p<\/code> and tell JPA to also fetch all instances of <code>phones<\/code> that belong to each person. This results with Hibernate in the following select query:<\/p>\n<pre class=\"brush:sql\">    select\n        person0_.id as id1_3_0_,\n        phones1_.id as id1_4_1_,\n        person0_.FIRST_NAME as FIRST_NA2_3_0_,\n        person0_.ID_CARD_ID as ID_CARD_4_3_0_,\n        person0_.LAST_NAME as LAST_NAM3_3_0_,\n        person0_1_.FAV_PROG_LANG as FAV_PROG1_1_0_,\n        case \n            when person0_1_.id is not null then 1 \n            when person0_.id is not null then 0 \n        end as clazz_0_,\n        phones1_.NUMBER as NUMBER2_4_1_,\n        phones1_.PERSON_ID as PERSON_I3_4_1_,\n        phones1_.PERSON_ID as PERSON_I3_3_0__,\n        phones1_.id as id1_4_0__ \n    from\n        T_PERSON person0_ \n    left outer join\n        T_GEEK person0_1_ \n            on person0_.id=person0_1_.id \n    left outer join\n        T_PHONE phones1_ \n            on person0_.id=phones1_.PERSON_ID\n<\/pre>\n<p>Please note that without the keyword <code>left<\/code> (i.e. only <code>join fetch<\/code>) Hibernate will create an inner join and only load persons that actually have at least one phone number.<br \/>\n[ulp id=&#8217;LoQtGl7SXNqSQXjk&#8217;]<br \/>\n&nbsp;<\/p>\n<h3><a name=\"relationships_manytomany\"><\/a>E.3. ManyToMany<\/h3>\n<p>Another interesting relationship is the <code>@ManyToMany<\/code> one. As one geek can join many projects and one project consists of many geeks, we model the relationship between <code>Project<\/code> and <code>Geek<\/code> as <code>@ManyToMany<\/code> relationship:<\/p>\n<pre class=\"brush:java\">@Entity\n@Table(name = \"T_PROJECT\")\npublic class Project {\n\tprivate Long id;\n\tprivate String title;\n\tprivate List&lt;Geek&gt; geeks = new ArrayList&lt;Geek&gt;();\n\n\t@Id\n\t@GeneratedValue\n\tpublic Long getId() {\n\t\treturn id;\n\t}\n\n\tpublic void setId(Long id) {\n\t\tthis.id = id;\n\t}\n\n\t@Column(name = \"TITLE\")\n\tpublic String getTitle() {\n\t\treturn title;\n\t}\n\n\tpublic void setTitle(String title) {\n\t\tthis.title = title;\n\t}\n\n\t@ManyToMany(mappedBy=\"projects\")\n\tpublic List&lt;Geek&gt; getGeeks() {\n\t\treturn geeks;\n\t}\n\n\tpublic void setGeeks(List&lt;Geek&gt; geeks) {\n\t\tthis.geeks = geeks;\n\t}\n}\n<\/pre>\n<p>Our project has an internal id, a title of type <code>String<\/code> and a list of <code>Geeks<\/code>. The getter method for the geeks attribute is annotated with <code>@ManyToMany(mappedBy=\"projects\")<\/code>. The value of the attribute <code>mappedBy<\/code> tells JPA the class member on the other side of the relation this relation belongs to as there can be more than one list of projects for a geek. The class <code>Geek<\/code> gets a list of projects and :<\/p>\n<pre class=\"brush:java\">private List&lt;Project&gt; projects = new ArrayList&lt;&gt;();\n...\n@ManyToMany\n@JoinTable(\n\t\tname=\"T_GEEK_PROJECT\",\n\t\tjoinColumns={@JoinColumn(name=\"GEEK_ID\", referencedColumnName=\"ID\")},\n\t\tinverseJoinColumns={@JoinColumn(name=\"PROJECT_ID\", referencedColumnName=\"ID\")})\npublic List&lt;Project&gt; getProjects() {\n\treturn projects;\n}\n<\/pre>\n<p>For a <code>@ManyToMany<\/code> we need an additional table. This table is configured by the <code>@JoinTable<\/code> annotation that describes the table used to store the geek&#8217;s assignments to the different projects. It has the name <code>GEEK_PROJECT<\/code> and stores the geek&#8217;s id in the column <code>GEEK_ID<\/code> and the project&#8217;s id in the column <code>PROJECT_ID<\/code>. The referenced column is on both sides just <code>ID<\/code> as we have named the internal id in both classes <code>ID<\/code>.<\/p>\n<p>A <code>@ManyToMany<\/code> is also per default fetched lazy, as in most cases we do not want to load all projects assignments when we load a single geek.<\/p>\n<p>As the relation <code>@ManyToMany<\/code> is equal on both sides, we could have also annotated the two lists in both classes the other way round:<\/p>\n<pre class=\"brush:java\">@ManyToMany\n@JoinTable(\n\t\tname=\"T_GEEK_PROJECT\",\n\t\tjoinColumns={@JoinColumn(name=\"PROJECT_ID\", referencedColumnName=\"ID\")},\n\t\tinverseJoinColumns={@JoinColumn(name=\"GEEK_ID\", referencedColumnName=\"ID\")})\npublic List&lt;Geek&gt; getGeeks() {\n\treturn geeks;\n}\n<\/pre>\n<p>And on the other <code>Geek<\/code> side:<\/p>\n<pre class=\"brush:java\">@ManyToMany(mappedBy=\"geeks\")\npublic List&lt;Project&gt; getProjects() {\n\treturn projects;\n}\n<\/pre>\n<p>In both cases Hibernate creates a new table <code>T_GEEK_PROJECT<\/code> with the two colums <code>PROJECT_ID<\/code> and <code>GEEK_ID<\/code>:<\/p>\n<pre class=\"brush:bash\">sql&gt; select * from t_geek_project;\nPROJECT_ID | GEEK_ID\n1          | 2\n1          | 4\n(2 rows, 2 ms)\n<\/pre>\n<p>The Java code to persist these relations is the following one:<\/p>\n<pre class=\"brush:java\">List&lt;Geek&gt; resultList = entityManager.createQuery(\"from Geek g where g.favouriteProgrammingLanguage = :fpl\", Geek.class).setParameter(\"fpl\", \"Java\").getResultList();\nEntityTransaction transaction = entityManager.getTransaction();\ntransaction.begin();\nProject project = new Project();\nproject.setTitle(\"Java Project\");\nfor (Geek geek : resultList) {\n\tproject.getGeeks().add(geek);\n\tgeek.getProjects().add(project);\n}\nentityManager.persist(project);\ntransaction.commit();\n<\/pre>\n<p>In this example we only want to add geeks to our &#8220;Java Project&#8221; whose favourite programming language is of course Java. Hence we add a where clause to our select query that restricts the result set to geeks with a specific value for the column <code>FAV_PROG_LANG<\/code>. As this column is mapped to the field <code>favouriteProgrammingLanguage<\/code>, we can reference it directly by its Java field name in the JPQL statement. The dynamic value for the query is passed into the statement by calling <code>setParameter()<\/code> for the corresponding variable in the JPQL query (here: <code>fpl<\/code>).<\/p>\n<h3><a name=\"relationships_embedded\"><\/a>E.4. Embedded \/ ElementCollection<\/h3>\n<p>It can happen that you want to structure your Java model more fine-grained than your database model. An example for such a use case is the Java class <code>Period<\/code> that models the time between a start and an end date. This construct can be reused in different entities as you do not want to copy the two class fields <code>startDate<\/code> and <code>endDate<\/code> to each entity that has a period of time.<\/p>\n<p>For such cases JPA offers the ability to model embedded entities. These entities are modeled as separate Java classes with the annotation <code>@Embeddable<\/code>:<\/p>\n<pre class=\"brush:java\">@Embeddable\npublic class Period {\n\tprivate Date startDate;\n\tprivate Date endDate;\n\n\t@Column(name =\"START_DATE\")\n\tpublic Date getStartDate() {\n\t\treturn startDate;\n\t}\n\n\tpublic void setStartDate(Date startDate) {\n\t\tthis.startDate = startDate;\n\t}\n\n\t@Column(name =\"END_DATE\")\n\tpublic Date getEndDate() {\n\t\treturn endDate;\n\t}\n\n\tpublic void setEndDate(Date endDate) {\n\t\tthis.endDate = endDate;\n\t}\n}\n<\/pre>\n<p>This entity can then be included in our <code>Project<\/code> entity:<\/p>\n<pre class=\"brush:java\">private Period projectPeriod;\n\n@Embedded\npublic Period getProjectPeriod() {\n\treturn projectPeriod;\n}\n\npublic void setProjectPeriod(Period projectPeriod) {\n\tthis.projectPeriod = projectPeriod;\n}\n<\/pre>\n<p>As this entity is embedded, Hibernate creates the two columns <code>START_DATE<\/code> and <code>END_DATE<\/code> for the table <code>T_PROJECT<\/code>:<\/p>\n<pre class=\"brush:sql\">create table T_PROJECT (\n\tid bigint generated by default as identity,\n\tEND_DATE timestamp,\n\tSTART_DATE timestamp,\n\tprojectType varchar(255),\n\tTITLE varchar(255),\n\tprimary key (id)\n)\n<\/pre>\n<p>Altough these two values are modelled within a separate Java class, we can query them as part of the project:<\/p>\n<pre class=\"brush:bash\">sql&gt; select * from t_project;\nID | END_DATE                | START_DATE              | PROJECTTYPE       | TITLE\n1  | 2015-02-01 00:00:00.000 | 2016-01-31 23:59:59.999 | TIME_AND_MATERIAL | Java Project\n(1 row, 2 ms)\n<\/pre>\n<p>A JPQL query has to reference the embedded period in order to formulate a condition that restricts the result set to projects that started on a certain day:<\/p>\n<pre class=\"brush:java\">entityManager.createQuery(\"from Project p where p.projectPeriod.startDate = :startDate\", Project.class).setParameter(\"startDate\", createDate(1, 1, 2015));\n<\/pre>\n<p>This yields to the following SQL query:<\/p>\n<pre class=\"brush:sql\">select\n\tproject0_.id as id1_5_,\n\tproject0_.END_DATE as END_DATE2_5_,\n\tproject0_.START_DATE as START_DA3_5_,\n\tproject0_.projectType as projectT4_5_,\n\tproject0_.TITLE as TITLE5_5_ \nfrom\n\tT_PROJECT project0_ \nwhere\n\tproject0_.START_DATE=?\n<\/pre>\n<p>Since version 2.0 of JPA you can even use <code>@Embeddable<\/code> entities in one-to-many relations. This is accomplished by using the new annotations <code>@ElementCollection<\/code> and <code>@CollectionTable<\/code> as shown in the following example for the class <code>Project<\/code>:<\/p>\n<pre class=\"brush:java\">private List&lt;Period&gt; billingPeriods = new ArrayList&lt;Period&gt;();\n\n@ElementCollection\n@CollectionTable(\n\t\tname=\"T_BILLING_PERIOD\",\n\t\tjoinColumns=@JoinColumn(name=\"PROJECT_ID\")\n)\npublic List&lt;Period&gt; getBillingPeriods() {\n\treturn billingPeriods;\n}\n\npublic void setBillingPeriods(List&lt;Period&gt; billingPeriods) {\n\tthis.billingPeriods = billingPeriods;\n}\n<\/pre>\n<p>As <code>Period<\/code> is an <code>@Embeddable<\/code> entity we cannot just use a normal <code>@OneToMany<\/code> relation.<\/p>\n<h2><a name=\"dataTypes\"><\/a>G. Data Types and Converters<\/h2>\n<p>When dealing with legacy databases it can happen that you the standard mapping provided by JPA may not be enough. The following table lists how the Java types are mapped to the different database types:<\/p>\n<table border=\"2\">\n<thead>\n<tr>\n<td style=\"background-color: #dedede; font-weight: bold;\">Java type<\/td>\n<td style=\"background-color: #dedede; font-weight: bold;\">Database type<\/td>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>String (char, char[])<\/td>\n<td>VARCHAR (CHAR, VARCHAR2, CLOB, TEXT)<\/td>\n<\/tr>\n<tr>\n<td>Number (BigDecimal, BigInteger, Integer, Double, Long, Float, Short, Byte)<\/td>\n<td>NUMERIC (NUMBER, INT, LONG, FLOAT, DOUBLE)<\/td>\n<\/tr>\n<tr>\n<td>int, long, float, double, short, byte<\/td>\n<td>NUMERIC (NUMBER, INT, LONG, FLOAT, DOUBLE)<\/td>\n<\/tr>\n<tr>\n<td>byte[]<\/td>\n<td>VARBINARY (BINARY, BLOB)<\/td>\n<\/tr>\n<tr>\n<td>boolean (Boolean)<\/td>\n<td>BOOLEAN (BIT, SMALLINT, INT, NUMBER)<\/td>\n<\/tr>\n<tr>\n<td>java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp, java.util.Calendar<\/td>\n<td>TIMESTAMP (DATE, DATETIME)<\/td>\n<\/tr>\n<tr>\n<td>java.lang.Enum<\/td>\n<td>NUMERIC (VARCHAR, CHAR)<\/td>\n<\/tr>\n<tr>\n<td>java.util.Serializable<\/td>\n<td>VARBINARY (BINARY, BLOB)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>An interesting point in this table is the mapping for enum types. To demonstrate the usage of enums in JPA let&#8217;s add the enum <code>ProjectType<\/code> to the entity:<\/p>\n<pre class=\"brush:java\">@Entity\n@Table(name = \"T_PROJECT\")\npublic class Project {\n...\n\tprivate ProjectType projectType;\n\n\tpublic enum ProjectType {\n\t\tFIXED, TIME_AND_MATERIAL\n\t}\n\t...\n\t@Enumerated(EnumType.ORDINAL)\n\tpublic ProjectType getProjectType() {\n\t\treturn projectType;\n\t}\n\n\tpublic void setProjectType(ProjectType projectType) {\n\t\tthis.projectType = projectType;\n\t}\n}\n<\/pre>\n<p>As we can see from the snippet above, the annotation <code>@Enumerated<\/code> allows us to map enums to database colums by specifying how to map the different values to the column. Choosing <code>EnumType.ORDINAL<\/code> means that each enum constant is mapped to a specific number in the database. When we set our &#8220;Java Project&#8221; to <code>TIME_AND_MATERIAL<\/code> we get the following output:<\/p>\n<pre class=\"brush:sql\">sql&gt; select * from t_project;\nID | PROJECTTYPE | TITLE\n1  | 1           | Java Project\n(1 row, 2 ms)\n<\/pre>\n<p>As an alternative we could also use the value <code>EnumType.STRING<\/code>. In this case the column is of type <code>String<\/code> and encodes the enum by calling its <code>name()<\/code> method:<\/p>\n<pre class=\"brush:sql\">sql&gt; select * from t_project;\nID | PROJECTTYPE       | TITLE\n1  | TIME_AND_MATERIAL | Java Project\n(1 row, 2 ms)\n<\/pre>\n<p>If both solutions do not satisfy your requirements, you can write your own converter. This is done by implementing the Java interface <code>AttributeConverter<\/code> and annotating the class with <code>@Converter<\/code>. The following class for example converts a boolean value into the two numeric values <code>1<\/code> and <code>-1<\/code>:<\/p>\n<pre class=\"brush:java\">@Converter\npublic class BooleanConverter implements AttributeConverter&lt;Boolean, Integer&gt; {\n\n\t@Override\n\tpublic Integer convertToDatabaseColumn(Boolean aBoolean) {\n\t\tif (Boolean.TRUE.equals(aBoolean)) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\t@Override\n\tpublic Boolean convertToEntityAttribute(Integer value) {\n\t\tif (value == null) {\n\t\t\treturn Boolean.FALSE;\n\t\t} else {\n\t\t\tif (value == 1) {\n\t\t\t\treturn Boolean.TRUE;\n\t\t\t} else {\n\t\t\t\treturn Boolean.FALSE;\n\t\t\t}\n\t\t}\n\t}\n}\n<\/pre>\n<p>This converter can be applied to our <code>IdCard<\/code> when we want provide the information if an ID card is valid or not as a boolean value:<\/p>\n<pre class=\"brush:java\">private boolean valid;\n...\n@Column(name = \"VALID\")\n@Convert(converter = BooleanConverter.class)\npublic boolean isValid() {\n\treturn valid;\n}\n\npublic void setValid(boolean valid) {\n\tthis.valid = valid;\n}\n<\/pre>\n<p>Inserting an ID card with <code>false<\/code> for the attribute <code>valid<\/code>, results in the following output:<\/p>\n<pre class=\"brush:sql\">sql&gt; select * from t_id_card;\nID | ID_NUMBER | ISSUE_DATE              | VALID\n1  | 4711      | 2015-02-04 16:43:30.233 | -1\n<\/pre>\n<h2><a name=\"criteriaapi\"><\/a>H. Criteria API<\/h2>\n<p>Until now we have used the Java Persistence Query Language (JPQL) to issue queries to the database. An alternative to the JPQL is the &#8220;Criteria API&#8221;. This API provides a pure Java method based API to construct a query.<\/p>\n<p>The following example queries the database for persons with <code>firstName = 'Homer'<\/code>:<\/p>\n<pre class=\"brush:java\">CriteriaBuilder builder = entityManager.getCriteriaBuilder();\nCriteriaQuery&lt;Person&gt; query = builder.createQuery(Person.class);\nRoot&lt;Person&gt; personRoot = query.from(Person.class);\nquery.where(builder.equal(personRoot.get(\"firstName\"), \"Homer\"));\nList&lt;Person&gt; resultList = entityManager.createQuery(query).getResultList();\n<\/pre>\n<p>When starting to build a criteria query, we have to ask the <code>EntityManager<\/code> for a <code>CriteriaBuilder<\/code> object. This builder can then be used to create the actual <code>Query<\/code> object. The way to tell this query which table(s) to query is accomplished by invoking the method <code>from()<\/code> and passing the entity that is mapped to the corresponding table. The <code>Query<\/code> object also offers a method to add the where clause:<\/p>\n<pre class=\"brush:java\">query.where(builder.equal(personRoot.get(\"firstName\"), \"Homer\"));\n<\/pre>\n<p>The condition itself is then created using the <code>CriteriaBuilder<\/code> and its <code>equal()<\/code> method. More complex queries can then be assembled by using the appropriate logical conjunction:<\/p>\n<pre class=\"brush:java\">query.where(builder.and(\n\tbuilder.equal(personRoot.get(\"firstName\"), \"Homer\"), \n\tbuilder.equal(personRoot.get(\"lastName\"), \"Simpson\")));\n<\/pre>\n<p>In general <code>CriteriaQuery<\/code> defines the following clauses and options:<\/p>\n<ul>\n<li><code>distinct()<\/code>: Specifies whether the database should filter out duplicate values.<\/li>\n<li><code>from()<\/code>: Specifies the table\/entity the query is submitted for.<\/li>\n<li><code>select()<\/code>: Specifies a <code>select<\/code> query.<\/li>\n<li><code>multiselect()<\/code>: Specifies a list of selections.<\/li>\n<li><code>where()<\/code>: Specifies the <code>where<\/code> clause of the query.<\/li>\n<li><code>orderBy()<\/code>: Specifies the ordering for the query.<\/li>\n<li><code>groupBy()<\/code>: Specifies groups that are formed over the result.<\/li>\n<li><code>having()<\/code>: Specifies restrictions for groups that are defined over the result.<\/li>\n<li><code>subquery()<\/code>: Specifies a subquery that can be used in other queries.<\/li>\n<\/ul>\n<p>The above methods allow you to assemble queries completely dynamically based on any filter restrictions the user has provided.<\/p>\n<h2><a name=\"sequences\"><\/a>I. Sequences<\/h2>\n<p>Until now we have used in this tutorial the annotation <code>@GeneratedValue<\/code> without any specific information on how this unique value should be assigned to each entity. Without any further information the JPA provider chooses on its on how to generate this unique value. But we can also decide the way how to generate unique ids for entities on our own. JPA provides therefore these three different approaches:<\/p>\n<ul>\n<li><code>TABLE<\/code>: This strategy lets the JPA provider create a separate table that contains one row for each entity. This row contains next to the name of the entity also the current value for the id. Each time a new value is requsted, the row in the table is updated accordingly.<\/li>\n<li><code>SEQUENCE<\/code>: If the database provides sequences, this strategy requests the unique values from the provided database sequence. Not all database products do support sequences.<\/li>\n<li><code>IDENTITY<\/code>: If the database provides identity columns, this strategy uses this kind of column provided by the underlying database implementation. Not all database products support identity columns.<\/li>\n<\/ul>\n<p>In order to use the <code>TABLE<\/code> strategy, we also have to tell the JPA provider some details about the table it should use for the sequence management:<\/p>\n<pre class=\"brush:java\">@Id\n@GeneratedValue(strategy = GenerationType.TABLE, generator = \"TABLE_GENERATOR\")\n@TableGenerator(name = \"TABLE_GENERATOR\", table=\"T_SEQUENCES\", pkColumnName = \"SEQ_NAME\", valueColumnName = \"SEQ_VALUE\", pkColumnValue = \"PHONE\")\npublic Long getId() {\n\treturn id;\n}\n<\/pre>\n<p>The <code>@TableGenerator<\/code> annotation tell our JPA provider that the table should have the name <code>T_SEQUENCES<\/code> and the two columns <code>SEQ_NAME<\/code> and <code>SEQ_VALUE<\/code>. The name for this sequence in the table should be <code>PHONE<\/code>:<\/p>\n<pre class=\"brush:bash\">sql&gt; select * from t_sequences;\nSEQ_NAME | SEQ_VALUE\nPHONE    | 1\n<\/pre>\n<p>The <code>SEQUENCE<\/code> strategy can be used in a similar way:<\/p>\n<pre class=\"brush:java\">@Id\n@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = \"S_PROJECT\")\n@SequenceGenerator(name = \"S_PROJECT\", sequenceName = \"S_PROJECT\", allocationSize = 100)\npublic Long getId() {\n\treturn id;\n}\n<\/pre>\n<p>By using the annotation <code>@SequenceGenerator<\/code> we tell the JPA provider how the sequence should be named (<code>S_PROJECT<\/code>) and tell it an allocation size (here 100), i.e. how many values should be pre-allocated. The attributes <code>generator<\/code> and <code>name<\/code> connect the two annotations with each other.<\/p>\n<p>As this strategy uses a separate table, it can easily become a performance bottleneck when requesting a lot of sequence values. This is especially true if you use the same table for a huge number of tables and the underlying database only supports table locks or locks on table pages. In this case the database has to lock the complete table\/page until the current transaction has been committed. Therefore JPA allows to define a pre-allocation size such that the database is not hit too often.<\/p>\n<p>In order to use the <code>IDENTITY<\/code> strategy, we just have to set the <code>strategy<\/code> attribute accordingly:<\/p>\n<pre class=\"brush:java\">@Id\n@GeneratedValue(strategy = GenerationType.IDENTITY)\npublic Long getId() {\n\treturn id;\n}\n<\/pre>\n<p>If the database supports identity columns, the table is created appropriately:<\/p>\n<pre class=\"brush:sql\">create table T_ID_CARD (\n\tid bigint generated by default as identity,\n\tID_NUMBER varchar(255),\n\tISSUE_DATE timestamp,\n\tVALID integer,\n\tprimary key (id)\n)\n<\/pre>\n<h2><a name=\"download\"><\/a>J. Download&nbsp;JPA Tutorial Source Code<\/h2>\n<p>This was a tutorial on Java Persistence API (JPA).<\/p>\n<div class=\"download\"><strong>Download<\/strong><br \/>\nYou can download the full source code of this tutorial here: <a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/02\/jpa.zip\"><strong>jpa_tutorial<\/strong><\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>EDITORIAL NOTE: In this post, we feature a comprehensive JPA Tutorial. The Java Persistence API (JPA) is a Java programming language application programming interface specification that describes the management of relational data in applications using Java Platform, Standard Edition and Java Platform, Enterprise Edition. JPA has become the de-facto standard to write application code that &hellip;<\/p>\n","protected":false},"author":506,"featured_media":112,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[33,1039],"class_list":["post-36797","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-jpa","tag-ultimate"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>JPA Tutorial - The ULTIMATE Guide (PDF Download) - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Interested to learn more about JPA? Then check out our detailed ULTIMATE jpa tutorial where all major aspects like onetomany and manytoone mappings, native queries, criteria, joins are explained to quickly get started! You can also download our FREE JPA Ultimate Guide!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"JPA Tutorial - The ULTIMATE Guide (PDF Download) - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Interested to learn more about JPA? Then check out our detailed ULTIMATE jpa tutorial where all major aspects like onetomany and manytoone mappings, native queries, criteria, joins are explained to quickly get started! You can also download our FREE JPA Ultimate Guide!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2015-02-16T16:05:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-12-05T14:32:17+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Martin Mois\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Martin Mois\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"22 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html\"},\"author\":{\"name\":\"Martin Mois\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/52c1e27ea19337c20d53df5286590760\"},\"headline\":\"JPA Tutorial &#8211; The ULTIMATE Guide (PDF Download)\",\"datePublished\":\"2015-02-16T16:05:58+00:00\",\"dateModified\":\"2023-12-05T14:32:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html\"},\"wordCount\":4900,\"commentCount\":24,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"keywords\":[\"JPA\",\"Ultimate\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html\",\"name\":\"JPA Tutorial - The ULTIMATE Guide (PDF Download) - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"datePublished\":\"2015-02-16T16:05:58+00:00\",\"dateModified\":\"2023-12-05T14:32:17+00:00\",\"description\":\"Interested to learn more about JPA? Then check out our detailed ULTIMATE jpa tutorial where all major aspects like onetomany and manytoone mappings, native queries, criteria, joins are explained to quickly get started! You can also download our FREE JPA Ultimate Guide!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"java-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/02\\\/jpa-tutorial.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"JPA Tutorial &#8211; The ULTIMATE Guide (PDF Download)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/52c1e27ea19337c20d53df5286590760\",\"name\":\"Martin Mois\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/051a80ba18f758940b686c6c4bb4b5f02d59abe8cc42a95b3545f7565c7a40a1?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/051a80ba18f758940b686c6c4bb4b5f02d59abe8cc42a95b3545f7565c7a40a1?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/051a80ba18f758940b686c6c4bb4b5f02d59abe8cc42a95b3545f7565c7a40a1?s=96&d=mm&r=g\",\"caption\":\"Martin Mois\"},\"description\":\"Martin is a Java EE enthusiast and works for an international operating company. He is interested in clean code and the software craftsmanship approach. He also strongly believes in automated testing and continuous integration.\",\"sameAs\":[\"http:\\\/\\\/martinsdeveloperworld.wordpress.com\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/martin-mois\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"JPA Tutorial - The ULTIMATE Guide (PDF Download) - Java Code Geeks","description":"Interested to learn more about JPA? Then check out our detailed ULTIMATE jpa tutorial where all major aspects like onetomany and manytoone mappings, native queries, criteria, joins are explained to quickly get started! You can also download our FREE JPA Ultimate Guide!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html","og_locale":"en_US","og_type":"article","og_title":"JPA Tutorial - The ULTIMATE Guide (PDF Download) - Java Code Geeks","og_description":"Interested to learn more about JPA? Then check out our detailed ULTIMATE jpa tutorial where all major aspects like onetomany and manytoone mappings, native queries, criteria, joins are explained to quickly get started! You can also download our FREE JPA Ultimate Guide!","og_url":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2015-02-16T16:05:58+00:00","article_modified_time":"2023-12-05T14:32:17+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","type":"image\/jpeg"}],"author":"Martin Mois","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Martin Mois","Est. reading time":"22 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html"},"author":{"name":"Martin Mois","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/52c1e27ea19337c20d53df5286590760"},"headline":"JPA Tutorial &#8211; The ULTIMATE Guide (PDF Download)","datePublished":"2015-02-16T16:05:58+00:00","dateModified":"2023-12-05T14:32:17+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html"},"wordCount":4900,"commentCount":24,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","keywords":["JPA","Ultimate"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html","url":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html","name":"JPA Tutorial - The ULTIMATE Guide (PDF Download) - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","datePublished":"2015-02-16T16:05:58+00:00","dateModified":"2023-12-05T14:32:17+00:00","description":"Interested to learn more about JPA? Then check out our detailed ULTIMATE jpa tutorial where all major aspects like onetomany and manytoone mappings, native queries, criteria, joins are explained to quickly get started! You can also download our FREE JPA Ultimate Guide!","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","width":150,"height":150,"caption":"java-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2015\/02\/jpa-tutorial.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"JPA Tutorial &#8211; The ULTIMATE Guide (PDF Download)"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/52c1e27ea19337c20d53df5286590760","name":"Martin Mois","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/051a80ba18f758940b686c6c4bb4b5f02d59abe8cc42a95b3545f7565c7a40a1?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/051a80ba18f758940b686c6c4bb4b5f02d59abe8cc42a95b3545f7565c7a40a1?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/051a80ba18f758940b686c6c4bb4b5f02d59abe8cc42a95b3545f7565c7a40a1?s=96&d=mm&r=g","caption":"Martin Mois"},"description":"Martin is a Java EE enthusiast and works for an international operating company. He is interested in clean code and the software craftsmanship approach. He also strongly believes in automated testing and continuous integration.","sameAs":["http:\/\/martinsdeveloperworld.wordpress.com\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/martin-mois"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/36797","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/506"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=36797"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/36797\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/112"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=36797"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=36797"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=36797"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}