Line edits regarding HHH-5441

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@20147 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
misty 2010-08-15 23:30:03 +00:00
parent 4857ccd369
commit 916a6ecb3e
2 changed files with 159 additions and 178 deletions

View File

@ -0,0 +1,48 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.hibernate.tutorials</groupId>
<artifactId>hibernate-tutorial-native</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>Hibernate Native Tutorial</name>
<build>
<!-- we dont want the version to be part of the generated war file name -->
<finalName>${artifactId}</finalName>
</build>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<!-- Because this is a web app, we also have a dependency on the servlet api. -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
<!-- Hibernate uses slf4j for logging, for our purposes here use the simple backend -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<!-- Hibernate gives you a choice of bytecode providers between cglib and javassist -->
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
</dependency>
<!-- The tutorial uses the H2 in-memory database -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -6,18 +6,18 @@
<note>
<para>
This tutorial will use the "standard layout" advocated by many build tools and best practices.
<ulink url="http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html"/>
provides a good description of the "standard layout" if you are unfamiliar.
This tutorial uses the <phrase>standard layout</phrase> described in
<ulink
url="http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html"/>.
</para>
</note>
<tip>
<para>
The tutorials in this guide utilize Maven, taking advantage of its transitive dependency management
capabilities as well as the ability of many IDEs to automatically set up a project based on the Maven
descriptor. Just be aware that it is not a requirement to use Maven as your build tool in order to use
Hibernate.
The tutorials in this guide use Maven, which includes superior
transitive dependency management capabilities and is easy to use
with many integrated development environments (IDEs). You can use
another build tool, adapting the examples to fit your needs.
</para>
</tip>
@ -27,59 +27,13 @@
<step id="hibernate-gsg-tutorial-native-pom">
<title>Create the Maven POM file</title>
<para>
Create a file named <filename>pom.xml</filename> in the root of your project directory with the
following contents
Create a file named <filename>pom.xml</filename> in the root of
your project directory, containing the the text in <xref
linkend="hibernate-gsg-tutorial-native-pom-ex1" />.
</para>
<example id="hibernate-gsg-tutorial-native-pom-ex1">
<title><filename>pom.xml</filename></title>
<programlisting role="XML"><![CDATA[<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.hibernate.tutorials</groupId>
<artifactId>hibernate-tutorial-native</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>Hibernate Native Tutorial</name>
<build>
<!-- we dont want the version to be part of the generated war file name -->
<finalName>${artifactId}</finalName>
</build>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<!-- Because this is a web app, we also have a dependency on the servlet api. -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
<!-- Hibernate uses slf4j for logging, for our purposes here use the simple backend -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<!-- Hibernate gives you a choice of bytecode providers between cglib and javassist -->
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
</dependency>
<!-- The tutorial uses the H2 in-memory database -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
</project>]]></programlisting>
<programlisting role="XML"><xi:include href="extras/example-pom.xml" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
</example>
</step>
@ -87,68 +41,36 @@
<title>Create the entity Java class</title>
<para>
Create a file named <filename>src/main/java/org/hibernate/tutorial/native/Event.java</filename>
with the following contents:
Create a file named <filename>src/main/java/org/hibernate/tutorial/native/Event.java</filename>, containing the text in <xref linkend="hibernate-gsg-tutorial-native-entity-ex1" />.
</para>
<example id="hibernate-gsg-tutorial-native-entity-ex1">
<title><filename>Entity.java</filename></title>
<programlisting role="JAVA"><![CDATA[package org.hibernate.tutorial.native;
import java.util.Date;
public class Event {
private Long id;
private String title;
private Date date;
public Event() {}
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}]]></programlisting>
<programlisting role="JAVA"><xi:include href="extras/example-entity.java" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
</example>
<para>
<!-- todo : what's the best way to refer to content in other books? -->
<!-- like here it would be nice to say something like: -->
<!-- "Entity class requirements are covered in detail in <x.y.z Some Developer Guide Chapter/Section>" -->
A few things to notice about the entity
<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.
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 (also a JavaBean convention) is a requirement for all
persistent classes. Hibernate has to create objects for you, using Java Reflection. The
constructor could be private, however package or public visibility is required for runtime
proxy generation and efficient data retrieval without bytecode instrumentation.
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>
@ -159,107 +81,118 @@
<title>Create the entity mapping file</title>
<para>
Create a file named <filename>src/main/resources/org/hibernate/tutorial/native/Event.hbm.xml</filename>
with the following contents:
Create a file named <filename>src/main/resources/org/hibernate/tutorial/native/Event.hbm.xml</filename>, with the contents in <xref linkend="example-Event.hbm.xml" />.
</para>
<example>
<title><filename>Event.hbm.xml</filename></title>
<programlisting role="XML"><![CDATA[
<hibernate-mapping package="org.hibernate.tutorial.native">
<class name="Event" table="EVENTS">
<id name="id" column="EVENT_ID">
<generator class="enhanced-sequence"/>
</id>
<property name="date" type="timestamp" column="EVENT_DATE"/>
<property name="title"/>
</class>
</hibernate-mapping>]]></programlisting>
<programlisting role="XML"><xi:include href="extras/example-Event.hbm.xml" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
</example>
<para>
Hibernate needs to know how to load and store objects of the persistent class. This is where the
"mapping metadata" comes into play. The Hibernate mapping file is one choice for providing Hibernate
with this metadata.
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.
</para>
<orderedlist>
<title>Functions of the <literal>class</literal> element</title>
<listitem>
<para>
The <literal>class</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.
</para>
</listitem>
<listitem>
<para>
The <literal>table</literal> attribute names the database
table which contains the data for this entity.
</para>
</listitem>
</orderedlist>
<para>
The <literal>class</literal> element here is doing 2 things.
<orderedlist>
<listitem>
<para>
The <literal>class</literal> attribute (here combined with the <literal>package</literal>
attribute from the containing <literal>hibernate-mapping</literal> element) names the FQN
of the class we want to define as an entity.
</para>
</listitem>
<listitem>
<para>
The <literal>table</literal> attribute names the database table which contains the data
for this entity.
</para>
</listitem>
</orderedlist>
Instances of <classname>Event</classname> are now mapped to rows
in the <literal>EVENTS</literal> table. Hibernate uses the
<literal>id</literal> element to uniquely identify rows in the
table.
</para>
<para>
Instances of <classname>Event</classname> are now "mapped" to rows in the <literal>EVENTS</literal> table.
But an assumption there is that Hibernate knows how to uniquely identify rows in the table. This is the
purpose of the <literal>id</literal> element. It names the column(s) which uniquely identify each row.
</para>
<note>
<important>
<para>
It is not strictly necessary that the <literal>id</literal> element map to the table's
actual primary key column(s); however that is the normal convention. Nor is it strictly
necessary that tables mapped in Hibernate even define primary keys, the Hibernate team
<emphasis>highly</emphasis> recommends all schemas define proper referential integrity.
Therefore <literal>id</literal> and primary key are used interchangeably throughout Hibernate
documentation.
It is not strictly necessary that the <literal>id</literal>
element 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.
</para>
</note>
</important>
<para>
The <literal>id</literal> element here identifies the <literal>EVENT_ID</literal> column as the primary
key of the <literal>EVENTS</literal> table. Further, it names the <literal>id</literal> property of
the <classname>Event</classname> class is the property to hold the identifier value.
The <literal>id</literal> element here identifies the
<literal>EVENT_ID</literal> column as the primary key of the
<literal>EVENTS</literal> table. It also identifies the
<literal>id</literal> property of the
<classname>Event</classname> class as the property to hold the
identifier value.
</para>
<para>
In regards to the <literal>generator</literal> element nested inside the <literal>id</literal> element,
for now just be aware that it tells Hibernate the strategy used to generated primary key values for
this entity. Here we are telling it to use a sequence-like value generation.
The important thing to be aware of about the
<literal>generator</literal> element nested inside the
<literal>id</literal> element is that it informs Hibernate which
strategy is used to generated primary key values for this
entity. In this instance, it uses a sequence-like value
generation.
</para>
<para>
The 2 <literal>property</literal> elements are declaring the remaining 2 properties of the
<classname>Event</classname> class: <literal>date</literal> and <literal>title</literal>. Notice
that the <literal>date</literal> property mapping include the <literal>column</literal>
attribute, but the <literal>title</literal> does not. Without the <literal>column</literal>
attribute, Hibernate by default uses the property name as the column name. This works for
<literal>title</literal>, however, <literal>date</literal> is a reserved keyword in most databases
so you will need to explicitly tell Hibernate the column name in this case.
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 include the
<literal>column</literal> attribute, but the
<literal>title</literal> does not. In the absense 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 word for the column name.
</para>
<para>
The <literal>title</literal> mapping also lacks a <literal>type</literal> attribute. The
types declared and used in the mapping files are not Java data types; they are not SQL
database types either. These types are called <emphasis>Hibernate mapping types</emphasis>,
converters which can translate from Java to SQL data types and vice versa. Hibernate will try to
determine the correct conversion and mapping type itself if the <literal>type</literal> 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. In some cases this automatic detection might not
have the default you expect or need. This is the case with the <literal>date</literal> property.
Hibernate cannot know if the property, which is of type <classname>java.util.Date</classname>, should
map to a SQL <literal>DATE</literal>, <literal>TIME</literal>, or <literal>TIMESTAMP</literal> datatype.
Full date and time information is preserved by mapping the property with a <literal>timestamp</literal>
converter.
The <literal>title</literal> mapping also lacks a
<literal>type</literal> 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 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 have the
default you expect or need, as seen with the
<literal>date</literal> property. Hibernate cannot know if the
property, which is of type
<classname>java.util.Date</classname>, should map to a SQL
<literal>DATE</literal>, <literal>TIME</literal>, or
<literal>TIMESTAMP</literal> datatype. Full date and time
information is preserved by mapping the property to a
<literal>timestamp</literal> converter.
</para>
<tip>
<para>
Hibernate makes this mapping type determination using reflection when the mapping files
are processed. This can take time and resources, so if startup performance is important
you should consider explicitly defining the type to use.
Hibernate makes this mapping type determination using
reflection when the mapping files are processed. This can
take time and resources. If startup performance is
important, consider explicitly defining the type to use.
</para>
</tip>
</step>
<step id="hibernate-gsg-tutorial-native-config">