HHH-5181 - Merge hibernate-annotations module code into hibernate-core
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@19997 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
6b8d49ca82
commit
5d742087ac
|
@ -1,186 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Middleware LLC.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<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>
|
||||
|
||||
<parent>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-parent</artifactId>
|
||||
<version>3.6.0-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-annotations</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Hibernate Annotations</name>
|
||||
<description>Annotations metadata for Hibernate</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-commons-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>hibernate-testing</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<testResources>
|
||||
<testResource>
|
||||
<filtering>true</filtering>
|
||||
<directory>src/test/resources</directory>
|
||||
</testResource>
|
||||
</testResources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jboss.maven.plugins</groupId>
|
||||
<artifactId>maven-test-ext-plugin</artifactId>
|
||||
</plugin>
|
||||
<!--
|
||||
<plugin>
|
||||
<groupId>org.jboss.maven.plugins</groupId>
|
||||
<artifactId>maven-injection-plugin</artifactId>
|
||||
<configuration>
|
||||
<bytecodeInjections>
|
||||
<bytecodeInjection>
|
||||
<expression>${project.version}</expression>
|
||||
<targetMembers>
|
||||
<methodBodyReturn>
|
||||
<className>org.hibernate.cfg.annotations.Version</className>
|
||||
<methodName>getVersionString</methodName>
|
||||
</methodBodyReturn>
|
||||
</targetMembers>
|
||||
</bytecodeInjection>
|
||||
</bytecodeInjections>
|
||||
</configuration>
|
||||
</plugin>
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.twdata.maven</groupId>
|
||||
<artifactId>maven-cli-plugin</artifactId>
|
||||
<version>0.6.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>jaxb</id>
|
||||
<activation>
|
||||
<jdk>1.5</jdk>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<version>2.1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>doc</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jboss.maven.plugins</groupId>
|
||||
<artifactId>maven-jdocbook-plugin</artifactId>
|
||||
<configuration>
|
||||
<sourceDocumentName>master.xml</sourceDocumentName>
|
||||
<sourceDirectory>${basedir}/src/main/docbook</sourceDirectory>
|
||||
<masterTranslation>en</masterTranslation>
|
||||
<imageResource>
|
||||
<directory>${basedir}/src/main/docbook/en/images</directory>
|
||||
</imageResource>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-doc</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>resources</goal>
|
||||
<goal>generate</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -1,55 +0,0 @@
|
|||
Hibernate Annotations
|
||||
==================================================
|
||||
Version: @version@, @releasedate@
|
||||
|
||||
THIS RELEASE OF HIBERNATE ANNOTATIONS REQUIRES HIBERNATE CORE 3.3 (and above)
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The EJB3 specification recognizes the interest and the success of
|
||||
the transparent object/relational mapping paradigm. The EJB3 specification
|
||||
standardizes the basic APIs and the metadata needed for any object/relational
|
||||
persistence mechanism.
|
||||
|
||||
Hibernate EntityManager implements the programming interfaces and lifecycle rules
|
||||
as defined by the EJB3 persistence specification. Together with Hibernate Annotations
|
||||
this wrapper implements a complete (and standalone) EJB3 persistence solution on
|
||||
top of the mature Hibernate core. You may use a combination of all three together,
|
||||
annotations without EJB3 programming interfaces and lifecycle, or even pure native
|
||||
Hibernate, depending on the business and technical needs of your project. You can
|
||||
at all times fall back to Hibernate native APIs, or if required, even to native
|
||||
JDBC and SQL.
|
||||
|
||||
|
||||
Instructions
|
||||
------------
|
||||
|
||||
Unzip to installation directory, read doc/reference
|
||||
|
||||
|
||||
Contact
|
||||
------------
|
||||
|
||||
Latest Documentation:
|
||||
|
||||
http://hibernate.org
|
||||
http://annotations.hibernate.org
|
||||
|
||||
Bug Reports:
|
||||
|
||||
Hibernate JIRA (preferred)
|
||||
hibernate-devel@lists.sourceforge.net
|
||||
|
||||
Free Technical Support:
|
||||
|
||||
http://forum.hibernate.org
|
||||
|
||||
|
||||
Notes
|
||||
-----------
|
||||
|
||||
If you want to contribute, go to http://www.hibernate.org/
|
||||
|
||||
This software and its documentation are distributed under the terms of the
|
||||
FSF Lesser Gnu Public License (see lgpl.txt).
|
|
@ -1,98 +0,0 @@
|
|||
<?xml version='1.0' encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Inc.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
<!ENTITY version "WORKING">
|
||||
<!ENTITY today "TODAY">
|
||||
<!ENTITY copyrightYear "2004">
|
||||
<!ENTITY copyrightHolder "Red Hat Inc. and the various authors">
|
||||
]>
|
||||
<book lang="en">
|
||||
<bookinfo>
|
||||
<title>Hibernate Annotations</title>
|
||||
<subtitle>Reference Guide</subtitle>
|
||||
|
||||
<releaseinfo>&version;</releaseinfo>
|
||||
<pubdate>&today;</pubdate>
|
||||
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="images/hibernate_logo_a.png" format="png" />
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
<copyright>
|
||||
<year>©rightYear;</year>
|
||||
<holder>©rightHolder;</holder>
|
||||
</copyright>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Emmanuel</firstname>
|
||||
<surname>Bernard</surname>
|
||||
</author>
|
||||
<!--TODO add translators like core did -->
|
||||
</authorgroup>
|
||||
</bookinfo>
|
||||
|
||||
<toc/>
|
||||
|
||||
<preface id="preface" revision="1">
|
||||
<title>Preface</title>
|
||||
|
||||
<para>Hibernate, like all other object/relational mapping tools, requires
|
||||
metadata that governs the transformation of data from one representation
|
||||
to the other. Hibernate Annotations provides annotation-based mapping metadata.
|
||||
</para>
|
||||
|
||||
<para>The JPA specification recognizes the interest and the success of
|
||||
the transparent object/relational mapping paradigm. It standardizes the
|
||||
basic APIs and the metadata needed for any object/relational persistence
|
||||
mechanism.
|
||||
<emphasis>Hibernate EntityManager</emphasis> implements the
|
||||
programming interfaces and lifecycle rules as defined by the JPA
|
||||
persistence specification and together with <emphasis>Hibernate
|
||||
Annotations</emphasis> offers a complete (and standalone) JPA persistence
|
||||
solution on top of the mature Hibernate Core. You may use a combination of
|
||||
all three together, annotations without JPA programming interfaces and
|
||||
lifecycle, or even pure native Hibernate Core, depending on the business and
|
||||
technical needs of your project. At all time you can fall back to
|
||||
Hibernate native APIs, or if required, even to native JDBC and SQL.</para>
|
||||
|
||||
<para>This release of <emphasis>Hibernate Annotations</emphasis> is based
|
||||
on the final release of the JPA 2 specification (aka <ulink
|
||||
url="http://jcp.org/en/jsr/detail?id=317">JSR-317</ulink>) and
|
||||
supports all its features (including the optional ones). Hibernate
|
||||
specific features and extensions are also available through
|
||||
unstandardized, Hibernate specific annotations.</para>
|
||||
|
||||
<para>If you are moving from previous Hibernate Annotations versions,
|
||||
please have a look at <ulink url="http://www.hibernate.org/398.html">Java
|
||||
Persistence migration guide</ulink>.</para>
|
||||
</preface>
|
||||
|
||||
<xi:include href="modules/setup.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="modules/entity.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="modules/xml-overriding.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="modules/additionalmodules.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
|
||||
</book>
|
|
@ -1,372 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Middleware LLC.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||
<chapter id="additionalmodules">
|
||||
<title>Additional modules</title>
|
||||
|
||||
<para>Hibernate Annotations mainly focuses on persistence metadata. The
|
||||
project also have a nice integration with some external modules.</para>
|
||||
|
||||
<section>
|
||||
<title>Bean Validation</title>
|
||||
|
||||
<para>Bean Validation standardizes how to define and declare domain model
|
||||
level constraints. You can, for example, express that a property should
|
||||
never be null, that the account balance should be strictly positive, etc.
|
||||
These domain model constraints are declared in the bean itself by
|
||||
annotating its properties. Bean Validation can then read them and check
|
||||
for constraint violations. The validation mechanism can be executed in
|
||||
different layers in your application without having to duplicate any of
|
||||
these rules (presentation layer, data access layer). Following the DRY
|
||||
principle, Bean Validation and its reference implementation Hibernate
|
||||
Validator has been designed for that purpose.</para>
|
||||
|
||||
<para>The integration between Hibernate and Bean Validation works at two
|
||||
levels. First, it is able to check in-memory instances of a class for
|
||||
constraint violations. Second, it can apply the constraints to the
|
||||
Hibernate metamodel and incorporate them into the generated database
|
||||
schema.</para>
|
||||
|
||||
<para>Each constraint annotation is associated to a validator
|
||||
implementation responsible for checking the constraint on the entity
|
||||
instance. A validator can also (optionally) apply the constraint to the
|
||||
Hibernate metamodel, allowing Hibernate to generate DDL that expresses the
|
||||
constraint. With the appropriate event listener, you can execute the
|
||||
checking operation on inserts, updates and deletes done by
|
||||
Hibernate.</para>
|
||||
|
||||
<para>When checking instances at runtime, Hibernate Validator returns
|
||||
information about constraint violations in a set of
|
||||
<classname>ConstraintViolation</classname>s. Among other information, the
|
||||
<classname>ConstraintViolation</classname> contains an error description
|
||||
message that can embed the parameter values bundle with the annotation
|
||||
(eg. size limit), and message strings that may be externalized to a
|
||||
<classname>ResourceBundle</classname>.</para>
|
||||
|
||||
<section>
|
||||
<title>Adding Bean Validation</title>
|
||||
|
||||
<para>To enable the Hibernate - Bean Validation integration, simply add
|
||||
a Bean Validation provider (preferably Hibernate Validation 4) in your
|
||||
classpath.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Configuration</title>
|
||||
|
||||
<para>By default, no configuration is necessary.</para>
|
||||
|
||||
<para>The <classname>Default</classname> group is validated on entity
|
||||
insert and update and the database model is updated accordingly based on
|
||||
the <classname>Default</classname> group as well.</para>
|
||||
|
||||
<para>You can customize the Bean Validation integration by setting the
|
||||
validation mode. Use the
|
||||
<literal>javax.persistence.validation.mode</literal> property and set it
|
||||
up for example in your <filename>persistence.xml</filename> file or your
|
||||
<filename>hibernate.cfg.xml</filename> file. Several options are
|
||||
possible:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>auto</literal> (default): enable integration between
|
||||
Bean Validation and Hibernate (callback and ddl generation) only if
|
||||
Bean Validation is present in the classpath.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>none</literal>: disable all integration between Bean
|
||||
Validation and Hibernate</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>callback</literal>: only validate entities when they
|
||||
are either inserted, updated or deleted. An exception is raised if
|
||||
no Bean Validation provider is present in the classpath.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>ddl</literal>: only apply constraints to the database
|
||||
schema when generated by Hibernate. An exception is raised if no
|
||||
Bean Validation provider is present in the classpath. This value is
|
||||
not defined by the Java Persistence spec and is specific to
|
||||
Hibernate.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<note>
|
||||
<para>You can use both <literal>callback</literal> and
|
||||
<literal>ddl</literal> together by setting the property to
|
||||
<literal>callback, dll</literal></para>
|
||||
|
||||
<programlisting language="XML" role="XML"><persistence ...>
|
||||
<persistence-unit ...>
|
||||
...
|
||||
<properties>
|
||||
<property name="javax.persistence.validation.mode"
|
||||
value="callback, ddl"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence></programlisting>
|
||||
|
||||
<para>This is equivalent to <literal>auto</literal> except that if no
|
||||
Bean Validation provider is present, an exception is raised.</para>
|
||||
</note>
|
||||
|
||||
<para>If you want to validate different groups during insertion, update
|
||||
and deletion, use:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>javax.persistence.validation.group.pre-persist</literal>:
|
||||
groups validated when an entity is about to be persisted (default to
|
||||
<classname>Default</classname>)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>javax.persistence.validation.group.pre-update</literal>:
|
||||
groups validated when an entity is about to be updated (default to
|
||||
<classname>Default</classname>)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>javax.persistence.validation.group.pre-remove</literal>:
|
||||
groups validated when an entity is about to be deleted (default to
|
||||
no group)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>org.hibernate.validator.group.ddl</literal>: groups
|
||||
considered when applying constraints on the database schema (default
|
||||
to <classname>Default</classname>)</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>Each property accepts the fully qualified class names of the
|
||||
groups validated separated by a comma (,)</para>
|
||||
|
||||
<example>
|
||||
<title>Using custom groups for validation</title>
|
||||
|
||||
<programlisting language="XML" role="XML"><persistence ...>
|
||||
<persistence-unit ...>
|
||||
...
|
||||
<properties>
|
||||
<property name="javax.persistence.validation.group.pre-update"
|
||||
value="javax.validation.group.Default, com.acme.group.Strict"/>
|
||||
<property name="javax.persistence.validation.group.pre-remove"
|
||||
value="com.acme.group.OnDelete"/>
|
||||
<property name="org.hibernate.validator.group.ddl"
|
||||
value="com.acme.group.DDL"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence></programlisting>
|
||||
</example>
|
||||
|
||||
<note>
|
||||
<para>You can set these properties in
|
||||
<filename>hibernate.cfg.xml</filename>,
|
||||
<filename>hibernate.properties</filename> or programmatically.</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Catching violations</title>
|
||||
|
||||
<para>If an entity is found to be invalid, the list of constraint
|
||||
violations is propagated by the
|
||||
<classname>ConstraintViolationException</classname> which exposes the
|
||||
set of <classname>ConstraintViolation</classname>s.</para>
|
||||
|
||||
<para>This exception is wrapped in a
|
||||
<classname>RollbackException</classname> when the violation happens at
|
||||
commit time. Otherwise the
|
||||
<classname>ConstraintViolationException</classname> is returned (for
|
||||
example when calling <methodname>flush()</methodname>. Note that
|
||||
generally, catchable violations are validated at a higher level (for
|
||||
example in Seam / JSF 2 via the JSF - Bean Validation integration or in
|
||||
your business layer by explicitly calling Bean Validation).</para>
|
||||
|
||||
<para>An application code will rarely be looking for a
|
||||
<classname>ConstraintViolationException</classname> raised by Hibernate.
|
||||
This exception should be treated as fatal and the persistence context
|
||||
should be discarded (<classname>EntityManager</classname> or
|
||||
<classname>Session</classname>).</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Database schema</title>
|
||||
|
||||
<para>Hibernate uses Bean Validation constraints to generate an accurate
|
||||
database schema:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><classname>@NotNull</classname> leads to a not null column
|
||||
(unless it conflicts with components or table inheritance)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><classname>@Size.max</classname> leads to a
|
||||
<literal>varchar(max)</literal> definition for Strings</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><classname>@Min</classname>, <classname>@Max</classname> lead
|
||||
to column checks (like <code>value <= max</code>)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><classname>@Digits</classname> leads to the definition of
|
||||
precision and scale (ever wondered which is which? It's easy now
|
||||
with <classname>@Digits</classname> :) )</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>These constraints can be declared directly on the entity
|
||||
properties or indirectly by using constraint composition.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Hibernate Validator 3</title>
|
||||
|
||||
<warning>
|
||||
<para>We strongly encourage you to use Hibernate Validator 4 and the
|
||||
Bean Validation integration. Consider Hibernate Validator 3 as
|
||||
legacy.</para>
|
||||
</warning>
|
||||
|
||||
<section>
|
||||
<title>Description</title>
|
||||
|
||||
<para>Annotations are a very convenient and elegant way to specify
|
||||
invariant constraints for a domain model. You can, for example, express
|
||||
that a property should never be null, that the account balance should be
|
||||
strictly positive, etc. These domain model constraints are declared in
|
||||
the bean itself by annotating its properties. A validator can then read
|
||||
them and check for constraint violations. The validation mechanism can
|
||||
be executed in different layers in your application without having to
|
||||
duplicate any of these rules (presentation layer, data access layer).
|
||||
Following the DRY principle, Hibernate Validator has been designed for
|
||||
that purpose.</para>
|
||||
|
||||
<para>Hibernate Validator works at two levels. First, it is able to
|
||||
check in-memory instances of a class for constraint violations. Second,
|
||||
it can apply the constraints to the Hibernate metamodel and incorporate
|
||||
them into the generated database schema.</para>
|
||||
|
||||
<para>Each constraint annotation is associated to a validator
|
||||
implementation responsible for checking the constraint on the entity
|
||||
instance. A validator can also (optionally) apply the constraint to the
|
||||
Hibernate metamodel, allowing Hibernate to generate DDL that expresses
|
||||
the constraint. With the appropriate event listener, you can execute the
|
||||
checking operation on inserts and updates done by Hibernate. Hibernate
|
||||
Validator is not limited to use with Hibernate. You can easily use it
|
||||
anywhere in your application.</para>
|
||||
|
||||
<para>When checking instances at runtime, Hibernate Validator returns
|
||||
information about constraint violations in an array of
|
||||
<classname>InvalidValue</classname> s. Among other information, the
|
||||
<classname>InvalidValue</classname> contains an error description
|
||||
message that can embed the parameter values bundle with the annotation
|
||||
(eg. length limit), and message strings that may be externalized to a
|
||||
<classname>ResourceBundle</classname> .</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Integration with Hibernate Annotations</title>
|
||||
|
||||
<para>If Hibernate Validator
|
||||
(<filename>hibernate-validator.jar</filename>) is available in the
|
||||
classpath, Hibernate Annotations will integrate in two ways:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>Constraints will be applied to the Data Definition Language.
|
||||
In other words, the database schema will reflect the constraints
|
||||
(provided that you use the hbm2ddl tool).</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Before an entity change is applied to the database (insert or
|
||||
update), the entity is validated. Validation errors, if any, will be
|
||||
carried over through an
|
||||
<classname>InvalidStateException</classname>.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>For entities free of validation rules, the runtime performance
|
||||
cost is null.</para>
|
||||
|
||||
<para>To disable constraint propagation to DDL, set up
|
||||
<literal>hibernate.validator.apply_to_ddl</literal> to false in the
|
||||
configuration file. Such a need is very uncommon and not
|
||||
recommended.</para>
|
||||
|
||||
<para>To disable pre-entity change validation, set up
|
||||
<literal>hibernate.validator.autoregister_listeners</literal> to false
|
||||
in the configuration file. Such a need is very uncommon and not
|
||||
recommended.</para>
|
||||
|
||||
<para>Check the Hibernate Validator reference documentation for more
|
||||
information.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Hibernate Search</title>
|
||||
|
||||
<section>
|
||||
<title>Description</title>
|
||||
|
||||
<para>Full text search engines like <productname>Apache
|
||||
Lucene</productname> are a very powerful technology to bring free
|
||||
text/efficient queries to applications. If suffers several mismatches
|
||||
when dealing with a object domain model (keeping the index up to date,
|
||||
mismatch between the index structure and the domain model, querying
|
||||
mismatch...) Hibernate Search indexes your domain model thanks to a few
|
||||
annotations, takes care of the database / index synchronization and
|
||||
brings you back regular managed objects from free text queries.
|
||||
Hibernate Search is using <ulink url="http://lucene.apache.org">Apache
|
||||
Lucene</ulink> under the cover.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Integration with Hibernate Annotations</title>
|
||||
|
||||
<para>Hibernate Search integrates with Hibernate Annotations
|
||||
transparently provided that hibernate-search.jar is present in the
|
||||
classpath. If you do not wish to automatically register Hibernate Search
|
||||
event listeners, you can set
|
||||
<literal>hibernate.search.autoregister_listeners</literal> to false.
|
||||
Such a need is very uncommon and not recommended.</para>
|
||||
|
||||
<para>Check the Hibernate Search reference documentation for more
|
||||
information.</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
File diff suppressed because it is too large
Load Diff
|
@ -1,327 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Middleware LLC.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||
<chapter>
|
||||
<title id="setup">Setting up an annotations project</title>
|
||||
|
||||
<section id="setup-requirements">
|
||||
<title>Requirements</title>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>Make sure you have JDK 5.0 or above installed.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Download and unpack the Hibernate Core distribution from the
|
||||
Hibernate website. Hibernate 3.5 and onward contains Hibernate
|
||||
Annotations.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Alternatively add the following dependency in your dependency
|
||||
manager (like Maven or Ivy). Here is an example</para>
|
||||
|
||||
<programlisting language="XML" role="XML"><project ...>
|
||||
...
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-annotations</artifactId>
|
||||
<version>${hibernate-core-version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project></programlisting>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section id="setup-configuration">
|
||||
<title>Configuration</title>
|
||||
|
||||
<para>First, set up your classpath (after you have created a new project
|
||||
in your favorite IDE): <itemizedlist>
|
||||
<listitem>
|
||||
<para>Copy <filename>hibernate3.jar</filename> and the required 3rd
|
||||
party libraries available in
|
||||
<filename>lib/required</filename>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Copy
|
||||
<filename>lib/jpa/hibernate-jpa-2.0-api-1.0.0.Final.jar</filename>
|
||||
to your classpath as well.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para>Alternatively, import your pom.xml in your favorite IDE and let the
|
||||
dependencies be resolved automatically,</para>
|
||||
|
||||
<note>
|
||||
<title>What is hibernate-jpa-2.0-api-x.y.z.jar</title>
|
||||
|
||||
<para>This is the JAR containing the JPA 2.0 API, it is fully compliant
|
||||
with the spec and passed the TCK signature test. You typically don't
|
||||
need it when you deploy your application in a Java EE 6 application
|
||||
server (like JBoss AS 6 for example).</para>
|
||||
</note>
|
||||
|
||||
<para>We recommend you use <ulink
|
||||
url="http://validator.hibernate.org">Hibernate Validator</ulink> and the
|
||||
Bean Validation specification capabilities as its integration with Java
|
||||
Persistence 2 has been standardized. Download Hibernate Validator 4 or
|
||||
above from the Hibernate website and add
|
||||
<filename>hibernate-validator.jar</filename> and
|
||||
<filename>validation-api.jar</filename> in your classpath. Alternatively
|
||||
add the following dependency in your <filename>pom.xml</filename>.</para>
|
||||
|
||||
<programlisting language="XML" role="XML"><project>
|
||||
...
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>${hibernate-validator-version}</version>
|
||||
</dependency>
|
||||
...
|
||||
</dependencies>
|
||||
...
|
||||
</project></programlisting>
|
||||
|
||||
<para>If you wish to use <ulink
|
||||
url="http://search.hibernate.org">Hibernate Search</ulink>, download it
|
||||
from the Hibernate website and add
|
||||
<filename>hibernate-search.jar</filename> and its dependencies in your
|
||||
classpath. Alternatively add the following dependency in your
|
||||
<filename>pom.xml</filename>.</para>
|
||||
|
||||
<programlisting language="XML" role="XML"><project>
|
||||
...
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-search</artifactId>
|
||||
<version>${hibernate-search-version}</version>
|
||||
</dependency>
|
||||
...
|
||||
</dependencies>
|
||||
...
|
||||
</project></programlisting>
|
||||
|
||||
<para>We recommend you use the JPA 2 APIs to bootstrap Hibernate (see the
|
||||
Hibernate EntityManager documentation for more information). If you use
|
||||
Hibernate Core and its native APIs read on.</para>
|
||||
|
||||
<para>If you boot Hibernate yourself, make sure to use the
|
||||
<classname>AnnotationConfiguration</classname> class instead of the
|
||||
<classname>Configuration</classname> class. Here is an example using the
|
||||
(legacy) <classname>HibernateUtil</classname> approach:</para>
|
||||
|
||||
<programlisting language="JAVA" role="JAVA">package hello;
|
||||
|
||||
import org.hibernate.*;
|
||||
import org.hibernate.cfg.*;
|
||||
import test.*;
|
||||
import test.animals.Dog;
|
||||
|
||||
public class HibernateUtil {
|
||||
|
||||
private static final SessionFactory sessionFactory;
|
||||
static {
|
||||
try {
|
||||
sessionFactory = new <emphasis role="bold">AnnotationConfiguration()</emphasis>
|
||||
.configure().buildSessionFactory();
|
||||
} catch (Throwable ex) {
|
||||
// Log exception!
|
||||
throw new ExceptionInInitializerError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static Session getSession()
|
||||
throws HibernateException {
|
||||
return sessionFactory.openSession();
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>Interesting here is the use of
|
||||
<classname>AnnotationConfiguration</classname>. The packages and annotated
|
||||
classes are declared in your regular XML configuration file (usually
|
||||
<filename>hibernate.cfg.xml</filename>). Here is the equivalent of the
|
||||
above declaration:</para>
|
||||
|
||||
<programlisting language="XML" role="XML"><!DOCTYPE hibernate-configuration PUBLIC
|
||||
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
|
||||
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
|
||||
<hibernate-configuration>
|
||||
<session-factory>
|
||||
<mapping package="test.animals"/>
|
||||
<mapping class="test.Flight"/>
|
||||
<mapping class="test.Sky"/>
|
||||
<mapping class="test.Person"/>
|
||||
<mapping class="test.animals.Dog"/>
|
||||
|
||||
<mapping resource="test/animals/orm.xml"/>
|
||||
</session-factory>
|
||||
</hibernate-configuration></programlisting>
|
||||
|
||||
<para>Note that you can mix the legacy hbm.xml use and the annotation
|
||||
approach. The resource element can be either an hbm file or an EJB3 XML
|
||||
deployment descriptor. The distinction is transparent for your
|
||||
configuration process.</para>
|
||||
|
||||
<para>Alternatively, you can define the annotated classes and packages
|
||||
using the programmatic API</para>
|
||||
|
||||
<programlisting language="JAVA" role="JAVA">sessionFactory = new <emphasis
|
||||
role="bold">AnnotationConfiguration()
|
||||
.addPackage("test.animals") //the fully qualified package name
|
||||
.addAnnotatedClass(Flight.class)
|
||||
.addAnnotatedClass(Sky.class)
|
||||
.addAnnotatedClass(Person.class)
|
||||
.addAnnotatedClass(Dog.class)
|
||||
.addResource("test/animals/orm.xml")</emphasis>
|
||||
.configure()
|
||||
.buildSessionFactory();</programlisting>
|
||||
|
||||
<para>There is no other difference in the way you use Hibernate APIs with
|
||||
annotations, except for this startup routine change or in the
|
||||
configuration file. You can use your favorite configuration method for
|
||||
other properties ( <filename>hibernate.properties</filename>,
|
||||
<filename>hibernate.cfg.xml</filename>, programmatic APIs, etc).</para>
|
||||
|
||||
<note>
|
||||
<para>You can mix annotated persistent classes and classic
|
||||
<filename>hbm.cfg.xml</filename> declarations with the same
|
||||
<classname>SessionFactory</classname>. You can however not declare a
|
||||
class several times (whether annotated or through hbm.xml). You cannot
|
||||
mix configuration strategies (hbm vs annotations) in an entity hierarchy
|
||||
either.</para>
|
||||
</note>
|
||||
|
||||
<para>To ease the migration process from hbm files to annotations, the
|
||||
configuration mechanism detects the mapping duplication between
|
||||
annotations and hbm files. HBM files are then prioritized over annotated
|
||||
metadata on a class to class basis. You can change the priority using
|
||||
<literal>hibernate.mapping.precedence</literal> property. The default is
|
||||
<literal>hbm, class</literal>, changing it to <literal>class,
|
||||
hbm</literal> will prioritize the annotated classes over hbm files when a
|
||||
conflict occurs.</para>
|
||||
</section>
|
||||
|
||||
<section id="ann-setup-properties">
|
||||
<title id="setup-properties">Properties</title>
|
||||
|
||||
<para>On top of the Hibernate Core properties, Hibernate Annotations
|
||||
reacts to the following one.<table>
|
||||
<title>Hibernate Annotations specific properties</title>
|
||||
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry align="center">Property</entry>
|
||||
|
||||
<entry align="center">Function</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><literal>hibernate.cache.default_cache_concurrency_strategy</literal></entry>
|
||||
|
||||
<entry><para>Setting used to give the name of the default
|
||||
<classname>org.hibernate.annotations.CacheConcurrencyStrategy</classname>
|
||||
to use when either <classname>@Cacheable</classname>
|
||||
<classname>@Cache</classname>} is used.
|
||||
<classname>@Cache(strategy="..")</classname> is used to override
|
||||
this default.</para></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>hibernate.id.new_generator_mappings</literal></entry>
|
||||
|
||||
<entry><para>true or false. Setting which indicates whether or
|
||||
not the new <classname>IdentifierGenerator</classname>
|
||||
implementations are used for AUTO, TABLE and SEQUENCE. Default
|
||||
to false to keep backward compatibility.</para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table><note>
|
||||
<para>We recommend all new projects to use
|
||||
<code>hibernate.id.new_generator_mappings=true</code> as the new
|
||||
generators are more efficient and closer to the JPA 2 specification
|
||||
semantic. However they are not backward compatible with existing
|
||||
databases (if a sequence or a table is used for id generation).</para>
|
||||
</note></para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Logging</title>
|
||||
|
||||
<para>Hibernate Annotations utilizes <ulink
|
||||
url="http://www.slf4j.org/">Simple Logging Facade for Java</ulink> (SLF4J)
|
||||
in order to log various system events. SLF4J can direct your logging
|
||||
output to several logging frameworks (NOP, Simple, log4j version 1.2, JDK
|
||||
1.4 logging, JCL or logback) depending on your chosen binding. In order to
|
||||
setup logging properly you will need <filename>slf4j-api.jar</filename> in
|
||||
your classpath together with the jar file for your preferred binding -
|
||||
<filename>slf4j-log4j12.jar</filename> in the case of Log4J. See the SLF4J
|
||||
<ulink type=""
|
||||
url="http://www.slf4j.org/manual.html">documentation</ulink> for more
|
||||
detail.</para>
|
||||
|
||||
<para>The logging categories interesting for Hibernate Annotations
|
||||
are:</para>
|
||||
|
||||
<table>
|
||||
<title>Hibernate Annotations Log Categories</title>
|
||||
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry align="center">Category</entry>
|
||||
|
||||
<entry align="center">Function</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><emphasis>org.hibernate.cfg</emphasis></entry>
|
||||
|
||||
<entry>Log all configuration related events (not only
|
||||
annotations).</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>For further category configuration refer to the <ulink
|
||||
url="http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#configuration-logging">Logging</ulink>
|
||||
in the Hibernate Core documentation.</para>
|
||||
</section>
|
||||
</chapter>
|
|
@ -1,427 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Middleware LLC.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||
<chapter id="xml-overriding">
|
||||
<title>Overriding metadata through XML</title>
|
||||
|
||||
<para>The primary target for metadata in EJB3 is annotations, but the EJB3
|
||||
specification provides a way to override or replace the annotation defined
|
||||
metadata through an XML deployment descriptor. In the current release only
|
||||
pure EJB3 annotations overriding are supported. If you wish to use Hibernate
|
||||
specific features in some entities, you'll have to either use annotations or
|
||||
fallback to hbm files. You can of course mix and match annotated entities
|
||||
and entities describes in hbm files.</para>
|
||||
|
||||
<para>The unit test suite shows some additional XML file samples.</para>
|
||||
|
||||
<section id="xml-overriding-principles">
|
||||
<title>Principles</title>
|
||||
|
||||
<para>The XML deployment descriptor structure has been designed to reflect
|
||||
the annotations one. So if you know the annotations structure, using the
|
||||
XML schema will be straightforward for you.</para>
|
||||
|
||||
<para>You can define one or more XML files describing your metadata, these
|
||||
files will be merged by the overriding engine.</para>
|
||||
|
||||
<section>
|
||||
<title>Global level metadata</title>
|
||||
|
||||
<para>You can define global level metadata available for all XML files.
|
||||
You must not define these metadata more than once per deployment.</para>
|
||||
|
||||
<programlisting language="XML" role="XML"><?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<entity-mappings
|
||||
xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
|
||||
version="2.0">
|
||||
|
||||
<persistence-unit-metadata>
|
||||
<xml-mapping-metadata-complete/>
|
||||
<persistence-unit-defaults>
|
||||
<schema>myschema</schema>
|
||||
<catalog>mycatalog</catalog>
|
||||
<cascade-persist/>
|
||||
</persistence-unit-defaults>
|
||||
</persistence-unit-metadata></programlisting>
|
||||
|
||||
<para><literal>xml-mapping-metadata-complete</literal> means that all
|
||||
entity, mapped-superclasses and embeddable metadata should be picked up
|
||||
from XML (ie ignore annotations).</para>
|
||||
|
||||
<para><literal>schema / catalog</literal> will override all default
|
||||
definitions of schema and catalog in the metadata (both XML and
|
||||
annotations).</para>
|
||||
|
||||
<para><literal>cascade-persist</literal> means that all associations
|
||||
have PERSIST as a cascade type. We recommend you to not use this
|
||||
feature.</para>
|
||||
</section>
|
||||
|
||||
<section id="xml-overriding-principles-entity">
|
||||
<title>Entity level metadata</title>
|
||||
|
||||
<para>You can either define or override metadata informations on a given
|
||||
entity.</para>
|
||||
|
||||
<programlistingco>
|
||||
<areaspec>
|
||||
<area coords="3" id="aa1" />
|
||||
|
||||
<area coords="9" id="aa2" />
|
||||
|
||||
<area coords="10" id="aa3" />
|
||||
|
||||
<area coords="11" id="aa4" />
|
||||
|
||||
<area coords="17" id="aa5" />
|
||||
|
||||
<area coords="23" id="aa6" />
|
||||
|
||||
<area coords="24" id="aa7" />
|
||||
|
||||
<area coords="25" id="aa8" />
|
||||
|
||||
<area coords="26" id="aa9" />
|
||||
|
||||
<area coords="31" id="aa10" />
|
||||
</areaspec>
|
||||
|
||||
<programlisting><?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<entity-mappings
|
||||
xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
|
||||
version="2.0">
|
||||
|
||||
<package>org.hibernate.test.annotations.reflection</package>
|
||||
<entity class="Administration" access="PROPERTY" metadata-complete="true">
|
||||
<table name="tbl_admin">
|
||||
<unique-constraint>
|
||||
<column-name>firstname</column-name>
|
||||
<column-name>lastname</column-name>
|
||||
</unique-constraint>
|
||||
</table>
|
||||
<secondary-table name="admin2">
|
||||
<primary-key-join-column name="admin_id" referenced-column-name="id"/>
|
||||
<unique-constraint>
|
||||
<column-name>address</column-name>
|
||||
</unique-constraint>
|
||||
</secondary-table>
|
||||
<id-class class="SocialSecurityNumber"/>
|
||||
<inheritance strategy="JOINED"/>
|
||||
<sequence-generator name="seqhilo" sequence-name="seqhilo"/>
|
||||
<table-generator name="table" table="tablehilo"/>
|
||||
...
|
||||
</entity>
|
||||
|
||||
<entity class="PostalAdministration">
|
||||
<primary-key-join-column name="id"/>
|
||||
...
|
||||
</entity>
|
||||
</entity-mappings></programlisting>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs="aa1">
|
||||
<para><literal>entity-mappings</literal>: entity-mappings is the
|
||||
root element for all XML files. You must declare the xml schema,
|
||||
the schema file is included in the hibernate-annotations.jar file,
|
||||
no internet access will be processed by Hibernate
|
||||
Annotations.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa2">
|
||||
<para><literal>package</literal> (optional): default package used
|
||||
for all non qualified class names in the given deployment
|
||||
descriptor file.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa3">
|
||||
<para><literal>entity</literal>: desribes an entity.</para>
|
||||
|
||||
<para><literal>metadata-complete</literal> defines whether the
|
||||
metadata description for this element is complete or not (in other
|
||||
words, if annotations present at the class level should be
|
||||
considered or not).</para>
|
||||
|
||||
<para>An entity has to have a <literal>class</literal> attribute
|
||||
refering the java class the metadata applies on.</para>
|
||||
|
||||
<para>You can overrides entity name through the
|
||||
<literal>name</literal> attribute, if none is defined and if an
|
||||
<literal>@Entity.name</literal> is present, then it is used
|
||||
(provided that metadata complete is not set).</para>
|
||||
|
||||
<para>For metadata complete (see below) element, you can define an
|
||||
<literal>access</literal> (either <literal>FIELD</literal> or
|
||||
<literal>PROPERTY</literal> (default)). For non medatada complete
|
||||
element, if <literal>access</literal> is not defined, the @Id
|
||||
position will lead position, if <literal>access</literal> is
|
||||
defined, the value is used.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa4">
|
||||
<para><literal>table</literal>: you can declare table properties
|
||||
(name, schema, catalog), if none is defined, the java annotation
|
||||
is used.</para>
|
||||
|
||||
<para>You can define one or several unique constraints as seen in
|
||||
the example</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa5">
|
||||
<para><literal>secondary-table</literal>: defines a secondary
|
||||
table very much like a regular table except that you can define
|
||||
the primary key / foreign key column(s) through the
|
||||
<literal>primary-key-join-column</literal> element. On non
|
||||
metadata complete, annotation secondary tables are used only if
|
||||
there is no <literal>secondary-table</literal> definition,
|
||||
annotations are ignored otherwise.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa6">
|
||||
<para><literal>id-class</literal>: defines the id class in a
|
||||
similar way <literal>@IdClass</literal> does</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa7">
|
||||
<para><literal>inheritance</literal>: defines the inheritance
|
||||
strategy (<literal>JOINED</literal>,
|
||||
<literal>TABLE_PER_CLASS</literal>,
|
||||
<literal>SINGLE_TABLE</literal>), Available only at the root
|
||||
entity level</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa8">
|
||||
<para><literal>sequence-generator</literal>: defines a sequence
|
||||
generator</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa9">
|
||||
<para><literal>table-generator</literal>: defines a table
|
||||
generator</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa10">
|
||||
<para><literal><literal>primary-key-join-column</literal></literal>:
|
||||
defines the primary key join column for sub entities when JOINED
|
||||
inheritance strategy is used</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</programlistingco>
|
||||
|
||||
<programlistingco>
|
||||
<areaspec>
|
||||
<area coords="11" id="ab1" />
|
||||
|
||||
<area coords="18" id="ab2" />
|
||||
|
||||
<area coords="22" id="ab3" />
|
||||
|
||||
<area coords="28" id="ab4" />
|
||||
|
||||
<area coords="34" id="ab5" />
|
||||
</areaspec>
|
||||
|
||||
<programlisting><?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<entity-mappings
|
||||
xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
|
||||
version="2.0">
|
||||
|
||||
<package>org.hibernate.test.annotations.reflection</package>
|
||||
<entity class="Music" access="PROPERTY" metadata-complete="true">
|
||||
<discriminator-value>Generic</discriminator-value>
|
||||
<discriminator-column length="34"/>
|
||||
...
|
||||
</entity>
|
||||
|
||||
<entity class="PostalAdministration">
|
||||
<primary-key-join-column name="id"/>
|
||||
<named-query name="adminById">
|
||||
<query>select m from Administration m where m.id = :id</query>
|
||||
<hint name="org.hibernate.timeout" value="200"/>
|
||||
</named-query>
|
||||
<named-native-query name="allAdmin" result-set-mapping="adminrs">
|
||||
<query>select *, count(taxpayer_id) as taxPayerNumber
|
||||
from Administration, TaxPayer
|
||||
where taxpayer_admin_id = admin_id group by ...</query>
|
||||
<hint name="org.hibernate.timeout" value="200"/>
|
||||
</named-native-query>
|
||||
<sql-result-set-mapping name="adminrs">
|
||||
<entity-result entity-class="Administration">
|
||||
<field-result name="name" column="fld_name"/>
|
||||
</entity-result>
|
||||
<column-result name="taxPayerNumber"/>
|
||||
</sql-result-set-mapping>
|
||||
<attribute-override name="ground">
|
||||
<column name="fld_ground" unique="true" scale="2"/>
|
||||
</attribute-override>
|
||||
<association-override name="referer">
|
||||
<join-column name="referer_id" referenced-column-name="id"/>
|
||||
</association-override>
|
||||
...
|
||||
</entity>
|
||||
</entity-mappings></programlisting>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs="ab1">
|
||||
<para><literal>discriminator-value /
|
||||
discriminator-column</literal>: defines the discriminator value
|
||||
and the column holding it when the SINGLE_TABLE inheritance
|
||||
strategy is chosen</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ab2">
|
||||
<para><literal>named-query</literal>: defines named queries and
|
||||
possibly the hints associated to them. Those definitions are
|
||||
additive to the one defined in annotations, if two definitions
|
||||
have the same name, the XML one has priority.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ab3">
|
||||
<para><literal>named-native-query</literal>: defines an named
|
||||
native query and its sql result set mapping. Alternatively, you
|
||||
can define the <literal>result-class</literal>. Those definitions
|
||||
are additive to the one defined in annotations, if two definitions
|
||||
have the same name, the XML one has priority.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ab4">
|
||||
<para><literal>sql-result-set-mapping</literal>: describes the
|
||||
result set mapping structure. You can define both entity and
|
||||
column mappings. Those definitions are additive to the one defined
|
||||
in annotations, if two definitions have the same name, the XML one
|
||||
has priority</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ab5">
|
||||
<para><literal>attribute-override /
|
||||
association-override</literal>: defines a column or join column
|
||||
overriding. This overriding is additive to the one defined in
|
||||
annotations</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</programlistingco>
|
||||
|
||||
<para>Same applies for <literal><embeddable></literal> and
|
||||
<literal><mapped-superclass></literal>.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Property level metadata</title>
|
||||
|
||||
<para>You can of course defines XML overriding for properties. If
|
||||
metadata complete is defined, then additional properties (ie at the Java
|
||||
level) will be ignored. Otherwise, once you start overriding a property,
|
||||
all annotations on the given property are ignored. All property level
|
||||
metadata behave in <literal>entity/attributes</literal>,
|
||||
<literal>mapped-superclass/attributes</literal> or
|
||||
<literal>embeddable/attributes</literal>.</para>
|
||||
|
||||
<programlisting language="XML" role="XML"> <attributes>
|
||||
<id name="id">
|
||||
<column name="fld_id"/>
|
||||
<generated-value generator="generator" strategy="SEQUENCE"/>
|
||||
<temporal>DATE</temporal>
|
||||
<sequence-generator name="generator" sequence-name="seq"/>
|
||||
</id>
|
||||
<version name="version"/>
|
||||
<embedded name="embeddedObject">
|
||||
<attribute-override name"subproperty">
|
||||
<column name="my_column"/>
|
||||
</attribute-override>
|
||||
</embedded>
|
||||
<basic name="status" optional="false">
|
||||
<enumerated>STRING</enumerated>
|
||||
</basic>
|
||||
<basic name="serial" optional="true">
|
||||
<column name="serialbytes"/>
|
||||
<lob/>
|
||||
</basic>
|
||||
<basic name="terminusTime" fetch="LAZY">
|
||||
<temporal>TIMESTAMP</temporal>
|
||||
</basic>
|
||||
</attributes></programlisting>
|
||||
|
||||
<para>You can override a property through <literal>id</literal>,
|
||||
<literal>embedded-id</literal>, <literal>version</literal>,
|
||||
<literal>embedded</literal> and <literal>basic</literal>. Each of these
|
||||
elements can have subelements accordingly: <literal>lob</literal>,
|
||||
<literal>temporal</literal>, <literal>enumerated</literal>,
|
||||
<literal>column</literal>.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Association level metadata</title>
|
||||
|
||||
<para>You can define XML overriding for associations. All association
|
||||
level metadata behave in <literal>entity/attributes</literal>,
|
||||
<literal>mapped-superclass/attributes</literal> or
|
||||
<literal>embeddable/attributes</literal>.</para>
|
||||
|
||||
<programlisting language="XML" role="XML"> <attributes>
|
||||
<one-to-many name="players" fetch="EAGER">
|
||||
<map-key name="name"/>
|
||||
<join-column name="driver"/>
|
||||
<join-column name="number"/>
|
||||
</one-to-many>
|
||||
<many-to-many name="roads" target-entity="Administration">
|
||||
<order-by>maxSpeed</order-by>
|
||||
<join-table name="bus_road">
|
||||
<join-column name="driver"/>
|
||||
<join-column name="number"/>
|
||||
<inverse-join-column name="road_id"/>
|
||||
<unique-constraint>
|
||||
<column-name>driver</column-name>
|
||||
<column-name>number</column-name>
|
||||
</unique-constraint>
|
||||
</join-table>
|
||||
</many-to-many>
|
||||
<many-to-many name="allTimeDrivers" mapped-by="drivenBuses">
|
||||
</attributes></programlisting>
|
||||
|
||||
<para>You can override an association through
|
||||
<literal>one-to-many</literal>, <literal>one-to-one</literal>,
|
||||
<literal>many-to-one</literal>, and <literal>many-to-many</literal>.
|
||||
Each of these elements can have subelements accordingly:
|
||||
<literal>join-table</literal> (which can have
|
||||
<literal>join-column</literal>s and
|
||||
<literal>inverse-join-column</literal>s),
|
||||
<literal><literal>join-column</literal>s</literal>,
|
||||
<literal>map-key</literal>, and <literal>order-by</literal>.
|
||||
<literal>mapped-by</literal> and <literal>target-entity</literal> can be
|
||||
defined as attributes when it makes sense. Once again the structure is
|
||||
reflects the annotations structure. You can find all semantic
|
||||
informations in the chapter describing annotations.</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
|
@ -1,85 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3CR3//EN"
|
||||
"../support/docbook-dtd/docbookx.dtd" [
|
||||
<!ENTITY setup SYSTEM "modules/setup.xml">
|
||||
<!ENTITY entity SYSTEM "modules/entity.xml">
|
||||
<!ENTITY xml-overriding SYSTEM "modules/xml-overriding.xml">
|
||||
<!ENTITY validator SYSTEM "modules/validator.xml">
|
||||
<!ENTITY lucene SYSTEM "modules/lucene.xml">
|
||||
<!ENTITY version "WORKING">
|
||||
<!ENTITY today "TODAY">
|
||||
]>
|
||||
<book lang="fr">
|
||||
<bookinfo>
|
||||
<title>Hibernate Annotations</title>
|
||||
|
||||
<subtitle>Guide de référence</subtitle>
|
||||
|
||||
<releaseinfo>&version;</releaseinfo>
|
||||
<pubdate>&today;</pubdate>
|
||||
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="images/hibernate_logo_a.png" format="png" />
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
</bookinfo>
|
||||
|
||||
<toc></toc>
|
||||
|
||||
<preface id="preface" revision="1">
|
||||
<title>Préface</title>
|
||||
<para>Traducteur(s): Vincent Ricard</para>
|
||||
|
||||
<para>Hibernate, comme tous les autres outils de mapping objet/relationnel,
|
||||
nécessite des méta-données qui régissent la transformation des données
|
||||
d'une représentation vers l'autre (et vice versa). Dans Hibernate 2.x, les
|
||||
méta-données de mapping sont la plupart du temps déclarées dans des fichiers
|
||||
XML. Une autre option est XDoclet, qui utilise les annotations du code source
|
||||
Javadoc et un préprocesseur au moment de la compilation. Le même genre
|
||||
d'annotation est maintenant disponible avec le JDK standard, quoique plus
|
||||
puissant et mieux pris en charge par les outils. IntelliJ IDEA et Eclipse,
|
||||
par exemple, prennent en charge la complétion automatique et la coloration
|
||||
syntaxique des annotations du JDK 5.0. Les annotations sont compilées en
|
||||
bytecode et lues au moment de l'exécution (dans le cas d'Hibernate, au
|
||||
démarrage) en utilisant la réflexion, donc pas besoin de fichiers XML
|
||||
externes.</para>
|
||||
|
||||
<para>La spécification EJB3 reconnaît l'intérêt et le succès du paradigme
|
||||
du mapping objet/relationnel transparent. La spécification EJB3 standardise
|
||||
les APIs de base et les méta-données requises par n'importe quel mécanisme
|
||||
de persistance objet/relationnel. <emphasis>Hibernate EntityManager</emphasis>
|
||||
implémente les interfaces de programmation et les règles de cycle de vie
|
||||
telles que définies par la spécification de persistance EJB3. Avec
|
||||
<emphasis>Hibernate Annotations</emphasis>, ce wrapper implémente une
|
||||
solution de persistance EJB3 complète (et autonome) au-dessus du noyau
|
||||
mature d'Hibernate. Vous pouvez utiliser soit les trois ensembles, soit les
|
||||
annotations sans le cycle de vie et les interfaces de programmations EJB3,
|
||||
ou même Hibernate tout seul, selon les besoins techniques et fonctionnels
|
||||
de votre projet. Vous pouvez à tout moment recourir aux APIs natives
|
||||
d'Hibernate ou même, si besoin est, à celles de JDBC et au SQL.</para>
|
||||
|
||||
<para>Cette version est basée sur la dernière version de la spécification
|
||||
EJB 3.0 / JPA (alias JSP-220) et prend en charge toutes les fonctionnalités
|
||||
de la spécification (dont certaines optionnelles). La plupart des
|
||||
fonctionnalités d'Hibernate et des extensions sont aussi disponibles à
|
||||
travers des annotations spécifiques à Hibernate. Bien que la couverture
|
||||
d'Hibernate en termes de fonctionnalités soit maintenant très grande,
|
||||
certaines sont encore manquantes. Le but ultime est de tout couvrir. Voir la
|
||||
section JIRA "road map" pour plus d'informations.</para>
|
||||
|
||||
<para>Si vous utilisiez une version précédente d'Hibernate Annotations,
|
||||
veuillez regarder <uri>http://www.hibernate.org/371.html</uri> pour un guide
|
||||
de migration.</para>
|
||||
</preface>
|
||||
|
||||
&setup;
|
||||
|
||||
&entity;
|
||||
|
||||
&xml-overriding;
|
||||
|
||||
&validator;
|
||||
|
||||
&lucene;
|
||||
</book>
|
File diff suppressed because it is too large
Load Diff
|
@ -1,197 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<chapter id="lucene" revision="1">
|
||||
<title>Intégration de Lucene avec Hibernate</title>
|
||||
|
||||
<para>Lucene est une bibliothèque de la fondation Apache fournissant un moteur
|
||||
de recherche en Java hautement performant. Hibernate Annotations inclut un
|
||||
ensemble d'annotations qui vous permettent de marquer n'importe quel objet
|
||||
du modèle de données comme indexable et de laisser Hibernate maintenir un
|
||||
index Lucene de toutes les instances persistées via Hibernate.</para>
|
||||
|
||||
<para>Hibernate Lucene est un projet en cours et de nouvelles fonctionnalités
|
||||
sont en préparation. Donc attendez-vous à certains changements avec les
|
||||
versions ultérieures.</para>
|
||||
|
||||
<section id="lucene-mapping">
|
||||
<title>Mapper les entités sur l'index</title>
|
||||
|
||||
<para>Tout d'abord, nous devons déclarer une classe persistante comme
|
||||
étant indexable. Ceci se fait en annotant la classe avec
|
||||
<literal>@Indexed</literal> :</para>
|
||||
|
||||
<programlisting>@Entity
|
||||
@Indexed(index="indexes/essays")
|
||||
public class Essay {
|
||||
...
|
||||
}</programlisting>
|
||||
|
||||
<para>L'attribut <literal>index</literal> indique à Hibernate quel est le
|
||||
nom du répertoire Lucene (en général un répertoire de votre système de
|
||||
fichiers). Si vous souhaitez définir un répertoire de départ pour tous vos
|
||||
index Lucene, vous pouvez utiliser la propriété
|
||||
<literal>hibernate.lucene.default.indexDir</literal> dans votre fichier de
|
||||
configuration.</para>
|
||||
|
||||
<para>Les index Lucene contiennent quatre types de champs :
|
||||
<emphasis>keyword</emphasis>, <emphasis>text</emphasis>,
|
||||
<emphasis>unstored</emphasis> et <emphasis>unindexed</emphasis>. Hibernate
|
||||
Annotations fournit des annotations pour marquer une propriété d'une entité
|
||||
comme étant d'un des trois premiers types.</para>
|
||||
|
||||
<programlisting>@Entity
|
||||
@Indexed(index="indexes/essays")
|
||||
public class Essay {
|
||||
...
|
||||
|
||||
@Id
|
||||
@Keyword(id=true)
|
||||
public Long getId() { return id; }
|
||||
|
||||
@Text(name="Abstract")
|
||||
public String getSummary() { return summary; }
|
||||
|
||||
@Lob
|
||||
@Unstored
|
||||
public String getText() { return text; }
|
||||
|
||||
}</programlisting>
|
||||
|
||||
<para>Ces annotations définissent un index avec trois champs :
|
||||
<literal>id</literal>, <literal>Abstract</literal> et
|
||||
<literal>text</literal>. Notez que par défaut le nom du champ n'a plus de
|
||||
majuscules, en suivant la spécification JavaBean.</para>
|
||||
|
||||
<para>Note : vous <emphasis>devez</emphasis> spécifier
|
||||
<literal>@Keyword(id=true)</literal> sur la propriété identifiante de
|
||||
votre entité.</para>
|
||||
|
||||
<para>Lucene a la notion of <emphasis>boost factor</emphasis>. C'est un
|
||||
moyen de donner plus de poids à un champ ou à un élément indexé durant la
|
||||
procédure d'indexation. Vous pouvez utiliser <literal>@Boost</literal> au
|
||||
niveau du champ ou de la classe.</para>
|
||||
|
||||
<para>La classe analyste utilisée pour indexer les éléments est
|
||||
configurable par la propriété
|
||||
<literal>hibernate.lucene.analyzer</literal>. Si aucune n'est définie,
|
||||
<classname>org.apache.lucene.analysis.standard.StandardAnalyzer</classname>
|
||||
est utilisée par défaut.</para>
|
||||
</section>
|
||||
|
||||
<section id="lucene-configuration">
|
||||
<title>Configuration</title>
|
||||
|
||||
<section id="lucene-configuration-directory">
|
||||
<title>Configuration du directory</title>
|
||||
|
||||
<para>Lucene a une notion de Directory où l'index est stocké.
|
||||
L'implémentation de Directory peut être personnalisée mais Lucene arrive,
|
||||
avec deux implémentations prêtes à l'emploi complètes, une sur un système
|
||||
de fichiers et une en mémoire. Hibernate Lucene a la notion de
|
||||
<literal>DirectoryProvider</literal> qui gère la configuration et
|
||||
l'initialisation du Directory Lucene.</para>
|
||||
|
||||
<table>
|
||||
<title>Liste des Directory Providers intégrés</title>
|
||||
|
||||
<tgroup cols="3">
|
||||
<thead>
|
||||
<row>
|
||||
<entry align="center">Classe</entry>
|
||||
|
||||
<entry align="center">Description</entry>
|
||||
|
||||
<entry align="center">Propriétés</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>org.hibernate.lucene.store.FSDirectoryProvider</entry>
|
||||
|
||||
<entry>Directory base sur le système de fichiers. Le répertoire
|
||||
utilisé sera
|
||||
<indexBase>/<<literal>@Index.name</literal>></entry>
|
||||
|
||||
<entry><literal>indexBase</literal> : répertoire de départ</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>org.hibernate.lucene.store.RAMDirectoryProvider</entry>
|
||||
|
||||
<entry>Directory utilisant la mémoire, le directory sera
|
||||
uniquement identifié par l'élément
|
||||
<literal>@Index.name</literal></entry>
|
||||
|
||||
<entry>aucune</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>Si les directory providers intégrés ne répondent pas à vos besoins,
|
||||
vous pouvez écrire votre propre directory provider en implémentant
|
||||
l'interface
|
||||
<classname>org.hibernate.store.DirectoryProvider</classname>.</para>
|
||||
|
||||
<para>Chaque entité indexée est associée à un index Lucene (un index peut
|
||||
être partagé par différentes entités mais ce n'est pas le cas en général).
|
||||
Vous pouvez configurer l'index à travers des propriétés préfixées par
|
||||
<literal><literal>hibernate.lucene.<indexname></literal></literal>.
|
||||
Les propriétés par défaut héritées par tous les index peuvent être
|
||||
définies en utilisant le préfixe hibernate.lucene.default.</para>
|
||||
|
||||
<para>Pour définir le directory provider d'un index donné, utilisez
|
||||
<literal>hibernate.lucene.<indexname>.directory_provider</literal>.</para>
|
||||
|
||||
<programlisting>hibernate.lucene.default.directory_provider org.hibernate.lucene.store.FSDirectoryProvider
|
||||
hibernate.lucene.default.indexDir=/usr/lucene/indexes
|
||||
|
||||
hibernate.lucene.Rules.directory_provider org.hibernate.lucene.store.RAMDirectoryProvider
|
||||
</programlisting>
|
||||
|
||||
<para>appliqué à</para>
|
||||
|
||||
<programlisting>@Indexed(name="Status")
|
||||
public class Status { ... }
|
||||
|
||||
@Indexed(name="Rules")
|
||||
public class Rule { ... }</programlisting>
|
||||
|
||||
<para>Ceci créera un directory système de fichiers dans
|
||||
<filename>/usr/lucene/indexes/Status</filename> où les entités Status
|
||||
seront indexées, et utilisera un directory mémoire nommé
|
||||
<literal>Rules</literal> où les entités Rule seront indexées.</para>
|
||||
|
||||
<para>Donc vous pouvez facilement définir des règles générales comme le
|
||||
directory provider et le répertoire de départ, et surcharger ces valeurs
|
||||
par défaut plus tard pour chaque index.</para>
|
||||
|
||||
<para>En écrivant votre propre DirectoryProvider, vous pouvez aussi
|
||||
bénéficier de ce mécanisme de configuration.</para>
|
||||
</section>
|
||||
|
||||
<section id="lucene-configuration-event">
|
||||
<title>Activer l'indexation automatique</title>
|
||||
|
||||
<para>Finalement, nous activons le <literal>LuceneEventListener</literal>
|
||||
pour les trois événements Hibernate qui ont lieu après que les changements
|
||||
sont validés dans la base de données.</para>
|
||||
|
||||
<programlisting><hibernate-configuration>
|
||||
...
|
||||
<event type="post-commit-update"
|
||||
<listener
|
||||
class="org.hibernate.lucene.event.LuceneEventListener"/>
|
||||
</event>
|
||||
<event type="post-commit-insert"
|
||||
<listener
|
||||
class="org.hibernate.lucene.event.LuceneEventListener"/>
|
||||
</event>
|
||||
<event type="post-commit-delete"
|
||||
<listener
|
||||
class="org.hibernate.lucene.event.LuceneEventListener"/>
|
||||
</event>
|
||||
</hibernate-configuration></programlisting>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
|
@ -1,158 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<chapter>
|
||||
<title id="setup" revision="1">Configurer un projet avec des annotations</title>
|
||||
|
||||
<section id="setup-requirements">
|
||||
<title>Prérequis</title>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>Téléchargez et installez la distribution Hibernate Annotations à
|
||||
partir du site web d'Hibernate.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><emphasis>Cette version requiert Hibernate 3.2.0.GA ou
|
||||
supérieur. N'utilisez pas cette version d'Hibernate Annotations avec
|
||||
une version plus ancienne d'Hibernate 3.x !</emphasis></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Cette version est connue pour fonctionner avec le noyau 3.2.0.CR5
|
||||
et 3.2.0.GA d'Hibernate.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Assurez-vous que vous avez le JDK 5.0 d'installé. Vous pouvez
|
||||
bien sûr continuer à utiliser XDoclet et avoir certains des avantages
|
||||
des méta-données basées sur les annotations avec des versions plus
|
||||
anciennes du JDK. Notez que ce document décrit seulement les annotations
|
||||
du JDK 5.0 et que vous devez vous référer à la documentation de XDoclet
|
||||
pour plus d'informations.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section id="setup-configuration">
|
||||
<title>Configuration</title>
|
||||
|
||||
<para>Tout d'abord, paramétrez votre classpath (après avoir créer un nouveau
|
||||
projet dans votre IDE favori) :<itemizedlist>
|
||||
<listitem>
|
||||
<para>Copiez toutes les bibliothèques du noyau Hibernate3 et toutes
|
||||
les bibliothèques tierces requises (voir lib/README.txt dans
|
||||
Hibernate).</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Copiez aussi <filename>hibernate-annotations.jar</filename> et
|
||||
<filename>lib/ejb3-persistence.jar</filename> de la distribution
|
||||
Hibernate Annotations dans votre classpath.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Pour utiliser <xref linkend="lucene" />, ajouter le fichier jar
|
||||
de lucene.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para>Nous recommandons aussi un petit wrapper pour démarrer Hibernate dans
|
||||
un bloc statique d'initialisation, connu en tant que
|
||||
<classname>HibernateUtil</classname>. Vous pourriez avoir vu cette classe
|
||||
sous diverses formes dans d'autres parties de la documentation Hibernate.
|
||||
Pour prendre en charge Annotation vous devez modifier cette classe d'aide
|
||||
de la manière suivante :<programlisting>package hello;
|
||||
|
||||
import org.hibernate.*;
|
||||
import org.hibernate.cfg.*;
|
||||
import test.*;
|
||||
import test.animals.Dog;
|
||||
|
||||
public class HibernateUtil {
|
||||
|
||||
private static final SessionFactory sessionFactory;
|
||||
|
||||
static {
|
||||
try {
|
||||
|
||||
sessionFactory = new <emphasis role="bold">AnnotationConfiguration()</emphasis>.buildSessionFactory();
|
||||
} catch (Throwable ex) {
|
||||
// Log exception!
|
||||
throw new ExceptionInInitializerError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static Session getSession()
|
||||
throws HibernateException {
|
||||
return sessionFactory.openSession();
|
||||
}
|
||||
}
|
||||
</programlisting></para>
|
||||
|
||||
<para>La partie intéressante ici est l'utilisation de
|
||||
<classname>AnnotationConfiguration</classname>. Les packages et les classes
|
||||
annotées sont déclarés dans votre fichier de configuration XML habituel
|
||||
(généralement <filename>hibernate.cfg.xml</filename>). Voici un équivalent
|
||||
de la déclaration ci-dessus :</para>
|
||||
|
||||
<programlisting><!DOCTYPE hibernate-configuration PUBLIC
|
||||
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
|
||||
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
|
||||
|
||||
<hibernate-configuration>
|
||||
<session-factory>
|
||||
<emphasis role="bold"><mapping package="test.animals"/>
|
||||
<mapping class="test.Flight"/>
|
||||
<mapping class="test.Sky"/>
|
||||
<mapping class="test.Person"/>
|
||||
<mapping class="test.animals.Dog"/></emphasis>
|
||||
<emphasis role="bold"> <mapping resource="test/animals/orm.xml"/></emphasis>
|
||||
</session-factory>
|
||||
</hibernate-configuration>
|
||||
</programlisting>
|
||||
|
||||
<para>Notez que vous pouvez mélanger l'utilisation du fichier hbm.xml et
|
||||
celle des annotations. L'élément de ressource peut être un fichier hbm ou
|
||||
un descripteur de déploiement XML EJB3. Cette distinction est transparente
|
||||
pour votre procédure de configuration.</para>
|
||||
|
||||
<para>Alternativement, vous pouvez définir les classes annotées et des
|
||||
packages en utilisant l'API :</para>
|
||||
|
||||
<programlisting> sessionFactory = new <emphasis role="bold">AnnotationConfiguration()
|
||||
.addPackage("test.animals") // le nom complet du package
|
||||
.addAnnotatedClass(Flight.class)
|
||||
.addAnnotatedClass(Sky.class)
|
||||
.addAnnotatedClass(Person.class)
|
||||
.addAnnotatedClass(Dog.class)</emphasis>
|
||||
<emphasis role="bold"> .addResource("test/animals/orm.xml")</emphasis>
|
||||
.buildSessionFactory();</programlisting>
|
||||
|
||||
<para>Vous pouvez aussi utiliser Hibernate EntityManager qui a son propre
|
||||
mécanisme de configuration. Veullez vous référer à la documentation de ce
|
||||
projet pour plus de détails.</para>
|
||||
|
||||
<para>Il n'y a pas d'autres différences dans la façon d'utiliser les APIs
|
||||
d'Hibernate, excepté ce changement de routine de démarrage ou le fichier
|
||||
de configuration. Vous pouvez utiliser votre méthode de configuration
|
||||
favorite pour d'autres propriétés (<filename>hibernate.properties</filename>,
|
||||
<filename>hibernate.cfg.xml</filename>, utilisation des APIs, etc). Vous
|
||||
pouvez même mélanger les classes persistantes annotées et des déclarations
|
||||
<filename>hbm.cfg.xml</filename> classiques avec la même
|
||||
<classname>SessionFactory</classname>. Vous ne pouvez cependant pas déclarer
|
||||
une classe plusieurs fois (soit avec les annotations, soit avec un fichier
|
||||
hbm.xml). Vous ne pouvez pas non plus mélanger des stratégies de
|
||||
configuration (hbm vs annotations) dans une hiérarchie d'entités
|
||||
mappées.</para>
|
||||
|
||||
<para>Pour faciliter la procédure de migration de fichiers hbm vers les
|
||||
annotations, le mécanisme de configuration détecte la duplication de mappings
|
||||
entre les annotations et les fichiers hbm. Les classes décrites dans les
|
||||
fichiers hbm se voient alors affecter une priorité plus grande que les
|
||||
classes annotées. Vous pouvez changer cette priorité avec la propriété
|
||||
<literal>hibernate.mapping.precedence</literal>. La valeur par défaut est :
|
||||
<literal>hbm, class</literal> ; la changer en : <literal>class, hbm</literal>
|
||||
donne alors la priorité aux classes annotées lorsqu'un conflit
|
||||
survient.</para>
|
||||
</section>
|
||||
</chapter>
|
|
@ -1,569 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<chapter id="validator">
|
||||
<title>Hibernate Validator</title>
|
||||
|
||||
<para>Les annotations sont une manière très commode et élégante pour spécifier
|
||||
des contraintes invariantes sur un modèle de données. Vous pouvez, par
|
||||
exemple, indiquer qu'une propriété ne devrait pas être nulle, que le solde
|
||||
d'un compte devrait être strictement positif, etc. Ces contraintes de modèle
|
||||
de données sont déclarées dans le bean lui-même en annotant ses propriétés.
|
||||
Un validateur peut alors les lire et vérifier les violations de contraintes.
|
||||
Le mécanisme de validation peut être exécuté dans différentes couches de
|
||||
votre application (présentation, accès aux données) sans devoir dupliquer
|
||||
ces règles. Hibernate Validator a été conçu dans ce but.</para>
|
||||
|
||||
<para>Hibernate Validator fonctionne sur deux niveaux. D'abord, il est capable
|
||||
de vérifier des violations de contraintes sur les instances d'une classe en
|
||||
mémoire. Ensuite, il peut appliquer les contraintes au méta-modèle d'Hibernate
|
||||
et les incorporer au schéma de base de données généré.</para>
|
||||
|
||||
<para>Chaque annotation de contrainte est associée à l'implémentation du
|
||||
validateur responsable de vérifier la contrainte sur l'instance de l'entité.
|
||||
Un validateur peut aussi (optionnellement) appliquer la contrainte au
|
||||
méta-modèle d'Hibernate, permettant à Hibernate de générer le DDL qui
|
||||
exprime la contrainte. Avec le listener d'événements approprié, vous pouvez
|
||||
exécuter l'opération de vérification lors des insertions et des mises à jour
|
||||
effectuées par Hibernate. Hibernate Validator n'est pas limité à Hibernate.
|
||||
Vous pouvez facilement l'utiliser n'importe où dans votre application.</para>
|
||||
|
||||
<para>Lors de la vérification des instances à l'exécution, Hibernate Validator
|
||||
retourne des informations à propos des violations de contraintes dans un
|
||||
tableau de <classname>InvalidValue</classname>s. Parmi d'autres informations,
|
||||
<classname>InvalidValue</classname> contient un message de description
|
||||
d'erreur qui peut inclure les valeurs des paramètres associés à l'annotation
|
||||
(p. ex. la limite de taille), et des chaînes de caractères qui peuvent être
|
||||
externalisées avec un <classname>ResourceBundle</classname>.</para>
|
||||
|
||||
<sect1 id="validator-constraints">
|
||||
<title>Contraintes</title>
|
||||
|
||||
<sect2>
|
||||
<title>Qu'est-ce qu'une contrainte ?</title>
|
||||
|
||||
<para>Une contrainte est représentée par une annotation. Une contrainte a
|
||||
généralement des attributs utilisés pour paramétrer les limites des
|
||||
contraintes. La contrainte s'applique à l'élément annoté.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Contraintes intégrées</title>
|
||||
|
||||
<para>Hibernate Validator arrive avec des contraintes intégrées,
|
||||
lesquelles couvrent la plupart des vérifications de données de base. Comme
|
||||
nous le verrons plus tard, vous n'êtes pas limité à celles-ci, vous pouvez
|
||||
écrire vos propres contraintes en une minute.</para>
|
||||
|
||||
<table>
|
||||
<title>Contraintes intégrées</title>
|
||||
|
||||
<tgroup cols="4">
|
||||
<colspec align="center" />
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Annotation</entry>
|
||||
|
||||
<entry>S'applique à</entry>
|
||||
|
||||
<entry>Vérification à l'exécution</entry>
|
||||
|
||||
<entry>Impact sur les méta-données d'Hibernate</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>@Length(min=, max=)</entry>
|
||||
|
||||
<entry>propriété (String)</entry>
|
||||
|
||||
<entry>vérifie si la longueur de la chaîne de caractères est
|
||||
comprise dans l'intervalle</entry>
|
||||
|
||||
<entry>la longueur de la colonne sera positionnée à max</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Max(value=)</entry>
|
||||
|
||||
<entry>propriété (nombre ou chaîne de caractères représentant un
|
||||
nombre)</entry>
|
||||
|
||||
<entry>vérifie si la valeur est inférieure ou égale à max</entry>
|
||||
|
||||
<entry>ajoute une contrainte de vérification sur la
|
||||
colonne</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Min(value=)</entry>
|
||||
|
||||
<entry>propriété (nombre ou chaîne de caractères représentant un
|
||||
nombre)</entry>
|
||||
|
||||
<entry>vérifie si la valeur est supérieure ou égale à max</entry>
|
||||
|
||||
<entry>ajoute une contrainte de vérification sur la
|
||||
colonne</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@NotNull</entry>
|
||||
|
||||
<entry>propriété</entry>
|
||||
|
||||
<entry>vérifie si la valeur n'est pas nulle</entry>
|
||||
|
||||
<entry>les colonnes sont marquées "not null"</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Past</entry>
|
||||
|
||||
<entry>propriété (Date ou Calendar)</entry>
|
||||
|
||||
<entry>vérifie si la date est dans le passé</entry>
|
||||
|
||||
<entry>ajoute une contrainte de vérification sur la
|
||||
colonne</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Future</entry>
|
||||
|
||||
<entry>propriété (Date ou Calendar)</entry>
|
||||
|
||||
<entry>vérifie si la date est dans le futur</entry>
|
||||
|
||||
<entry>aucun</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Pattern(regex="regexp", flag=)</entry>
|
||||
|
||||
<entry>propriété (String)</entry>
|
||||
|
||||
<entry>vérifie si la propriété correspond à l'expression
|
||||
rationnelle donnée (pour "flag", voir
|
||||
<classname> java.util.regex.Pattern</classname>)</entry>
|
||||
|
||||
<entry>aucun</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Range(min=, max=)</entry>
|
||||
|
||||
<entry>propriété (nombre ou chaîne de caractères représentant un
|
||||
nombre)</entry>
|
||||
|
||||
<entry>vérifie si la valeur est comprise entre min et max
|
||||
(inclus)</entry>
|
||||
|
||||
<entry>ajoute une contrainte de vérification sur la
|
||||
colonne</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Size(min=, max=)</entry>
|
||||
|
||||
<entry>propriété (tableau, collection, map)</entry>
|
||||
|
||||
<entry>vérifie si la taille de l'élément est comprise entre min et
|
||||
max (inclus)</entry>
|
||||
|
||||
<entry>aucun</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@AssertFalse</entry>
|
||||
|
||||
<entry>propriété</entry>
|
||||
|
||||
<entry>vérifie que la méthode est évaluée à faux (utile pour les
|
||||
contraintes exprimées dans le code plutôt que dans les
|
||||
annotations)</entry>
|
||||
|
||||
<entry>aucun</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@AssertTrue</entry>
|
||||
|
||||
<entry>propriété</entry>
|
||||
|
||||
<entry>vérifie que la méthode est évaluée à vrai (utile pour les
|
||||
contraintes exprimées dans le code plutôt que dans les
|
||||
annotations)</entry>
|
||||
|
||||
<entry>aucun</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Valid</entry>
|
||||
|
||||
<entry>propriété (objet)</entry>
|
||||
|
||||
<entry>exécute la validation récursivement sur l'objet associé.
|
||||
Si l'objet est une Collection ou un tableau, les éléments sont
|
||||
validés récursivement. Si l'objet est une Map, les éléments
|
||||
valeur sont validés récursivement.</entry>
|
||||
|
||||
<entry>aucun</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Email</entry>
|
||||
|
||||
<entry>propriété (String)</entry>
|
||||
|
||||
<entry>vérifie si la chaîne de caractères est conforme à la
|
||||
spécification d'une adresse e-mail</entry>
|
||||
|
||||
<entry>aucun</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="validator-constraints-error" xreflabel="Messages d'erreur">
|
||||
<title>Messages d'erreur</title>
|
||||
|
||||
<para>Hibernate Validator arrive avec un ensemble de messages d'erreur par
|
||||
défaut traduits dans environ dix langues (si la vôtre n'en fait pas
|
||||
partie, veuillez nous envoyer un patch). Vous pouvez surcharger ces
|
||||
messages en créant un <filename>ValidatorMessages.properties</filename>
|
||||
(ou <filename>ValidatorMessages_loc.properties</filename>) et en
|
||||
surchargeant les clefs dont vous avez besoin. Vous pouvez même ajouter
|
||||
votre propre ensemble de messages supplémentaire lorsque vous écrivez
|
||||
vos annotations de validation. Si Hibernate Validator ne peut pas trouver
|
||||
une clef à partir de votre resourceBundle ou de votre ValidatorMessage,
|
||||
il se repliera sur les valeurs intégrées par défaut.</para>
|
||||
|
||||
<para>Alternativement vous pouvez fournir un
|
||||
<classname>ResourceBundle</classname> pendant la vérification par
|
||||
programmation des règles de validation sur un bean, ou si vous voulez un
|
||||
mécanisme d'interpolation complètement différent, vous pouvez fournir une
|
||||
implémentation de
|
||||
<literal>org.hibernate.validator.MessageInterpolator</literal> (lisez la
|
||||
JavaDoc pour plus d'informations).</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Ecrire vos propres contraintes</title>
|
||||
|
||||
<para>Etendre l'ensemble de contraintes intégrées est extrêment facile.
|
||||
N'importe quelle contrainte est constituée deux morceaux : le
|
||||
<emphasis>descripteur</emphasis> de contrainte (l'annotation) et le
|
||||
<emphasis>validateur</emphasis> de contrainte (la classe
|
||||
d'implémentation). Voici un simple descripteur personnalisé :</para>
|
||||
|
||||
<programlisting>@ValidatorClass(CapitalizedValidator.class)
|
||||
@Target(METHOD)
|
||||
@Retention(RUNTIME)
|
||||
@Documented
|
||||
public @interface Capitalized {
|
||||
CapitalizeType type() default Capitalize.FIRST;
|
||||
String message() default "has incorrect capitalization";
|
||||
}</programlisting>
|
||||
|
||||
<para><literal>type</literal> est un paramètre décrivant comment la
|
||||
propriété devrait être mise en majuscule. Ceci est un paramètre
|
||||
utilisateur complètement dépendant du fonctionnement de
|
||||
l'annotation.</para>
|
||||
|
||||
<para><literal>message</literal> est la chaîne de caractères par défaut
|
||||
utilisée pour décrire la violation de contrainte et est obligatoire. Vous
|
||||
pouvez mettre la chaîne de caractères dans le code ou bien l'externaliser
|
||||
en partie ou complètement avec le mécanisme ResourceBundle Java. Les
|
||||
valeurs des paramètres sont injectées à l'intérieur du message quand
|
||||
la chaîne de caractères <literal>{parameter}</literal> est trouvée (dans
|
||||
notre exemple <literal>Capitalization is not {type}</literal> générerait
|
||||
<literal>Capitalization is not FIRST</literal>), externaliser toute la
|
||||
chaîne dans <filename>ValidatorMessages.properties</filename> est
|
||||
considéré comme une bonne pratique. Voir <xref
|
||||
linkend="validator-constraints-error" />.</para>
|
||||
|
||||
<programlisting>@ValidatorClass(CapitalizedValidator.class)
|
||||
@Target(METHOD)
|
||||
@Retention(RUNTIME)
|
||||
@Documented
|
||||
public @interface Capitalized {
|
||||
CapitalizeType type() default Capitalize.FIRST;
|
||||
String message() default "{validator.capitalized}";
|
||||
}
|
||||
|
||||
...
|
||||
#in ValidatorMessages.properties
|
||||
validator.capitalized=<literal>Capitalization is not {type}</literal></programlisting>
|
||||
|
||||
<para>Comme vous pouvez le voir la notation {} est récursive.</para>
|
||||
|
||||
<para>Pour lier un descripteur à l'implémentation de son validateur, nous
|
||||
utilisons la méta-annotation <literal>@ValidatorClass</literal>. Le
|
||||
paramètre de la classe du validateur doit nommer une classe qui implémente
|
||||
<literal>Validator<ConstraintAnnotation></literal>.</para>
|
||||
|
||||
<para>Nous devons maintenant implémenter le validateur (ie
|
||||
l'implémentation vérifiant la règle). Une implémentation de validation
|
||||
peut vérifier la valeur d'une propriété (en implémentant
|
||||
<literal>PropertyConstraint</literal>) et/ou peut modifier les
|
||||
méta-données de mapping d'Hibernate pour exprimer la contrainte au niveau
|
||||
de la base de données (en implémentant
|
||||
<literal>PersistentClassConstraint</literal>).</para>
|
||||
|
||||
<programlisting>public class CapitalizedValidator
|
||||
implements Validator<Capitalized>, PropertyConstraint {
|
||||
private CapitalizeType type;
|
||||
|
||||
// partie du contrat de Validator<Annotation>,
|
||||
// permet d'obtenir et d'utiliser les valeurs de l'annotation
|
||||
public void initialize(Capitalized parameters) {
|
||||
type = parameters.type();
|
||||
}
|
||||
|
||||
// partie du contrat de la contrainte de la propriété
|
||||
public boolean isValid(Object value) {
|
||||
if (value==null) return true;
|
||||
if ( !(value instanceof String) ) return false;
|
||||
String string = (String) value;
|
||||
if (type == CapitalizeType.ALL) {
|
||||
return string.equals( string.toUpperCase() );
|
||||
}
|
||||
else {
|
||||
String first = string.substring(0,1);
|
||||
return first.equals( first.toUpperCase();
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>La méthode <literal>isValid()</literal> devrait retourner false si
|
||||
la contrainte a été violée. Pour plus d'exemples, référez-vous aux
|
||||
implémentations intégrées du validateur.</para>
|
||||
|
||||
<para>Nous avons seulement vu la validation au niveau propriété, mais vous
|
||||
pouvez écrire une annotation de validation au niveau d'un bean. Plutôt
|
||||
que de recevoir l'instance de retour d'une propriété, le bean lui-même
|
||||
sera passé au validateur. Pour activer la vérification de validation,
|
||||
annotez juste le bean lui-même. Un petit exemple peut être trouvé dans la
|
||||
suite de tests unitaires.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Annoter votre modèle de données</title>
|
||||
|
||||
<para>Maintenant que vous vous êtes familiarisés avec les annotations, la
|
||||
syntaxe devrait être connue.</para>
|
||||
|
||||
<programlisting>public class Address {
|
||||
private String line1;
|
||||
private String line2;
|
||||
private String zip;
|
||||
private String state;
|
||||
private String country;
|
||||
private long id;
|
||||
|
||||
// une chaîne non nulle de 20 caractères maximum
|
||||
@Length(max=20)
|
||||
@NotNull
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
// une chaîne de caractères non nulle
|
||||
@NotNull
|
||||
public String getLine1() {
|
||||
return line1;
|
||||
}
|
||||
|
||||
// pas de contrainte
|
||||
public String getLine2() {
|
||||
return line2;
|
||||
}
|
||||
|
||||
// une chaîne non nulle de 3 caractères maximum
|
||||
@Length(max=3) @NotNull
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
// une chaîne non nulle de 5 caractères maximum représentant un nombre
|
||||
// si la chaîne de caractères est plus longue, le message sera recherché
|
||||
// dans le resource bundle avec la clef 'long'
|
||||
@Length(max=5, message="{long}")
|
||||
@Pattern(regex="[0-9]+")
|
||||
@NotNull
|
||||
public String getZip() {
|
||||
return zip;
|
||||
}
|
||||
|
||||
// devrait toujours être vrai
|
||||
@AssertTrue
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// un nombre entre 1 et 2000
|
||||
@Id @Min(1)
|
||||
@Range(max=2000)
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>Bien que l'exemple montre seulement la validation de propriétés
|
||||
publiques, vous pouvez aussi annoter des champs avec n'importe quelle
|
||||
visibilité.</para>
|
||||
|
||||
<programlisting>@MyBeanConstraint(max=45)
|
||||
public class Dog {
|
||||
@AssertTrue private boolean isMale;
|
||||
@NotNull protected String getName() { ... };
|
||||
...
|
||||
}</programlisting>
|
||||
|
||||
<para>Vous pouvez aussi annoter des inferfaces. Hibernate Validator
|
||||
vérifiera toutes les classes parentes et les interfaces héritées ou
|
||||
implémentées par un bean donné pour lire les annotations appropriées du
|
||||
validateur.</para>
|
||||
|
||||
<programlisting>public interface Named {
|
||||
@NotNull String getName();
|
||||
...
|
||||
}
|
||||
|
||||
public class Dog implements Named {
|
||||
|
||||
@AssertTrue private boolean isMale;
|
||||
|
||||
public String getName() { ... };
|
||||
|
||||
}</programlisting>
|
||||
|
||||
<para>La propriété "name" sera vérifiée pour la nullité lorsque le bean
|
||||
Dog sera validé.</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Utiliser le framework Validator</title>
|
||||
|
||||
<para>Hibernate Validator est destiné à être utilisé pour implémenter une
|
||||
validation de données à plusieurs couches, où nous exprimons des contraintes
|
||||
à un seul endroit (le modèle de données annoté) et les appliquons aux
|
||||
différents niveaux de l'application.</para>
|
||||
|
||||
<sect2>
|
||||
<title>Validation au niveau du schéma de la base de données</title>
|
||||
|
||||
<para>Par défaut, Hibernate Annotations traduira les contraintes que vous
|
||||
avez définies sur vos entités en méta-données de mapping. Par exemple, si
|
||||
une propriété de votre entité est annotée avec
|
||||
<literal>@NotNull</literal>, ses colonnes seront déclarées comme
|
||||
<literal>not null</literal> dans le schéma DDL généré par
|
||||
Hibernate.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>La validation basée sur les événements Hibernate</title>
|
||||
|
||||
<para>Hibernate Validator a deux listeners d'événements Hibernate
|
||||
intégrés. Quand un <literal>PreInsertEvent</literal> ou un
|
||||
<literal>PreUpdateEvent</literal> survient, les listeners vérifieront
|
||||
toutes les contraintes de l'instance de l'entité et lèveront une exception
|
||||
si une contrainte est violée. Fondamentalement, les objets seront vérifiés
|
||||
avant les insertions et avant les mises à jour effectuées par Hibernate.
|
||||
C'est le plus commode et la manière la plus simple d'activer le processus
|
||||
de validation. Sur une violation de contrainte, l'événement lèvera une
|
||||
exception d'exécution <classname>InvalidStateException</classname> (NdT :
|
||||
c'est une RuntimeException) laquelle contient un tableau
|
||||
d'<literal>InvalidValue</literal>s décrivant chaque échec.</para>
|
||||
|
||||
<programlisting><hibernate-configuration>
|
||||
...
|
||||
<event type="pre-update">
|
||||
<listener
|
||||
class="org.hibernate.validator.event.ValidatePreUpdateEventListener"/>
|
||||
</event>
|
||||
<event type="pre-insert">
|
||||
<listener
|
||||
class="org.hibernate.validator.event.ValidatePreInsertEventListener"/>
|
||||
</event>
|
||||
</hibernate-configuration></programlisting>
|
||||
|
||||
<note>
|
||||
<para>Lors de l'utilisation d'Hibernate Entity Manager, le framework
|
||||
Validation est activé par défaut. Si les beans ne sont pas annotés avec
|
||||
des annotations de validation, il n'y a pas de coût en terme de
|
||||
performance.</para>
|
||||
</note>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>La validation au niveau applicatif</title>
|
||||
|
||||
<para>Hibernate Validator peut être utilisé n'importe où dans le code de
|
||||
votre application.</para>
|
||||
|
||||
<programlisting>ClassValidator personValidator = new ClassValidator( Person.class );
|
||||
ClassValidator addressValidator = new ClassValidator( Address.class, ResourceBundle.getBundle("messages", Locale.ENGLISH) );
|
||||
|
||||
InvalidValue[] validationMessages = addressValidator.getInvalidValues(address);</programlisting>
|
||||
|
||||
<para>Les deux premières lignes préparent Hibernate Validator pour la
|
||||
vérification de classes. La première s'appuie sur les messages d'erreur
|
||||
intégrés à Hibernate Validator (voir
|
||||
<xref linkend="validator-constraints-error" />), la seconde utilise un
|
||||
resource bundle pour ses messages. Il est considéré comme une bonne
|
||||
pratique d'exécuter ces lignes une fois et de cacher les instances de
|
||||
validateur.</para>
|
||||
|
||||
<para>La troisième ligne valide en fait l'instance
|
||||
<literal>Address</literal> et retourne un tableau
|
||||
d'<literal>InvalidValue</literal>s. Votre logique applicative sera alors
|
||||
capable de réagir aux échecs.</para>
|
||||
|
||||
<para>Vous pouvez aussi vérifier une propriété particulière plutôt que
|
||||
tout le bean. Ceci pourrait être utile lors d'interactions avec
|
||||
l'utilisateur propriété par propriété.</para>
|
||||
|
||||
<programlisting>ClassValidator addressValidator = new ClassValidator( Address.class, ResourceBundle.getBundle("messages", Locale.ENGLISH) );
|
||||
|
||||
// récupère seulement les valeurs invalides de la propriété "city"
|
||||
InvalidValue[] validationMessages = addressValidator.getInvalidValues(address, "city");
|
||||
|
||||
// récupère seulement les valeurs potentielles invalides de la propriété "city"
|
||||
InvalidValue[] validationMessages = addressValidator.getPotentialInvalidValues("city", "Paris")</programlisting>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Informations de validation</title>
|
||||
|
||||
<para>Comme un transporteur d'informations de validation, Hibernate
|
||||
fournit un tableau d'<classname>InvalidValue</classname>s. Chaque
|
||||
<literal>InvalidValue</literal> a un groupe de méthodes décrivant les
|
||||
problèmes individuels.</para>
|
||||
|
||||
<para><methodname>getBeanClass()</methodname> récupère le type du bean
|
||||
ayant échoué.</para>
|
||||
|
||||
<para><methodname>getBean()</methodname> récupère l'instance du bean ayant
|
||||
échoué (s'il y en a, c'est-à-dire pas lors de l'utilisation de
|
||||
<methodname>getPotentianInvalidValues()</methodname>).</para>
|
||||
|
||||
<para><methodname>getValue()</methodname> récupère la valeur ayant
|
||||
échouée.</para>
|
||||
|
||||
<para><methodname>getMessage()</methodname> récupère le message d'erreur
|
||||
internationalisé.</para>
|
||||
|
||||
<para><methodname>getRootBean()</methodname> récupère l'instance du bean
|
||||
racine ayant généré le problème (utile en conjonction avec
|
||||
<literal>@Valid</literal>), est nulle si getPotentianInvalidValues() est
|
||||
utilisée.</para>
|
||||
|
||||
<para><literal>getPropertyPath()</literal> récupère le chemin (séparé par
|
||||
des points) de la propriété ayant échouée à partir du bean racine.</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
|
@ -1,413 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<chapter id="xml-overriding">
|
||||
<title>Surcharger des méta-données à travers du XML</title>
|
||||
|
||||
<para>La cible primaire pour les méta-données dans EJB3 sont les annotations,
|
||||
mais la spécification EJB3 fournit un moyen de surcharger ou remplacer les
|
||||
méta-données définies par des annotations à travers un descripteur de
|
||||
déploiement XML. Dans la version courante, seule la surcharge des annotations
|
||||
pure EJB3 est prise en charge. Si vous souhaitez utiliser des caractéristiques
|
||||
spécifiques à Hibernate dans des entités, vous devrez utiliser les annotations
|
||||
ou vous replier sur les fichiers hbm. Vous pouvez bien sûr mélanger et faire
|
||||
correspondre des entités annotées et des entités décrites dans des fichiers
|
||||
hbm.</para>
|
||||
|
||||
<para>La suite de test unitaires montre des exemples supplémentaires de
|
||||
fichier XML.</para>
|
||||
|
||||
<section id="xml-overriding-principles">
|
||||
<title>Principes</title>
|
||||
|
||||
<para>La structure du descripteur de déploiement XML a été conçue pour
|
||||
refléter celle des annotations. Donc si vous connaissez la structure des
|
||||
annotations, utiliser le schéma XML sera facile pour vous.</para>
|
||||
|
||||
<para>Vous pouvez définir un ou plusieurs fichiers XML décrivant vos
|
||||
méta-données, ces fichiers seront fusionnés par le moteur de surcharge.</para>
|
||||
|
||||
<section>
|
||||
<title>Méta-données de niveau global</title>
|
||||
|
||||
<para>Vous pouvez définir des méta-données de niveau global disponibles
|
||||
pour tous les fichiers XML. Vous ne devez pas définir ces méta-données
|
||||
plus d'une fois par déploiement.</para>
|
||||
|
||||
<programlisting><?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<entity-mappings
|
||||
xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit-metadata>
|
||||
<xml-mapping-metadata-complete/>
|
||||
<persistence-unit-defaults>
|
||||
<schema>myschema</schema>
|
||||
<catalog>mycatalog</catalog>
|
||||
<cascade-persist/>
|
||||
</persistence-unit-defaults>
|
||||
</persistence-unit-metadata></programlisting>
|
||||
|
||||
<para><literal>xml-mapping-metadata-complete</literal> signifie que toutes
|
||||
les entités, classes mères mappées et méta-données devraient être
|
||||
récupérées à partir du XML (c'est-à-dire ignorer les annotations).</para>
|
||||
|
||||
<para><literal>schema / catalog</literal> surchargera toutes les
|
||||
définitions par défaut de schéma et de catalogue dans les méta-données
|
||||
(XML et annotations).</para>
|
||||
|
||||
<para><literal>cascade-persist</literal> signifie que toutes les
|
||||
associations ont PERSIST comme type de cascade. Nous vous recommandons de
|
||||
ne pas utiliser cette fonctionnalité.</para>
|
||||
</section>
|
||||
|
||||
<section id="xml-overriding-principles-entity" revision="1">
|
||||
<title>Méta-données de niveau entité</title>
|
||||
|
||||
<para>Vous pouvez définir ou surcharger des informations de méta-données
|
||||
sur une entité donnée.</para>
|
||||
|
||||
<programlistingco>
|
||||
<areaspec>
|
||||
<area coords="3" id="aa1" />
|
||||
|
||||
<area coords="9" id="aa2" />
|
||||
|
||||
<area coords="10" id="aa3" />
|
||||
|
||||
<area coords="11" id="aa4" />
|
||||
|
||||
<area coords="17" id="aa5" />
|
||||
|
||||
<area coords="23" id="aa6" />
|
||||
|
||||
<area coords="24" id="aa7" />
|
||||
|
||||
<area coords="25" id="aa8" />
|
||||
|
||||
<area coords="26" id="aa9" />
|
||||
|
||||
<area coords="31" id="aa10" />
|
||||
</areaspec>
|
||||
|
||||
<programlisting><?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<entity-mappings
|
||||
xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<package>org.hibernate.test.annotations.reflection</package>
|
||||
<entity class="Administration" access="PROPERTY" metadata-complete="true">
|
||||
<table name="tbl_admin">
|
||||
<unique-constraint>
|
||||
<column-name>firstname</column-name>
|
||||
<column-name>lastname</column-name>
|
||||
</unique-constraint>
|
||||
</table>
|
||||
<secondary-table name="admin2">
|
||||
<primary-key-join-column name="admin_id" referenced-column-name="id"/>
|
||||
<unique-constraint>
|
||||
<column-name>address</column-name>
|
||||
</unique-constraint>
|
||||
</secondary-table>
|
||||
<id-class class="SocialSecurityNumber"/>
|
||||
<inheritance strategy="JOINED"/>
|
||||
<sequence-generator name="seqhilo" sequence-name="seqhilo"/>
|
||||
<table-generator name="table" table="tablehilo"/>
|
||||
...
|
||||
</entity>
|
||||
|
||||
<entity class="PostalAdministration">
|
||||
<primary-key-join-column name="id"/>
|
||||
...
|
||||
</entity>
|
||||
</entity-mappings></programlisting>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs="aa1">
|
||||
<para><literal>entity-mappings</literal> : entity-mappings est
|
||||
l'élément racine pour tous les fichiers XML. Vous devez déclarer le
|
||||
schéma xml, le fichier du schéma est inclus dans le fichier
|
||||
hibernate-annotations.jar, aucun accès à internet ne sera effectué
|
||||
par Hibernate Annotations.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa2">
|
||||
<para><literal>package</literal> (optionnel) : package par défaut
|
||||
utilisé pour tous les noms de classes sans package dans le fichier
|
||||
de descripteur de déploiement donné.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa3">
|
||||
<para><literal>entity</literal> : décrit une entité.</para>
|
||||
|
||||
<para><literal>metadata-complete</literal> définit si la description
|
||||
des méta-données pour cet élément est complète ou pas (en d'autres
|
||||
mots, si les annotations présentes au niveau de la classe devraient
|
||||
être prises en compte ou pas).</para>
|
||||
|
||||
<para>Une entité doit avoir un attribut <literal>class</literal>
|
||||
référençant une classe java à laquelle s'applique les
|
||||
méta-données.</para>
|
||||
|
||||
<para>Vous pouvez surcharger un nom d'entité avec l'attribut
|
||||
<literal>name</literal>, si aucun n'est défini et si une annotation
|
||||
<literal>@Entity.name</literal> est présente, alors elle est
|
||||
utilisée (et établit que les méta-données ne sont pas
|
||||
complètes).</para>
|
||||
|
||||
<para>Pour un élément avec des méta-données complètes (voir
|
||||
ci-dessous), vous pouvez définir un attribut
|
||||
<literal>access</literal> (soit <literal>FIELD</literal>, soit
|
||||
<literal>PROPERTY</literal> (valeur par défaut)). Pour un élément
|
||||
avec des méta-données incomplètes, si <literal>access</literal>
|
||||
n'est pas défini, la position de @Id permettra de le déterminer, si
|
||||
<literal>access</literal> est défini, sa valeur est utilisée.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa4">
|
||||
<para><literal>table</literal> : vous pouvez déclarer des propriétés
|
||||
de table (nom, schéma, catalogue), si aucune n'est définie,
|
||||
l'annotation java est utilisée.</para>
|
||||
|
||||
<para>Vous pouvez définir une ou plusieurs contraintes d'unicité
|
||||
comme dans l'exemple.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa5">
|
||||
<para><literal>secondary-table</literal> : définit une table
|
||||
secondaire très semblable à une table habituelle excepté que vous
|
||||
pouvez définir les colonnes de clef primaire / clef étrangère avec
|
||||
l'élément <literal>primary-key-join-column</literal>. Sur des
|
||||
méta-données incomplètes, les annotations de table secondaire sont
|
||||
utilisées seulement s'il n'y a pas de <literal>secondary-table</literal>
|
||||
de défini, sinon les annotations sont ignorées.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa6">
|
||||
<para><literal>id-class</literal> : définit la classe identifiante
|
||||
comme le fait <literal>@IdClass</literal>.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa7">
|
||||
<para><literal>inheritance</literal> : définit la stratégie
|
||||
d'héritage (<literal>JOINED</literal>,
|
||||
<literal>TABLE_PER_CLASS</literal>,
|
||||
<literal>SINGLE_TABLE</literal>) ; disponible seulement au niveau de
|
||||
l'élément racine.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa8">
|
||||
<para><literal>sequence-generator</literal> : définit un générateur
|
||||
de séquence.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa9">
|
||||
<para><literal>table-generator</literal> : définit un générateur de
|
||||
table.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa10">
|
||||
<para><literal><literal>primary-key-join-column</literal></literal> :
|
||||
définit la colonne de jointure sur la clef primaire pour les
|
||||
entités filles lorsque la stratégie d'héritage utilisée est
|
||||
JOINED.</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</programlistingco>
|
||||
|
||||
<programlistingco>
|
||||
<areaspec>
|
||||
<area coords="11" id="ab1" />
|
||||
|
||||
<area coords="18" id="ab2" />
|
||||
|
||||
<area coords="22" id="ab3" />
|
||||
|
||||
<area coords="28" id="ab4" />
|
||||
|
||||
<area coords="34" id="ab5" />
|
||||
</areaspec>
|
||||
|
||||
<programlisting><?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<entity-mappings
|
||||
xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<package>org.hibernate.test.annotations.reflection</package>
|
||||
<entity class="Music" access="PROPERTY" metadata-complete="true">
|
||||
<discriminator-value>Generic</discriminator-value>
|
||||
<discriminator-column length="34"/>
|
||||
...
|
||||
</entity>
|
||||
|
||||
<entity class="PostalAdministration">
|
||||
<primary-key-join-column name="id"/>
|
||||
<named-query name="adminById">
|
||||
<query>select m from Administration m where m.id = :id</query>
|
||||
<hint name="org.hibernate.timeout" value="200"/>
|
||||
</named-query>
|
||||
<named-native-query name="allAdmin" result-set-mapping="adminrs">
|
||||
<query>select *, count(taxpayer_id) as taxPayerNumber
|
||||
from Administration, TaxPayer
|
||||
where taxpayer_admin_id = admin_id group by ...</query>
|
||||
<hint name="org.hibernate.timeout" value="200"/>
|
||||
</named-native-query>
|
||||
<sql-result-set-mapping name="adminrs">
|
||||
<entity-result entity-class="Administration">
|
||||
<field-result name="name" column="fld_name"/>
|
||||
</entity-result>
|
||||
<column-result name="taxPayerNumber"/>
|
||||
</sql-result-set-mapping>
|
||||
<attribute-override name="ground">
|
||||
<column name="fld_ground" unique="true" scale="2"/>
|
||||
</attribute-override>
|
||||
<association-override name="referer">
|
||||
<join-column name="referer_id" referenced-column-name="id"/>
|
||||
</association-override>
|
||||
...
|
||||
</entity>
|
||||
</entity-mappings></programlisting>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs="ab1">
|
||||
<para><literal>discriminator-value /
|
||||
discriminator-column</literal> : définissent la colonne et la valeur
|
||||
discriminantes lorsque la stratégie d'héritage choisie est
|
||||
SINGLE_TABLE.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ab2">
|
||||
<para><literal>named-query</literal> : définit les requêtes nommées
|
||||
et potentiellement les indices qui leur sont associés. Ces
|
||||
définitions sont ajoutées à celles définies dans les annotations,
|
||||
si deux définitions ont le même nom, la version XML a la
|
||||
priorité.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ab3">
|
||||
<para><literal>named-native-query</literal> : définit une requête
|
||||
SQL nommée et le mapping de son résultat. Alternativement, vous
|
||||
pouvez définir <literal>result-class</literal>. Ces définitions
|
||||
sont ajoutées à celles definies dans les annotations, si deux
|
||||
définitions ont le même nom, la version XML a la priorité.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ab4">
|
||||
<para><literal>sql-result-set-mapping</literal> : décrit la
|
||||
structure du mapping des résultats. Vous pouvez définir des mappings
|
||||
de colonnes et d'entité. Ces définitions sont ajoutées à celles
|
||||
définies dans les annotations, si deux définitions ont le même nom,
|
||||
la version XML a la priorité.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ab5">
|
||||
<para><literal>attribute-override /
|
||||
association-override</literal> : surcharge la définition d'une
|
||||
colonne ou d'une colonne de jointure. Cette surcharge est ajoutée à
|
||||
celle définie dans les annotations.</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</programlistingco>
|
||||
|
||||
<para>La même chose s'applique à <literal><embeddable></literal> et
|
||||
<literal><mapped-superclass></literal>.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Méta-données de niveau propriété</title>
|
||||
|
||||
<para>Vous pouvez bien sûr définir des surcharges XML pour des propriétés.
|
||||
Si les méta-données sont définies comme incomplètes, alors les propriétés
|
||||
supplémentaires (c'est-à-dire au niveau Java) seront ignorées. Toutes les
|
||||
méta-données de niveau propriété sont définies par
|
||||
<literal>entity/attributes</literal>,
|
||||
<literal>mapped-superclass/attributes</literal> ou
|
||||
<literal>embeddable/attributes</literal>.</para>
|
||||
|
||||
<programlisting> <attributes>
|
||||
<id name="id">
|
||||
<column name="fld_id"/>
|
||||
<generated-value generator="generator" strategy="SEQUENCE"/>
|
||||
<temporal>DATE</temporal>
|
||||
<sequence-generator name="generator" sequence-name="seq"/>
|
||||
</id>
|
||||
<version name="version"/>
|
||||
<embedded name="embeddedObject">
|
||||
<attribute-override name"subproperty">
|
||||
<column name="my_column"/>
|
||||
</attribute-override>
|
||||
</embedded>
|
||||
<basic name="status" optional="false">
|
||||
<enumerated>STRING</enumerated>
|
||||
</basic>
|
||||
<basic name="serial" optional="true">
|
||||
<column name="serialbytes"/>
|
||||
<lob/>
|
||||
</basic>
|
||||
<basic name="terminusTime" fetch="LAZY">
|
||||
<temporal>TIMESTAMP</temporal>
|
||||
</basic>
|
||||
</attributes></programlisting>
|
||||
|
||||
<para>Vous pouvez surcharger une propriété avec <literal>id</literal>,
|
||||
<literal>embedded-id</literal>, <literal>version</literal>,
|
||||
<literal>embedded</literal> et <literal>basic</literal>. Chacun de ces
|
||||
éléments peuvent avoir des sous-éléments : <literal>lob</literal>,
|
||||
<literal>temporal</literal>, <literal>enumerated</literal>,
|
||||
<literal>column</literal>.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Méta-données au niveau association</title>
|
||||
|
||||
<para>Vous pouvez définir des surcharges XML pour les associations. Toutes
|
||||
les méta-données de niveau association sont définies par
|
||||
<literal>entity/attributes</literal>,
|
||||
<literal>mapped-superclass/attributes</literal> ou
|
||||
<literal>embeddable/attributes</literal>.</para>
|
||||
|
||||
<programlisting> <attributes>
|
||||
<one-to-many name="players" fetch="EAGER">
|
||||
<map-key name="name"/>
|
||||
<join-column name="driver"/>
|
||||
<join-column name="number"/>
|
||||
</one-to-many>
|
||||
<many-to-many name="roads" target-entity="Administration">
|
||||
<order-by>maxSpeed</order-by>
|
||||
<join-table name="bus_road">
|
||||
<join-column name="driver"/>
|
||||
<join-column name="number"/>
|
||||
<inverse-join-column name="road_id"/>
|
||||
<unique-constraint>
|
||||
<column-name>driver</column-name>
|
||||
<column-name>number</column-name>
|
||||
</unique-constraint>
|
||||
</join-table>
|
||||
</many-to-many>
|
||||
<many-to-many name="allTimeDrivers" mapped-by="drivenBuses">
|
||||
</attributes></programlisting>
|
||||
|
||||
<para>Vous pouvez surcharger une association avec
|
||||
<literal>one-to-many</literal>, <literal>one-to-one</literal>,
|
||||
<literal>many-to-one</literal>, et <literal>many-to-many</literal>.
|
||||
Chacun de ces éléments peut avoir des sous-éléments :
|
||||
<literal>join-table</literal> (qui peut avoir des
|
||||
<literal>join-column</literal>s et des
|
||||
<literal>inverse-join-column</literal>s),
|
||||
<literal><literal>join-column</literal>s</literal>,
|
||||
<literal>map-key</literal>, et <literal>order-by</literal>.
|
||||
<literal>mapped-by</literal> et <literal>target-entity</literal> peuvent
|
||||
être définis en tant qu'attributs lorsque cela a du sens. Une fois de plus
|
||||
la structure est le reflet de la structure des annotations. Vous pouvez
|
||||
trouver toutes les informations de sémantique dans le chapitre décrivant
|
||||
les annotations.</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
|
@ -1,4 +0,0 @@
|
|||
simhei.ttf has been removed as it's copyrighted.
|
||||
simsun.ttf has been removed just in case.
|
||||
|
||||
TODO find open source fonts or migrate to jdocbook's system and list of fonts.
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,114 +0,0 @@
|
|||
<!--<!DOCTYPE configuration SYSTEM "config.dtd">-->
|
||||
<!--
|
||||
this file contains templates which allow an user easy
|
||||
configuration of Fop. Actually normally you don't need this configuration
|
||||
file, but if you need to change configuration, you should
|
||||
always use this file and *not* config.xml.
|
||||
Usage: java org.apache.fop.apps.Fop -c userconfig.xml -fo fo-file -pdf pdf-file
|
||||
-->
|
||||
|
||||
|
||||
<configuration>
|
||||
|
||||
<!--
|
||||
baseDir: normally the base directory is the directory where the fo file is
|
||||
located. if you want to specify your own, uncomment this entry.
|
||||
This value can also be a URL. Actually, the value is converted to
|
||||
a URL.
|
||||
-->
|
||||
<!--
|
||||
<entry>
|
||||
<key>baseDir</key>
|
||||
<value></value>
|
||||
</entry>
|
||||
-->
|
||||
|
||||
<!--
|
||||
fontBaseDir: Similar to baseDir, except that this value is used for fonts. If
|
||||
it isn't specified, the value from baseDir is used.
|
||||
-->
|
||||
<!--
|
||||
<entry>
|
||||
<key>fontBaseDir</key>
|
||||
<value></value>
|
||||
</entry>
|
||||
-->
|
||||
|
||||
<!--
|
||||
************************************************************************
|
||||
HYPHENATION
|
||||
************************************************************************
|
||||
-->
|
||||
|
||||
<!--
|
||||
hyphenation directory
|
||||
if you want to specify your own directory with hyphenation pattern
|
||||
then uncomment the next entry and add the directory name
|
||||
-->
|
||||
|
||||
<!--
|
||||
<entry>
|
||||
<key>hyphenation-dir</key>
|
||||
<value>/java/xml-fop/hyph</value>
|
||||
</entry>
|
||||
-->
|
||||
|
||||
<!--
|
||||
************************************************************************
|
||||
Add fonts here
|
||||
************************************************************************
|
||||
-->
|
||||
|
||||
<fonts>
|
||||
<!-- example -->
|
||||
<!--
|
||||
<font metrics-file="arial.xml" kerning="yes" embed-file="arial.ttf">
|
||||
<font-triplet name="Arial" style="normal" weight="normal"/>
|
||||
<font-triplet name="ArialMT" style="normal" weight="normal"/>
|
||||
</font>
|
||||
<font metrics-file="arialb.xml" kerning="yes" embed-file="arialb.ttf">
|
||||
<font-triplet name="Arial" style="normal" weight="bold"/>
|
||||
<font-triplet name="ArialMT" style="normal" weight="bold"/>
|
||||
</font>
|
||||
<font metrics-file="ariali.xml" kerning="yes" embed-file="ariali.ttf">
|
||||
<font-triplet name="Arial" style="italic" weight="normal"/>
|
||||
<font-triplet name="ArialMT" style="italic" weight="normal"/>
|
||||
</font>
|
||||
<font metrics-file="arialbi.xml" kerning="yes" embed-file="arialbi.ttf">
|
||||
<font-triplet name="Arial" style="italic" weight="bold"/>
|
||||
<font-triplet name="ArialMT" style="italic" weight="bold"/>
|
||||
</font>
|
||||
-->
|
||||
<!-- Example Japanese fonts
|
||||
<font metrics-file="msgothic.xml" embed-file="D:\winnt\font\msgothic.ttc" kerning="yes">
|
||||
<font-triplet name="Gothic" style="normal" weight="normal"/>
|
||||
<font-triplet name="Gothic" style="normal" weight="bold"/>
|
||||
<font-triplet name="Gothic" style="italic" weight="normal"/>
|
||||
<font-triplet name="Gothic" style="italic" weight="bold"/>
|
||||
</font>
|
||||
<font metrics-file="msmincho.xml" embed-file="Cyberbit.ttf" kerning="yes">
|
||||
<font-triplet name="Mincho" style="normal" weight="normal"/>
|
||||
<font-triplet name="Mincho" style="normal" weight="bold"/>
|
||||
<font-triplet name="Mincho" style="italic" weight="normal"/>
|
||||
<font-triplet name="Mincho" style="italic" weight="bold"/>
|
||||
</font>
|
||||
-->
|
||||
<!-- font metrics-file="simhei.xml" embed-file="simhei.ttf" kerning="yes">
|
||||
<font-triplet name="simhei" style="normal" weight="normal"/>
|
||||
<font-triplet name="simhei" style="normal" weight="bold"/>
|
||||
<font-triplet name="simhei" style="italic" weight="normal"/>
|
||||
<font-triplet name="simhei" style="italic" weight="bold"/>
|
||||
</font>
|
||||
<font metrics-file="simsun.xml" embed-file="simsun.ttc" kerning="yes">
|
||||
<font-triplet name="simsun" style="normal" weight="normal"/>
|
||||
<font-triplet name="simsun" style="normal" weight="bold"/>
|
||||
<font-triplet name="simsun" style="italic" weight="normal"/>
|
||||
<font-triplet name="simsun" style="italic" weight="bold"/>
|
||||
</font -->
|
||||
</fonts>
|
||||
|
||||
|
||||
</configuration>
|
||||
|
||||
|
||||
|
|
@ -1,297 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3CR3//EN"
|
||||
"../support/docbook-dtd/docbookx.dtd" [
|
||||
<!ENTITY setup SYSTEM "modules/setup.xml">
|
||||
<!ENTITY entity SYSTEM "modules/entity.xml">
|
||||
<!ENTITY xml-overriding SYSTEM "modules/xml-overriding.xml">
|
||||
<!ENTITY validator SYSTEM "modules/validator.xml">
|
||||
<!ENTITY lucene SYSTEM "modules/lucene.xml">
|
||||
<!ENTITY version "WORKING">
|
||||
<!ENTITY today "TODAY">
|
||||
]>
|
||||
<book lang="zh_cn">
|
||||
<bookinfo>
|
||||
<title>Hibernate Annotations</title>
|
||||
|
||||
<subtitle>参考文档</subtitle>
|
||||
|
||||
<releaseinfo>&version;</releaseinfo>
|
||||
<pubdate>&today;</pubdate>
|
||||
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="images/hibernate_logo_a.png" format="png" />
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
</bookinfo>
|
||||
|
||||
<toc></toc>
|
||||
|
||||
<preface id="preface" revision="2">
|
||||
<title>前言</title>
|
||||
|
||||
<para>WARNING! This is a translated version of the English Hibernate
|
||||
reference documentation. The translated version might not be up to date!
|
||||
However, the differences should only be very minor. Consult the English
|
||||
reference documentation if you are missing information or encounter a
|
||||
translation error. If you like to contribute to a particular translation,
|
||||
contact us on the Hibernate developer mailing list.</para>
|
||||
|
||||
<para>Translator(s): RedSaga Translate Team 满江红翻译团队
|
||||
<caoxg@yahoo.com></para>
|
||||
|
||||
<sect1 id="preface-translate-comments-zh-cn">
|
||||
<title>翻译说明</title>
|
||||
|
||||
<para>本文档的翻译是在网络上协作进行的,也会不断根据Hibernate的升级进行更新。提供此文档的目的是为了减缓学习Hibernate的坡度,而非代替原文档。我们建议所有有能力的读者都直接阅读英文原文。若您对翻译有异议,或发现翻译错误,敬请不吝赐教,报告到如下地址:http://wiki.redsaga.com/confluence/display/HART/Home</para>
|
||||
|
||||
<table frame="topbot" id="redsaga-translate-team">
|
||||
<title>Hibernate Annotation v3翻译团队</title>
|
||||
|
||||
<tgroup cols="6" colsep="1" rowsep="1">
|
||||
<colspec colname="c1" colwidth="1*" />
|
||||
|
||||
<colspec colname="c2" colwidth="2*" />
|
||||
|
||||
<colspec colname="c3" colwidth="2*" />
|
||||
|
||||
<colspec colname="c4" colwidth="2*" />
|
||||
|
||||
<colspec colname="c5" colwidth="2*" />
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry align="center">序号</entry>
|
||||
|
||||
<entry align="center">标题</entry>
|
||||
|
||||
<entry align="center">中文标题</entry>
|
||||
|
||||
<entry align="center">翻译</entry>
|
||||
|
||||
<entry align="center">1审</entry>
|
||||
|
||||
<entry align="center"> 2审</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>--</entry>
|
||||
|
||||
<entry>Contents</entry>
|
||||
|
||||
<entry>目录</entry>
|
||||
|
||||
<entry>Liu Chang</entry>
|
||||
|
||||
<entry></entry>
|
||||
|
||||
<entry></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>#1</entry>
|
||||
|
||||
<entry>Setting up an annotations projec</entry>
|
||||
|
||||
<entry>创建一个注解项目</entry>
|
||||
|
||||
<entry>melthaw</entry>
|
||||
|
||||
<entry>Zheng Shuai</entry>
|
||||
|
||||
<entry>superq</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>#2</entry>
|
||||
|
||||
<entry>Entity Beans-Introduction</entry>
|
||||
|
||||
<entry>实体Bean-简介</entry>
|
||||
|
||||
<entry>melthaw</entry>
|
||||
|
||||
<entry>Zheng Shuai</entry>
|
||||
|
||||
<entry>superq</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>#3</entry>
|
||||
|
||||
<entry>Entity Beans-Mapping with EJB3 Annotations</entry>
|
||||
|
||||
<entry>实体Bean-用EJB3注解进行映射</entry>
|
||||
|
||||
<entry>melthaw</entry>
|
||||
|
||||
<entry>Zheng Shuai</entry>
|
||||
|
||||
<entry>superq, Liu Chang, Sean Chan</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>#4</entry>
|
||||
|
||||
<entry>Entity Beans-Mapping Queries</entry>
|
||||
|
||||
<entry>实体Bean-映射查询</entry>
|
||||
|
||||
<entry>melthaw</entry>
|
||||
|
||||
<entry>Zheng Shuai</entry>
|
||||
|
||||
<entry>superq, Liu Chang, Sean Chan</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>#5</entry>
|
||||
|
||||
<entry>Entity Beans-Hibernate Annotation Extensions</entry>
|
||||
|
||||
<entry>实体Bean-Hibernate独有的注解扩展</entry>
|
||||
|
||||
<entry>Sean Chan</entry>
|
||||
|
||||
<entry>morning</entry>
|
||||
|
||||
<entry>melthaw</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>#6</entry>
|
||||
|
||||
<entry>Overriding metadata through XML</entry>
|
||||
|
||||
<entry>通过XML覆写元数据</entry>
|
||||
|
||||
<entry>icess</entry>
|
||||
|
||||
<entry>melthaw</entry>
|
||||
|
||||
<entry>Sean Chan</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>#7</entry>
|
||||
|
||||
<entry>Hibernate Validator</entry>
|
||||
|
||||
<entry>Hibernate验证器</entry>
|
||||
|
||||
<entry>DigitalSonic</entry>
|
||||
|
||||
<entry>morning</entry>
|
||||
|
||||
<entry>melthaw</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>#8</entry>
|
||||
|
||||
<entry>Hibernate Lucene Integration</entry>
|
||||
|
||||
<entry>Hibernate与Lucene集成</entry>
|
||||
|
||||
<entry>mochow</entry>
|
||||
|
||||
<entry>morning</entry>
|
||||
|
||||
<entry>melthaw</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>#9</entry>
|
||||
|
||||
<entry>Appendix:Glossary</entry>
|
||||
|
||||
<entry>附录:术语表</entry>
|
||||
|
||||
<entry>mochow</entry>
|
||||
|
||||
<entry>Liu Chang</entry>
|
||||
|
||||
<entry>曹晓钢</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>关于我们</para>
|
||||
|
||||
<variablelist spacing="compact">
|
||||
<varlistentry>
|
||||
<term>满江红.开源, http://www.redsaga.com</term>
|
||||
|
||||
<listitem>
|
||||
<para>从成立之初就致力于Java开放源代码在中国的传播与发展,与国内多个Java团体及出版社有深入交流。坚持少说多做的原则,目前有两个团队,“OpenDoc团队”与“翻译团队”,本翻译文档即为翻译团队作品。OpenDoc团队已经推出包括Hibernate、iBatis、Spring、WebWork的多份开放文档,并于2005年5月在Hibernate开放文档基础上扩充成书,出版了原创书籍:《深入浅出Hibernate》,本书400余页,适合各个层次的Hibernate用户。(http://www.redsaga.com/hibernate_book.html)敬请支持。</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>致谢</term>
|
||||
|
||||
<listitem>
|
||||
<para>在我们翻译Hibernate
|
||||
Annotation参考文档的同时,还有一位热心的朋友也在进行着同样的工作,这位朋友就是icess(冰雨),由icess翻译的中文版的地址:
|
||||
http://icess.my.china.com/hibernate/a/ref/index.htm</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="preface-translate-licence-zh-cn">
|
||||
<title>版权声明</title>
|
||||
|
||||
<para>Hibernate英文文档属于Hibernate发行包的一部分,遵循LGPL协议。本翻译版本同样遵循LGPL协议。参与翻译的译者一致同意放弃除署名权外对本翻译版本的其它权利要求。</para>
|
||||
|
||||
<para>您可以自由链接、下载、传播此文档,或者放置在您的网站上,甚至作为产品的一部分发行。但前提是必须保证全文完整转载,包括完整的版权信息和作译者声明,并不能违反LGPL协议。这里“完整”的含义是,不能进行任何删除/增添/注解。若有删除/增添/注解,必须逐段明确声明那些部分并非本文档的一部分。</para>
|
||||
</sect1>
|
||||
</preface>
|
||||
|
||||
<preface>
|
||||
<title>前言</title>
|
||||
|
||||
<para>正如其他的ORM工具,Hibernate同样需要元数据来控制在不同数据表达形式之间的转化. 在Hibernate
|
||||
2.x里,多数情况下表示映射关系的元数据保存在XML文本文件中.
|
||||
还有一种方式就是Xdoclet,它可以在编译时利用Javadoc中的源码注释信息来进行预处理.
|
||||
现在新的JDK标准(JDK1.5以上)也支持类似的注解功能,但相比之下很多工具对此提供了更强大更好用的支持. 以IntelliJ
|
||||
IDEA和Eclipse为例,这些IDE工具为JDK 5.0注解功能提供了自动完成和语法高亮功能. 注解被直接编译到字节码里,并
|
||||
在运行时(对于Hibernate来讲就是启动的时候)通过反射读取这些注解, 因此外部XML文件就不再需要了.</para>
|
||||
|
||||
<para>EJB3规范最终认可了透明化ORM的成功范例以及市场对于这种技术的兴趣.
|
||||
EJB3规范标准化了ORM的基础API而且在任何ORM持久化机制中使用元数据. <emphasis>Hibernate
|
||||
EntityManager</emphasis>实现了EJB3持久化规范中定义的编程接口和生命周期规则. 在<emphasis>Hibernate
|
||||
Core</emphasis>的基础上再结合 <emphasis>Hibernate
|
||||
Annotations</emphasis>就实现了一套完整(并且独立)的EJB3持久化解决方案.
|
||||
你可以结合三者来使用,也可以抛开EJB3编程接口和生命周期规则而独立使用注解, 甚至只单独使用<emphasis>Hibernate
|
||||
Core</emphasis>. 这些都取决于项目的商业和技术上的实际需求. Hibernate允许你直接使用native APIs,如果有需要,
|
||||
甚至可以直接操作JDBC和SQL.</para>
|
||||
|
||||
<para>注意本文档基于Hibernate Annotations的预览版(遵从EJB 3.0/JSR-220最终草案).
|
||||
这个版本和新规范中定义的最终概念已经非常接近了.我们的目标是提供一套完整的ORM注解,
|
||||
包括EJB3的标准注解以及Hibernate3的扩展(后者是EJB3规范中没有涉及到的). 最终通过注解你可以完成任何可能的映射.详情参考<xref
|
||||
linkend="compliance" />.</para>
|
||||
|
||||
<para>EJB3最终草案修改了部分注解,
|
||||
http://www.hibernate.org/371.html提供了从上一个版本到最新版本的迁移指南.</para>
|
||||
</preface>
|
||||
|
||||
&setup;
|
||||
|
||||
&entity;
|
||||
|
||||
&xml-overriding;
|
||||
|
||||
&validator;
|
||||
|
||||
&lucene;
|
||||
|
||||
<appendix>
|
||||
<title id="glossary">术语表</title>
|
||||
|
||||
<para>Redsaga的wiki上维护了本文翻译过程中所参照的中英文对照的术语表,地址:http://wiki.redsaga.com/confluence/display/HART/glossary.</para>
|
||||
</appendix>
|
||||
</book>
|
File diff suppressed because it is too large
Load Diff
|
@ -1,86 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter id="lucene">
|
||||
<title id="lucene">Hibernate与Lucene集成</title>
|
||||
|
||||
<para>Lucene是一个高性能的java搜索引擎库,可以从 Apache软件基金组织获取。
|
||||
Hibernate Annotations包括一个注解包,它允许把任何域模型对象标记为可索引的,
|
||||
并且对任何经由Hibernate进行持续化的实例,Hibernate 都会为之维护一个对应的Lucene索引。</para>
|
||||
|
||||
<sect1 id="lucene-intro">
|
||||
<title>使用Lucene为实体建立索引</title>
|
||||
|
||||
<sect2>
|
||||
<title>注解领域模型</title>
|
||||
|
||||
<para>首先,必须将一个持久类声明为
|
||||
<literal>@Indexed</literal>:</para>
|
||||
|
||||
<programlisting>@Entity
|
||||
@Indexed(index="indexes/essays")
|
||||
public class Essay {
|
||||
...
|
||||
}</programlisting>
|
||||
|
||||
<para>属性<literal>index</literal>是告诉Hibernate, Lucene索引信息所在的位置(你文件系统的某个目录)。
|
||||
如果你想为所有的Lucene索引定义一个根目录,你可以在配置文件中用属性<literal>hibernate.lucene.index_dir</literal>进行配置。
|
||||
</para>
|
||||
|
||||
<para>Lucene索引包括四种字段:<emphasis>keyword</emphasis> 字段,<emphasis>text</emphasis>
|
||||
字段,<emphasis>unstored</emphasis>字段和<emphasis>unindexed</emphasis>字段。
|
||||
Hibernate注解提供了将实体属性标记为前三种被索引字段的注解。</para>
|
||||
|
||||
<programlisting>@Entity
|
||||
@Indexed(index="indexes/essays")
|
||||
public class Essay {
|
||||
...
|
||||
|
||||
@Id
|
||||
@Keyword(id=true)
|
||||
public Long getId() { return id; }
|
||||
|
||||
@Text(name="Abstract")
|
||||
public String getSummary() { return summary; }
|
||||
|
||||
@Lob
|
||||
@Unstored
|
||||
public String getText() { return text; }
|
||||
|
||||
}</programlisting>
|
||||
|
||||
<para>这些注解定义了一个带有三个字段的索引:
|
||||
<literal>Id</literal>, <literal>Abstract</literal> 和
|
||||
<literal>Text</literal>.</para>
|
||||
|
||||
<para>注意:你必须在你的实体类的标志属性上指定
|
||||
<literal>@Keyword(id=true)</literal> .</para>
|
||||
|
||||
<para>用于对元素建立索引的分析器类是可以通过<literal>hibernate.lucene.analyzer</literal>属性进行配置的。
|
||||
如果没有定义,则把 <classname>org.apache.lucene.analysis.standard.StandardAnalyzer</classname>作为缺省。</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>启用自动索引</title>
|
||||
|
||||
<para>我们激活用于帧听三类Hibernate事件的 <literal>LuceneEventListener</literal>,
|
||||
这些事件会在变更被提交至数据库后产生。</para>
|
||||
|
||||
<programlisting><hibernate-configuration>
|
||||
...
|
||||
<event type="post-commit-update"
|
||||
<listener
|
||||
class="org.hibernate.lucene.event.LuceneEventListener"/>
|
||||
</event>
|
||||
<event type="post-commit-insert"
|
||||
<listener
|
||||
class="org.hibernate.lucene.event.LuceneEventListener"/>
|
||||
</event>
|
||||
<event type="post-commit-delete"
|
||||
<listener
|
||||
class="org.hibernate.lucene.event.LuceneEventListener"/>
|
||||
</event>
|
||||
</hibernate-configuration></programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter>
|
||||
<title id="setup" revision="1">创建一个注解项目</title>
|
||||
|
||||
<section id="setup-requirements">
|
||||
<title>系统需求</title>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>首先从Hibernate官方网站下载并解压Hibernate Annotations的发布包。</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><emphasis>这个版本(预览版)要求使用Hibernate 3.2.0.CR2或更高版本。请不要和老版本的Hibernate 3.x混合起来使用。</emphasis></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>这个版本在Hibernate core 3.2.0.CR2的基础上工作良好。</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>首先确定你已经安装了JDK 5.0。当然就算使用低版本的JDK,
|
||||
Xdoclet也可以提供(基于注解的)元数据所带来的部分功能。
|
||||
不过请注意本文档只描述跟JDK5.0注解有关的内容,关于Xdoclet请参考相关文档。</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section id="setup-configuration">
|
||||
<title>系统配置</title>
|
||||
|
||||
<para>首先就是设置classpath(当然是在IDE中创建了一个新项目之后)。 <itemizedlist>
|
||||
<listitem>
|
||||
<para>将Hibernate3核心文件以及其依赖的第三方库文件(请参考lib/README.txt文件)加入到你的classpath里面。</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>将<filename>hibernate-annotations.jar</filename>
|
||||
和<filename>lib/ejb3-persistence.jar</filename>加入到你的classpath里面。</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>如果要使用 <xref linkend="lucene" />,还需要将lucene的jar文件加入你的classpath。</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para>我们推荐在一个包装器(wrapper)类<classname>HibernateUtil</classname>
|
||||
的静态初始化代码块中启动Hibernate。或许你在Hibernate文档的其他很多地方看到过这个类,
|
||||
但是要在你的项目中使用注解,还需要对这个辅助(helper)类进行扩展。扩展如下:
|
||||
<programlisting>package hello;
|
||||
|
||||
import org.hibernate.*;
|
||||
import org.hibernate.cfg.*;
|
||||
import test.*;
|
||||
import test.animals.Dog;
|
||||
|
||||
public class HibernateUtil {
|
||||
|
||||
private static final SessionFactory sessionFactory;
|
||||
|
||||
static {
|
||||
try {
|
||||
|
||||
sessionFactory = new <emphasis role="bold">AnnotationConfiguration()</emphasis>.buildSessionFactory();
|
||||
} catch (Throwable ex) {
|
||||
// Log exception!
|
||||
throw new ExceptionInInitializerError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static Session getSession()
|
||||
throws HibernateException {
|
||||
return sessionFactory.openSession();
|
||||
}
|
||||
}
|
||||
</programlisting></para>
|
||||
|
||||
<para>这里比较有意思的是使用到了<classname>AnnotationConfiguration</classname>类。
|
||||
在XML配置文件(通常是<filename>hibernate.cfg.xml</filename>)中则定义了包和经过注解的类。下面的xml和前面的声明等价:
|
||||
</para>
|
||||
|
||||
<programlisting><!DOCTYPE hibernate-configuration PUBLIC
|
||||
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
|
||||
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
|
||||
|
||||
<hibernate-configuration>
|
||||
<session-factory>
|
||||
<emphasis role="bold"><mapping package="test.animals"/>
|
||||
<mapping class="test.Flight"/>
|
||||
<mapping class="test.Sky"/>
|
||||
<mapping class="test.Person"/>
|
||||
<mapping class="test.animals.Dog"/></emphasis>
|
||||
<emphasis role="bold"> <mapping resource="test/animals/orm.xml"/></emphasis>
|
||||
</session-factory>
|
||||
</hibernate-configuration>
|
||||
</programlisting>
|
||||
|
||||
<para>注意现在你可以混合使用hbm.xml和注解。资源元素(resource element)可以是hbm文件也可以是EJB3 XML发布描述符,此差别对于配置过程是透明的。</para>
|
||||
|
||||
<para>除了上面的方式,你还可以通过编程的方式定义包括注解的类和包</para>
|
||||
|
||||
<programlisting> sessionFactory = new <emphasis role="bold">AnnotationConfiguration()
|
||||
.addPackage("test.animals") //the fully qualified package name
|
||||
.addAnnotatedClass(Flight.class)
|
||||
.addAnnotatedClass(Sky.class)
|
||||
.addAnnotatedClass(Person.class)
|
||||
.addAnnotatedClass(Dog.class)</emphasis>
|
||||
.buildSessionFactory();</programlisting>
|
||||
|
||||
<para>你也可以使用Hibernate Entity Manager来完成以上功能。Hibernate Entity Manager有自己的一套配置机制,详情请参考相关文档。</para>
|
||||
|
||||
<para>除了启动方式和配置文件有所改变之外,结合注解来使用Hibernate API和以前没有什么区别,
|
||||
在其他方面你还是可以继续保持以前的习惯和喜好(<filename>hibernate.properties</filename>,
|
||||
<filename>hibernate.cfg.xml</filename>, programmatic APIs等等)。
|
||||
甚至对于同一个<classname>SessionFactory</classname>,你都可以混合带注解的持久类以及传统的bm.cfg.xml声明方式。
|
||||
然而你不能多次声明同一个类(要么通过注解要么通过hbm.xml配置文件),
|
||||
而且在一个映射实体的类继承层次中,这两个配置策略不能同时使用.
|
||||
</para>
|
||||
|
||||
<para>为了简化从hbm文件到注解的迁移过程,
|
||||
配置机制将自动检测在注解和hbm文件中重复的映射。
|
||||
默认情况下hbm文件中的声明比类中的注解元数据具有更高的优先级。
|
||||
这种优先级的设定是以类为单位的。
|
||||
你也可以通过<literal>hibernate.mapping.precedence</literal>修改这种优先级。
|
||||
默认的值是<literal>hbm, class</literal>,
|
||||
如果改为<literal>class,hbm</literal>,当发生冲突的时候,类中的注解将比hbm文件具有更高的优先级。
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
|
@ -1,464 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter id="validator">
|
||||
<title>Hibernate验证器</title>
|
||||
|
||||
<para>注解是一种为领域模型(domain model)指定不变约束的简洁而幽雅的方法。例如,你能
|
||||
表示一个属性永远不为null,一个帐户余额一定是正值,等等。这些域模型约束通过为bean中的属性添加
|
||||
注解来加以声明。随后一个验证器(validator)会读取并检查这些约束。验证机制可以执行于应用程序中的
|
||||
不同层(表现层、数据访问层),而不必复述任何(前述)这些规则。Hibernate验证器正为这一目的而设计的。</para>
|
||||
|
||||
<para>Hibernate验证器工作在两个层次上。第一层,它能检查内存中一个类的实例是否违反约束。
|
||||
第二层,它能将约束应用于Hibernate元模型上,并将它们融入生成的数据库schema中。</para>
|
||||
|
||||
<para>每个约束注解(constraint annotation)和一个验证器实现关联,该验证器负责检查位于实体实例上的约束。
|
||||
一个验证器也能(可选地)将约束应用于Hibernate元模型上,让Hibernate生成表示这一约束的DDL。使用合适的事件监听器,你能
|
||||
让Hibernate在插入和更新时执行检查操作。Hibernate验证器并不局限于同Hibernate一起使用。
|
||||
你能在你应用程序的任何地方方便地使用它。</para>
|
||||
|
||||
<para>在运行时检查实例时,Hibernate验证器返回违反约束的信息,
|
||||
这些信息以一个<classname>InvalidValue</classname>数组的形式返回。
|
||||
除了众多其他信息外,<classname>InvalidValue</classname>包含了一个错误描述消
|
||||
息,该信息可以内嵌与注解相捆绑的参数值(例如长度限制),以及能被提取至ResourceBundle的消息字串。</para>
|
||||
|
||||
<sect1 id="validator-constraints">
|
||||
<title>约束</title>
|
||||
|
||||
<sect2>
|
||||
<title>什么是约束?</title>
|
||||
|
||||
<para>约束通过注解表示。一个约束通常有一些用来参数化约束限制的属性。约束应用于带注解的元素。</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>内建约束</title>
|
||||
|
||||
<para>Hibernate验证器有些内建约束,这些约束覆盖了大多数的基本数据检查。随后我们会看到,
|
||||
你不必受制于这些内置约束,因为一分钟内就可以写出你自己的约束。</para>
|
||||
|
||||
<table>
|
||||
<title>内建约束</title>
|
||||
|
||||
<tgroup cols="4">
|
||||
<colspec align="center" />
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry>注解</entry>
|
||||
|
||||
<entry>应用目标</entry>
|
||||
|
||||
<entry>运行时检查</entry>
|
||||
|
||||
<entry>Hibernate元数据影响</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
<row>
|
||||
<entry>@Length(min=, max=)</entry>
|
||||
|
||||
<entry>属性(String)</entry>
|
||||
|
||||
<entry>检查字符串长度是否符合范围</entry>
|
||||
|
||||
<entry>列长度会被设到最大值</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Max(value=)</entry>
|
||||
|
||||
<entry>属性 (以numeric或者string类型来表示一个数字)</entry>
|
||||
|
||||
<entry>检查值是否小于或等于最大值</entry>
|
||||
|
||||
<entry>对列增加一个检查约束</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Min(value=)</entry>
|
||||
|
||||
<entry>属性(以numeric或者string类型来表示一个数字)</entry>
|
||||
|
||||
<entry>检查值是否大于或等于最小值</entry>
|
||||
|
||||
<entry>对列增加一个检查约束</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@NotNull</entry>
|
||||
|
||||
<entry>属性</entry>
|
||||
|
||||
<entry>检查值是否非空(not null)</entry>
|
||||
|
||||
<entry>列不为空</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Past</entry>
|
||||
|
||||
<entry>属性(date或calendar)</entry>
|
||||
|
||||
<entry>检查日期是否是过去时</entry>
|
||||
|
||||
<entry>对列增加一个检查约束</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Future</entry>
|
||||
|
||||
<entry>属性 (date 或 calendar)</entry>
|
||||
|
||||
<entry>检查日期是否是将来时</entry>
|
||||
|
||||
<entry>无</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Pattern(regex="regexp", flag=)</entry>
|
||||
|
||||
<entry>属性 (string)</entry>
|
||||
|
||||
<entry>检查属性是否与给定匹配标志的正则表达式相匹配(见<classname>
|
||||
java.util.regex.Pattern </classname>)</entry>
|
||||
|
||||
<entry>无</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Range(min=, max=)</entry>
|
||||
|
||||
<entry>属性(以numeric或者string类型来表示一个数字)</entry>
|
||||
|
||||
<entry>检查值是否在最小和最大值之间(包括临界值)</entry>
|
||||
|
||||
<entry>对列增加一个检查约束</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Size(min=, max=)</entry>
|
||||
|
||||
<entry>属性 (array, collection, map)</entry>
|
||||
|
||||
<entry>检查元素大小是否在最小和最大值之间(包括临界值)</entry>
|
||||
|
||||
<entry>无</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@AssertFalse</entry>
|
||||
|
||||
<entry>属性</entry>
|
||||
|
||||
<entry>检查方法的演算结果是否为false(对以代码方式而不是注解表示的约束很有用)</entry>
|
||||
|
||||
<entry>无</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@AssertTrue</entry>
|
||||
|
||||
<entry>属性</entry>
|
||||
|
||||
<entry>检查方法的演算结果是否为true(对以代码方式而不是注解表示的约束很有用)</entry>
|
||||
|
||||
<entry>无</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Valid</entry>
|
||||
|
||||
<entry>属性 (object)</entry>
|
||||
|
||||
<entry>对关联对象递归的进行验证。如果对象是集合或数组,就递归地验证其元素。如果对象是Map,则递归验证其值元素。</entry>
|
||||
|
||||
<entry>无</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>@Email</entry>
|
||||
|
||||
<entry>属性(String)</entry>
|
||||
|
||||
<entry>检查字符串是否符合有效的email地址规范。</entry>
|
||||
|
||||
<entry>无</entry>
|
||||
</row>
|
||||
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="validator-constraints-error" xreflabel="Error messages">
|
||||
<title id="validator-constraints-error">错误信息</title>
|
||||
|
||||
<para>Hibernate验证器提供了一组默认的错误提示信息,它们被翻译成多种语言(如果你的语言不在其中,请给
|
||||
我们寄一个补丁)。你可以在<filename>org.hibernate.validator.resources.DefaultValidatorMessages.properties</filename>
|
||||
之外创建<filename>ValidatorMessages.properties</filename>或<filename>ValidatorMessages_loc.properties</filename>
|
||||
文件并改变相应的键值,籍此覆盖那些(默认)信息。你甚至可以在写自己的验证器
|
||||
注解时添加你自己的附加消息集。</para>
|
||||
|
||||
<para>或者你可以以编程方式检查bean的验证规则并提供相应的<classname>ResourceBundle</classname>。</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>编写你自己的约束</title>
|
||||
|
||||
<para>扩展内建约束集是极其方便的。任何约束都包括两部分:约束<emphasis>描述符</emphasis>(注解)
|
||||
和约束<emphasis>验证器</emphasis>(实现类)。下面是一个简单的用户定义描述符:</para>
|
||||
|
||||
<programlisting>@ValidatorClass(CapitalizedValidator.class)
|
||||
@Target(METHOD)
|
||||
@Retention(RUNTIME)
|
||||
@Documented
|
||||
public @interface Capitalized {
|
||||
CapitalizeType type() default Capitalize.FIRST;
|
||||
String message() default "has incorrect capitalization";
|
||||
}</programlisting>
|
||||
|
||||
<para><literal>type</literal>参数描述属性应该如何被大写。这是一个完全依赖于注解业务(逻辑)的用户
|
||||
参数。</para>
|
||||
|
||||
<para><literal>message</literal>是用于描述约束违规的默认字符串,它是强制要求的。你可以采取硬编码的方式,
|
||||
或者通过Java ResourceBundle机制将message的部分/全部内容提取至外部文件。一旦发现message中{parameter}字符串,
|
||||
就会在{parameter}这个位置注入相应的参数值(在我们的例子里Capitalization is not {type}会生成 Capitalization is not FIRST),
|
||||
可以将message对应的整个字符串提取至外部文件ValidatorMessages.properties,这也是一种良好实践。
|
||||
见<xref linkend="validator-constraints-error" />。</para>
|
||||
|
||||
<programlisting>@ValidatorClass(CapitalizedValidator.class)
|
||||
@Target(METHOD)
|
||||
@Retention(RUNTIME)
|
||||
@Documented
|
||||
public @interface Capitalized {
|
||||
CapitalizeType type() default Capitalize.FIRST;
|
||||
String message() default "{validator.capitalized}";
|
||||
}
|
||||
|
||||
...
|
||||
#in ValidatorMessages.properties
|
||||
validator.capitalized=<literal>Capitalization is not {type}</literal></programlisting>
|
||||
|
||||
<para>如你所见{}符号是递归的。</para>
|
||||
|
||||
<para>为了将一个描述符连接到它的验证器实现,我们使用<literal>@ValidatorClass</literal>
|
||||
元注解。验证器类参数必须指定一个实现了<literal>Validator<ConstraintAnnotation></literal>
|
||||
的类。</para>
|
||||
|
||||
<para>我们现在要实现验证器(也就是实现规则检查)。一个验证器实现能检查一个属性的值
|
||||
(实现<literal>PropertyConstraint</literal>),并且/或者可以修改hibernate映射元数据
|
||||
(实现<literal>PersistentClassConstraint</literal>),籍此表示数据库级的约束。</para>
|
||||
|
||||
<programlisting>public class CapitalizedValidator
|
||||
implements Validator<Capitalized>, PropertyConstraint {
|
||||
private CapitalizeType type;
|
||||
|
||||
//part of the Validator<Annotation> contract,
|
||||
//allows to get and use the annotation values
|
||||
public void initialize(Capitalized parameters) {
|
||||
type = parameters.type();
|
||||
}
|
||||
|
||||
//part of the property constraint contract
|
||||
public boolean isValid(Object value) {
|
||||
if (value==null) return true;
|
||||
if ( !(value instanceof String) ) return false;
|
||||
String string = (String) value;
|
||||
if (type == CapitalizeType.ALL) {
|
||||
return string.equals( string.toUpperCase() );
|
||||
}
|
||||
else {
|
||||
String first = string.substring(0,1);
|
||||
return first.equals( first.toUpperCase();
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>如果违反约束,<literal>isValid()</literal>方法将返回false。更多例子请参考内建验证器实现。</para>
|
||||
|
||||
<para>至此我们只看到属性级的验证,你还可以写一个Bean级别的验证注解。Bean自身会被传递给验证器,
|
||||
而不是bean的属性实例。只要对bean自身进行注解即可激活验证检查。在单元测试套件中还可以找到一个小例子。</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>注解你的领域模型</title>
|
||||
|
||||
<para>既然你现在已经熟悉注解了,那么对语法也应该很清楚了。</para>
|
||||
|
||||
<programlisting>public class Address {
|
||||
private String line1;
|
||||
private String line2;
|
||||
private String zip;
|
||||
private String state;
|
||||
private String country;
|
||||
private long id;
|
||||
|
||||
// a not null string of 20 characters maximum
|
||||
@Length(max=20)
|
||||
@NotNull
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
// a non null string
|
||||
@NotNull
|
||||
public String getLine1() {
|
||||
return line1;
|
||||
}
|
||||
|
||||
//no constraint
|
||||
public String getLine2() {
|
||||
return line2;
|
||||
}
|
||||
|
||||
// a not null string of 3 characters maximum
|
||||
@Length(max=3) @NotNull
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
// a not null numeric string of 5 characters maximum
|
||||
// if the string is longer, the message will
|
||||
//be searched in the resource bundle at key 'long'
|
||||
@Length(max=5, message="{long}")
|
||||
@Pattern(regex="[0-9]+")
|
||||
@NotNull
|
||||
public String getZip() {
|
||||
return zip;
|
||||
}
|
||||
|
||||
// should always be true
|
||||
@AssertTrue
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// a numeric between 1 and 2000
|
||||
@Id @Min(1)
|
||||
@Range(max=2000)
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>上面的例子只展示了公共属性验证,你还可以对任何可见度的字段(field)进行注解。</para>
|
||||
|
||||
<programlisting>@MyBeanConstraint(max=45)
|
||||
public class Dog {
|
||||
@AssertTrue private boolean isMale;
|
||||
@NotNull protected String getName() { ... };
|
||||
...
|
||||
}</programlisting>
|
||||
|
||||
<para>你可以对接口进行注解。Hibernate验证器会检查给定bean所扩展或实现的所有父类和接口,
|
||||
籍以读取相应的验证器注解(信息)。</para>
|
||||
|
||||
<programlisting>public interface Named {
|
||||
@NotNull String getName();
|
||||
...
|
||||
}
|
||||
|
||||
public class Dog implements Named {
|
||||
|
||||
@AssertTrue private boolean isMale;
|
||||
|
||||
public String getName() { ... };
|
||||
|
||||
}</programlisting>
|
||||
|
||||
<para>在验证Dog bean时会检查name属性的有效性(不为null)。</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>使用验证器框架</title>
|
||||
|
||||
<para>Hibernate验证器旨在实现多层数据验证,我们在一处表示约束(带注解的域模型),然后将其运用于
|
||||
应用程序的不同层。</para>
|
||||
|
||||
<sect2>
|
||||
<title>数据库schema层次验证</title>
|
||||
|
||||
<para>无须额外手续,Hibernate Annotations会自动将你为实体定义的约束翻译为映射元数据。例如,如果你的实体
|
||||
的一个属性注解为<literal>@NotNull</literal>,在Hibernate生成的DDL schema中这列会被定义为
|
||||
<literal>not null</literal>。</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Hibernate基于事件的验证</title>
|
||||
|
||||
<para>Hibernate验证器有两个内建Hibernate事件监听器。当一个<literal>PreInsertEvent</literal>
|
||||
或<literal>PreUpdateEvent</literal>发生时,监听器会验证该实体实例的所有约束,如有违反会抛出一个异常。
|
||||
基本上,在Hibernate执行任何插入和更新前对象会被检查。这是激活验证过程的最便捷最简单的方法。当遇到约束
|
||||
违规时,事件会引发一个运行时<classname>InvalidStateException</classname>,该异常包含一个描述每个错误的
|
||||
<literal>InvalidValue</literal>数组。</para>
|
||||
|
||||
<programlisting><hibernate-configuration>
|
||||
...
|
||||
<event type="pre-update">
|
||||
<listener
|
||||
class="org.hibernate.validator.event.ValidatePreUpdateEventListener"/>
|
||||
</event>
|
||||
<event type="pre-insert">
|
||||
<listener
|
||||
class="org.hibernate.validator.event.ValidatePreInsertEventListener"/>
|
||||
</event>
|
||||
</hibernate-configuration></programlisting>
|
||||
|
||||
<para><note>
|
||||
<para>在使用Hibernate Entity Manager时,Validation框架会被自动激活。如果bean不带验证注解,
|
||||
就不会有性能损失。</para>
|
||||
</note></para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>程序级验证</title>
|
||||
|
||||
<para>Hibernate验证器能应用于你应用程序代码中的任何地方。</para>
|
||||
|
||||
<programlisting>ClassValidator personValidator = new ClassValidator( Person.class );
|
||||
ClassValidator addressValidator = new ClassValidator( Address.class, ResourceBundle.getBundle("messages", Locale.ENGLISH) );
|
||||
|
||||
InvalidValue[] validationMessages = addressValidator.getInvalidValues(address);</programlisting>
|
||||
|
||||
<para>头两行为执行类检查而准备Hibernate验证器。第一行依赖于嵌入在Hibernate验证器内的错误
|
||||
消息(见<xref linkend="validator-constraints-error" />),第二行为这些消息准备资源包。这些代码只执行一次,
|
||||
并将验证器进行缓存处理,这种方式是一种良好实践。</para>
|
||||
|
||||
<para>第三行真正验证了<literal>Address</literal>实例并返回一个<literal>InvalidValue</literal>数组。
|
||||
你的应用程序逻辑随后可以对错误做出响应。</para>
|
||||
|
||||
<para>除了针对整个bean你还可以对某个特定属性进行检查。这对于一个属性一个属性的用户交互情形或许是有用的。</para>
|
||||
|
||||
<programlisting>ClassValidator addressValidator = new ClassValidator( Address.class, ResourceBundle.getBundle("messages", Locale.ENGLISH) );
|
||||
|
||||
//only get city property invalid values
|
||||
InvalidValue[] validationMessages = addressValidator.getInvalidValues(address, "city");
|
||||
|
||||
//only get potential city property invalid values
|
||||
InvalidValue[] validationMessages = addressValidator.getPotentialInvalidValues("city", "Paris")</programlisting>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>验证信息</title>
|
||||
|
||||
<para>作为一个验证信息的载体,hibernate提供了一个<classname>InvalidValue</classname>数组。
|
||||
每个<literal>InvalidValue</literal>有一组,这些方法分别描述相应的个体问题。</para>
|
||||
|
||||
<para><methodname>getBeanClass()</methodname>获取失败的bean类型。</para>
|
||||
|
||||
<para><methodname>getBean()</methodname>获取验证失败的实例(如果有的话,当使用
|
||||
<methodname>getPotentianInvalidValues()</methodname>时则不会取到) </para>
|
||||
|
||||
<para><methodname>getValue()</methodname>获取验证失败的值</para>
|
||||
|
||||
<para><methodname>getMessage()</methodname>获取合适的国际化错误消息</para>
|
||||
|
||||
<para><methodname>getRootBean()</methodname>获取产生问题的根bean实例(在与<literal>@Valid</literal>连用
|
||||
时很有用),如用getPotentianInvalidValues()则返回null。</para>
|
||||
|
||||
<para><literal>getPropertyPath()</literal>获取“问题”属性从根bean开始的带点的路径</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
|
@ -1,345 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter id="xml-overriding">
|
||||
<title>通过XML覆写元数据</title>
|
||||
|
||||
<para>在EJB3中元数据的主要目标是使用注释,但是EJB3规范也提供通过XML部署文件来覆写或者替换元数据注释.
|
||||
在当前的发布版本仅仅支持EJB3注释的覆写,如果你想使用Hibernate特有的一些实体注释,
|
||||
你有两种选择:一,只使用注释;二,使用原来的hbm 映射文件.你当然还是可以同时使用注释实体和hbm XML映射文件的实体.</para>
|
||||
|
||||
<para>在测试套件中有一些附加的XML文件的样例.</para>
|
||||
|
||||
<section>
|
||||
<title>原则</title>
|
||||
|
||||
<para>XML部署文件结构被设计为直接映射注释结构,所以如果你知道注释的结构,那么使用XML语法是很简单的.</para>
|
||||
|
||||
|
||||
<para>你可以定义一个或者多个XML文件来描述你的元数据,这些文件会被覆写引擎合并(merged).</para>
|
||||
|
||||
<section>
|
||||
<title>全局级别的元数据</title>
|
||||
|
||||
<para>你可以使用XML文件来定义全局元数据,对每一个部署文件你不能定义多于一个的元数据.</para>
|
||||
|
||||
<programlisting><?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<entity-mappings
|
||||
xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit-metadata>
|
||||
<xml-mapping-metadata-complete/>
|
||||
<persistence-unit-defaults>
|
||||
<schema>myschema</schema>
|
||||
<catalog>mycatalog</catalog>
|
||||
<cascade-persist/>
|
||||
</persistence-unit-defaults>
|
||||
</persistence-unit-metadata></programlisting>
|
||||
|
||||
<para><literal>xml-mapping-metadata-complete</literal> 意味着所有的实体,mapped-superclasses和嵌套的元数据应该从XML文件中启用(忽略注释).</para>
|
||||
|
||||
|
||||
<para><literal>schema / catalog</literal> 将覆写所有在元数据中默认定义的schema 和 catalog(包括XML和注释).</para>
|
||||
|
||||
<para><literal>cascade-persist</literal> 意味着所有注释作为一个 cascade type 都是PERSIST的. 我们推荐你不要使用该特性.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>实体级别的元数据</title>
|
||||
|
||||
<para>你也可以在一个给定的实体上定义或者覆写元数据</para>
|
||||
|
||||
<programlistingco>
|
||||
<areaspec>
|
||||
<area coords="3" id="aa1" />
|
||||
|
||||
<area coords="9" id="aa2" />
|
||||
|
||||
<area coords="10" id="aa3" />
|
||||
|
||||
<area coords="11" id="aa4" />
|
||||
|
||||
<area coords="17" id="aa5" />
|
||||
|
||||
<area coords="23" id="aa6" />
|
||||
|
||||
<area coords="24" id="aa7" />
|
||||
|
||||
<area coords="25" id="aa8" />
|
||||
|
||||
<area coords="26" id="aa9" />
|
||||
|
||||
<area coords="31" id="aa10" />
|
||||
</areaspec>
|
||||
|
||||
<programlisting><?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<entity-mappings
|
||||
xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<package>org.hibernate.test.annotations.reflection</package>
|
||||
<entity class="Administration" access="PROPERTY" metadata-complete="true">
|
||||
<table name="tbl_admin">
|
||||
<unique-constraint>
|
||||
<column-name>firstname</column-name>
|
||||
<column-name>lastname</column-name>
|
||||
</unique-constraint>
|
||||
</table>
|
||||
<secondary-table name="admin2">
|
||||
<primary-key-join-column name="admin_id" referenced-column-name="id"/>
|
||||
<unique-constraint>
|
||||
<column-name>address</column-name>
|
||||
</unique-constraint>
|
||||
</secondary-table>
|
||||
<id-class class="SocialSecurityNumber"/>
|
||||
<inheritance strategy="JOINED"/>
|
||||
<sequence-generator name="seqhilo" sequence-name="seqhilo"/>
|
||||
<table-generator name="table" table="tablehilo"/>
|
||||
...
|
||||
</entity>
|
||||
|
||||
<entity class="PostalAdministration">
|
||||
<primary-key-join-column name="id"/>
|
||||
...
|
||||
</entity>
|
||||
</entity-mappings></programlisting>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs="aa1">
|
||||
<para><literal>entity-mappings</literal>:entity-mappings 是所有XML文件的根元素.你必须定义XML Schema, 该文件包含在hibernate-annotations.jar中,使用Hibernate Annotations 不需要访问网络.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa2">
|
||||
<para><literal>package</literal> (可选的): 作为默认的package用于在一个给定的部署描述文件中所有没有限定的类.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa3">
|
||||
<para><literal>entity</literal>: 描述一个实体. </para>
|
||||
|
||||
<para><literal>metadata-complete</literal> 定义对于该元素是否全部使用元数据(换句话来说就是,如果注释出现在类级别应该考虑或者忽略).</para>
|
||||
|
||||
<para>一个实体不得不有一个 class 属性来引用 元数据所应用的类. </para>
|
||||
|
||||
<para>通过<literal>name</literal>属性你可以覆写实体的名字,
|
||||
如果没有定义并且<literal>@Entity.name</literal>出现了的话,那么就使用该注释(假如metadata complete 没有被设置).</para>
|
||||
|
||||
<para>
|
||||
对于metadata complete (参考下面)元素, 你可以定义一个 <literal>access</literal>(<literal>FIELD</literal> 或者 <literal>PROPERTY</literal>(默认值)),
|
||||
对于非metadata complete 元素,使用注释的access type.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa4">
|
||||
<para><literal>table</literal>: 你可以声明table 属性(name, schema, catalog), 如果没有定义, 将使用Java注释.</para>
|
||||
|
||||
<para>就象例子中所示的那样你可以定义一个或者多个unique constraints</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa5">
|
||||
<para><literal>secondary-table</literal>: 定义一个secondary-table,除了你可以通过<literal>primary-key-join-column </literal>元素定义 primary key / foreign key 列以外是和一般的table一样的. 在非metadata complete下, annotation secondary tables 仅仅在没有<literal>secondary-table </literal>定义的情况下使用, 否则 注释将被忽略.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa6">
|
||||
<para><literal>id-class</literal>: 和<literal>@IdClass</literal>一样定义一个id class.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa7">
|
||||
<para><literal>inheritance</literal>:
|
||||
定义继承策略(<literal>JOINED</literal>,
|
||||
<literal>TABLE_PER_CLASS</literal>,
|
||||
<literal>SINGLE_TABLE</literal>), 仅仅在根实体级别可以使用.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa8">
|
||||
<para><literal>sequence-generator</literal>: 定义一个序列产生器.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa9">
|
||||
<para><literal>table-generator</literal>: 定义一个table generator</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aa10">
|
||||
<para><literal><literal>primary-key-join-column</literal></literal>:
|
||||
当 JOINED 继承策略使用时,为sub entities定义一个 primary key join column.</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
|
||||
|
||||
</programlistingco>
|
||||
|
||||
<programlistingco>
|
||||
<areaspec>
|
||||
<area coords="11" id="ab1" />
|
||||
|
||||
<area coords="18" id="ab2" />
|
||||
|
||||
<area coords="22" id="ab3" />
|
||||
|
||||
<area coords="28" id="ab4" />
|
||||
|
||||
<area coords="34" id="ab5" />
|
||||
</areaspec>
|
||||
|
||||
<programlisting><?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<entity-mappings
|
||||
xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<package>org.hibernate.test.annotations.reflection</package>
|
||||
<entity class="Music" access="PROPERTY" metadata-complete="true">
|
||||
<discriminator-value>Generic</discriminator-value>
|
||||
<discriminator-column length="34"/>
|
||||
...
|
||||
</entity>
|
||||
|
||||
<entity class="PostalAdministration">
|
||||
<primary-key-join-column name="id"/>
|
||||
<named-query name="adminById">
|
||||
<query>select m from Administration m where m.id = :id</query>
|
||||
<hint name="org.hibernate.timeout" value="200"/>
|
||||
</named-query>
|
||||
<named-native-query name="allAdmin" result-set-mapping="adminrs">
|
||||
<query>select *, count(taxpayer_id) as taxPayerNumber
|
||||
from Administration, TaxPayer
|
||||
where taxpayer_admin_id = admin_id group by ...</query>
|
||||
<hint name="org.hibernate.timeout" value="200"/>
|
||||
</named-native-query>
|
||||
<sql-result-set-mapping name="adminrs">
|
||||
<entity-result entity-class="Administration">
|
||||
<field-result name="name" column="fld_name"/>
|
||||
</entity-result>
|
||||
<column-result name="taxPayerNumber"/>
|
||||
</sql-result-set-mapping>
|
||||
<attribute-override name="ground">
|
||||
<column name="fld_ground" unique="true" scale="2"/>
|
||||
</attribute-override>
|
||||
<association-override name="referer">
|
||||
<join-column name="referer_id" referenced-column-name="id"/>
|
||||
</association-override>
|
||||
...
|
||||
</entity>
|
||||
</entity-mappings></programlisting>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs="ab1">
|
||||
<para><literal>discriminator-value /
|
||||
discriminator-column</literal>: 当SINGLE_TABLE继承策略使用时,定义鉴别器值 和 保存该值的列.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ab2">
|
||||
<para><literal>named-query</literal>: 定义命名查询和一些相关的可能的线索. 该定义附加在注释的定义中,如果两个都定义了相同的名字,那么XML将优先考虑.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ab3">
|
||||
<para><literal>named-native-query</literal>: 定义一个命名本地查询 和他的 sql result set 映射. 作为另外一种选择,你可以定义<literal>result-class</literal>. 这些定义附加在注释的定义中.如果两个定义了同样的名字,XML文件优先考虑.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ab4">
|
||||
<para><literal>sql-result-set-mapping</literal>: 描述了 result set mapping 的结构. 你可以定义 实体和列映射. 这些定义附加在注释的定义中,如果定义了同样的名字,XML文件优先考虑.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="ab5">
|
||||
<para><literal>attribute-override /
|
||||
association-override</literal>: 定义一列或者join column overriding. 该overriding 附加在注释的定义中.</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</programlistingco>
|
||||
|
||||
<para>一些应用于 <literal><embeddable></literal> 和
|
||||
<literal><mapped-superclass></literal>.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>属性级别的元数据</title>
|
||||
|
||||
<para>
|
||||
你当然可以定义XML来覆写属性. 如果metadata complete 给定义了,那么附加的属性(如: 在Java 级别的)将被忽略.
|
||||
另外,一旦你开始覆写一个属性,在该属性上的所有注释都会被忽略.所有属性级别的元数据应用于<literal>entity/attributes</literal>,
|
||||
<literal>mapped-superclass/attributes</literal> 或
|
||||
<literal>embeddable/attributes</literal>.</para>
|
||||
|
||||
<programlisting> <attributes>
|
||||
<id name="id">
|
||||
<column name="fld_id"/>
|
||||
<generated-value generator="generator" strategy="SEQUENCE"/>
|
||||
<temporal>DATE</temporal>
|
||||
<sequence-generator name="generator" sequence-name="seq"/>
|
||||
</id>
|
||||
<version name="version"/>
|
||||
<embedded name="embeddedObject">
|
||||
<attribute-override name"subproperty">
|
||||
<column name="my_column"/>
|
||||
</attribute-override>
|
||||
</embedded>
|
||||
<basic name="status" optional="false">
|
||||
<enumerated>STRING</enumerated>
|
||||
</basic>
|
||||
<basic name="serial" optional="true">
|
||||
<column name="serialbytes"/>
|
||||
<lob/>
|
||||
</basic>
|
||||
<basic name="terminusTime" fetch="LAZY">
|
||||
<temporal>TIMESTAMP</temporal>
|
||||
</basic>
|
||||
</attributes></programlisting>
|
||||
|
||||
<para>
|
||||
通过 <literal>id</literal>,
|
||||
<literal>embedded-id</literal>, <literal>version</literal>,
|
||||
<literal>embedded</literal> 和 <literal>basic</literal>你可以覆写一个属性,
|
||||
这些元素中的每一个元素都有相应的subelements:<literal>lob</literal>,
|
||||
<literal>temporal</literal>, <literal>enumerated</literal>,
|
||||
<literal>column</literal>.</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>关联级别的元数据</title>
|
||||
|
||||
<para>你可以定义XML覆写关联注释. 所有的关联级别的元数据作用于
|
||||
<literal>entity/attributes</literal>,
|
||||
<literal>mapped-superclass/attributes</literal> 或
|
||||
<literal>embeddable/attributes</literal>.</para>
|
||||
|
||||
<programlisting> <attributes>
|
||||
<one-to-many name="players" fetch="EAGER">
|
||||
<map-key name="name"/>
|
||||
<join-column name="driver"/>
|
||||
<join-column name="number"/>
|
||||
</one-to-many>
|
||||
<many-to-many name="roads" target-entity="Administration">
|
||||
<order-by>maxSpeed</order-by>
|
||||
<join-table name="bus_road">
|
||||
<join-column name="driver"/>
|
||||
<join-column name="number"/>
|
||||
<inverse-join-column name="road_id"/>
|
||||
<unique-constraint>
|
||||
<column-name>driver</column-name>
|
||||
<column-name>number</column-name>
|
||||
</unique-constraint>
|
||||
</join-table>
|
||||
</many-to-many>
|
||||
<many-to-many name="allTimeDrivers" mapped-by="drivenBuses">
|
||||
</attributes></programlisting>
|
||||
|
||||
<para>通过<literal>one-to-many</literal>, <literal>one-to-one</literal>,
|
||||
<literal>many-to-one</literal>, 和 <literal>many-to-many</literal>.
|
||||
你可以重写一个关联关系.这些元素中的每一个都有相应的subelements. <literal>join-table</literal> (可以有
|
||||
<literal>join-column</literal>和
|
||||
<literal>inverse-join-column</literal>),
|
||||
<literal><literal>join-column</literal></literal>,
|
||||
<literal>map-key</literal>, 和 <literal>order-by</literal>.
|
||||
<literal>mapped-by</literal> 和 <literal>target-entity</literal>
|
||||
当他们有意义的时候可以定义属性. 再一次强调 该结构映射于注释的结构.在描述注释的一章中 你可以找到所有的语义信息.</para>
|
||||
|
||||
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
|
@ -133,11 +133,6 @@
|
|||
<artifactId>hibernate-core</artifactId>
|
||||
<version>${version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-annotations</artifactId>
|
||||
<version>${version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
|
|
Loading…
Reference in New Issue