Você está na página 1de 60

First steps and detailed concepts

Java Persistence API


Java Persistence API

Mini Book
Mini Book
Hebert Coelho
Byron Kiourtzoglou
JPA Mini Book www.javacodegeeks.com
Table of Contents
Reasons that led to the creation of JPA ...................................................................................................... 3
What is JPA? What is a JPA Imlementation? ........................................................................................... !
What is the ersistence."ml file #sed for? And its config#rations? ........................................................... $
%ntit& definitions. What are the 'ogic and Ph&sical annotations? ............................................................. (
Id )eneration* +efinition, #sing Identit& or -e.#ence ............................................................................ /0
Identit& ................................................................................................................................................. //
-e.#ence .............................................................................................................................................. /1
Id )eneration* 2a3le)enerator and A#to ................................................................................................ /3
2a3le)enerator .................................................................................................................................... /3
A#to ..................................................................................................................................................... /$
-imle 4omosite 5e& ............................................................................................................................ /$
6Id4lass ............................................................................................................................................. /$
6%m3edda3le ..................................................................................................................................... /(
4omle" 4omosite 5e& ......................................................................................................................... 10
7ow to get an %ntit&Manager .................................................................................................................. 1!
Maing two or more ta3les in one entit& ............................................................................................... 1$
Maing 7ierarch&* Maed-#erclass .................................................................................................. 1$
Maing 7ierarch&* -ingle 2a3le ............................................................................................................ 18
Maing 7ierarch&* Joined ...................................................................................................................... 19
Maing 7ierarch&* 2a3le er 4oncrete 4lass ........................................................................................ 3/
Pros:4ons of each hierarch& maing aroach ...................................................................................... 33
%m3edded ;3jects ................................................................................................................................... 3!
%lement4ollection < how to ma a list of val#es into a class .................................................................. 3$
;ne2o;ne #nidirectional and 3idirectional ............................................................................................. 3=
>nidirectional ...................................................................................................................................... 3=
Bidirectional ........................................................................................................................................ 3(
2here is no s#ch ?a#to relationshi@ ........................................................................................................ 3(
;ne2oMan&:Man&2o;ne #nidirectional and 3idirectional ..................................................................... 39
2here is no s#ch ?a#to relationshi@ ........................................................................................................ !0
Man&2oMan& #nidirectional and 3idirectional ........................................................................................ !0
2here is no s#ch ?a#to relationshi@ ........................................................................................................ !3
Man&2oMan& with e"tra fields ................................................................................................................ !3
7ow the 4ascade f#nctionalit& works? 7ow sho#ld a develoer #se the ;rhanRemoval? 7andling the
org.hi3ernate.2ransient;3ject%"cetion .................................................................................................. !=
;rhanRemoval ................................................................................................................................... $3
7ow to delete an entit& with relationshis. 4larif& which relationshis are raising the e"cetion ......... $!
4reating one %ntit&ManagerAactor& 3& alication ................................................................................ $$
>nderstanding how the 'aB&:%ager otion works ................................................................................... $=
7andling the ?cannot sim#ltaneo#sl& fetch m#ltile 3ags@ error ............................................................ $8
1 of =0
JPA Mini Book www.javacodegeeks.com
Reasons that led to the creation of JPA
One of the problems of Object Orientation is how to map the objects as the database requires. It is possible to have
a class with the name Car but its data is persisted in a table named TB_CAR. The table name is just the beinnin
of the problem! what if the Car class has the attribute "name# but in the database $ou find the column
%TR_&A'(_CAR)
The basic *ava framewor+ to access the database is *,BC. -nfortunatel$! with *,BC! a lot of hand wor+ is needed
to convert a database quer$ result into *ava classes.
In the code snippet bellow we demonstrate how to transform a *,BC quer$ result into Car objects.
import java.sql.*;
import java.util.LinkedList;
import java.util.List;

public class MainWithJDBC {
public static void main(String! args" throws #$%e&ti'n {
Class.('r)ame(*'rg.hsqld+.jd+%Driver*";

C'nne%ti'n %'nne%ti'n , -- get a valid %'nne%ti'n

Statement statement , %'nne%ti'n.%reateStatement(";

.esultSet rs , statement.e$e%ute/uer0(*S#L#C1 2*3d2*4 2*)ame2* 5.6M 2*Car2**";

List7Car8 %ars , new LinkedList7Car8(";

while(rs.ne$t(""{
Car %ar , new Car(";
%ar.set3d(rs.get3nt(*3d*"";
%ar.set)ame(rs.getString(*)ame*"";
%ars.add(%ar";
9

for (Car %ar : %ars" {
S0stem.'ut.&rintln(*Car id: * ; %ar.get3d(" ; * Car )ame: * ; %ar.get)ame("";
9

%'nne%ti'n.%l'se(";
9
9
As $ou can understand there is a lot of boilerplate code involved usin this approach. *ust imaine the Car class
the have not two but thirt$ attributes/ To ma+e thins even worse! imaine a class with 01 attributes and with a
relationship to another class that has 01 attributes also e.. a Car class ma$ maintain a list of 2erson classes
3 of =0
JPA Mini Book www.javacodegeeks.com
representin the drivers of the specific car where the 2erson class ma$ have 01 attributes to be populated.
Other disadvantaes of *,BC is its portabilit$. The quer$ s$nta3 will chane from one database to another. 4or
e3ample with Oracle database the command RO5&-' is used to limit the amount of returned lines! whereas with
%ql%erver the command is TO2.
Application portabilit$ is a problematic issue when database native queries are used. There are several solutions to
this +ind of problem! e.. a separate file with all quer$ code could be stored outside the application deplo$able file.
5ith this approach for each database vendor a sql specific file would be required.
It is possible to find other problems when developin with *,BC li+e. update a database table and its relationships!
do not leave an$ orphans records or an eas$ wa$ to use hierarch$.
What is JPA? What is a JPA Implementation?
*2A was created as a solution to the problems mentioned earlier.
*2A allows us to wor+ with *ava classes as it provides a transparent la$er to each database specific details6 *2A will
do the hard wor+ of mappin table to class structure and semantics for the developer.
An eas$ definition to *2A is. "A roup of specifications 7a lot of te3ts! reulari8ations and *ava Interfaces9 to define
how a *2A implementation should behave#. There are man$ *2A implementations available both free and paid! e..
:ibernate! Open*2A! (clipse;in+ and the "new born# Batoo etc.
'ost *2A implementations are free to add e3tra codes! annotations that are not present in the *2A specification! but
must conform to the *2A specification scemantics.
The main *2A feature to address application portabilit$ is the abilit$ to map database tables into the classes. In the
followin sections we will demonstrate how it is possible to map the column of a table into a *ava class field
reardless of the names of both the batabase column and *ava class field.
*2A created a database lanuae named *2<; to perform database queries. The advantae of *2<; is that the
quer$ can be e3ecuted in all databases.
SELECT id4 name4 %'l'r4 age4 d''rs FROM Car
The quer$ above could be translated to the *2<; below.
! of =0
JPA Mini Book www.javacodegeeks.com
SELECT % FROM Car %
&otice that the result of the quer$ above is "c#! that means! a car object and not the fields=values found in the
database table. *2A will create the object automaticall$.
If $ou want to see several wa$s to run a database query wth |PA cck here.
*2A will be responsible to translate the *2<; quer$ to the database native quer$6 the developer will not need to
worr$ about which is the required sql database s$nta3.
What is the persistence.xml file used for? And its
configurations?
The persistence.3ml file is responsible for all *2A evironment confiuration6 it can hold database! application and
*2A implementation specific confiuration.
In the persistence.3ml code presented here we use the (clipse;in+ *2A implementation specific confiuration! but
the concept and the theor$ applied to the *ava classes in this post can be applied when usin an$ *2A
implementation framewro+ available.
The persistence.3ml file must be located in a '(TA>I&4 folder in the same path as the *ava classes. Below is a
picture that shows where the file should be placed.
This picture is valid when usin (clipse I,(. 4or &etbeans it is necessar$ to chec+ its documentation as of where
the correct place to put the file is.
If $ou ot the error messae. "Could not find an$ '(TA>I&4=persistence.3ml file in the classpath# here are some
tips that $ou can chec+.
Open the generated WAR fe and check f the persstence.xm s ocated at "/WEB-
INF/casses/META-INF/". If the fe s automatcay generated and s not there your error s at the
WAR creaton, you need to put the persstence.xm fe where the IDE expects. If the artfact
$ of =0
JPA Mini Book www.javacodegeeks.com
creaton s done manuay check the creaton scrpt (ant, maven).
If your pro|ect s depoyed wth EAR fe check f the persstence.xm fe s n the E|B |ar root. If
the fe s automatcay generated and s not there your error s at the WAR creaton, you need to
put the persstence.xm fe where the IDE expects. If the artfact creaton s manuay check the
creaton scrpt (ant, maven).
If your pro|ect s a |SE pro|ect (desktop) you shoud check f the fe s not n the foder "META-
INF". As defaut behavor the |PA w search n the |AR root for the foder and fe: "/META-
INF/persstence.xm".
Check f the fe has the name: "persstence.xm". The fe must have the name wth a etters n
owercase.
If *2A cannot find the file the error above will be displa$ed. As a eneral rule! it is a ood practice to put the file as
displa$ed above.
Chec+ below a sample of persistence.3ml.
7<xml versi'n,*=.>* en%'ding,*?15@A*<8

7persistence versi'n,*B.>*
$mlns,*htt&:--java.sun.%'m-$ml-ns-&ersisten%e* $mlns:$si,*htt&:--CCC.CD.'rg-B>>=-EMLS%hema@instan%e*
$si:s%hemaL'%ati'n,*htt&:--java.sun.%'m-$ml-ns-&ersisten%e
htt&:--java.sun.%'m-$ml-ns-&ersisten%e-&ersisten%eFBF>.$sd*8

7persistence-unit name,*M0G?* transa%ti'n@t0&e,*.#S6?.C#FL6CHL*8
7provider8'rg.e%li&se.&ersisten%e.j&a.Gersisten%eGr'vider7-provider8

7class8&ageB>.Gers'n7-class8
7class8&ageB>.Cellular7-class8
7class8&ageB>.Call7-class8
7class8&ageB>.D'g7-class8

7exclude-unlisted-classes8true7-exclude-unlisted-classes8

7properties8
7property name,*java$.&ersisten%e.jd+%.driver* value,*'rg.hsqld+.jd+%Driver* -8
7property name,*java$.&ersisten%e.jd+%.url* value,*jd+%:hsqld+:mem:m0DataBase* -8
7property name,*java$.&ersisten%e.jd+%.user* value,*sa* -8
7property name,*java$.&ersisten%e.jd+%.&assC'rd* value,** -8
7property name,*e%li&selink.ddl@generati'n* value,*%reate@ta+les* -8
7property name,*e%li&selink.l'gging.level* value,*53)#S1* -8
7-properties8
7-persistence-unit8

7persistence-unit name,*G'stgresG?* transa%ti'n@t0&e,*.#S6?.C#FL6CHL*8
7provider8'rg.e%li&se.&ersisten%e.j&a.Gersisten%eGr'vider7-provider8

7class8&ageBI.Car7-class8
7class8&ageBI.D'g7-class8
= of =0
JPA Mini Book www.javacodegeeks.com
7class8&ageBI.Gers'n7-class8

7exclude-unlisted-classes8true7-exclude-unlisted-classes8

7properties8
7property name,*java$.&ersisten%e.jd+%.url* value,*jd+%:&'stgresql:--l'%alh'st-J&a.elati'nshi&s*
-8
7property name,*java$.&ersisten%e.jd+%.driver* value,*'rg.&'stgresql.Driver* -8
7property name,*java$.&ersisten%e.jd+%.user* value,*&'stgres* -8
7property name,*java$.&ersisten%e.jd+%.&assC'rd* value,*&'stgres* -8
7J@@ 7&r'&ert0 name,*e%li&selink.ddl@generati'n* value,*dr'&@and@%reate@ta+les* -8 @@8
7property name,*e%li&selink.ddl@generati'n* value,*%reate@ta+les* -8
7J@@ 7&r'&ert0 name,*e%li&selink.l'gging.level* value,*53)#S1* -8 @@8
7-properties8
7-persistence-unit8
7-persistence8
About the code above.
<persstence-unt name="MyPU" => wth ths confguraton t s possbe to defne the
Persstence Unt name. The Persstence Unt can be understood as the |PA unverse of your
appcaton. It contans nformaton about a casses, reatonshps, keys and others
confguratons a reatng the database to your appcaton. It s possbe to add more than one
Persstence Unt at the same persstence.xm fe as dspayed n the code above.
transacton-type="RESOURCE_LOCAL" => Defne the transacton type. Two vaues are aowed
here: RESOURCE_LOCAL and |TA. For desktop appcatons RESOURCE_LOCAL shoud be use; for
web appcaton both vaues can be used, the correct vaue depends on the appcaton desgn.
<provder>org.ecpse.persstence.|pa.PersstenceProvder</provder> => Defnes the |PA
mpementaton provder. The provder s the appcaton |PA mpementaton. If your appcaton
s usng Hbernate, the provder vaue shoud be "org.hbernate.e|b.HbernatePersstence" and
for Open|PA "org.apache.open|pa.persstence.PersstenceProvderImp".
<cass></cass> => Used to decare the |ava casses. In a |EE/|SE usuay ths s not requred;
e.g. for a Hbernate desktop appcaton there s no need to decare the casses wth ths tags,
but wth EcpseLnk and Open|PA requres the presence of the cass tag.
<excude-unsted-casses>true</excude-unsted-casses> => ths confguratons defnes that
f a cass s not sted n the persstence.xm t shoud not be handed as an entty (we w see
more about entty n the next page) n the Persstence Unt. Ths confguraton s very usefu for
appcatons wth more than one Persstence Unts, where an Entty shoud appear n one
database but not n the other.
It s possbe to comment a code use the tag <!- ->
<propertes> => It s possbe to add specfc |PA mpementatons confguratons. Vaues ke
drver, password and user t s norma to fnd t to a mpementatons; usuay these vaues are
wrtten n the persstence.xm fe for a RESOUCE_LOCAL appcaton. To |TA appcatons the
datasources are used by the contaners. A datasource can be specfed wth the tags <|ta-data-
8 of =0
JPA Mini Book www.javacodegeeks.com
source></|ta-data-source><non-|ta-data-source></non-|ta-data-source>. Some |Boss versons
requre the data source decaraton to be present even f the connecton s oca. Two
confguratons are worth mentonng:
Configurations Implementation Used for
ecpsenk.dd-generaton EcpseLnk W actvate the automatcay
database tabe creaton, or
|ust vadate the database
schema aganst the |PA
confguraton.
hbernate.hbm2dd.auto Hbernate
open|pa.|dbc.SynchronzeMappngs Open|PA
ecpsenk.oggng.eve EcpseLnk W defne the LOG eve of
the |PA mpementaton.
org.hbernate.SOL.eve=FINEST
org.hbernate.type.eve=FINEST
Hbernate
open|pa.Log Open|PA
On the nternet you w fnd the aowed vaues to each mpementaton.
Entity definitions. What are the Logic and Physical
annotations?
4or *2A to correctl$ map database tables into *ava classes the concept of (ntit$ was created. An (ntit$ must be
created to support the same database table structure6 thus *2A handles table data modification throuh an entit$.
4or a *ava class to be considerate an (ntit$ it must follow the rules below.
To be annotated wth @Entty
A pubc constructor wthout arguments
The |ava cass w need to have a fed wth the @Id annotaton
The class below follows all the requirements to be considerate an entit$.
import java$.&ersisten%e.#ntit0;
import java$.&ersisten%e.3d;

K#ntit0
public class Car {

( of =0
JPA Mini Book www.javacodegeeks.com
public Car("{

9

public Car(int id"{
this.id , id;
9

-- Just t' sh'C that there is n' need t' have get-set Chen Ce talk a+'ut JGH 3d
K3d
private int id;

private String name;

public String get)ame(" {
return name;
9

public void set)ame(String name" {
this.name , name;
9
9
About the code above.
The cass has the annotaton @Entty above ts name
There s an attrbute consdered the d of the cass that s annotated wth @Id. Every entity must
have an id. Usuay ths fed s a sequenta nteger fed, but t can be a Strng or other aowed
vaues
Notce that there s no get/set for the d attrbute. For |PA s concdered that an entty's d s
mmutabe, so there s no need to edt the d vaue.
The presence of a pubc constructor wthout arguments s mandatory. Other constructors may
be added
As shown in the code snippet above we onl$ used two annotations! one to define an entit$ and another to declare
the ?id? field6 b$ default *2A will loo+ for a table named CAR in the database with columns named I, and &A'(. B$
default *2A will use the class name and the class attribute names to find the tables and its structures.
Accordin to the boo+ "2ro *2A @# we can define the *2A annotations in two wa$s. ;oical annotations and 2h$sical
annotations. The ph$sical annotations will map the confiuration of the database into the class. The loical
annotations will define the application modelin. Chec+ the code below.
import java.util.List;

import java$.&ersisten%e.*;

K#ntit0
K1a+le(name , *1BFG#.S6)F>BADL*"
9 of =0
JPA Mini Book www.javacodegeeks.com
public class Gers'n {

K3d
KMeneratedNalue(strateg0 , Menerati'n10&e.H?16"
private int id;

KBasi%((et%h , 5et%h10&e.LHOP"
KC'lumn(name , *G#.S6)F)HM#*4 length , =>>4 unique , true4 nulla+le , false"
private String name;

K6ne1'Man0
private List7Car8 %ars;

public String get)ame(" {
return name;
9

public void set)ame(String name" {
this.name , name;
9
9
In the code snippet above the followin annotations are shown. A(ntit$! AId and AOneTo'an$ 7we will see about
this annotation later96 these are considered loical annotations. &otice that these annotations do not define
an$thin related to database! but define how a *ava class will behave as an (ntit$.
Additionall$ in the code above we demonstrate another set of annotations. ATable! AColumn and ABasic. These
annotations will create the relationship between the database table and the entit$. It is possible to define the table
name! column name and other information reardin the database. This +ind of annotations are +nown as 2h$sical
annotations! it is their job to "connect# the database to the *2A code.
Its out of the scope of this mini boo+ to present ever$ annotation supported b$ *2A! but it is ver$ eas$ to find this
information on the internet6 e... @Column(name = PERSON_NAME len!th = "## uni$ue = true nulla%le = &alse'.
The ph$sical annotations are the easier to understand because it loo+s li+e database confiuration.
Id Generation !efinition" using Identity or #e$uence
As said in previous chapters! ever$ entit$ must have an id. *2A has the option to automaticall$ enerate the entit$
id.
There are three options for automatic id eneration.
Identty
Sequence
TabeGenerator
/0 of =0
JPA Mini Book www.javacodegeeks.com
5e must have in mind that ever$ database has its own id eneration mechanism. Oracle and 2ostres databases
use the %equence approach! %ql%erver and '$%<; use the Identit$ approach. It is not possible to use an id
eneration approach in a server when the server does not support it.
The followin *ava t$pes are allowed to be used for an id attribute. b$te=B$te! int=Inteer! short=%hort! lon=;on!
char=Character! %trin! BiInteer! java.util.,ate and java.sql.,ate.
Identity
This is the simplest id eneration approach. *ust annotate the id field li+e below.
import java$.&ersisten%e.#ntit0;
import java$.&ersisten%e.MeneratedNalue;
import java$.&ersisten%e.Menerati'n10&e;
import java$.&ersisten%e.3d;

K#ntit0
public class Gers'n {

K3d
KMeneratedNalue(strateg0 , Menerati'n10&e.3D#)131P"
private int id;

private String name;

public String get)ame(" {
return name;
9

public void set)ame(String name" {
this.name , name;
9
9
The database controls the I, eneration! *2A does not act on the id at all. Thus in order to retrieve the id from the
databse an entit$ needs to be persisted first! and after the transaction commits! a quer$ is e3ecuted so as to
retrieve the enerated id for the specific entit$. This procedure leads to a small performance deradation! but not
somethin troublesome.
The aforementioned id eneration approach does not allow allocatin ids in memor$. 5e will e3amine what this ids
allocation means in the followin chapters.
// of =0
JPA Mini Book www.javacodegeeks.com
#e$uence
The %equence approach can be confiured li+e below.
import java$.&ersisten%e.#ntit0;
import java$.&ersisten%e.MeneratedNalue;
import java$.&ersisten%e.Menerati'n10&e;
import java$.&ersisten%e.3d;
import java$.&ersisten%e.Sequen%eMenerat'r;

K#ntit0
KSequen%eMenerat'r(name , Car.CH.FS#/?#)C#F)HM#4 sequen%e)ame , Car.CH.FS#/?#)C#F)HM#4 initialNalue , =>4
all'%ati'nSiQe , RD"
public class Car {

public static final String CH.FS#/?#)C#F)HM# , *CH.FS#/?#)C#F3D*;

K3d
KMeneratedNalue(strateg0 , Menerati'n10&e.S#/?#)C#4 generat'r , CH.FS#/?#)C#F)HM#"
private int id;

private String name;

public String get)ame(" {
return name;
9

public void set)ame(String name" {
this.name , name;
9
9
About the code above.
The @SequenceGenerator annotaton w defne that there w be a sequence n the database
wth the specfed name (sequenceName attrbute). The same sequence coud be shared
between enttes but s not recomended. If we use the Car sequence n the House entty, the d
vaues n the tabes woud not be sequenta; when the frst car s perssted the d woud be 1, f
another car s perssted the d woud be 2; when the frst house s perssted ts d woud be 3,
ths w happen f the House entty uses the same sequence as the Car entty.
The attrbute "name = Car.CAR_SEOUENCE_NAME" defnes the name of the sequence nsde the
appcaton. Sequence decaraton shoud be done ony once. A Enttes that w use the same
sequence w |ust have to use the specfc sequence name. That s why we assgn the sequence
name vaue to a statc attrbute at the specfc entty.
The vaue "sequenceName = Car.CAR_SEOUENCE_NAME" refects the sequence name at the
database eve.
The "ntaVaue = 10" defnes the frst d vaue of the sequence. A deveoper must be cautous
/1 of =0
JPA Mini Book www.javacodegeeks.com
wth ths confguraton; f after nsertng the frst row the appcaton s restarted, |PA w try to
nsert a new entty wth the same vaue defned n the ntaVaue attrbute. An error message
w be dspayed ndcatng that the d s aready n use.
"aocatonSze = 53" represents the amount of ds that |PA w store n cache. Works ke ths:
when the appcaton s started |PA w aocate n memory the specfed number of ds and w
share these vaues to each new perssted entty. In the code above, the ds woud go from 10
(ntaVaue) up to 63 (ntaVaue + aocatonSze). When the number of aocated ds ends |PA
w request from the database and aocate n memory 53 more ds. Ths act of aocatng ds nto
memory s a good approach to optmze server memory, snce |PA w not need to trgger the
database wth every nsert so as to get the created d |ust ke wth the @Identty approach.
The @GeneratedVaue(strategy = GeneratonType.SEOUENCE, generator =
CAR_SEOUENCE_NAME) annotaton defnes that the generaton type as SEOUENCE and the name
of the generator.
Id Generation %a&leGenerator and Auto
%a&leGenerator
The te3t below describes how the TableBenerator wor+s.
A tabe s used to store the d vaues
Ths tabe has a coumn that w store the tabe name and the actua d vaue
So far, ths s the ony Generaton ID approach that aows database portabty, wthout the
need of aterng the d generaton approach. Imagne an appcaton that s runnng wth Postgres
and uses a Sequence. If we were to use the same appcaton wth SqServer too we woud have
to create two dstnct artfacts (WAR/|AR/EAR) of t, one for each database - snce SqServer doen
not support Sequences. Wth the TabeGenerator approach the same artfact can be used for
both databases.
Chec+ the code below to see how the TableBenerator approach can be used.
import java$.&ersisten%e.*;

K#ntit0
public class Gers'n {

K3d
K1a+leMenerat'r(name,*1HBL#FM#)#.H16.*4 ta+le,*3DF1HBL#*4 &kC'lumn)ame,*3DF1HBL#F)HM#*4
&kC'lumnNalue,*G#.S6)F3D*4 valueC'lumn)ame,*3DF1HBL#FNHL?#*"
KMeneratedNalue(strateg0 , Menerati'n10&e.1HBL#4 generat'r,*1HBL#FM#)#.H16.*"
/3 of =0
JPA Mini Book www.javacodegeeks.com
private int id;

private String name;

public String get)ame(" {
return name;
9

public void set)ame(String name" {
this.name , name;
9
9
The code above will use the table in the imae below 7it is possible to confiure *2A to create the specific table
automaticall$! just add the needed confiuration as presented in the section about persistence.3ml9.
About the code above.
?name" => Is the TabeGenerator d nsde the appcaton.
?tabe" => Name of the tabe that w hod the vaues.
?pkCoumnName" => Coumn name that w hod the d name. In the code above the coumn
name "d_tabe_name" w be used.
?vaueCoumnName" => Coumn name that w hod the d vaue.
?pkCoumnVaue" => Tabe name that w persst n the tabe. The defaut vaue s the entty
name + d (entty attrbute defned as d). In the code above w be PERSON_ID that s the same
vaue descrbed above.
ntaVaue, aocatonSze => These optons can be used n the @TabeGenerator annotaton
aso. Check the Sequence approach secton above to see how they shoud be used.
It s possbe to decare TabeGenerator across dfferent enttes wthout the probem of oosng
sequenced ds (ke the Sequence probem that we saw earyer).
The best practice to use the table enerator declartion is in an orm.3ml file. This file is used to override *2A
confiuration throuh annotations and is out of the scope of this mini boo+.
/! of =0
JPA Mini Book www.javacodegeeks.com
Auto
The Auto approach 7automaticall$9 allows *2A to choose an approach to use. This is the default value and can be
used li+e below.
K3d
KMeneratedNalue(strateg0 , Menerati'n10&e.H?16" -- 'r just KMeneratedNalue
private int id;
5ith the Auto approach an$ strate$ can be used b$ *2A. *2A will choose between the 0 approaches discussed
earl$er.
#imple 'omposite (ey
A simple +e$ is when the id uses just one field. A simple +e$ is used li+e below.
A composite +e$ is needed when more than one attribute is required as an entit$ id. It is possible to find simple
composite +e$ and comple3 composite +e$. 5ith a %imple composite +e$ use onl$ plain *ava attributes for the id
7e. %trin! int! /9. In the followin sections we will disquas all about comple3 composite +e$ semantics.
There are two wa$s to map a simple composite +e$! with AIdClass or A(mbeddedId.
)Id'lass
Chec+ the code below.
import java$.&ersisten%e.*;

K#ntit0
K3dClass(Car3d.class"
public class Car {

K3d
private int serial;

K3d
private String +rand;

/$ of =0
JPA Mini Book www.javacodegeeks.com
private String name;

public String get)ame(" {
return name;
9

public void set)ame(String name" {
this.name , name;
9

public int getSerial(" {
return serial;
9

public void setSerial(int serial" {
this.serial , serial;
9

public String getBrand(" {
return +rand;
9

public void setBrand(String +rand" {
this.+rand , +rand;
9
9
About the code above6
@IdCass(CarId.cass) => ths annotaton ndcates that the CarId has nsde of t the d
attrbutes found n the Car entty.
A feds annotated wth @Id must be found n the IdCass.
It s possbe to use the @GeneratedVaue annotaton wth ths knd of composte key. For
exampe n the code above t woud be possbe to use the @GeneratedVaue wth the "sera"
attrbute.
Chec+ below the CarId class code.
import java.i'.SerialiQa+le;

public class Car3d implements SerialiQa+le{

private static final lon serialNersi'n?3D , DSDL;

private int serial;
private String +rand;

-- must have a de(ault %'nstru%'t
public Car3d(" {

9

/= of =0
JPA Mini Book www.javacodegeeks.com
public Car3d(int serial4 String +rand" {
this.serial , serial;
this.+rand , +rand;
9

public int getSerial(" {
return serial;
9

public String getBrand(" {
return +rand;
9

-- Must have a hashC'de meth'd
K6verride
public int hashC'de(" {
return serial ; +rand.hashC'de(";
9

-- Must have an equals meth'd
K6verride
public boolean equals(6+je%t '+j" {
if ('+j instanceof Car3d" {
Car3d %ar3d , (Car3d" '+j;
return %ar3d.serial ,, this.serial TT %ar3d.+rand.equals(this.+rand";
9

return false;
9
9
The class CarId has the fields listed as AId in the Car entit$.
To use a class as I, it must follow the rules below.
A pubc constructor wth no arguments must be found
Impements the Serazabe nterface
Overwrte the hashCode/equas method
To do a quer$ aainst a database to find an entit$ iven a simple composite +e$ just do li+e below.
#ntit0Manager em , -- get valid entit0 manager

Car3d %ar3d , new Car3d(DD4 *5'rd*";

Car &ersistedCar , em.(ind(Car.class4 %ar3d";

S0stem.'ut.&rintln(&ersistedCar.get)ame(" ; * @ * ; &ersistedCar.getSerial("";
To use the find method it is necessar$ to provide the id class with the required information.
/8 of =0
JPA Mini Book www.javacodegeeks.com
)Em&edda&le
The other approach to use the composite +e$ is presented below.
import java$.&ersisten%e.*;

K#ntit0
public class Car {

K#m+edded3d
private Car3d %ar3d;

private String name;

public String get)ame(" {
return name;
9

public void set)ame(String name" {
this.name , name;
9

public Car3d getCar3d(" {
return %ar3d;
9

public void setCar3d(Car3d %ar3d" {
this.%ar3d , %ar3d;
9
9
About the code above.
The d cass was wrtten nsde the Car cass.
The @EmbeddedId s used to defne the cass as an d cass.
There s no need to use the @Id annotaton anymore.
The class id will be li+e below.
import java.i'.SerialiQa+le;

import java$.&ersisten%e.#m+edda+le;

K#m+edda+le
public class Car3d implements SerialiQa+le{

private static final lon serialNersi'n?3D , DSDL;

private int serial;
private String +rand;

/( of =0
JPA Mini Book www.javacodegeeks.com
-- must have a de(ault %'nstru%'t
public Car3d(" {

9

public Car3d(int serial4 String +rand" {
this.serial , serial;
this.+rand , +rand;
9

public int getSerial(" {
return serial;
9

public String getBrand(" {
return +rand;
9

-- Must have a hashC'de meth'd
K6verride
public int hashC'de(" {
return serial ; +rand.hashC'de(";
9

-- Must have an equals meth'd
K6verride
public boolean equals(6+je%t '+j" {
if ('+j instanceof Car3d" {
Car3d %ar3d , (Car3d" '+j;
return %ar3d.serial ,, this.serial TT %ar3d.+rand.equals(this.+rand";
9

return false;
9
9
About the code above.
The @Embeddabe annotaton aows the cass to be used as d.
The feds nsde the cass w be used as ds.
To use a class as I, it must follow the rules below.
A pubc constructor wth no arguments must be found
Impements the Serazabe nterface
Overwrte the hashCode/equas method
It is possible to do queries with this +ind of composite +e$ just li+e the AIdClass presented above.
/9 of =0
JPA Mini Book www.javacodegeeks.com
'omplex 'omposite (ey
A comple3 composite +e$ is composed of other entities C not plain *ava attributes.
Imaine an entit$ ,o:ouse where it uses the ,o as the id. Ta+e a loo+ at the code below.
import java$.&ersisten%e.*;

K#ntit0
public class D'g {
K3d
private int id;

private String name;

public int get3d(" {
return id;
9

public void set3d(int id" {
this.id , id;
9

public String get)ame(" {
return name;
9

public void set)ame(String name" {
this.name , name;
9
9
import java$.&ersisten%e.*;

K#ntit0
public class D'gU'use {

K3d
K6ne1'6ne
KJ'inC'lumn(name , *D6MF3D*"
private D'g d'g;

private String +rand;

public D'g getD'g(" {
return d'g;
9

public void setD'g(D'g d'g" {
this.d'g , d'g;
9

public String getBrand(" {
10 of =0
JPA Mini Book www.javacodegeeks.com
return +rand;
9

public void setBrand(String +rand" {
this.+rand , +rand;
9
9
About the code above.
The @Id annotaton s used n the entty DogHouse to nform |PA that the DogHouse w have
the same d as the Dog.
We can combne the @Id annotaton wth the @OneToOne annotaton to dctate that there s an
expct reatonshp between the casses. More nformaton about the @OneToOne annotaton
w be avaabe ater on.
Imaine a scenario where it is required to access the ,o:ouse id without passin throuh the class ,o
7do:ouse.et,o79.etId799. *2A has a wa$ of doin it without the need of the Demeter Law pattern.
import java$.&ersisten%e.*;

K#ntit0
public class D'gU'useB {

K3d
private int d'g3d;

KMa&s3d
K6ne1'6ne
KJ'inC'lumn(name , *D6MF3D*"
private D'g d'g;

private String +rand;

public D'g getD'g(" {
return d'g;
9

public void setD'g(D'g d'g" {
this.d'g , d'g;
9

public String getBrand(" {
return +rand;
9

public void setBrand(String +rand" {
this.+rand , +rand;
9

public int getD'g3d(" {
return d'g3d;
1/ of =0
JPA Mini Book www.javacodegeeks.com
9

public void setD'g3d(int d'g3d" {
this.d'g3d , d'g3d;
9
9
About the code above.
There s an expct fed mapped wth @Id.
The Dog entty s mapped wth the @MapsId annotaton. Ths annotaton ndcates that |PA w
use the Dog.Id as the DogHouse.DogId (|ust ke before); the dogId attrbute w have the same
vaue as the dog.getId() and ths vaue w be attrbuted at run tme.
dogId fed does not need to be expctey mapped to a database tabe coumn. When the
appcaton starts |PA w attrbute the dog.getId() to the dogId attrbute.
To finish this subject! let us see one more topic. :ow can we map an entit$ id with more than one entities)
Chec+ the code below.
import java$.&ersisten%e.*;

K#ntit0
K3dClass(D'gU'use3d.class"
public class D'gU'use {

K3d
K6ne1'6ne
KJ'inC'lumn(name , *D6MF3D*"
private D'g d'g;

K3d
K6ne1'6ne
KJ'inC'lumn(name , *G#.S6)F3D*"
private Gers'n &ers'n;

private String +rand;

-- get and set
9
About the code above.
Notce that both enttes (Dog and Person) were annotated wth @Id.
The annotaton @IdCass s used to ndcate the need of a cass to map the d.
import java.i'.SerialiQa+le;

public class D'gU'use3d implements SerialiQa+le{
11 of =0
JPA Mini Book www.javacodegeeks.com

private static final lon serialNersi'n?3D , =L;

private int &ers'n;
private int d'g;

public int getGers'n(" {
return &ers'n;
9

public void setGers'n(int &ers'n" {
this.&ers'n , &ers'n;
9

public int getD'g(" {
return d'g;
9

public void setD'g(int d'g" {
this.d'g , d'g;
9

K6verride
public int hashC'de(" {
return &ers'n ; d'g;
9

K6verride
public boolean equals(6+je%t '+j" {
if('+j instanceof D'gU'use3d"{
D'gU'use3d d'gU'use3d , (D'gU'use3d" '+j;
return d'gU'use3d.d'g ,, d'g TT d'gU'use3d.&ers'n ,, &ers'n;
9

return false;
9
9
About the code above.
The cass has the same amount of attrbutes as the number of attrbutes n the cass DogHouse
annotated wth @Id
Notce that the attrbutes nsde the DogHouseId have the same name as the attrbutes nsde
the DogHouse annotated wth @Id. Ths s mandatory for |PA to correcty utze d functonaty.
For exampe If we named the Person type attrbute nsde the DogHouse cass as
"dogHousePerson" the name of the Person type attrbute nsde the DogHouseId cass woud
have to change aso to "dogHousePerson".
To use a class as I, it must follow the rules below.
A pubc constructor wth no arguments must be found
13 of =0
JPA Mini Book www.javacodegeeks.com
Impements the Serazabe nterface
Overwrte the hashCode/equas method
*o+ to get an Entity,anager
There are two wa$s to et an (ntit$'anaer. One is with injection and the other throuh a factor$.
The easiest wa$ to et an (ntit$'anaer is with injection! the container will inject the (ntit$'anaer. Below is how
the injection code wor+s.
KGersisten%eC'nte$t(unit)ame , *G#.S3S1#)C#F?)31FMHGG#DF3)F1U#FG#.S3S1#)C#FEML*"
private #ntit0Manager entit0Manager;
It is needed to annotate the (ntit$'anaer field with. "A2ersistenceConte3t7unit&ame D
"2(R%I%T(&C(_-&IT_'A22(,_I&_T:(_2(R%I%T(&C(_E';#9#. The injection option will onl$ wor+ for *((
applications! runnin inside applications servers li+e *Boss! Blassfish/ To achieve the injection without problems
the persistence.3ml must be in the riht place! and must have 7if needed9 a datasource defined.
The (ntit$'anaer injection! until toda$! will wor+ onl$ with a server that supports an (*B container. Tomcat and
other 5(B=%ervlet onl$ containers will not inject it.
5hen the application is a *%( 7des+top9 application or when a web application wants to handle the database
connection manuall$ just use the code bellow.
#ntit0Manager5a%t'r0 em( ,
Gersisten%e.%reate#ntit0Manager5a%t'r0(*G#.S3S1#)C#F?)31FMHGG#DF3)F1U#FG#.S3S1#)C#FEML*";
#ntit0Manager entit0Manager , em(.%reate#ntit0Manager(";

entit0Manager.get1ransa%ti'n(".+egin(";

-- d' s'mething

entit0Manager.get1ransa%ti'n(".%'mmit(";
entit0Manager.%l'se(";
&otice that it is required to et an instance of the (ntit$'anaer4actor$ first! which will be lin+ed to a
2ersistence-nit created in the persistence.3ml file. Throuh the (ntit$'anaer4actor$ is possible to et an
instance of the (ntit$'anaer.
1! of =0
JPA Mini Book www.javacodegeeks.com
,apping t+o or more ta&les in one entity
A class ma$ have information in more than one table.
To map an (ntit$ that has its data in more than one table! just do li+e below.
import java$.&ersisten%e.*;

K#ntit0
K1a+le(name,*D6M*"
KSe%'ndar01a+les({
KSe%'ndar01a+le(name,*D6MFS#C6)DH.PFH*4 &kJ'inC'lumns,{KGrimar0Ve0J'inC'lumn(name,*D6MF3D*"9"4
KSe%'ndar01a+le(name,*D6MFS#C6)DH.PFB*4 &kJ'inC'lumns,{KGrimar0Ve0J'inC'lumn(name,*D6MF3D*"9"
9"
public class D'g {
K3d
KMeneratedNalue(strateg0 , Menerati'n10&e.H?16"
private int id;

private String name;
private int age;
private double Ceight;

-- get and set

9
About the code above.
The annotaton @SecundaryTabe s used to ndcate at whch tabe the Entty data can be
found. If the data s found n |ust one secondary tabe |ust the @SecundaryTabe annotaton s
enough.
The annotaton @SecundaryTabes s used to group up severa tabes n one cass. It groups
severa @SecundaryTabe annotatons.
,apping *ierarchy ,apped#uperclass
%ometimes is needed to share methods=attributes between classes6 thus create a class hierarch$. In case the super
class C the one with the shared methods=attributes > is not an entit$! it is required to be mar+ed as
'apped%uperclass.
Chec+ below how the 'apped%uperclass concept can be applied.
import java$.&ersisten%e.Ma&&edSu&er%lass;

KMa&&edSu&er%lass
1$ of =0
JPA Mini Book www.javacodegeeks.com
public abstract class D'g5ather {
private String name;

public String get)ame(" {
return name;
9

public void set)ame(String name" {
this.name , name;
9

9
K#ntit0
K1a+le(name , *D6M*"
public class D'g extends D'g5ather {

K3d
KMeneratedNalue(strateg0 , Menerati'n10&e.H?16"
private int id;

private String %'l'r;

public int get3d(" {
return id;
9

public void set3d(int id" {
this.id , id;
9

public String getC'l'r(" {
return %'l'r;
9

public void setC'l'r(String %'l'r" {
this.%'l'r , %'l'r;
9
9
About the code above.
The DogFather cass s annotated wth the @MappedSupercass annotaton. Wth ths annotaton
a DogFather chd casses w have ts attrbutes perssted n the database, but DogFather w
not be mapped to a database tabe.
A MappedSupercass can be an abstract or a concrete cass.
The Dog cass has the ID generator, ony Dog s an entty. DogFather s not an entty.
%ome recommendations about 'apped%uperclass.
A MappedSupercass cannot be annotated wth @Entty\@Tabe. It s not a cass that w be
1= of =0
JPA Mini Book www.javacodegeeks.com
perssted. Its attrbutes/methods w be refected n ts chd casses.
It s aways a good practce to create t as abstract. A MappedSupercass w not be used n the
queres.
Cannot be perssted, t s not an entty.
5hen do we use it)
If we do not need to use the super class in database queries! it would be a ood idea to use a 'apped%uperclass.
In the opposite case it is a ood idea to use (ntit$ hierarch$ 7see the followin sections for details9.
,apping *ierarchy #ingle %a&le
5ith *2A it is possible to find different approaches for persistin class hierarchies. In an Object Orientated lanuae
li+e *ava it is ver$ eas$ to find hierarch$ between classes that will have their data persisted.
The %inle Table strate$ will store all hierarch$ data into one table. Chec+ the code below.
import java$.&ersisten%e.*;

K#ntit0
K1a+le(name , *D6M*"
K3nheritan%e(strateg0 , 3nheritan%e10&e.S3)ML#F1HBL#"
KDis%riminat'rC'lumn(name , *D6MFCLHSSF)HM#*"
public abstract class D'g {
K3d
KMeneratedNalue(strateg0 , Menerati'n10&e.H?16"
private int id;

private String name;

-- get and set
9
import java$.&ersisten%e.#ntit0;

K#ntit0
KDis%riminat'rNalue(*SMHLLFD6M*"
public class SmallD'g extends D'g {
private String littleBark;

public String getLittleBark(" {
return littleBark;
9

public void setLittleBark(String littleBark" {
this.littleBark , littleBark;
9
18 of =0
JPA Mini Book www.javacodegeeks.com
9
import java$.&ersisten%e.*;

K#ntit0
KDis%riminat'rNalue(*U?M#FD6M*"
public class UugeD'g extends D'g {
private int hugeG''Weight;

public int getUugeG''Weight(" {
return hugeG''Weight;
9

public void setUugeG''Weight(int hugeG''Weight" {
this.hugeG''Weight , hugeG''Weight;
9
9
About the code above.
@Inhertance(strategy = InhertanceType.SINGLE_TABLE) => ths annotaton shoud be paced
n the hghest pace of the herarchy (the "father" cass), aso known as "root". Ths annotaton
w defne the herarch pattern to be foowed, n the annotaton above the herarchy mappng
strategy s set to Snge Tabe.
@DscrmnatorCoumn(name = "DOG_CLASS_NAME") => w defne the name of the coumn
that w nk a database tabe row to a cass. Check n the mage beow how the data s stored.
@DscrmnatorVaue => W set the vaue to be perssted n the coumn defned n the
annotaton @DscrmnatorCoumn. Check n the mage beow how the data s stored.
Notce that the d s ony defned n the root cass. It s not aowed to a chd cass to decare an
d.
It is also possible to define the class discriminator column as inteer.
@DscrmnatorCoumn(name = "DOG_CLASS_NAME", dscrmnatorType =
DscrmnatorType.INTEGER) => defne the fed as nteger
1( of =0
JPA Mini Book www.javacodegeeks.com
@DscrmnatorVaue("1) => The vaue to be perssted n the Entty must change, a number
w be perssted nstead a text.
,apping *ierarchy Joined
5hen a hierarch$ is usin the *oined strate$ each entit$ will have its data stored in the respective table. Instead of
usin just one table for all hierarch$ classes! each entit$ will have its own table.
Chec+ the code below to see how *oined strate$ can be used.
import java$.&ersisten%e.*;

K#ntit0
K1a+le(name , *D6M*"
K3nheritan%e(strateg0 , 3nheritan%e10&e.J63)#D"
KDis%riminat'rC'lumn(name , *D6MFCLHSSF)HM#*"
public abstract class D'g {

K3d
KMeneratedNalue(strateg0 , Menerati'n10&e.H?16"
private int id;

private String name;

-- get and set
9
import java$.&ersisten%e.*;

K#ntit0
KDis%riminat'rNalue(*U?M#FD6M*"
public class UugeD'g extends D'g {
private int hugeG''Weight;

public int getUugeG''Weight(" {
return hugeG''Weight;
9
public void setUugeG''Weight(int hugeG''Weight" {
this.hugeG''Weight , hugeG''Weight;
9
9
import java$.&ersisten%e.*;

K#ntit0
KDis%riminat'rNalue(*SMHLLFD6M*"
public class SmallD'g extends D'g {
private String littleBark;

19 of =0
JPA Mini Book www.javacodegeeks.com
public String getLittleBark(" {
return littleBark;
9

public void setLittleBark(String littleBark" {
this.littleBark , littleBark;
9
9
About the code above.
The annotaton @Inhertance(strategy = InhertanceType.|OINED) now has the |oned vaue.
Check beow how the tabes are:
,o table
:ue,o table
%mall,o table
30 of =0
JPA Mini Book www.javacodegeeks.com
&otice in the imaes above how the data is persisted to each table. (ver$ entit$ has its information persisted
across unique tables6 for this strate$ *2A will use one table per entit$ reardlessthe entit$ bein concrete or
abstract.
The ,o table maintains all data common to all the classes of the hierarch$6 The ,o table maintains a column
indicatin to which entit$ a row belons to.
,apping *ierarchy %a&le per 'oncrete 'lass
The Table 2er Concrete strate$ will create a table per concrete entit$. If an abstract entit$ is found in the hierarch$
this data will be persisted in the concrete children entities database tables.
Chec+ the code below.
import java$.&ersisten%e.*;

K#ntit0
K1a+le(name , *D6M*"
K3nheritan%e(strateg0 , 3nheritan%e10&e.1HBL#FG#.FCLHSS"
public abstract class D'g {

K3d
KMeneratedNalue(strateg0 , Menerati'n10&e.H?16"
private int id;

private String name;

-- get and set
9
import java$.&ersisten%e.#ntit0;

K#ntit0
public class UugeD'g extends D'g {
private int hugeG''Weight;

public int getUugeG''Weight(" {
return hugeG''Weight;
9

public void setUugeG''Weight(int hugeG''Weight" {
this.hugeG''Weight , hugeG''Weight;
9
9
import java$.&ersisten%e.#ntit0;

K#ntit0
3/ of =0
JPA Mini Book www.javacodegeeks.com
public class SmallD'g extends D'g {
private String littleBark;

public String getLittleBark(" {
return littleBark;
9

public void setLittleBark(String littleBark" {
this.littleBark , littleBark;
9
9
About the code above.
@Inhertance(strategy = InhertanceType.TABLE_PER_CLASS) => defne the herarchy type as
tabe per cass.
The annotaton @DscrmnatorCoumn(name = "DOG_CLASS_NAME") s not used n the chdren
casses anymore. Each concrete cass w have ts own data, |PA w not spread entty data
across tabes.
There s no need for the annotaton @DscrmnatorVaue for the same prncpa as above.
Check beow the database tabes:
:ue,o Table
%mall,o Table
&otice that the attributes of the ,o entit$ are persisted in the :ue,o and %mall,o table.
31 of =0
JPA Mini Book www.javacodegeeks.com
Pros-'ons of each hierarchy mapping approach
-nfortunatel$ there is no ?better? approach to follow! each approach has its advantaes and disadvantaes. It is
necessar$ to anal$8e the pros=cons of each approach and decide which is better for the application.
Approach Pros Cons
SINGLE_TABLE
Easer to understand the
tabe mode. |ust one tabe s
requred.
Cannot have "non nu" feds.
Imagne that SmaDog has
the harCoor attrbute non
nu n the database. When
HugeDog get perssted an
error message from the
database w be receve, t
w nform that harCoor
cannot be nu.
The enttes attrbutes can be
found a n one tabe.
As genera rue has a good
performance.
|OINED
Each entty w have ts own
database tabe to store the
data.
The nsert has a hgher
performance cost. An nsert
w be done to each database
tabe used n the herarchy.
Imagne a herarchy ke C
extends B extends A, when C
s perssted 3 nserts w be
executed - one to each
mapped entty.
It w foow the OO patterns
apped n the appcaton
code.
The |on number executed n
the database queres w
ncrease n deeper
herarches.
TABLE_PER_CLASS
When the query s executed
to brng |ust one entty the
performance s better. A
database tabe w have ony
one entty data.
Coumns w be repeated.
The attrbutes found n the
abstract enttes w repeated
n the concrete chd enttes.
When a query brngs more
than one entty of the
herarchy ths query w have
a hgher cost. It w be used
UNION or one query per
tabe.
33 of =0
JPA Mini Book www.javacodegeeks.com
Em&edded .&/ects
(mbedded Objects is a wa$ to orani8e entities that have different data in the same table. Imaine a database
table that maintains ?person? information 7e.. name! ae9 and address data 7street name! house number! cit$ etc9.
Chec+ the picture below.
It is possible to see data related to a person and their correspondin address also. Chec+ the code below to see an
e3ample of how to implement the (mbedded Objects concept with the 2erson and Address entities.
import java$.&ersisten%e.*;

K#m+edda+le
public class Hddress {
KC'lumn(name , *h'useFaddress*"
private String address;

KC'lumn(name , *h'useF%'l'r*"
private String %'l'r;

KC'lumn(name , *h'useFnum+er*"
private int num+er;

public String getHddress(" {
return address;
9

public void setHddress(String address" {
this.address , address;
9

-- get and set
9
import java$.&ersisten%e.*;

K#ntit0
K1a+le(name , *&ers'n*"
public class Gers'n {

K3d
private int id;
private String name;
private int age;
3! of =0
JPA Mini Book www.javacodegeeks.com

K#m+edded
private Hddress address;

public Hddress getHddress(" {
return address;
9

public void setHddress(Hddress address" {
this.address , address;
9

-- get and set
9
About the code above.
The @Embeddabe annotaton (Address cass) aows the cass to be used nsde an entty,
notce that Address s not an entty. It s |ust a cass to hep organze the database data.
A @Coumn annotaton s used n the Address cass to ndcate the tabe database coumn
name.
The @Embedded annotaton (Person entty) ndcates that |PA w map a the feds that are
nsde the Address cass as beongng to the Person entty.
The Address cass can be used n other enttes. There are ways to overrde the @Coumn
annotaton at runtme.
Element'ollection 0 ho+ to map a list of 1alues into a
class
%ometimes it is needed to map a list of values to an entit$ but those values are not entities themselves! e.. person
has emails! do has nic+names etc.
Chec+ the code below that demonstrates this situation.
import java.util.List;
import java.util.Set;

import java$.&ersisten%e.*;

K#ntit0
K1a+le(name , *&ers'n*"
public class Gers'n {

K3d
KMeneratedNalue
private int id;
3$ of =0
JPA Mini Book www.javacodegeeks.com
private String name;

K#lementC'lle%ti'n
KC'lle%ti'n1a+le(name , *&ers'nFhasFemails*"
private Set7String8 emails;

K#lementC'lle%ti'n(targetClass , CarBrands.class"
K#numerated(#num10&e.S1.3)M"
private List7CarBrands8 +rands;

-- get and set
9
public enum CarBrands {
56.D4 53H14 S?O?V3
9
About the code above.
Notce that two sts of data are used: Set<Strng>, Lst<CarBrand>. The @EementCoecton
annotaton s used not wth enttes but wth "smpe" attrbutes (e.g. Strng, Enum etc).
The @EementCoecton annotato s used to aow an attrbute to repeat tsef severa tmes.
The @Enumerated(EnumType.STRING) annotaton s used wth the @EementCoecton
annotaton. It defnes how the enum w be perssted n the database, as Strng or as Ordna
(cck here to more nformaton).
@CoectonTabe(name = "person_has_emas") => confgure |PA to whch tabe the nformaton
w be stored. When ths annotaton s not present |PA w create a database tabe named after
the cass and attrbute name by defaut. For exampe wth the "Lst<CarBrand> brands"
attrbute the database tabe woud be named as "person_brands".
.ne%o.ne unidirectional and &idirectional
It is ver$ eas$ to find entities with relationships. A person has dos! dos have fleas! fleas has/ hum/ never
mind.
2nidirectional
A one to one relationship is the easiest to understand. Imaine that a 2erson has onl$ one Cellular and onl$ 2erson
will "see# the Cellular! the Cellular will not see 2erson. Chec+ the imae below.
3= of =0
JPA Mini Book www.javacodegeeks.com
Chec+ how the 2erson class will be.
import java$.&ersisten%e.*;

K#ntit0
public class Gers'n {

K3d
KMeneratedNalue
private int id;

private String name;

K6ne1'6ne
KJ'inC'lumn(name,*%ellularFid*"
private Cellular %ellular;

-- get and set
9
import java$.&ersisten%e.*;

K#ntit0
public class Cellular {

K3d
KMeneratedNalue
private int id;

private int num+er;

-- get and set
9
About the code above.
In a undrectona reatonshp |ust one sde of the reatonshp knows ("sees") the other. Notce
that Person knows Ceuar but Ceuar does not know Person. It s possbe to do
person.getCeuar() but t s not possbe to do ceuar.getPerson().
In the Person entty t s possbe to use the annotaton @OneToOne. Ths annotaton ndcates to
|PA that there s a reatonshp between the enttes.
38 of =0
JPA Mini Book www.javacodegeeks.com
(ver$ relationship needs one of the entities to be the "relationship owner#. Bein the relationship owner is nothin
more than to have the forein +e$ in the database table. In the code above $ou can see that the annotation
A*oinColumn has been used. This annotation indicates that the forein +e$ will be located in the person database
table! ma+in the 2erson entit$ owner of the relationship.
3idirectional
To transform this relationship in a bidirectional one we just have to edit the Cellular entit$. Chec+ the class below.
import java$.&ersisten%e.*;

K#ntit0
public class Cellular {

K3d
KMeneratedNalue
private int id;

private int num+er;

K6ne1'6ne(ma&&edB0,*%ellular*"
private Gers'n &ers'n;

-- get and set
9
About the code above.
The same annotaton @OneToOne to the Person attrbute s used n the Ceuar entty.
The parameter "ma((ed)y" was used n the @OneToOnea nnotaton. Ths parameter ndcates
that the entty Person s the owner of the reatonshp; the foregn key must exst nsde the
person tabe, and not the Ceuar tabe.
A developer must have in mind that for *2A to wor+ in an optimal wa$ it is a ood practice to leave one side of the
relationship as the owner. If the annotation AOneToOne found in the Cellular entit$ was without the "mappedB$#
parameter! *2A would handle the Cellular entit$ as the owner of the relationship too. It is not a ood idea to leave
either sides of a relationship without definin ?mappedB$?! or both with ?mappedB$? setted.
%here is no such 4auto relationship5
4or a Bidirectional relationship to wor+ correctl$ it is necessar$ to do li+e below.
&ers'n.setCellular(%ellular";
%ellular.setGers'n(&ers'n";
3( of =0
JPA Mini Book www.javacodegeeks.com
*2A uses the *ava concept of class reference! a class must maintain a reference to another one if there will be a
join between them. *2A will not create a relationship automaticall$6 to have the relationship in both sides it is
needed to do li+e above.
.ne%o,any-,any%o.ne unidirectional and
&idirectional
The one to man$ relationship is used when an entit$ has a relationship with a list of other entities! e.. a Cellular
ma$ have several Calls but a Call can have onl$ one Cellular. The OneTo'an$ relationship is represented with a
list of values! there is more than one entit$ associate with it.
;et us start with the 'an$ToOne side.
import java$.&ersisten%e.*;

K#ntit0
public class Call {

K3d
KMeneratedNalue
private int id;

KMan01'6ne
KJ'inC'lumn(name , *%ellularFid*"
private Cellular %ellular;

private lon durati'n;

-- get and set
9
About the code above.
The annotaton @ManyToOne s used.
Notce that annotaton @|onCoumn s used to defne who the owner of the reatonshp s.
The @ManyToOne sde w aways be the owner of the reatonshp. There s no way of usng the
mappedBy attrbute nsde the @ManyToOne annotaton.
To do a bidirectional relationship we need to edit the Cellular entit$ 7created in the previous sections9. Chec+ the
code below.
import java$.&ersisten%e.*;

39 of =0
JPA Mini Book www.javacodegeeks.com
K#ntit0
public class Cellular {

K3d
KMeneratedNalue
private int id;

K6ne1'6ne(ma&&edB0 , *%ellular*"
private Gers'n &ers'n;

K6ne1'Man0(ma&&edB0 , *%ellular*"
private List7Call8 %alls;

private int num+er;

-- get and set
9
About the code above.
The @OneToMany annotaton s used. Ths annotaton must be paced n a coecton.
The mappedBy drecttve s used to defne the Ca entty as the reatonshp owner.
(ver$ relationship needs one of the entities to be the "relationship owner#. Bein the relationship owner is nothin
more than to have the forein +e$ in the database table. In the code above $ou can see that the annotation
A*oinColumn has been used. This annotation indicates that the forein +e$ will be located in the call database
table! ma+in the Call entit$ owner of the relationship.
%here is no such 4auto relationship5
4or a Bidirectional relationship to wor+ correctl$ it is necessar$ to do li+e below.
%all.setCellular(%ellular";
%ellular.setCalls(%alls";
*2A uses the *ava concept of class reference! a class must maintain a reference to another one if there will be a
join between them. *2A will not create a relationship automaticall$6 to have the relationship in both sides it is
needed to do li+e above.
,any%o,any unidirectional and &idirectional
In a 'an$To'an$ e3ample a person ma$ have several dos and a do ma$ have several persons 7imaine a do
that lives in a house with FG persons9.
In a 'an$To'an$ approach it is necessar$ to use an e3tra database table to store the ids that relate the database
!0 of =0
JPA Mini Book www.javacodegeeks.com
tables of ever$ entit$ of the relationship. Thus for the specific e3ample we will have a person table! a do table and
a relationship table named person_do. The person_do table would onl$ maintain the person_id and do_id
values that represent which do belons to which person.
%ee the database table imaes below.
2erson table
,o table
person_do table
&otice that the person_do has onl$ ids.
Chec+ the 2erson entit$ below.
import java.util.List;

import java$.&ersisten%e.*;

K#ntit0
public class Gers'n {

K3d
KMeneratedNalue
private int id;

!/ of =0
JPA Mini Book www.javacodegeeks.com
private String name;

KMan01'Man0
KJ'in1a+le(name , *&ers'nFd'g*4 j'inC'lumns , KJ'inC'lumn(name , *&ers'nFid*"4 inverseJ'inC'lumns ,
KJ'inC'lumn(name , *d'gFid*""
private List7D'g8 d'gs;

K6ne1'6ne
KJ'inC'lumn(name , *%ellularFid*"
private Cellular %ellular;

-- get and set
9
About the code above.
The @ManyToMany annotaton s used.
The @|onTabe annotaton s used to set the reatonshp tabe between the enttes; "name"
sets the tabe name; "|onCoumn" defnes the coumn name n the tabe of the reatonshp
owner; "nverse|onCoumns" defnes the coumn name n the tabe of the non-reatonshp
owner.
The 2erson entit$ has unidirectional relationship with the ,o entit$. Chec+ how the ,o entit$ would loo+ li+e in a
bidirectional relationship.
import java.util.List;

import java$.&ersisten%e.*;

K#ntit0
public class D'g {

K3d
KMeneratedNalue
private int id;

private String name;

KMan01'Man0(ma&&edB0,*d'gs*"
private List7Gers'n8 &ers'ns;

-- get and set
9
As $ou can see the A'an$To'an$ annotation is confiured with the ?mappedB$? option! which establishes the
2erson entit$ as the relationship owner.
(ver$ relationship needs that one of the entities be the "relationship owner#. 4or the 'an$To'an$ association the
relationship owner entit$ is the one that is dictated b$ the ?mappedB$? option usuall$ copnfiured with the
!1 of =0
JPA Mini Book www.javacodegeeks.com
A'an$To'an$ annotation at the non>owner entit$ of the relation. If the ?mappedB$? option is not found in an$ of
the related entities *2A will define both entities as the relationship owners. The ?mappedB$? option must point to the
associated entit$Hs attribute name and not the associated entit$Hs name.
%here is no such 4auto relationship5
4or a Bidirectional relationship to wor+ correctl$ it is necessar$ to do li+e below.
&ers'n.setD'g(d'gs";
d'g.setGers'ns(&ers'ns";
*2A uses the *ava concept of class reference! a class must maintain a reference to another one if there will be a
join between them. *2A will not create a relationship automaticall$6 to have the relationship in both sides it is
needed to do li+e above.
,any%o,any +ith extra fields
Imaine a 2erson entit$ that has a 'an$To'an$ relationship with the ,o entit$6 ever$ time that a do is adopted
b$ a person the application should reister the adoption date. This value must be stored in the relationship and not
an an attribute on person nor do.
To handle this +ind of situationwe use the ?Associative Class? alias ?Associative (ntit$? approach. 5ith this
approach it is possible to store e3tra data when the 'an$To'an$ relationship is created.
The imae below shows how this entit$ can be mapped.
!3 of =0
JPA Mini Book www.javacodegeeks.com
To map this e3tra field! implement li+e the followin code.
import java.util.List;

import java$.&ersisten%e.*;

K#ntit0
public class Gers'n {

K3d
KMeneratedNalue
private int id;

private String name;

K6ne1'Man0(ma&&edB0 , *&ers'n*"
private List7Gers'nD'g8 d'gs;

-- get and set
9
import java.util.List;

import java$.&ersisten%e.*;

K#ntit0
public class D'g {

K3d
KMeneratedNalue
private int id;
!! of =0
JPA Mini Book www.javacodegeeks.com

private String name;

K6ne1'Man0(ma&&edB0 , *d'g*"
private List7Gers'nD'g8 &ers'ns;

-- get and set
9
The code above is usin the AOneTo'an$ relationship with the mappedB$ option. &otice that there is no
A'an$To'an$ relationship between the entities! but there is an entit$ 2erson,o that unite both entities.
Below is the 2erson,o code.
import java.util.Date;

import java$.&ersisten%e.*;

K#ntit0
K3dClass(Gers'nD'g3d.class"
public class Gers'nD'g {

K3d
KMan01'6ne
KJ'inC'lumn(name,*&ers'nFid*"
private Gers'n &ers'n;

K3d
KMan01'6ne
KJ'inC'lumn(name,*d'gFid*"
private D'g d'g;

K1em&'ral(1em&'ral10&e.DH1#"
private Date ad'&ti'nDate;

-- get and set
9
In the code above $ou can see the relationships between 2erson,o! ,o and 2erson! and an e3tra attribute to
store the adoption date. There is an id class to store the relationship ids named ?2erson,oId?.
import java.i'.SerialiQa+le;

public class Gers'nD'g3d implements SerialiQa+le {

private static final lon serialNersi'n?3D , =L;

private int &ers'n;
private int d'g;

public int getGers'n(" {
return &ers'n;
9
!$ of =0
JPA Mini Book www.javacodegeeks.com

public void setGers'n(int &ers'n" {
this.&ers'n , &ers'n;
9

public int getD'g(" {
return d'g;
9

public void setD'g(int d'g" {
this.d'g , d'g;
9

K6verride
public int hashC'de(" {
return &ers'n ; d'g;
9

K6verride
public boolean equals(6+je%t '+j" {
if('+j instanceof Gers'nD'g3d"{
Gers'nD'g3d &ers'nD'g3d , (Gers'nD'g3d" '+j;
return &ers'nD'g3d.d'g ,, d'g TT &ers'nD'g3d.&ers'n ,, &ers'n;
9

return false;
9
9
One thin to notice here is that person and do attributes must have the same name > ?person? and ?do? here >
between the 2erson,oId and 2erson,o entities. It is how *2A wor+s. 'ore information about comple3 +e$s can
be found at earlier sections of this document.
*o+ the 'ascade functionality +or6s? *o+ should a
de1eloper use the .rphanRemo1al? *andling the
org.hi&ernate.%ransient.&/ectException
It is ver$ common two or more entities to receive updates in the same transaction. 5hen editin a personHs data for
e3ample! we could chane their name! address! ae! car color etc. These chanes should trier updates to three
different entities. 2erson! Car and Address.
The updates above could be done as shown in the code snippet below.
%ar.setC'l'r(C'l'r..#D";
%ar.set6Cner(neCGers'n";
%ar.setS'undS0stem(neCS'und";
!= of =0
JPA Mini Book www.javacodegeeks.com
If the code below were to be e3ecuted the e3ception or.hibernate.TransientObject(3ception would be thrown.
#ntit0Manager entit0Manager , -- get a valid entit0 manager

Car %ar , new Car(";
%ar.set)ame(*Bla%k 1hunder*";

Hddress address , new Hddress(";
address.set)ame(*Street H*";

entit0Manager.get1ransa%ti'n(".+egin(";

Gers'n &ers'n , entit0Manager.(ind(Gers'n.class4 DD";
&ers'n.setCar(%ar";
&ers'n.setHddress(address";

entit0Manager.get1ransa%ti'n(".%'mmit(";
entit0Manager.%l'se(";
5ith the (clipse;in+ *2A implementation the followin messae would be fired. "Caused %y*
+ava,lan!,-lle!alStateE./e(tion* 0urin! syn/hroni1ation a ne2 o%+e/t 2as &ound throu!h a relationshi( that 2as not mar3ed
/as/ade PERS-S4.
5hat means that an entit$ is transient) Or what a relationship not mar+ed with cascade persist is all about)
*2A wor+s as a trac+er for ever$ entit$ that participates in a transaction. An entit$ that participates in a transaction is
an entit$ that will be created! updated! deleted. *2A needs to +now where that entit$ came from and where it is
oin to. 5hen a transaction is opened ever$ entit$ brouht from the database is "attached#. 5ith "attached# we
mean that the entit$ is inside a transaction! bein monitored b$ *2A. An entit$ remains attached until the transaction
is closed 7rules for *%( applications or transactions without (*B %tateful %ession Beans with 2ersistence %cope
(3tended are different96 to be attached an entit$ needs to come from a database 7b$ quer$! entit$ manaer find
method/9! or receive some contact inside the transaction 7mere! refresh9.
&otice the code below.
entit0Manager.get1ransa%ti'n(".+egin(";
Car m0Car , entit0Manager.(ind(Car.class4 DD";
m0Car.setC'l'r(C'l'r..#D";
entit0Manager. get1ransa%ti'n(".%'mmit(";
The transaction is opened! an update is made in the entit$ and the transaction is committed. It was not required to
do an e3plicit update to the entit$! with the transaction committin all updates made to the entit$ will be persisted to
the database. The updates made to the Car entit$ were persisted to the database because the entit$ is attached!
an$ update to an attached entit$ will be persisted in the database after the transaction commits79 or a flush call is
made.
!8 of =0
JPA Mini Book www.javacodegeeks.com
As shown In the code snippet above ?m$Car? entit$ was brouht from the database inside a transaction! thus *2A
will have the ?m$Car? entit$ attached into that 2ersistence Conte3t. It is possible to define a 2ersistence Conte3t as
a place where *2A will put all attached entities to that transaction! or as a bi ba. The imaes below show this
concept.
!( of =0
JPA Mini Book www.javacodegeeks.com
&otice in the imae above that the Car entit$ is added to the 2ersistence Conte3t onl$ after a database quer$ is
performed to retrieve it from the database. (ver$ update in the Car entit$ will be monitored b$ *2A. Once the
transaction is finished 7or the flush command invo+ed9! *2A will persist this chanes to the database.
The aforementioned problem occures when we update a relationship between two entities. Chec+ the code and the
imae below.
entit0Manager.get1ransa%ti'n(".+egin(";
Gers'n neCGers'n , new Gers'n(";
neCGers'n.set)ame(*Mar0*";
Car m0Car , entit0Manager.(ind(Car.class4 DD";
m0Car.set6Cner(neCGers'n";
entit0Manager. get1ransa%ti'n(".%'mmit(";
The Car entit$ establishes a relationship with the 2erson entit$. The problem is that the 2erson entit$ is outside of
the 2ersistence Conte3t! notice that the person entit$ was not brouht from the database nor was attached to the
transaction. -pon commit *2A cannot reconi8e that 2erson is a new entit$! which does not e3ist in the database.
(ven if the 2erson entit$ e3isted in the database! since it came from outside a transaction 7e.. a *%4
'anaedBean! %truts Action9 it will be considerate unmanaable in this 2ersistence Conte3t. An object outside the
2ersistence Conte3t is +nown as "detached#.
This detached entit$ situation ma$ happen in an$ *2A operations. I&%(RT! -2,AT(! ,(;(T(/
To help in these situations *2A created the option Cascade. This option can be defined in the annotations.
AOneToOne! AOneTo'an$ and A'an$To'an$. The enum java3.persistence.CascadeT$pe has all Cascade
options available.
!9 of =0
JPA Mini Book www.javacodegeeks.com
Chec+ the cascade options below.
CascadeType.DETACH
CascadeType.MERGE
CascadeType.PERSIST
CascadeType.REFRESH
CascadeType.REMOVE
CascadeType.ALL
The Cascade applies the behavior to repeat the action defined in the relationship. %ee the code below.
import java$.&ersisten%e.*;

K#ntit0
public class Car {

K3d
KMeneratedNalue
private int id;

private String name;

K6ne1'6ne(%as%ade , Cas%ade10&e.G#.S3S1"
private Gers'n &ers'n;

-- get and set
9
In the persistence code above it is defined that the AOneToOne 2erson relationship will have the
Cascade.2(R%I%T action e3ecuted ever$ time the command entit$'anaer.persist7car9 is e3ecuted6 thus for ever$
persist action invo+ed in a Car entit$ *2A will invo+e persist in the 2erson relationship also.
The Cascade advantae is that the propaation of an action is automatic! just need to confiure it in a relationship.
Chec+ below the Cascade options.
Type Action Triggered by
CascadeType.DETACH When the entty s
removed from the
Persstence Context (t w
cause the entty to be
detached) ths acton w
be refected n the
reatonshp.
Fnshed Persstence Context or
by command:
enttyManager.detach(),
enttyManager.cear().
CascadeType.MERGE When an entty has any When the entty s updated and
$0 of =0
JPA Mini Book www.javacodegeeks.com
data updated ths acton
w be refected n the
reatonshp.
the transacton fnshes or by
command:
enttyManager.merge().
CascadeType.PERSIST When a new entty s
perssted n the database
ths acton w be
refected n the
reatonshp.
When a transacton fnshes or
by
command:enttyManager.perss
t().
CascadeType.REFRESH When an entty has ts
data synchronzed wth
the database ths acton
w be refected n the
reatonshp.
By command:
enttyManager.refresh().
CascadeType.REMOVE When an entty s deeted
from the database ths
acton w be refected n
the reatonshp.
By command:
enttyManager.remove().
CascadeType.ALL When any of the actons
above s nvoked by the
|PA or by command, ths
acton w be refected n
the reatonshp.
By any command or acton
descrbed above.
Once the cascade is defined! the code below should run without error.
entit0Manager.get1ransa%ti'n(".+egin(";
Gers'n neCGers'n , new Gers'n(";
neCGers'n.set)ame(*Mar0*";
Car m0Car , entit0Manager.(ind(Car.class4 DD";
m0Car.set6Cner(neCGers'n";
entit0Manager. get1ransa%ti'n(".%'mmit(";
Observations about Cascade.
A deveoper must be cautous when usng CascadeType.ALL n a reatonshp. When the entty s
deeted ts reatonshp woud be deeted as we. In the sampe code above, f the cascade type
n the Car entty was set to the ALL opton, when a Car entty was deeted from the database the
Person entty woud be deeted aso.
CascadeType.ALL (or ndvdua cascades) can cause ow performance n every acton trggered
n the entty. If for exampe an entty has a ot of sts of referenced enttes a merge() acton
nvoked on the specfc entty coud cause a sts to be merged too.
car.setOwner(personFromDB) => f the "personFromDB" entty exsts n the DB but s detached
$/ of =0
JPA Mini Book www.javacodegeeks.com
for the persstence context, Cascade w not hep. When the command
enttyManager.persst(car) s executed |PA w run the persst command for every reatonshp
defned wth CascadeType.PERSIST (e.g. enttyManager.persst(person)). If the Person entty
aready exsts n the database |PA w try to nsert the same record agan and an error message
w be thrown. In ths case ony "attached" enttes can be used, the best way to do t s by usng
the getReference() method that we present here n more deta.
In order for *2A to trier the cascade it is necessar$ alwa$s to e3ecute the action in the entit$ that has the cascade
option defined. Chec+ the code below.
import java$.&ersisten%e.*;

K#ntit0
public class Car {

K3d
KMeneratedNalue
private int id;

private String name;

K6ne1'6ne(%as%ade , Cas%ade10&e.G#.S3S1"
private Gers'n &ers'n;

-- get and set
9
import java$.&ersisten%e.*;

K#ntit0
public class Gers'n {

K3d
private int id;

private String name;

K6ne1'6ne(ma&&edB0,*&ers'n*"
private Car %ar;

-- get and set
9
The correct wa$ to trier the cascade in the entities above is.
entit0Manager.&ersist(%ar";
$1 of =0
JPA Mini Book www.javacodegeeks.com
*2A will search inside the Car entit$ if there is a Cascade option that should be triered. If the persist was
e3ecuted li+e below the transient error messae would be thrown.
entit0Manager.&ersist(&ers'n";
Remem%er* the /as/ade 2ill only %e tri!!ered %y 5PA 2hen the a/tion is e.e/uted in the entity that has the Cas/ade /on&i!ured
in the sam(le a%ove the Car /lass de&ined the Cas/ade to Person6 only the Car /lass 2ill tri!!er the Cas/ade,
.rphanRemo1al
The OrphanRemoval option wor+s almost li+e the CascadeT$pe.R('OI(. The OrphanRemoval is usuall$ applied
in cases where an entit$ just e3ists inside another entit$.
Imaine a situation where an Address entit$ will onl$ e3ist inside a 2erson entit$.
If a new 2erson entit$ is persisted to the database an Address entit$ will be created too. Conceptuall$ the Address
entit$ is created onl$ when a new 2erson entit$ is created and when the 2erson entit$ is deleted the Address entit$
is deleted also! just li+e b$ usin the CascadeT$pe.R('OI( option.
The OrphanRemoval has almost the same functionalit$ as the CascadeT$pe.R('OI(! but conceptuall$ it must be
applied at class composition level.
;oo+ at the code below.
import java$.&ersisten%e.*;

K#ntit0
public class Hddress {

$3 of =0
JPA Mini Book www.javacodegeeks.com
K3d
KMeneratedNalue
private int id;

private String name;

-- get and set
9
import java$.&ersisten%e.*;

K#ntit0
public class Gers'n {

K3d
private int id;

private String name;

K6ne1'Man0('r&han.em'val,true"
private List7Hddress8 address;

-- get and set
9
Imaine that a specific Address entit$ is assined to a specific 2erson entit$ and onl$ that 2erson entit$ has access
to it.
As stated above OrphanRemoval is almost li+e CascadeT$pe.R('OI(. The difference is that the dependent
entit$ will be deleted from the database if the attribute is set to null as showin at the code snippet below.
&ers'n.setHddress(null";
5hen the 2erson entit$ ets updated in the database! the Address entit$ will be deleted from the database. The
person.setAddress7null9 would cause the Address entit$ to be orphan.
The OrphanRemoval option is onl$ available in the annotations. AOneToOne and AOneTo'an$.
*o+ to delete an entity +ith relationships. 'larify
+hich relationships are raising the exception
5hen an entit$ is deleted from the database a constraint error ma$ appear! somethin
li+e."+ava,s$l,S78-nte!rityConstraint9iolationE./e(tion. This error miht happen if we tr$ to delete a 2erson entit$ that
is related to a Car entit$ and the CascadeT$pe.R('OI( is not defined for the specific association 7see the last
chapter about Cascade definition9.
$! of =0
JPA Mini Book www.javacodegeeks.com
In order to perform the removal of the 2erson entit$ we could do.
CascadeType.REMOVE => Once the entty s deeted ts chd entty (Car) w be deeted too.
Check the prevous secton to see how to do t.
OrphanRemova => Can be apped but have a dfferent behavor than CascadeType.REMOVE.
Check the ast chapter to see how to do t.
Set the reatonshp to nu before excudng t:
&ers'n.setCar(null";
entit0Manager.rem've(&ers'n";
-nfortunatel$ locatin the actual entit$ that is the cause of the specific e3ception is not straihtforward at all. 5hat
can be done is catch the class name displa$ed in the error messae of the e3ception and o on from there. This
solution is not accurate because the error messae is a %trin with a lon te3t containin the database table name.
&evertheless this messae ma$ chane b$ each distinct *2A implementation! *,BC driver! local database
lanuae etc.
'reating one Entity,anager7actory &y application
5hen controllin database transactions prorammaticall$ one (ntit$'anaer4actor$ per application is usuall$
used. This is the optimal approach since loadin an (ntit$'anaer4actor$ has a hih performance cost6 *2A will
anal$8e the database! validate entities and perform several other tas+s when creatin a new (ntit$'anaer4actor$.
Thus it is unviable to create a new (ntit$'anaer4actor$ per transaction.
Below is a code that can be used.
import java$.&ersisten%e.*;

public abstract class C'nne%ti'n5a%t'r0 {
private C'nne%ti'n5a%t'r0(" {
9

private static #ntit0Manager5a%t'r0 entit0Manager5a%t'r0;

public static #ntit0Manager get#ntit0Manager("{
if (entit0Manager5a%t'r0 ,, null"{
entit0Manager5a%t'r0 , Gersisten%e.%reate#ntit0Manager5a%t'r0(*M0Gersisten%e?nit*";
9

return entit0Manager5a%t'r0.%reate#ntit0Manager(";
9
9
$$ of =0
JPA Mini Book www.javacodegeeks.com
2nderstanding ho+ the La8y-Eager option +or6s
An entit$ ma$ have an attribute with a hue si8e 7e.. a lare file9 or a bi list of entities e. a person ma$ have
several cars or a picture with FG1 'B of si8e.
Chec+ the code below.
import java$.&ersisten%e.*;

K#ntit0
public class Car {

K3d
KMeneratedNalue
private int id;

private String name;

KMan01'6ne
private Gers'n &ers'n;

-- get and set
9
import java.util.List;

import java$.&ersisten%e.*;

K#ntit0
public class Gers'n {

K3d
private int id;

private String name;

K6ne1'Man0(ma&&edB0 , *&ers'n*4 (et%h , 5et%h10&e.LHOP"
private List7Car8 %ars;

KL'+
KBasi%((et%h , 5et%h10&e.LHOP"
private B0te! hugeGi%ture;

-- get and set
9
About the code above.
Notce that the coecton s assgned a FetchType.LAZY opton.
Notce that the mage Byte|| hugePcture s assgned a FetchType.LAZY opton aso.
$= of =0
JPA Mini Book www.javacodegeeks.com
5hen a field is mar+ed with a la8$ fetch t$pe option it is implied that *2A should not load the specific attribute
"naturall$#. 5hen the command entit$'anaer.find72erson.class! person_id9 is used to retrieve the specific person
from the database the ?cars? list and the ?hue2icture? field will not be loaded. The amount of data returned from
the database will be smaller. The advantae of this approach is that the quer$ has less performance impact and the
data traffic over the networ+ is smaller.
This data can be accessed when the relevant et methods of the 2erson entit$ are invo+ed. 5hen the command
person.et:ue2icture79 is e3ecuted a new quer$ will be fired aainst the database searchin this information.
(ver$ simple attribute will have the 4etchT$pe.(AB(R option enabled b$ default. To mar+ a simple attribute as
;AJK fetched just add the annotation ABasic with the ;a8$ option selected just li+e above.
The relationship between entities has a default behavior too.
Reatonshps fnsh wth "One" w be EAGERy fetched: @OneToOne and @ManyToOne.
Reatonshps fnsh wth "Many" w be LAZYy fetched: @OneToMany and @ManyToMany.
To chane the default behavior $ou should do li+e demonstrated above.
5hen we use the ;AJK behavior the e3ception ";a8$ Initiali8ation (3ception# ma$ happen. This error happens
when the ;AJK attribute is accessed without an$ opened connection. Chec+ this post to see how to solve this
problem. Four soutons to the LazyIntazatonExcepton.
The problem with (AB(R fetch t$pe in all list=attributes is that the database quer$ ma$ increase a lot. 4or e3ample
if ever$ 2erson entit$ has a list of thousant of actions los! imaine the cost to brin hundred or even thousants of
2erson entities from the databaseL A developer must be ver$ cautious when choosin which +ind of fetch strate$
will be used to ever$ attribute=relationship.
*andling the 4cannot simultaneously fetch multiple
&ags5 error
This error happens when *2A retrieves an entit$ from the database and this entit$ has more than one list fields
mar+ed for (AB(Rl$ fetchin.
Chec+ the code below.
import java.util.List;

$8 of =0
JPA Mini Book www.javacodegeeks.com
import java$.&ersisten%e.*;

K#ntit0
public class Gers'n {

K3d
private int id;

private String name;

K6ne1'Man0(ma&&edB0 , *&ers'n*4 (et%h , 5et%h10&e.#HM#.4 %as%ade , Cas%ade10&e.HLL"
private List7Car8 %ars;

K6ne1'Man0((et%h , 5et%h10&e.#HM#."
private List7D'g8 d'gs;

-- get and set
9
5hen a quer$ to et the 2erson entit$ above is fired the followin error messae is displa$ed.
"java3.persistence.2ersistence(3ception. or.hibernate.:ibernate(3ception. cannot simultaneousl$ fetch multiple
bas#! a list can be +nown as ba.
This error happens because :ibernate 7the specific *2A implementation farmewor+ used for this e3ample9 tries to
brin the same result amount for each list. If the enerated %<; returns @ lines for the ?do? entit$ list and one for
the ?car? entit$ list! :ibernate will repeat the ?car? quer$ to ma+e the result equal. Chec+ the imaes below to
understand what is happenin when the entit$'anaer.find72erson.class! person_id9 command is e3ecuted.
$( of =0
JPA Mini Book www.javacodegeeks.com
The problem arises when repeated results appear and brea+ the correct quer$ result. The red cells in the imae
above are the repeated results.
There are four solutions for this situation.
To use |ava.ut.Set nstead of other coecton types => wth ths easy change the error can be
avoded.
To use EcpseLnk => t s a radca souton, but for |PA ony users that use ony |PA annotatons
ths change w have mnma mpact.
To use FetchType.LAZY nstead of EAGER => ths souton s a temporary souton, because f a
query fetches data from two coectons ths error may occur agan. For exampe the foowng
query coud trgger the error: "seect p from Person p |on fetch p.dogs d |on fetch p.cars c".
Addtonay when usng ths approach the LazyIntazatonExcepton error may happen.
To use @LazyCoecton or @IndexCoumn of the Hbernate mpementaton n the coecton =>
t s a very good dea to understand how the @IndexCoumn works and ts effects when used, ts
behavor w change varyng to whch sde of the reatonshp t s added (the expanaton of ths
annotaton s outsde the scope of ths mn book).
$9 of =0
JPA Mini Book www.javacodegeeks.com
ABOUT THE AUTHOR
Hebert Coelho is a senior *ava ,evelopment! with M certifications and a published
boo+ about *%4 7portuuese onl$9. 4ounder of the blo uai:ebert.com visited from
more than FN1 different countries.
ABOUT THE EDITOR
Byron Kiourtzoglou is a master software enineer wor+in in the IT and Telecom domains.
:e is an applications developer in a wide variet$ of applications=services. :e is currentl$
actin as the team leader and technical architect for a proprietar$ service creation and
interation platform for both the IT and Telecom industries in addition to a in>house bi data
real>time anal$tics solution. :e is alwa$s fascinated b$ %OA! middleware services and
mobile development. B$ron is co>founder and (3ecutive (ditor at *ava Code Bee+s.
=0 of =0

Você também pode gostar