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> <note>
<para> <para>
This tutorial will use the "standard layout" advocated by many build tools and best practices. 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"/> <ulink
provides a good description of the "standard layout" if you are unfamiliar. url="http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html"/>.
</para> </para>
</note> </note>
<tip> <tip>
<para> <para>
The tutorials in this guide utilize Maven, taking advantage of its transitive dependency management The tutorials in this guide use Maven, which includes superior
capabilities as well as the ability of many IDEs to automatically set up a project based on the Maven transitive dependency management capabilities and is easy to use
descriptor. Just be aware that it is not a requirement to use Maven as your build tool in order to use with many integrated development environments (IDEs). You can use
Hibernate. another build tool, adapting the examples to fit your needs.
</para> </para>
</tip> </tip>
@ -27,59 +27,13 @@
<step id="hibernate-gsg-tutorial-native-pom"> <step id="hibernate-gsg-tutorial-native-pom">
<title>Create the Maven POM file</title> <title>Create the Maven POM file</title>
<para> <para>
Create a file named <filename>pom.xml</filename> in the root of your project directory with the Create a file named <filename>pom.xml</filename> in the root of
following contents your project directory, containing the the text in <xref
linkend="hibernate-gsg-tutorial-native-pom-ex1" />.
</para> </para>
<example id="hibernate-gsg-tutorial-native-pom-ex1"> <example id="hibernate-gsg-tutorial-native-pom-ex1">
<title><filename>pom.xml</filename></title> <title><filename>pom.xml</filename></title>
<programlisting role="XML"><![CDATA[<project xmlns="http://maven.apache.org/POM/4.0.0" <programlisting role="XML"><xi:include href="extras/example-pom.xml" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
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>
</example> </example>
</step> </step>
@ -87,68 +41,36 @@
<title>Create the entity Java class</title> <title>Create the entity Java class</title>
<para> <para>
Create a file named <filename>src/main/java/org/hibernate/tutorial/native/Event.java</filename> 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" />.
with the following contents:
</para> </para>
<example id="hibernate-gsg-tutorial-native-entity-ex1"> <example id="hibernate-gsg-tutorial-native-entity-ex1">
<title><filename>Entity.java</filename></title> <title><filename>Entity.java</filename></title>
<programlisting role="JAVA"><![CDATA[package org.hibernate.tutorial.native; <programlisting role="JAVA"><xi:include href="extras/example-entity.java" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
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>
</example> </example>
<para> <para>
<!-- todo : what's the best way to refer to content in other books? --> <!-- todo : what's the best way to refer to content in other books? -->
<!-- like here it would be nice to say something like: --> <!-- 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>" --> <!-- "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> <itemizedlist>
<title>Notes About the Entity</title>
<listitem> <listitem>
<para> <para>
This class uses standard JavaBean naming conventions for property getter and setter This class uses standard JavaBean naming conventions
methods, as well as private visibility for the fields. Although this is the for property getter and setter methods, as well as
recommended design, it is not required. private visibility for the fields. Although this is
the recommended design, it is not required.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
The no-argument constructor (also a JavaBean convention) is a requirement for all The no-argument constructor, which is also a JavaBean
persistent classes. Hibernate has to create objects for you, using Java Reflection. The convention, is a requirement for all persistent
constructor could be private, however package or public visibility is required for runtime classes. Hibernate needs to create objects for you,
proxy generation and efficient data retrieval without bytecode instrumentation. 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> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -159,107 +81,118 @@
<title>Create the entity mapping file</title> <title>Create the entity mapping file</title>
<para> <para>
Create a file named <filename>src/main/resources/org/hibernate/tutorial/native/Event.hbm.xml</filename> 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" />.
with the following contents:
</para> </para>
<example> <example>
<title><filename>Event.hbm.xml</filename></title> <title><filename>Event.hbm.xml</filename></title>
<programlisting role="XML"><![CDATA[ <programlisting role="XML"><xi:include href="extras/example-Event.hbm.xml" xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>
<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>
</example> </example>
<para> <para>
Hibernate needs to know how to load and store objects of the persistent class. This is where the Hibernate uses the mapping metadata to find out how to load and
"mapping metadata" comes into play. The Hibernate mapping file is one choice for providing Hibernate store objects of the persistent class. The Hibernate mapping
with this metadata. file is one choice for providing Hibernate with this metadata.
</para> </para>
<para>
The <literal>class</literal> element here is doing 2 things.
<orderedlist> <orderedlist>
<title>Functions of the <literal>class</literal> element</title>
<listitem> <listitem>
<para> <para>
The <literal>class</literal> attribute (here combined with the <literal>package</literal> The <literal>class</literal> attribute, combined here with the
attribute from the containing <literal>hibernate-mapping</literal> element) names the FQN <literal>package</literal> attribute from the containing
of the class we want to define as an entity. <literal>hibernate-mapping</literal> element, names the FQN of
the class you want to define as an entity.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
The <literal>table</literal> attribute names the database table which contains the data The <literal>table</literal> attribute names the database
for this entity. table which contains the data for this entity.
</para> </para>
</listitem> </listitem>
</orderedlist> </orderedlist>
<para>
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>
<important>
<para>
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>
</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. It also identifies the
<literal>id</literal> property of the
<classname>Event</classname> class as the property to hold the
identifier value.
</para> </para>
<para> <para>
Instances of <classname>Event</classname> are now "mapped" to rows in the <literal>EVENTS</literal> table. The important thing to be aware of about the
But an assumption there is that Hibernate knows how to uniquely identify rows in the table. This is the <literal>generator</literal> element nested inside the
purpose of the <literal>id</literal> element. It names the column(s) which uniquely identify each row. <literal>id</literal> element is that it informs Hibernate which
</para> strategy is used to generated primary key values for this
<note> entity. In this instance, it uses a sequence-like value
<para> generation.
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.
</para>
</note>
<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.
</para> </para>
<para> <para>
In regards to the <literal>generator</literal> element nested inside the <literal>id</literal> element, The two <literal>property</literal> elements declare the
for now just be aware that it tells Hibernate the strategy used to generated primary key values for remaining two properties of the <classname>Event</classname>
this entity. Here we are telling it to use a sequence-like value generation. 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>
<para> <para>
The 2 <literal>property</literal> elements are declaring the remaining 2 properties of the The <literal>title</literal> mapping also lacks a
<classname>Event</classname> class: <literal>date</literal> and <literal>title</literal>. Notice <literal>type</literal> attribute. The types declared and used
that the <literal>date</literal> property mapping include the <literal>column</literal> in the mapping files are neither Java data types nor SQL
attribute, but the <literal>title</literal> does not. Without the <literal>column</literal> database types. Instead, they are <firstterm><phrase>Hibernate
attribute, Hibernate by default uses the property name as the column name. This works for mapping types</phrase></firstterm>. Hibernate mapping types are
<literal>title</literal>, however, <literal>date</literal> is a reserved keyword in most databases converters which translate between Java and SQL data types.
so you will need to explicitly tell Hibernate the column name in this case. 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>
<para> <para>
The <literal>title</literal> mapping also lacks a <literal>type</literal> attribute. The In some cases this automatic detection might not have the
types declared and used in the mapping files are not Java data types; they are not SQL default you expect or need, as seen with the
database types either. These types are called <emphasis>Hibernate mapping types</emphasis>, <literal>date</literal> property. Hibernate cannot know if the
converters which can translate from Java to SQL data types and vice versa. Hibernate will try to property, which is of type
determine the correct conversion and mapping type itself if the <literal>type</literal> attribute is not <classname>java.util.Date</classname>, should map to a SQL
present in the mapping by using Java reflection to determine the Java type of the declared property <literal>DATE</literal>, <literal>TIME</literal>, or
and using a default mapping type for that Java type. In some cases this automatic detection might not <literal>TIMESTAMP</literal> datatype. Full date and time
have the default you expect or need. This is the case with the <literal>date</literal> property. information is preserved by mapping the property to a
Hibernate cannot know if the property, which is of type <classname>java.util.Date</classname>, should <literal>timestamp</literal> converter.
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.
</para> </para>
<tip> <tip>
<para> <para>
Hibernate makes this mapping type determination using reflection when the mapping files Hibernate makes this mapping type determination using
are processed. This can take time and resources, so if startup performance is important reflection when the mapping files are processed. This can
you should consider explicitly defining the type to use. take time and resources. If startup performance is
important, consider explicitly defining the type to use.
</para> </para>
</tip> </tip>
</step> </step>
<step id="hibernate-gsg-tutorial-native-config"> <step id="hibernate-gsg-tutorial-native-config">