Merge branch 'master' of github.com:hibernate/hibernate-core
This commit is contained in:
commit
4bdf804a37
|
@ -39,49 +39,49 @@
|
|||
|
||||
<para>
|
||||
Working with both Object-Oriented software and Relational Databases can be cumbersome and time consuming.
|
||||
Development costs are significantly higher due to a paradigm mismatch between how data is represented in
|
||||
objects versus relational databases. Hibernate is an Object/Relational Mapping solution for Java environments.
|
||||
The term Object/Relational Mapping refers to the technique of mapping data from an object model representation
|
||||
to a relational data model representation (and visa versa). See
|
||||
<ulink url="http://en.wikipedia.org/wiki/Object-relational_mapping"/> for a good high-level discussion.
|
||||
Development costs are significantly higher due to a paradigm mismatch between how data is represented in objects
|
||||
versus relational databases. Hibernate is an Object/Relational Mapping solution for Java environments. The
|
||||
term Object/Relational Mapping refers to the technique of mapping data between an object model representation to
|
||||
a relational data model representation. See <ulink
|
||||
url="http://en.wikipedia.org/wiki/Object-relational_mapping"/> for a good high-level discussion.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
While having a strong background in SQL is not required to use Hibernate, having a basic understanding of
|
||||
the concepts can greatly help you understand Hibernate more fully and quickly. Probably the single
|
||||
best background is an understanding of data modeling principles. You might want to consider these resources
|
||||
as a good starting point:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<ulink url="http://www.agiledata.org/essays/dataModeling101.html"/>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<ulink url="http://en.wikipedia.org/wiki/Data_modeling"/>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
You do not need a strong background in SQL to use Hibernate, but having a basic understanding of the
|
||||
concepts can help you understand Hibernate more fully and quickly. An understanding of data modeling
|
||||
principles is especially important. You might want to consider these resources as a good starting point:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<title>Data Modeling Resources</title>
|
||||
<listitem>
|
||||
<para>
|
||||
<ulink url="http://www.agiledata.org/essays/dataModeling101.html"/>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<ulink url="http://en.wikipedia.org/wiki/Data_modeling"/>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
Hibernate not only takes care of the mapping from Java classes to database tables (and from Java data types to
|
||||
SQL data types), but also provides data query and retrieval facilities. It can significantly reduce
|
||||
development time otherwise spent with manual data handling in SQL and JDBC. Hibernate’s design goal is to
|
||||
relieve the developer from 95% of common data persistence-related programming tasks by eliminating the need for
|
||||
manual, hand-crafted data processing using SQL and JDBC. However, unlike many other persistence solutions,
|
||||
Hibernate does not hide the power of SQL from you and guarantees that your investment in relational technology
|
||||
and knowledge is as valid as always.
|
||||
Hibernate takes care of the mapping from Java classes to database tables, and from Java data types to SQL data
|
||||
types. In addition, it provides data query and retrieval facilities. It can significantly reduce development
|
||||
time otherwise spent with manual data handling in SQL and JDBC. Hibernate’s design goal is to relieve the
|
||||
developer from 95% of common data persistence-related programming tasks by eliminating the need for manual,
|
||||
hand-crafted data processing using SQL and JDBC. However, unlike many other persistence solutions, Hibernate
|
||||
does not hide the power of SQL from you and guarantees that your investment in relational technology and
|
||||
knowledge is as valid as always.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Hibernate may not be the best solution for data-centric applications that only use stored-procedures to
|
||||
implement the business logic in the database, it is most useful with object-oriented domain models and business
|
||||
logic in the Java-based middle-tier. However, Hibernate can certainly help you to remove or encapsulate
|
||||
vendor-specific SQL code and will help with the common task of result set translation from a tabular
|
||||
vendor-specific SQL code and streamlines the common task of translating result sets from a tabular
|
||||
representation to a graph of objects.
|
||||
</para>
|
||||
|
||||
|
|
|
@ -5,38 +5,40 @@
|
|||
<title>Tutorial Using Native Hibernate APIs and Annotation Mappings</title>
|
||||
|
||||
<para>
|
||||
This tutorial is located within the download bundle under <filename>basic</filename> and illustrates
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
using annotations to provide mapping information
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
using the <phrase>native</phrase> Hibernate APIs
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
This tutorial is located within the download bundle under <filename>basic</filename>.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<title>Objectives</title>
|
||||
<listitem>
|
||||
<para>
|
||||
Use annotations to provide mapping information
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Use the <phrase>native</phrase> Hibernate APIs
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
<section id="hibernate-gsg-tutorial-annotations-config">
|
||||
<title>The Hibernate configuration file</title>
|
||||
|
||||
<para>
|
||||
The contents are exactly the same as in <xref linkend="hibernate-gsg-tutorial-basic-config"/>.
|
||||
The single difference is the <literal>mapping</literal> element at the very end naming the
|
||||
annotated entity class using the <literal>class</literal> attribute.
|
||||
The contents are identical to <xref linkend="hibernate-gsg-tutorial-basic-config"/>, with one important
|
||||
difference. The <varname>mapping</varname> element at the very end naming the annotated entity class using
|
||||
the <option>class</option> attribute.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="hibernate-gsg-tutorial-annotations-entity">
|
||||
<title>The annotated entity Java class</title>
|
||||
<para>
|
||||
The entity class in this tutorial is <classname>org.hibernate.tutorial.annotations.Event</classname>
|
||||
which is still following JavaBean conventions. In fact the class itself is exactly the same as we saw
|
||||
in <xref linkend="hibernate-gsg-tutorial-basic-entity"/>, the only difference being the use of
|
||||
annotations to provide the metadata instead of a separate <filename>hbm.xml</filename> file.
|
||||
The entity class in this tutorial is <classname>org.hibernate.tutorial.annotations.Event</classname> which
|
||||
follows JavaBean conventions. In fact the class itself is identical to the one in <xref
|
||||
linkend="hibernate-gsg-tutorial-basic-entity"/>, except that annotations are used to provide the metadata,
|
||||
rather than a separate <filename>hbm.xml</filename> file.
|
||||
</para>
|
||||
|
||||
<example id="hibernate-gsg-tutorial-annotations-entity-entity">
|
||||
|
@ -49,17 +51,18 @@ public class Event {
|
|||
</example>
|
||||
|
||||
<para>
|
||||
The <interfacename>@javax.persistence.Entity</interfacename> annotation is used to mark a
|
||||
class as an entity. It's function is essentially the same as the <literal>class</literal>
|
||||
mapping element discussed in <xref linkend="hibernate-gsg-tutorial-basic-mapping"/>.
|
||||
Additionally the <interfacename>@javax.persistence.Table</interfacename> annotation is
|
||||
used to explicitly specify the table name (the default table name would have been
|
||||
<database class="table">EVENT</database>).
|
||||
<!-- Is an entity an interface?? -->
|
||||
The <interfacename>@javax.persistence.Entity</interfacename> annotation is used to mark a class as an entity.
|
||||
It functions the same as the <varname>class</varname> mapping element discussed in <xref
|
||||
linkend="hibernate-gsg-tutorial-basic-mapping"/>. Additionally the
|
||||
<interfacename>@javax.persistence.Table</interfacename> annotation explicitly specifies the table
|
||||
name. Without this specification, the default table name would be <literal>EVENT</literal>).<!-- It is a
|
||||
literal value, not a table as a table -->
|
||||
</para>
|
||||
|
||||
<example id="hibernate-gsg-tutorial-annotations-entity-id">
|
||||
<title>Identifying the identifier property</title>
|
||||
<programlisting role="JAVA">@Id
|
||||
<title>Identifying the identifier property</title>
|
||||
<programlisting role="JAVA">@Id
|
||||
@GeneratedValue(generator="increment")
|
||||
@GenericGenerator(name="increment", strategy = "increment")
|
||||
public Long getId() {
|
||||
|
@ -68,7 +71,7 @@ public Long getId() {
|
|||
</example>
|
||||
|
||||
<para>
|
||||
<interfacename>@javax.persistence.Id</interfacename> marks the property defining the
|
||||
<interfacename>@javax.persistence.Id</interfacename> marks the property which defines the
|
||||
entity's identifier. <interfacename>@javax.persistence.GeneratedValue</interfacename> and
|
||||
<interfacename>@org.hibernate.annotations.GenericGenerator</interfacename> work in tandem
|
||||
to indicate that Hibernate should use Hibernate's <literal>increment</literal> generation
|
||||
|
@ -76,8 +79,8 @@ public Long getId() {
|
|||
</para>
|
||||
|
||||
<example id="hibernate-gsg-tutorial-annotations-entity-properties">
|
||||
<title>Identifying basic properties</title>
|
||||
<programlisting role="JAVA">public String getTitle() {
|
||||
<title>Identifying basic properties</title>
|
||||
<programlisting role="JAVA">public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
|
@ -89,9 +92,8 @@ public Date getDate() {
|
|||
</example>
|
||||
|
||||
<para>
|
||||
Just as discussed in <xref linkend="hibernate-gsg-tutorial-basic-mapping"/>, the
|
||||
<literal>date</literal> property needs special handling to account for its special naming
|
||||
and its SQL type.
|
||||
As in <xref linkend="hibernate-gsg-tutorial-basic-mapping"/>, the <varname>date</varname> property needs
|
||||
special handling to account for its special naming and its SQL type.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
@ -106,23 +108,21 @@ public Date getDate() {
|
|||
|
||||
<section id="hibernate-gsg-tutorial-annotations-further">
|
||||
<title>Take it further!</title>
|
||||
<para>
|
||||
Try the following exercises:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
With help of the <citetitle pubwork="book">Developer Guide</citetitle>, add an association to
|
||||
the <classname>Event</classname> entity to model a message thread.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
With help of the <citetitle pubwork="book">Developer Guide</citetitle>, add a callback to
|
||||
receive notifications when an <classname>Event</classname> is created, updated or deleted. Try
|
||||
the same with an event listener.
|
||||
</para>
|
||||
</listitem>
|
||||
<title>Practice Exercises</title>
|
||||
<listitem>
|
||||
<para>
|
||||
Add an association to the <classname>Event</classname> entity to model a message thread. Use the
|
||||
<citetitle pubwork="book">Developer Guide</citetitle> as a guide.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Add a callback to receive notifications when an <classname>Event</classname> is created, updated or
|
||||
deleted. Try the same with an event listener. Use the <citetitle pubwork="book">Developer
|
||||
Guide</citetitle> as a guide.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
|
|
|
@ -5,50 +5,51 @@
|
|||
<title>Tutorial Using Envers</title>
|
||||
|
||||
<para>
|
||||
This tutorial is located within the download bundle under <filename>envers</filename> and illustrates
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
configuring Envers
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
using the Envers APIs to look back through history
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
This tutorial is located within the download bundle under <filename>envers</filename>.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<title>Objectives</title>
|
||||
<listitem>
|
||||
<para>
|
||||
Configure Envers.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Use the Envers APIs to view and analyze historical data.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<section id="hibernate-gsg-tutorial-envers-config">
|
||||
<title><filename>persistence.xml</filename></title>
|
||||
<para>
|
||||
This file was discussed in the <phrase>JPA</phrase> tutorial, and is largely the same here. The major
|
||||
difference is the set of properties defining <firstterm><phrase>listeners</phrase></firstterm>.
|
||||
Essentially this enables Envers to recieve notfications from Hibernate processing of certain
|
||||
<firstterm><phrase>events</phrase></firstterm> such as an entity being saved or updated.
|
||||
</para>
|
||||
<title><filename>persistence.xml</filename></title>
|
||||
<para>
|
||||
This file was discussed in the <systemitem>JPA</systemitem> tutorial in <xref
|
||||
linkend="hibernate-gsg-tutorial-jpa-config" />, and is largely the same here. The major difference is the set
|
||||
of properties defining <firstterm>listeners</firstterm>. Listeners enable Envers to receive notfications from
|
||||
Hibernate processing about <firstterm>events</firstterm> such as saving or updating of entities.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="hibernate-gsg-tutorial-envers-entity">
|
||||
<title>The annotated entity Java class</title>
|
||||
<para>
|
||||
Again, the entity is largely the same as seen in the <phrase>JPA</phrase> tutorial. The major
|
||||
difference to notice is the addition of the <interfacename>@org.hibernate.envers.Audited</interfacename>
|
||||
annotation which tells Envers to automatically track changes to this entity.
|
||||
</para>
|
||||
<title>The annotated entity Java class</title>
|
||||
<para>
|
||||
Again, the entity is largely the same as in <xref linkend="hibernate-gsg-tutorial-jpa-entity" /> . The major
|
||||
difference is the addition of the <interfacename>@org.hibernate.envers.Audited</interfacename> annotation, which
|
||||
tells Envers to automatically track changes to this entity.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="hibernate-gsg-tutorial-envers-test">
|
||||
<title>Example code</title>
|
||||
<para>
|
||||
Again, this tutorial makes use of the <phrase>JPA</phrase> APIs. However, the code also makes a
|
||||
change to one of the entites and then uses the Envers API to pull back the initial revision (version)
|
||||
as well as the updated revision.
|
||||
</para>
|
||||
<example id="hibernate-gsg-tutorial-envers-test-api">
|
||||
<title>Using the <interfacename>org.hibernate.envers.AuditReader</interfacename></title>
|
||||
<programlisting role="JAVA">public void testBasicUsage() {
|
||||
<title>Example code</title>
|
||||
<para>
|
||||
Again, this tutorial makes use of the <systemitem>JPA</systemitem> APIs. However, the code also makes a change to one
|
||||
of the entites, then uses the Envers API to pull back the initial <firstterm>revision</firstterm> as well as the updated
|
||||
revision. A revision refers to a version of an entity.
|
||||
</para>
|
||||
<example id="hibernate-gsg-tutorial-envers-test-api">
|
||||
<title>Using the <interfacename>org.hibernate.envers.AuditReader</interfacename></title>
|
||||
<programlisting role="JAVA">public void testBasicUsage() {
|
||||
...
|
||||
AuditReader reader = AuditReaderFactory.get( entityManager );
|
||||
Event firstRevision = reader.find( Event.class, 2L, 1 );
|
||||
|
@ -56,17 +57,41 @@
|
|||
Event secondRevision = reader.find( Event.class, 2L, 2 );
|
||||
...
|
||||
}</programlisting>
|
||||
</example>
|
||||
<para>
|
||||
First an <interfacename>org.hibernate.envers.AuditReader</interfacename> is obtained
|
||||
from the <classname>org.hibernate.envers.AuditReaderFactory</classname> wrapping the
|
||||
</example>
|
||||
<procedure>
|
||||
<title>Description of Example</title>
|
||||
<step>
|
||||
<para>
|
||||
An <interfacename>org.hibernate.envers.AuditReader</interfacename> is obtained from the
|
||||
<classname>org.hibernate.envers.AuditReaderFactory</classname> which wraps the
|
||||
<interfacename>javax.persistence.EntityManager</interfacename>.
|
||||
</para>
|
||||
<para>
|
||||
Then the <methodname>find</methodname> method is used to retrieve specific revisions of the entity. The
|
||||
first call reads "find revision number 1 of Event with id 2". The second call reads "find revision
|
||||
number 2 of Event with id 2".
|
||||
</para>
|
||||
</para>
|
||||
</step>
|
||||
<step>
|
||||
<para>
|
||||
Next,the <methodname>find</methodname> method retrieves specific revisions of the entity. The first call
|
||||
reads <literal>find revision number 1 of Event with id 2</literal>. The second call reads <literal>find
|
||||
revision number 2 of Event with id 2</literal>.
|
||||
</para>
|
||||
</step>
|
||||
</procedure>
|
||||
</section>
|
||||
|
||||
<section id="hibernate-gsg-tutorial-annotations-further">
|
||||
<title>Take it further!</title>
|
||||
<itemizedlist>
|
||||
<title>Practice Exercises</title>
|
||||
<listitem>
|
||||
<para>
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
</chapter>
|
|
@ -5,38 +5,38 @@
|
|||
<title>Tutorial Using the <firstterm><phrase>Java Persistence API (JPA)</phrase></firstterm></title>
|
||||
|
||||
<para>
|
||||
This tutorial is located within the download bundle under <filename>entitymanager</filename> and illustrates
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
using annotations to provide mapping information
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
using <phrase>JPA</phrase>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
This tutorial is located within the download bundle under <filename>entitymanager</filename>.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<title>Objectives</title>
|
||||
<listitem>
|
||||
<para>
|
||||
Use annotations to provide mapping information.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Use <systemitem>JPA</systemitem>.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<section id="hibernate-gsg-tutorial-jpa-config">
|
||||
<title><filename>persistence.xml</filename></title>
|
||||
|
||||
<para>
|
||||
The previous tutorials used the Hibernate-specific
|
||||
<filename><replaceable>hibernate.cfg.xml</replaceable></filename> configuration file. <phrase>JPA</phrase>,
|
||||
however, defines a different <phrase>bootstrap</phrase> process that uses its own configuration file
|
||||
named <filename>persistence.xml</filename>. How this <phrase>bootstrapping</phrase> works is defined
|
||||
by the <phrase>JPA</phrase> specification. In <trademark>Java</trademark> SE environments the
|
||||
persistence provider (Hibernate in this case) is required to locate all <phrase>JPA</phrase>
|
||||
configuration files by classpath lookup of the <filename>META-INF/persistence.xml</filename> resource
|
||||
name.
|
||||
<filename><replaceable>hibernate.cfg.xml</replaceable></filename> configuration file.
|
||||
<systemitem>JPA</systemitem>, however, defines a different bootstrap process that uses its own configuration
|
||||
file named <filename>persistence.xml</filename>. This bootstrapping process is defined by the
|
||||
<systemitem>JPA</systemitem> specification. In <trademark>Java</trademark> SE environments the persistence
|
||||
provider (Hibernate in this case) is required to locate all <systemitem>JPA</systemitem> configuration files
|
||||
by classpath lookup of the <filename>META-INF/persistence.xml</filename> resource name.
|
||||
</para>
|
||||
|
||||
<example id="hibernate-gsg-tutorial-jpa-config-pu">
|
||||
<title><filename>persistence.xml</filename></title>
|
||||
<programlisting role="XML"><![CDATA[<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
<title><filename>persistence.xml</filename></title>
|
||||
<programlisting role="XML"><![CDATA[<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
||||
version="2.0">
|
||||
|
@ -47,53 +47,52 @@
|
|||
</example>
|
||||
|
||||
<para>
|
||||
<filename>persistence.xml</filename> files should provide a unique name for each
|
||||
<phrase>persistence unit</phrase>. This name is how applications reference the configuration
|
||||
while obtaining an <interfacename>javax.persistence.EntityManagerFactory</interfacename> reference.
|
||||
<filename>persistence.xml</filename> files should provide a unique name for each <phrase>persistence
|
||||
unit</phrase>. Applications use this name to reference the configuration when obtaining an
|
||||
<interfacename>javax.persistence.EntityManagerFactory</interfacename> reference.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The settings defined in the <literal>properties</literal> element were already discussed in
|
||||
<xref linkend="hibernate-gsg-tutorial-basic-config"/>. Here the <literal>javax.persistence</literal>-prefixed
|
||||
varieties are used when possible. For the remaining Hibernate-specific configuration setting names notice
|
||||
that they are now prefixed with <literal>hibernate.</literal>.
|
||||
The settings defined in the <varname>properties</varname> element are discussed in <xref
|
||||
linkend="hibernate-gsg-tutorial-basic-config"/>. Here the <literal>javax.persistence</literal>-prefixed
|
||||
varieties are used when possible. Notice that the remaining Hibernate-specific configuration setting names
|
||||
are now prefixed with <literal>hibernate.</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Additionally, the <literal>class</literal> element functions the same as discussed in
|
||||
<xref linkend="hibernate-gsg-tutorial-annotations-config"/>.
|
||||
Additionally, the <varname>class</varname> element functions the same as in <xref
|
||||
linkend="hibernate-gsg-tutorial-annotations-config"/>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="hibernate-gsg-tutorial-jpa-entity">
|
||||
<title>The annotated entity Java class</title>
|
||||
<para>
|
||||
The entity is exactly the same as that from the annotations tutorial. See
|
||||
<xref linkend="hibernate-gsg-tutorial-annotations-entity"/>
|
||||
The entity is exactly the same as in <xref linkend="hibernate-gsg-tutorial-annotations-entity"/>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="hibernate-gsg-tutorial-jpa-test">
|
||||
<title>Example code</title>
|
||||
<para>
|
||||
The previous tutorials used the Hibernate APIs. This tutorial uses the <phrase>JPA</phrase> APIs.
|
||||
The previous tutorials used the Hibernate APIs. This tutorial uses the <systemitem>JPA</systemitem> APIs.
|
||||
</para>
|
||||
|
||||
<example id="hibernate-gsg-tutorial-jpa-test-setUp">
|
||||
<title>Obtaining the <interfacename>javax.persistence.EntityManagerFactory</interfacename></title>
|
||||
<programlisting role="JAVA">protected void setUp() throws Exception {
|
||||
<title>Obtaining the <interfacename>javax.persistence.EntityManagerFactory</interfacename></title>
|
||||
<programlisting role="JAVA">protected void setUp() throws Exception {
|
||||
entityManagerFactory = Persistence.createEntityManagerFactory( "org.hibernate.tutorial.jpa" );
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Notice again the use of <literal>org.hibernate.tutorial.jpa</literal> as the
|
||||
<phrase>persistence unit</phrase> name, which matches from <xref linkend="hibernate-gsg-tutorial-jpa-config-pu"/>
|
||||
Notice again that the persistence unit name is <literal>org.hibernate.tutorial.jpa</literal>, which matches
|
||||
<xref linkend="hibernate-gsg-tutorial-jpa-config-pu"/>
|
||||
</para>
|
||||
|
||||
<example id="hibernate-gsg-tutorial-jpa-test-saving">
|
||||
<title>Saving (persisting) entities</title>
|
||||
<programlisting role="JAVA">EntityManager entityManager = entityManagerFactory.createEntityManager();
|
||||
<title>Saving (persisting) entities</title>
|
||||
<programlisting role="JAVA">EntityManager entityManager = entityManagerFactory.createEntityManager();
|
||||
entityManager.getTransaction().begin();
|
||||
entityManager.persist( new Event( "Our very first event!", new Date() ) );
|
||||
entityManager.persist( new Event( "A follow up event", new Date() ) );
|
||||
|
@ -102,15 +101,15 @@ entityManager.close();</programlisting>
|
|||
</example>
|
||||
|
||||
<para>
|
||||
The code is pretty similar to <xref linkend="hibernate-gsg-tutorial-basic-test-saving"/>. Here
|
||||
we use an <interfacename>javax.persistence.EntityManager</interfacename> as opposed to a
|
||||
<interfacename>org.hibernate.Session</interfacename>. <phrase>JPA</phrase> calls this operation
|
||||
<literal>persist</literal> instead of <literal>save</literal>.
|
||||
The code is similar to <xref linkend="hibernate-gsg-tutorial-basic-test-saving"/>. An
|
||||
<interfacename>javax.persistence.EntityManager</interfacename> interface is used instead of a
|
||||
<interfacename>org.hibernate.Session</interfacename> interface. <systemitem>JPA</systemitem> calls this
|
||||
operation <methodname>persist</methodname> instead of <methodname>save</methodname>.
|
||||
</para>
|
||||
|
||||
<example id="hibernate-gsg-tutorial-jpa-test-list">
|
||||
<title>Obtaining a list of entities</title>
|
||||
<programlisting role="JAVA"><![CDATA[entityManager = entityManagerFactory.createEntityManager();
|
||||
<title>Obtaining a list of entities</title>
|
||||
<programlisting role="JAVA"><![CDATA[entityManager = entityManagerFactory.createEntityManager();
|
||||
entityManager.getTransaction().begin();
|
||||
List<Event> result = entityManager.createQuery( "from Event", Event.class ).getResultList();
|
||||
for ( Event event : result ) {
|
||||
|
@ -121,8 +120,12 @@ entityManager.close();]]></programlisting>
|
|||
</example>
|
||||
|
||||
<para>
|
||||
Again, the code is pretty similar to <xref linkend="hibernate-gsg-tutorial-basic-test-list"/>.
|
||||
Again, the code is pretty similar to <xref linkend="hibernate-gsg-tutorial-basic-test-list"/>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
<section id="hibernate-gsg-tutorial-annotations-further">
|
||||
<title>Take it further!</title>
|
||||
<itemizedlist>
|
||||
<title>Practice Exercises</title> <listitem> <para> </para> </listitem> <listitem> <para> </para> </listitem>
|
||||
</itemizedlist> </section> </chapter>
|
|
@ -5,20 +5,22 @@
|
|||
<title>Tutorial Using Native Hibernate APIs and <phrase>hbm.xml</phrase> Mappings</title>
|
||||
|
||||
<para>
|
||||
This tutorial is located within the download bundle under <filename>basic</filename> and illustrates
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
using Hibernate mapping files (<phrase>hbm.xml</phrase>) to provide mapping information
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
using the <phrase>native</phrase> Hibernate APIs
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
This tutorial is located within the download bundle under <filename>basic/</filename>.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<title>Objectives</title>
|
||||
<listitem>
|
||||
<para>
|
||||
using Hibernate mapping files (<phrase>hbm.xml</phrase>) to provide mapping information
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
using the <phrase>native</phrase> Hibernate APIs
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
<section id="hibernate-gsg-tutorial-basic-config">
|
||||
<title>The Hibernate configuration file</title>
|
||||
|
@ -29,44 +31,44 @@
|
|||
</para>
|
||||
|
||||
<para>
|
||||
The <literal>connection.driver_class</literal>, <literal>connection.url</literal>,
|
||||
<literal>connection.username</literal> and <literal>connection.password</literal>
|
||||
<literal>property</literal> elements define JDBC connection information. These tutorials
|
||||
utilize the H2 in-memory database. So these are all specific to running H2 in its in-memory mode.
|
||||
<literal>connection.pool_size</literal> is used to configure Hibernate's built-in connection pool
|
||||
how many connections to pool.
|
||||
The <varname>connection.driver_class</varname>, <varname>connection.url</varname>,
|
||||
<varname>connection.username</varname> and <varname>connection.password</varname>
|
||||
<varname>property</varname> elements define JDBC connection information. These tutorials utilize the H2
|
||||
in-memory database, So the values of these properties are all specific to running H2 in its in-memory mode.
|
||||
<varname>connection.pool_size</varname> is used to configure the number of connections in Hibernate's
|
||||
built-in connection pool.
|
||||
</para>
|
||||
|
||||
<important>
|
||||
<para>
|
||||
The built-in Hibernate connection pool is in no way intended for production use. It
|
||||
lacks several features found on any decent connection pool. See the section discussion in
|
||||
<citetitle pubwork="book">Hibernate Developer Guide</citetitle> for further information.
|
||||
The built-in Hibernate connection pool is in no way intended for production use. It lacks several
|
||||
features found on production-ready connection pools. See the section discussion in <citetitle
|
||||
pubwork="book">Hibernate Developer Guide</citetitle> for further information.
|
||||
</para>
|
||||
</important>
|
||||
|
||||
<para>
|
||||
The <literal>dialect</literal> property specifies the particular SQL variant Hibernate with which
|
||||
Hibernate will converse.
|
||||
The <varname>dialect</varname> property specifies the particular SQL variant with which Hibernate will
|
||||
converse.
|
||||
</para>
|
||||
|
||||
<tip>
|
||||
<para>
|
||||
In most cases, Hibernate is able to properly determine which dialect to use which is invaluable if
|
||||
your application targets multiple databases. This is discussed in detail in the
|
||||
<citetitle pubwork="book">Hibernate Developer Guide</citetitle>
|
||||
In most cases, Hibernate is able to properly determine which dialect to use. This is particularly useful
|
||||
if your application targets multiple databases. This is discussed in detail in the <citetitle
|
||||
pubwork="book">Hibernate Developer Guide</citetitle>
|
||||
</para>
|
||||
</tip>
|
||||
|
||||
<para>
|
||||
The <literal>hbm2ddl.auto</literal> property turns on automatic generation of database schemas directly
|
||||
into the database.
|
||||
The <varname>hbm2ddl.auto</varname> property enables automatic generation of database schemas directly into
|
||||
the database.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Finally, add the mapping file(s) for persistent classes to the configuration. The <literal>resource</literal>
|
||||
attribute of the <literal>mapping</literal> element says to attempt to locate that mapping as a
|
||||
classpath resource (via a <classname>java.lang.ClassLoader</classname> lookup).
|
||||
Finally, add the mapping file(s) for persistent classes to the configuration. The <option>resource</option>
|
||||
attribute of the <varname>mapping</varname> element causes Hibernate to attempt to locate that mapping as a
|
||||
classpath resource, using a <classname>java.lang.ClassLoader</classname> lookup.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
@ -76,44 +78,38 @@
|
|||
<title>The entity Java class</title>
|
||||
<para>
|
||||
The entity class for this tutorial is <classname>org.hibernate.tutorial.hbm.Event</classname>.
|
||||
<itemizedlist>
|
||||
<title>Notes About the Entity</title>
|
||||
<listitem>
|
||||
<para>
|
||||
This class uses standard JavaBean naming conventions
|
||||
for property getter and setter methods, as well as
|
||||
private visibility for the fields. Although this is
|
||||
the recommended design, it is not required.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The no-argument constructor, which is also a JavaBean
|
||||
convention, is a requirement for all persistent
|
||||
classes. Hibernate needs to create objects for you,
|
||||
using Java Reflection. The constructor can be
|
||||
private. However, package or public visibility is
|
||||
required for runtime proxy generation and efficient
|
||||
data retrieval without bytecode instrumentation.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<title>Notes About the Entity</title>
|
||||
<listitem>
|
||||
<para>
|
||||
This class uses standard JavaBean naming conventions for property getter and setter methods, as well as
|
||||
private visibility for the fields. Although this is the recommended design, it is not required.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <methodname>no-argument</methodname> constructor, which is also a JavaBean convention, is a
|
||||
requirement for all persistent classes. Hibernate needs to create objects for you, using Java
|
||||
Reflection. The constructor can be private. However, package or public visibility is required for runtime
|
||||
proxy generation and efficient data retrieval without bytecode instrumentation.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="hibernate-gsg-tutorial-basic-mapping">
|
||||
<title>The mapping file</title>
|
||||
<para>
|
||||
The <phrase>hbm.xml</phrase> mapping file for this tutorial is the classpath resource
|
||||
The <filename>hbm.xml</filename> mapping file for this tutorial is the classpath resource
|
||||
<filename>org/hibernate/tutorial/hbm/Event.hbm.xml</filename> as we saw in
|
||||
<xref linkend="hibernate-gsg-tutorial-basic-config"/>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Hibernate uses the mapping metadata to find out how to load and
|
||||
store objects of the persistent class. The Hibernate mapping
|
||||
file is one choice for providing Hibernate with this metadata.
|
||||
Hibernate uses the mapping metadata to determine how to load and store objects of the persistent class. The
|
||||
Hibernate mapping file is one choice for providing Hibernate with this metadata.
|
||||
</para>
|
||||
|
||||
<example id="hibernate-gsg-tutorial-basic-mapping-class">
|
||||
|
@ -124,18 +120,18 @@
|
|||
</example>
|
||||
|
||||
<orderedlist>
|
||||
<title>Functions of the <literal>class</literal> mapping element</title>
|
||||
<title>Functions of the <varname>class</varname> mapping element</title>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>name</literal> attribute (combined here with the <literal>package</literal>
|
||||
attribute from the containing <literal>hibernate-mapping</literal> element) names the FQN of
|
||||
the class you want to define as an entity.
|
||||
The <option>name</option> attribute (combined here with the <option>package</option> attribute from
|
||||
the containing <varname>hibernate-mapping</varname> element) names the FQN of the class to be
|
||||
defined as an entity.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>table</literal> attribute names the database table which contains the data for
|
||||
this entity.
|
||||
The <option>table</option> attribute names the database table which contains the data for this
|
||||
entity.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
@ -153,30 +149,30 @@
|
|||
</example>
|
||||
|
||||
<para>
|
||||
Hibernate uses the property named by the <literal>id</literal> element to uniquely identify rows
|
||||
in the table.
|
||||
Hibernate uses the property named by the <varname>id</varname> element to uniquely identify rows in the
|
||||
table.
|
||||
</para>
|
||||
|
||||
<important>
|
||||
<!-- Again, perhaps more sense moving this to the Dev Guide -->
|
||||
<para>
|
||||
It is not strictly necessary for the <literal>id</literal> element to map to the table's actual
|
||||
primary key column(s), but it is the normal convention. Tables mapped in Hibernate do not even
|
||||
need to define primary keys. However, the Hibernate team <emphasis>strongly</emphasis>
|
||||
recommends that all schemas define proper referential integrity. Therefore <literal>id</literal>
|
||||
and <phrase>primary key</phrase> are used interchangeably throughout Hibernate documentation.
|
||||
It is not required for the <varname>id</varname> element to map to the table's actual primary key
|
||||
column(s), but it is the normal convention. Tables mapped in Hibernate do not even need to define
|
||||
primary keys. However, it is strongly recommend that all schemas define proper referential
|
||||
integrity. Therefore <varname>id</varname> and <phrase>primary key</phrase> are used interchangeably
|
||||
throughout Hibernate documentation.
|
||||
</para>
|
||||
</important>
|
||||
<para>
|
||||
The <literal>id</literal> element here identifies the <database class="field">EVENT_ID</database>
|
||||
column as the primary key of the <database class="table">EVENTS</database> table. It also identifies
|
||||
the <literal>id</literal> property of the <classname>Event</classname> class as the property
|
||||
containing the identifier value.
|
||||
The <varname>id</varname> element here identifies the <database class="field">EVENT_ID</database> column as
|
||||
the primary key of the <database class="table">EVENTS</database> table. It also identifies the
|
||||
<varname>id</varname> property of the <classname>Event</classname> class as the property containing the
|
||||
identifier value.
|
||||
</para>
|
||||
<para>
|
||||
The <literal>generator</literal> element nested inside the <literal>id</literal> element informs
|
||||
Hibernate about which strategy is used to generated primary key values for this entity. In this
|
||||
example a simple incrementing count is used.
|
||||
The <varname>generator</varname> element nested inside the <varname>id</varname> element informs Hibernate
|
||||
about which strategy is used to generated primary key values for this entity. This example uses a simple
|
||||
incrementing count.
|
||||
</para>
|
||||
|
||||
<example id="hibernate-gsg-tutorial-basic-mapping-property">
|
||||
|
@ -186,38 +182,37 @@
|
|||
</example>
|
||||
|
||||
<para>
|
||||
The two <literal>property</literal> elements declare the remaining two properties of the
|
||||
<classname>Event</classname> class: <literal>date</literal> and<literal>title</literal>. The
|
||||
<literal>date</literal> property mapping includes the <literal>column</literal> attribute, but the
|
||||
<literal>title</literal> does not. In the absence of a <literal>column</literal> attribute, Hibernate
|
||||
uses the property name as the column name. This is appropriate for <literal>title</literal>, but since
|
||||
<literal>date</literal> is a reserved keyword in most databases, you need to specify a non-reserved
|
||||
The two <varname>property</varname> elements declare the remaining two properties of the
|
||||
<classname>Event</classname> class: <varname>date</varname> and <varname>title</varname>. The
|
||||
<varname>date</varname> property mapping includes the <option>column</option> attribute, but the
|
||||
<varname>title</varname> does not. In the absence of a <option>column</option> attribute, Hibernate
|
||||
uses the property name as the column name. This is appropriate for <varname>title</varname>, but since
|
||||
<varname>date</varname> is a reserved keyword in most databases, you need to specify a non-reserved
|
||||
word for the column name.
|
||||
</para>
|
||||
<para>
|
||||
The <literal>title</literal> mapping also lacks a <literal>type</literal> attribute. The types
|
||||
The <varname>title</varname> mapping also lacks a <option>type</option> attribute. The types
|
||||
declared and used in the mapping files are neither Java data types nor SQL database types. Instead,
|
||||
they are <firstterm><phrase>Hibernate mapping types</phrase></firstterm>. Hibernate mapping types are
|
||||
converters which translate between Java and SQL data types. Hibernate attempts to determine the correct
|
||||
conversion and mapping type autonomously if the <literal>type</literal> attribute is not present in the
|
||||
conversion and mapping type autonomously if the <option>type</option> attribute is not present in the
|
||||
mapping, by using Java reflection to determine the Java type of the declared property and using a
|
||||
default mapping type for that Java type.
|
||||
</para>
|
||||
<para>
|
||||
In some cases this automatic detection might not chose the default you expect or need, as seen with the
|
||||
<literal>date</literal> property. Hibernate cannot know if the property, which is of type
|
||||
<varname>date</varname> property. Hibernate cannot know if the property, which is of type
|
||||
<classname>java.util.Date</classname>, should map to a SQL <database class="datatype">DATE</database>,
|
||||
<database class="datatype">TIME</database>, or <database class="datatype">TIMESTAMP</database> datatype.
|
||||
Full date and time information is preserved by mapping the property to a <literal>timestamp</literal>
|
||||
converter (which identifies an instance of the class
|
||||
<classname>org.hibernate.type.TimestampType</classname>).
|
||||
Full date and time information is preserved by mapping the property to a <type>timestamp</type> converter,
|
||||
which identifies an instance of the class <classname>org.hibernate.type.TimestampType</classname>.
|
||||
</para>
|
||||
|
||||
<tip>
|
||||
<!-- This tip probably makes more sense in the Dev Guide -->
|
||||
<para>
|
||||
Hibernate makes this mapping type determination using reflection when the mapping files are
|
||||
processed. This process can take time and resources. If startup performance is important, consider
|
||||
Hibernate determines the mapping type using reflection when the mapping files are processed. This
|
||||
process adds overhead in terms of time and resources. If startup performance is important, consider
|
||||
explicitly defining the type to use.
|
||||
</para>
|
||||
</tip>
|
||||
|
@ -232,10 +227,10 @@
|
|||
</para>
|
||||
<note>
|
||||
<para>
|
||||
The example code in these tutorials is done as JUnit tests mainly for ease of use. However it is
|
||||
nice in that <methodname>setUp</methodname> and <methodname>tearDown</methodname> roughly illustrate
|
||||
how a <interfacename>org.hibernate.SessionFactory</interfacename> would be created at the start up
|
||||
of an application and closed at the end of the application lifecycle.
|
||||
The examples in these tutorials are presented as JUnit tests, for ease of use. One benefit of this
|
||||
approach is that <methodname>setUp</methodname> and <methodname>tearDown</methodname> roughly illustrate
|
||||
how a <interfacename>org.hibernate.SessionFactory</interfacename> is created at the start-up of an
|
||||
application and closed<!--destroyed?--> at the end of the application lifecycle.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
|
@ -249,26 +244,42 @@
|
|||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
The <classname>org.hibernate.cfg.Configuration</classname> class is the first thing to notice. In this
|
||||
tutorial everything is simply configured via the <filename>hibernate.cfg.xml</filename> file
|
||||
discussed in<xref linkend="hibernate-gsg-tutorial-basic-config"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <classname>org.hibernate.cfg.Configuration</classname> is then used to create the
|
||||
<interfacename>org.hibernate.SessionFactory</interfacename> which is a thread-safe object that is
|
||||
instantiated once to serve the entire application.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <interfacename>org.hibernate.SessionFactory</interfacename> acts as a factory for
|
||||
<interfacename>org.hibernate.Session</interfacename> instances as can be seen in the
|
||||
<methodname>testBasicUsage</methodname> method. A <interfacename>org.hibernate.Session</interfacename>
|
||||
should be thought of as a corollary to a "unit of work".
|
||||
<procedure>
|
||||
<title>Tutorial Workflow</title>
|
||||
<step>
|
||||
<title>The configuration is loaded.</title>
|
||||
<para>
|
||||
The <classname>org.hibernate.cfg.Configuration</classname> class is the first thing to notice. In this
|
||||
tutorial, all configuration details are located in the <filename>hibernate.cfg.xml</filename> file
|
||||
discussed in <xref linkend="hibernate-gsg-tutorial-basic-config"/>.
|
||||
</para>
|
||||
</step>
|
||||
<step>
|
||||
<title>The <interfacename>org.hibernate.SessionFactory</interfacename> is created.</title>
|
||||
<para>
|
||||
The <classname>org.hibernate.cfg.Configuration</classname> then creates the
|
||||
<interfacename>org.hibernate.SessionFactory</interfacename> which is a thread-safe object that is
|
||||
instantiated once to serve the entire application.
|
||||
</para>
|
||||
</step>
|
||||
<step>
|
||||
<title><interfacename>SessionFactory</interfacename> creates <classname>Session</classname> instances.</title>
|
||||
<para>
|
||||
The <interfacename>org.hibernate.SessionFactory</interfacename> acts as a factory for
|
||||
<interfacename>org.hibernate.Session</interfacename> instances as can be seen in the
|
||||
<methodname>testBasicUsage</methodname> method.
|
||||
<!-- todo : reference to a discussion in dev guide -->
|
||||
</para>
|
||||
|
||||
</para>
|
||||
</step>
|
||||
<step>
|
||||
<title><classname>Session</classname>s perform work.</title>
|
||||
<para>
|
||||
A <interfacename>org.hibernate.Session</interfacename> should be thought of as a corollary to a "unit of
|
||||
work".
|
||||
</para>
|
||||
</step>
|
||||
</procedure>
|
||||
|
||||
<example id="hibernate-gsg-tutorial-basic-test-saving">
|
||||
<title>Saving entities</title>
|
||||
<programlisting role="JAVA">Session session = sessionFactory.openSession();
|
||||
|
@ -280,9 +291,9 @@ session.close();</programlisting>
|
|||
</example>
|
||||
|
||||
<para>
|
||||
<methodname>testBasicUsage</methodname> first creates some new <classname>Event</classname> objects
|
||||
and hands them over to Hibernate for "management" via the <methodname>save</methodname> method. At that
|
||||
point, Hibernate takes responsibility to perform an <literal>INSERT</literal> on the database.
|
||||
<methodname>testBasicUsage</methodname> first creates some new <classname>Event</classname> objects and
|
||||
hands them over to Hibernate for management, using the <methodname>save</methodname> method. Hibernate now
|
||||
takes responsibility to perform an <command>INSERT</command> on the database.
|
||||
</para>
|
||||
|
||||
<example id="hibernate-gsg-tutorial-basic-test-list">
|
||||
|
@ -298,19 +309,17 @@ session.close();]]></programlisting>
|
|||
</example>
|
||||
|
||||
<para>
|
||||
<methodname>testBasicUsage</methodname> then illustrates use of the Hibernate Query Language (HQL) to
|
||||
load all existing <classname>Event</classname> objects from the database. Hibernate will generate the
|
||||
appropriate <literal>SELECT</literal> SQL, send it to the database and populate
|
||||
<classname>Event</classname> objects with the result set data.
|
||||
<methodname>testBasicUsage</methodname> illustrates use of the <firstterm>Hibernate Query Language
|
||||
(HQL)</firstterm> to load all existing <classname>Event</classname> objects from the database and generate the
|
||||
appropriate <literal>SELECT</literal> SQL, send it to the database and populate <classname>Event</classname>
|
||||
objects with the result set data.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="hibernate-gsg-tutorial-annotations-further">
|
||||
<title>Take it further!</title>
|
||||
<para>
|
||||
Try the following exercises:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<title>Practice Exercises</title>
|
||||
<listitem>
|
||||
<para>
|
||||
Reconfigure the examples to connect to your own persistent relational database.
|
||||
|
|
Loading…
Reference in New Issue