HHH-10022 - Continue documentation TLC (part 2)
This commit is contained in:
parent
9b007f6d91
commit
6fdc4cab8d
|
@ -45,15 +45,18 @@
|
|||
<xi:include href="Preface.xml" />
|
||||
|
||||
<xi:include href="chapters/categoizations/Data_Categorizations.xml" />
|
||||
<xi:include href="chapters/entity/Entity.xml" />
|
||||
<xi:include href="chapters/basic/Basic_Types.xml" />
|
||||
<xi:include href="chapters/composition/Composition.xml" />
|
||||
<xi:include href="chapters/collection/Collection.xml" />
|
||||
<xi:include href="chapters/entity/Entity.xml" />
|
||||
<!--
|
||||
<xi:include href="chapters/association/Associations.xml" />
|
||||
-->
|
||||
|
||||
<xi:include href="chapters/id/Identifiers.xml" />
|
||||
<xi:include href="chapters/natural_id/Natural_Id.xml" />
|
||||
|
||||
<!--
|
||||
<xi:include href="chapters/association/Associations.xml" />
|
||||
<xi:include href="chapters/secondary/Secondary_Tables.xml" />
|
||||
|
||||
<xi:include href="chapters/constraints/Database_Constraints.xml" /> pk, fk, index, check, unique
|
||||
|
@ -68,6 +71,8 @@
|
|||
|
||||
<xi:include href="chapters/naming/Naming_Strategies.xml" />
|
||||
<xi:include href="chapters/quoting/SQL_Identifier_Quoting.xml" />
|
||||
|
||||
XML mappings
|
||||
-->
|
||||
|
||||
<!-- appendices? -->
|
||||
|
|
|
@ -6,17 +6,330 @@
|
|||
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
-->
|
||||
<chapter xml:id="entity"
|
||||
version="5.0"
|
||||
xml:lang="en"
|
||||
xmlns="http://docbook.org/ns/docbook"
|
||||
>
|
||||
<title>Entity</title>
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns="http://docbook.org/ns/docbook" version="5.0">
|
||||
<info>
|
||||
<title>Entity</title>
|
||||
<abstract>
|
||||
<para>Discuss mapping entities in the application domain model.</para>
|
||||
</abstract>
|
||||
</info>
|
||||
|
||||
<sidebar>
|
||||
<title>Related Topics</title>
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><xref linkend="categorization" </para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><xref linkend="locking" /></para>
|
||||
</listitem>
|
||||
<!-- caching? -->
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sidebar>
|
||||
|
||||
<section xml:id="entity-pojo">
|
||||
<title>POJO Models</title>
|
||||
|
||||
<para>
|
||||
Section <citetitle>2.1 The Entity Class</citetitle> of the <citetitle>JPA 2.1 specification</citetitle>
|
||||
defines its requirements for an entity class. Applications that wish to remain portable across JPA providers
|
||||
should adhere to these requirements.
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The entity class must be annotated with the <interfacename>javax.persistence.Entity</interfacename>
|
||||
annotation (or be denoted as such in XML mapping)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The entity class must have a public or protected no-argument constructor. It may define
|
||||
additional constructors as well.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The entity class must be a top-level class.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
An enum or interface may not be designated as an entity.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The entity class must not be final. No methods or persistent instance variables of the entity
|
||||
class may be final.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If an entity instance is to be used remotely as a detached object, the entity class must
|
||||
implement the Serializable interface.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Both abstract and concrete classes can be entities. Entities may extend non-entity classes as
|
||||
well as entity classes, and non-entity classes may extend entity classes.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The persistent state of an entity is represented by instance variables, which may correspond to
|
||||
JavaBean-style properties. An instance variable must be directly accessed only from within the
|
||||
methods of the entity by the entity instance itself. The state of the entity is available to
|
||||
clients only through the entity’s accessor methods (getter/setter methods) or other business
|
||||
methods.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Hibernate, however, is not as strict in its requirements. The differences from the list above include:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The entity class must have a no-argument constructor, which may be public, protected or package
|
||||
visibility. It may define additional constructors as well.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The entity class <emphasis>need not</emphasis> be a top-level class.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Technically Hibernate can persist final classes or classes with final persistent state
|
||||
accessor (getter/setter) methods. However, it is generally not a good idea as doing
|
||||
so will stop Hibernate from being able to generate proxies for lazy-loading the entity.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Hibernate does not really care if you expose direct access to your instance variables and
|
||||
use them from outside the entity itself. The validity of such a paradigm, however, is debatable
|
||||
at best.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Let's look at each requirement in detail.
|
||||
</para>
|
||||
|
||||
<section xml:id="entity-pojo-final">
|
||||
<title>Prefer non-final classes</title>
|
||||
|
||||
<para>
|
||||
This is a requirement for JPA. It is more of a recommendation for Hibernate.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A central feature of Hibernate is the ability to lazy load an entity's data via runtime proxies. This
|
||||
feature depends upon the entity class being non-final or else implementing an interface that declares
|
||||
all the attribute getters/setters. You can still persist classes that are declared final and that do
|
||||
not implement such an interface with Hibernate; you just will not be able to use proxies for lazy
|
||||
association fetching which will ultimately limit your options for performance tuning.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Starting in 5.0 Hibernate offers a more robust version of bytecode enhancement as another means
|
||||
for handling lazy loading. Hibernate had some bytecode re-writing capabilities prior to 5.0 but
|
||||
they were very rudimentary.
|
||||
<!-- todo : xref to discussion of bytecode enhancement -->
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
You should also avoid declaring persistent attribute getters and setters as final for the reasons
|
||||
already mentioned. And of course making the instance variable hold the entiy's persistent state would
|
||||
just simply not make any sense.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="entity-pojo-constructor">
|
||||
<title>Implement a no-argument constructor</title>
|
||||
|
||||
<para>
|
||||
The entity class should have a no-argument constructor. Both Hibernate and JPA require this.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
JPA requires that this constructor be defined as public or protected. Hibernate for the most part does
|
||||
note care about the visibility as long as the system's SecurityManager allows overriding the visibility.
|
||||
That said, the constructor should be defined with at least package visibility if you wish to leverage
|
||||
runtime proxy generation.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="domainmodel-pojo-accessors">
|
||||
<title>Declare getters and setters for persistent attributes</title>
|
||||
|
||||
<para>
|
||||
Standard, portable JPA essentially requires this. Otherwise your model would violate the requirement
|
||||
quoted above in regards to accessing the entity persistent state fields directly from outside the
|
||||
entity itself.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Although Hibernate does not require it, it is recommended to follow JavaBean conventions by defining
|
||||
getters and setters for you entities persistent attributes. You can still tell Hibernate to directly
|
||||
access the entity's fields.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Attributes (whether fields or getters/setters) need not be declared public. Hibernate can deal with
|
||||
attributes declared with public, protected, package or private visibility. Again, if wanting to use
|
||||
runtime proxy generation for lazy loading the visibility for the getter/setter should be at least
|
||||
package visibility.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
<section xml:id="entity-pojo-identifier">
|
||||
<title>Provide identifier attribute(s)</title>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Historically this was considered optional. However, not defining identifier attribute(s) on the
|
||||
entity should be considered a deprecated feature that will be removed in an upcoming release.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
The identifier attribute does not necessarily need to be mapped to the column(s) that physically
|
||||
define the primary key. However, it should map to column(s) that can uniquely identify each row.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
We recommend that you declare consistently-named identifier attributes on persistent classes and
|
||||
that you use a nullable (i.e., non-primitive) type.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="entity-pojo-mapping">
|
||||
<title>Mapping the entity</title>
|
||||
|
||||
<para>
|
||||
The main piece in mapping the entity is the <interfacename>javax.persistence.Entity</interfacename>
|
||||
annotation. The Entity annotation defines just one attribute <methodname>name</methodname> which
|
||||
is used to give the entity a specific name for use in JPQL queries; by default the name is the
|
||||
unqualified name of the entity class.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Simple @Entity</title>
|
||||
<programlisting role="JAVA"><xi:include href="extras/SimpleEntity.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
An entity models a database table. The identifier uniquely identifies each row in that table. By
|
||||
default the name of the table is assumed to be the same as the name of the entity. To explicitly
|
||||
give the name of the table or to specify other information about the table, we would use the
|
||||
<interfacename>javax.persistence.Table</interfacename> annotation.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Simple @Entity with @Table</title>
|
||||
<programlisting role="JAVA"><xi:include href="extras/SimpleEntityWithTable.java" parse="text" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
For details on mapping the identifier, see <xref linkend="identifiers" />
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="entity-pojo-optlock">
|
||||
<title>Mapping optimistic locking</title>
|
||||
|
||||
<para>
|
||||
JPA defines support for optimistic locking based on either a version (sequential numeric) or timestamp
|
||||
strategy. To enable this style of optimistic locking simply add the
|
||||
<interfacename>javax.persistence.Version</interfacename> to the persistent attribute that defines the
|
||||
optimistic locking value. According to JPA, the valid types for these attributes are limited to:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>int, or Integer</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>short, or Short</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>long, or Long</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>java.sql.Timestamp</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Version</title>
|
||||
<programlisting role="JAVA"><xi:include href="extras/Version.java" parse="text" /></programlisting>
|
||||
<programlisting role="JAVA"><xi:include href="extras/Timestamp.java" parse="text" /></programlisting>
|
||||
<programlisting role="JAVA"><xi:include href="extras/Instant.java" parse="text" /></programlisting>
|
||||
<!-- ^^ Coming soon : HHH-10026 -->
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Hibernate supports a form of optimistic locking that does not require a dedicated "version attribute".
|
||||
This is intended mainly for use with modeling legacy schemas. The idea is that you can get Hibernate
|
||||
to perform "version checks" using either all of the entity's attributes, or just the attributes that
|
||||
have changed. This is achieved through the use of the
|
||||
<interfacename>org.hibernate.annotations.OptimisticLocking</interfacename> annotation which defines a
|
||||
single attribute of type <interfacename>org.hibernate.annotations.OptimisticLockType</interfacename>.
|
||||
There are 4 available OptimisticLockTypes:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>NONE</literal> - optimistic locking is disabled. Even if there is a @Version
|
||||
annotation present.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>VERSION</literal> (the default) - performs optimistic locking based on a @Version
|
||||
as described above.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>ALL</literal> - Perform optimistic locking based on *all* fields as part of an
|
||||
expanded WHERE clause restriction for the UPDATE/DELETE SQL statement.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>DIRTY</literal> - Perform optimistic locking based on *dirty* fields as part of
|
||||
an expanded WHERE clause restriction for the UPDATE/DELETE SQL statement
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="entity-pojo-inheritance">
|
||||
<title>Inheritance</title>
|
||||
<para>
|
||||
<!-- todo : keep it going! -->
|
||||
blah blah blah
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<para>
|
||||
* POJO, etc discussion from manual/en-US/chapters/domain/DomainModel.xml
|
||||
* dynamic models (hbm.xml)
|
||||
* Map mode
|
||||
* proxy solutions (hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer2)
|
||||
* inheritance
|
||||
* optimistic locking
|
||||
</para>
|
||||
</chapter>
|
|
@ -0,0 +1,8 @@
|
|||
@Entity
|
||||
public class Thing2 {
|
||||
@Id
|
||||
private Integer id;
|
||||
@Version
|
||||
private Instant ts;
|
||||
...
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
@Entity
|
||||
public class Simple {
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
@Entity
|
||||
@Table( catalog="CRM", schema="purchasing", name="t_simple" )
|
||||
public class Simple {
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
@Entity
|
||||
public class Thing {
|
||||
@Id
|
||||
private Integer id;
|
||||
@Version
|
||||
Timestamp ts;
|
||||
...
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
@Entity
|
||||
public class Course {
|
||||
@Id
|
||||
private Integer id;
|
||||
@Version
|
||||
private Integer version;
|
||||
...
|
||||
}
|
|
@ -104,7 +104,7 @@
|
|||
</note>
|
||||
|
||||
<para>
|
||||
You should also avoid declaring persistemt attribute getters and setters as final for the reasons
|
||||
You should also avoid declaring persistent attribute getters and setters as final for the reasons
|
||||
already mentioned.
|
||||
</para>
|
||||
</section>
|
||||
|
@ -113,7 +113,7 @@
|
|||
<title>Declare getters and setters for persistent attributes</title>
|
||||
|
||||
<para>
|
||||
Although not required, it is recommended to follow POJO/JavaBean conventions by defining getters and
|
||||
Although not required, it is recommended to follow JavaBean conventions by defining getters and
|
||||
setters for you entities persistent attributes. Hibernate can also directly access the entity's
|
||||
fields.
|
||||
</para>
|
||||
|
|
Loading…
Reference in New Issue