Hibernate SVN: r14086 - core/trunk/core/src/main/java/org/hibernate/dialect.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2007-10-16 17:09:37 -0400 (Tue, 16 Oct 2007)
New Revision: 14086
Modified:
core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java
Log:
HHH-2857 : assume schema support in HSQLDialect
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java 2007-10-16 21:09:15 UTC (rev 14085)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java 2007-10-16 21:09:37 UTC (rev 14086)
@@ -11,7 +11,6 @@
import org.hibernate.JDBCException;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.persister.entity.Lockable;
-import org.hibernate.util.ReflectHelper;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
@@ -29,14 +28,13 @@
* <p/>
* Note this version supports HSQLDB version 1.8 and higher, only.
*
- * @author Christoph Sturm, Phillip Baird
+ * @author Christoph Sturm
+ * @author Phillip Baird
*/
public class HSQLDialect extends Dialect {
private static final Logger log = LoggerFactory.getLogger( HSQLDialect.class );
- private boolean schemaSupport;
-
public HSQLDialect() {
super();
registerColumnType( Types.BIGINT, "bigint" );
@@ -130,17 +128,6 @@
registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) );
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
-
- try {
- // Does present HSQLDB Database class support schemas?
- // yuck! Perhaps we should think about a new dialect? Especially
- // if more things are going to break back-compat moving forward
- ReflectHelper.classForName( "org.hsqldb.Database" ).getDeclaredField( "schemaManager" );
- schemaSupport = true;
- }
- catch (Throwable t) {
- schemaSupport = false;
- }
}
public String getAddColumnString() {
@@ -219,12 +206,8 @@
}
public String getQuerySequencesString() {
- if ( schemaSupport ) {
- return "select sequence_name from information_schema.system_sequences";
- }
- else {
- return "select sequence_name from system_sequences";
- }
+ // this assumes schema support, which is present in 1.8.0 and later...
+ return "select sequence_name from information_schema.system_sequences";
}
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
18 years, 6 months
Hibernate SVN: r14085 - core/branches/Branch_3_2/src/org/hibernate/dialect.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2007-10-16 17:09:15 -0400 (Tue, 16 Oct 2007)
New Revision: 14085
Modified:
core/branches/Branch_3_2/src/org/hibernate/dialect/HSQLDialect.java
Log:
HHH-2857 : assume schema support in HSQLDialect
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/HSQLDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/HSQLDialect.java 2007-10-16 21:04:41 UTC (rev 14084)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/HSQLDialect.java 2007-10-16 21:09:15 UTC (rev 14085)
@@ -11,7 +11,6 @@
import org.hibernate.JDBCException;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.persister.entity.Lockable;
-import org.hibernate.util.ReflectHelper;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
@@ -29,14 +28,13 @@
* <p/>
* Note this version supports HSQLDB version 1.8 and higher, only.
*
- * @author Christoph Sturm, Phillip Baird
+ * @author Christoph Sturm
+ * @author Phillip Baird
*/
public class HSQLDialect extends Dialect {
private static final Log log = LogFactory.getLog( HSQLDialect.class );
- private boolean schemaSupport;
-
public HSQLDialect() {
super();
registerColumnType( Types.BIGINT, "bigint" );
@@ -130,17 +128,6 @@
registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) );
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
-
- try {
- // Does present HSQLDB Database class support schemas?
- // yuck! Perhaps we should think about a new dialect? Especially
- // if more things are going to break back-compat moving forward
- ReflectHelper.classForName( "org.hsqldb.Database" ).getDeclaredField( "schemaManager" );
- schemaSupport = true;
- }
- catch (Throwable t) {
- schemaSupport = false;
- }
}
public String getAddColumnString() {
@@ -219,12 +206,8 @@
}
public String getQuerySequencesString() {
- if ( schemaSupport ) {
- return "select sequence_name from information_schema.system_sequences";
- }
- else {
- return "select sequence_name from system_sequences";
- }
+ // this assumes schema support, which is present in 1.8.0 and later...
+ return "select sequence_name from information_schema.system_sequences";
}
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
18 years, 6 months
Hibernate SVN: r14084 - in core/branches/Branch_3_2: src/org/hibernate/tuple/entity and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2007-10-16 17:04:41 -0400 (Tue, 16 Oct 2007)
New Revision: 14084
Modified:
core/branches/Branch_3_2/src/org/hibernate/loader/Loader.java
core/branches/Branch_3_2/src/org/hibernate/tuple/entity/EntityMetamodel.java
core/branches/Branch_3_2/test/org/hibernate/test/naturalid/immutable/ImmutableNaturalIdTest.java
core/branches/Branch_3_2/test/org/hibernate/test/naturalid/immutable/User.hbm.xml
core/branches/Branch_3_2/test/org/hibernate/test/naturalid/immutable/User.java
core/branches/Branch_3_2/test/org/hibernate/test/naturalid/mutable/MutableNaturalIdTest.java
core/branches/Branch_3_2/test/org/hibernate/test/naturalid/mutable/User.hbm.xml
Log:
HHH-2892 : natural id caching
Modified: core/branches/Branch_3_2/src/org/hibernate/loader/Loader.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/loader/Loader.java 2007-10-16 21:04:09 UTC (rev 14083)
+++ core/branches/Branch_3_2/src/org/hibernate/loader/Loader.java 2007-10-16 21:04:41 UTC (rev 14084)
@@ -2156,18 +2156,13 @@
final QueryCache queryCache,
final QueryKey key) {
List result = null;
-
- if ( session.getCacheMode().isGetEnabled() ) {
- result = queryCache.get(
- key,
- resultTypes,
- queryParameters.isNaturalKeyLookup(),
- querySpaces,
- session
- );
+ if ( session.getCacheMode().isGetEnabled() ) {
+ boolean isImmutableNaturalKeyLookup = queryParameters.isNaturalKeyLookup()
+ && getEntityPersisters()[0].getEntityMetamodel().hasImmutableNaturalId();
+ result = queryCache.get( key, resultTypes, isImmutableNaturalKeyLookup, querySpaces, session );
if ( factory.getStatistics().isStatisticsEnabled() ) {
- if (result==null) {
+ if ( result == null ) {
factory.getStatisticsImplementor()
.queryCacheMiss( getQueryIdentifier(), queryCache.getRegionName() );
}
@@ -2176,9 +2171,8 @@
.queryCacheHit( getQueryIdentifier(), queryCache.getRegionName() );
}
}
-
}
-
+
return result;
}
@@ -2189,13 +2183,12 @@
final QueryCache queryCache,
final QueryKey key,
final List result) {
-
if ( session.getCacheMode().isPutEnabled() ) {
boolean put = queryCache.put(
key,
resultTypes,
result,
- queryParameters.isNaturalKeyLookup(),
+ queryParameters.isNaturalKeyLookup(),
session
);
if ( put && factory.getStatistics().isStatisticsEnabled() ) {
Modified: core/branches/Branch_3_2/src/org/hibernate/tuple/entity/EntityMetamodel.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/tuple/entity/EntityMetamodel.java 2007-10-16 21:04:09 UTC (rev 14083)
+++ core/branches/Branch_3_2/src/org/hibernate/tuple/entity/EntityMetamodel.java 2007-10-16 21:04:41 UTC (rev 14084)
@@ -82,6 +82,7 @@
private final boolean hasNonIdentifierPropertyNamedId;
private final int[] naturalIdPropertyNumbers;
+ private final boolean hasImmutableNaturalId;
private boolean lazy; //not final because proxy factory creation can fail
private final boolean hasCascades;
@@ -159,6 +160,7 @@
boolean foundNonIdentifierPropertyNamedId = false;
boolean foundInsertGeneratedValue = false;
boolean foundUpdateGeneratedValue = false;
+ boolean foundUpdateableNaturalIdProperty = false;
while ( iter.hasNext() ) {
Property prop = ( Property ) iter.next();
@@ -173,6 +175,9 @@
if ( prop.isNaturalIdentifier() ) {
naturalIdNumbers.add( new Integer(i) );
+ if ( prop.isUpdateable() ) {
+ foundUpdateableNaturalIdProperty = true;
+ }
}
if ( "id".equals( prop.getName() ) ) {
@@ -229,9 +234,11 @@
if (naturalIdNumbers.size()==0) {
naturalIdPropertyNumbers = null;
+ hasImmutableNaturalId = false;
}
else {
naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers);
+ hasImmutableNaturalId = !foundUpdateableNaturalIdProperty;
}
hasInsertGeneratedValues = foundInsertGeneratedValue;
@@ -373,6 +380,10 @@
return naturalIdPropertyNumbers!=null;
}
+ public boolean hasImmutableNaturalId() {
+ return hasImmutableNaturalId;
+ }
+
public Set getSubclassEntityNames() {
return subclassEntityNames;
}
Modified: core/branches/Branch_3_2/test/org/hibernate/test/naturalid/immutable/ImmutableNaturalIdTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/naturalid/immutable/ImmutableNaturalIdTest.java 2007-10-16 21:04:09 UTC (rev 14083)
+++ core/branches/Branch_3_2/test/org/hibernate/test/naturalid/immutable/ImmutableNaturalIdTest.java 2007-10-16 21:04:41 UTC (rev 14084)
@@ -1,8 +1,30 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
package org.hibernate.test.naturalid.immutable;
+import java.lang.reflect.Field;
+
import junit.framework.Test;
import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.criterion.Restrictions;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
@@ -24,20 +46,23 @@
return new FunctionalTestClassTestSuite( ImmutableNaturalIdTest.class );
}
+ public void configure(Configuration cfg) {
+ cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "true" );
+ cfg.setProperty( Environment.USE_QUERY_CACHE, "true" );
+ cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
+ }
+
public void testUpdate() {
// prepare some test data...
Session session = openSession();
- session.beginTransaction();
- User user = new User();
- user.setUserName( "steve" );
- user.setEmail( "steve(a)hibernate.org" );
- user.setFirstName( "Steve" );
- user.setInitial( null);
- user.setLastName( "Ebersole" );
- user.setPassword( "brewhaha" );
+ session.beginTransaction();
+ User user = new User();
+ user.setUserName( "steve" );
+ user.setEmail( "steve(a)hibernate.org" );
+ user.setPassword( "brewhaha" );
session.save( user );
- session.getTransaction().commit();
- session.close();
+ session.getTransaction().commit();
+ session.close();
// 'user' is now a detached entity, so lets change a property and reattch...
user.setPassword( "homebrew" );
@@ -54,4 +79,82 @@
session.getTransaction().commit();
session.close();
}
+
+ public void testNaturalIdCheck() throws Exception {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ User u = new User( "steve", "superSecret" );
+ s.persist( u );
+ u.setUserName( "Steve" );
+ try {
+ s.flush();
+ fail();
+ }
+ catch ( HibernateException he ) {
+ }
+ u.setUserName( "steve" );
+ s.delete( u );
+ t.commit();
+ s.close();
+ }
+
+ public void testNaturalIdCache() {
+ Session s = openSession();
+ s.beginTransaction();
+ User u = new User( "steve", "superSecret" );
+ s.persist( u );
+ s.getTransaction().commit();
+ s.close();
+
+ getSessions().getStatistics().clear();
+
+ s = openSession();
+ s.beginTransaction();
+ u = ( User ) s.createCriteria( User.class )
+ .add( Restrictions.naturalId().set( "userName", "steve" ) )
+ .setCacheable( true )
+ .uniqueResult();
+ assertNotNull( u );
+ s.getTransaction().commit();
+ s.close();
+
+ assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 1 );
+ assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 0 );
+ assertEquals( getSessions().getStatistics().getQueryCachePutCount(), 1 );
+
+ s = openSession();
+ s.beginTransaction();
+ User v = new User( "gavin", "supsup" );
+ s.persist( v );
+ s.getTransaction().commit();
+ s.close();
+
+ getSessions().getStatistics().clear();
+
+ s = openSession();
+ s.beginTransaction();
+ u = ( User ) s.createCriteria( User.class )
+ .add( Restrictions.naturalId().set( "userName", "steve" ) )
+ .setCacheable( true )
+ .uniqueResult();
+ assertNotNull( u );
+ assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 0 );
+ assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 1 );
+ u = ( User ) s.createCriteria( User.class )
+ .add( Restrictions.naturalId().set( "userName", "steve" ) )
+ .setCacheable( true )
+ .uniqueResult();
+ assertNotNull( u );
+ assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 0 );
+ assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 2 );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ s.createQuery( "delete User" ).executeUpdate();
+ s.getTransaction().commit();
+ s.close();
+ }
}
Modified: core/branches/Branch_3_2/test/org/hibernate/test/naturalid/immutable/User.hbm.xml
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/naturalid/immutable/User.hbm.xml 2007-10-16 21:04:09 UTC (rev 14083)
+++ core/branches/Branch_3_2/test/org/hibernate/test/naturalid/immutable/User.hbm.xml 2007-10-16 21:04:41 UTC (rev 14084)
@@ -1,11 +1,32 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+
+<!--
+
+ This mapping illustrates use of <natural-id mutable="false"/>
+
+-->
<hibernate-mapping package="org.hibernate.test.naturalid.immutable">
- <class name="User" table="IMM_NAT_ID_USER" lazy="true">
+ <class name="User" table="IMM_NAT_ID_USER" lazy="true">
<comment>Users may bid for or sell auction items.</comment>
<id name="myUserId" type="java.lang.Integer">
<generator class="increment"/>
@@ -16,9 +37,6 @@
<version name="version"/>
<property name="password" not-null="true" length="15" column="`password`"/>
<property name="email"/>
- <property name="firstName" length="50" not-null="true"/>
- <property name="initial" column="`initial`"/>
- <property name="lastName" length="50" not-null="true"/>
</class>
</hibernate-mapping>
\ No newline at end of file
Modified: core/branches/Branch_3_2/test/org/hibernate/test/naturalid/immutable/User.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/naturalid/immutable/User.java 2007-10-16 21:04:09 UTC (rev 14083)
+++ core/branches/Branch_3_2/test/org/hibernate/test/naturalid/immutable/User.java 2007-10-16 21:04:41 UTC (rev 14084)
@@ -12,13 +12,15 @@
private String userName;
private String password;
private String email;
- private String firstName;
- private Character initial;
- private String lastName;
public User() {
}
+ public User(String userName, String password) {
+ this.userName = userName;
+ this.password = password;
+ }
+
public Integer getMyUserId() {
return this.myUserId;
}
@@ -51,30 +53,6 @@
this.email = email;
}
- public String getFirstName() {
- return this.firstName;
- }
-
- public void setFirstName(String firstName) {
- this.firstName = firstName;
- }
-
- public Character getInitial() {
- return this.initial;
- }
-
- public void setInitial(Character initial) {
- this.initial = initial;
- }
-
- public String getLastName() {
- return this.lastName;
- }
-
- public void setLastName(String lastName) {
- this.lastName = lastName;
- }
-
public Integer getVersion() {
return this.version;
}
Modified: core/branches/Branch_3_2/test/org/hibernate/test/naturalid/mutable/MutableNaturalIdTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/naturalid/mutable/MutableNaturalIdTest.java 2007-10-16 21:04:09 UTC (rev 14083)
+++ core/branches/Branch_3_2/test/org/hibernate/test/naturalid/mutable/MutableNaturalIdTest.java 2007-10-16 21:04:41 UTC (rev 14084)
@@ -76,26 +76,6 @@
s.close();
}
- public void testNaturalIdCheck() throws Exception {
- Session s = openSession();
- Transaction t = s.beginTransaction();
-
- User u = new User("gavin", "hb", "secret");
- s.persist(u);
- Field name = u.getClass().getDeclaredField("name");
- name.setAccessible(true);
- name.set(u, "Gavin");
- try {
- s.flush();
- fail();
- }
- catch (HibernateException he) {}
- name.set(u, "gavin");
- s.delete(u);
- t.commit();
- s.close();
- }
-
public void testNonexistentNaturalIdCache() {
getSessions().getStatistics().clear();
@@ -248,12 +228,22 @@
.uniqueResult();
assertNotNull(u);
+ assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 1 );
+ assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 0 );
+
+ u = (User) s.createCriteria( User.class)
+ .add( Restrictions.naturalId()
+ .set("name", "gavin")
+ .set("org", "hb")
+ ).setCacheable(true)
+ .uniqueResult();
+
+ assertNotNull(u);
+ assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 1 );
+ assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 1 );
t.commit();
s.close();
-
- assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 0 );
- assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 1 );
s = openSession();
t = s.beginTransaction();
Modified: core/branches/Branch_3_2/test/org/hibernate/test/naturalid/mutable/User.hbm.xml
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/naturalid/mutable/User.hbm.xml 2007-10-16 21:04:09 UTC (rev 14083)
+++ core/branches/Branch_3_2/test/org/hibernate/test/naturalid/mutable/User.hbm.xml 2007-10-16 21:04:41 UTC (rev 14084)
@@ -5,7 +5,7 @@
<!--
- This mapping illustrates use of <natural-id>.
+ This mapping illustrates use of <natural-id mutable="true"/>
-->
18 years, 6 months
Hibernate SVN: r14083 - in core/trunk: core/src/main/java/org/hibernate/tuple/entity and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2007-10-16 17:04:09 -0400 (Tue, 16 Oct 2007)
New Revision: 14083
Modified:
core/trunk/core/src/main/java/org/hibernate/loader/Loader.java
core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java
core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/ImmutableNaturalIdTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/User.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/User.java
core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/mutable/MutableNaturalIdTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/mutable/User.hbm.xml
Log:
HHH-2892 : natural id caching
Modified: core/trunk/core/src/main/java/org/hibernate/loader/Loader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/Loader.java 2007-10-16 11:15:21 UTC (rev 14082)
+++ core/trunk/core/src/main/java/org/hibernate/loader/Loader.java 2007-10-16 21:04:09 UTC (rev 14083)
@@ -2147,23 +2147,18 @@
}
private List getResultFromQueryCache(
- final SessionImplementor session,
- final QueryParameters queryParameters,
- final Set querySpaces,
+ final SessionImplementor session,
+ final QueryParameters queryParameters,
+ final Set querySpaces,
final Type[] resultTypes,
- final QueryCache queryCache,
+ final QueryCache queryCache,
final QueryKey key) {
List result = null;
-
- if ( session.getCacheMode().isGetEnabled() ) {
- result = queryCache.get(
- key,
- resultTypes,
- queryParameters.isNaturalKeyLookup(),
- querySpaces,
- session
- );
+ if ( session.getCacheMode().isGetEnabled() ) {
+ boolean isImmutableNaturalKeyLookup = queryParameters.isNaturalKeyLookup()
+ && getEntityPersisters()[0].getEntityMetamodel().hasImmutableNaturalId();
+ result = queryCache.get( key, resultTypes, isImmutableNaturalKeyLookup, querySpaces, session );
if ( factory.getStatistics().isStatisticsEnabled() ) {
if ( result == null ) {
factory.getStatisticsImplementor()
@@ -2174,28 +2169,20 @@
.queryCacheHit( getQueryIdentifier(), queryCache.getRegion().getName() );
}
}
-
}
-
+
return result;
}
private void putResultInQueryCache(
- final SessionImplementor session,
- final QueryParameters queryParameters,
+ final SessionImplementor session,
+ final QueryParameters queryParameters,
final Type[] resultTypes,
- final QueryCache queryCache,
- final QueryKey key,
+ final QueryCache queryCache,
+ final QueryKey key,
final List result) {
-
if ( session.getCacheMode().isPutEnabled() ) {
- boolean put = queryCache.put(
- key,
- resultTypes,
- result,
- queryParameters.isNaturalKeyLookup(),
- session
- );
+ boolean put = queryCache.put( key, resultTypes, result, queryParameters.isNaturalKeyLookup(), session );
if ( put && factory.getStatistics().isStatisticsEnabled() ) {
factory.getStatisticsImplementor()
.queryCachePut( getQueryIdentifier(), queryCache.getRegion().getName() );
Modified: core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java 2007-10-16 11:15:21 UTC (rev 14082)
+++ core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java 2007-10-16 21:04:09 UTC (rev 14083)
@@ -82,6 +82,7 @@
private final boolean hasNonIdentifierPropertyNamedId;
private final int[] naturalIdPropertyNumbers;
+ private final boolean hasImmutableNaturalId;
private boolean lazy; //not final because proxy factory creation can fail
private final boolean hasCascades;
@@ -159,6 +160,7 @@
boolean foundNonIdentifierPropertyNamedId = false;
boolean foundInsertGeneratedValue = false;
boolean foundUpdateGeneratedValue = false;
+ boolean foundUpdateableNaturalIdProperty = false;
while ( iter.hasNext() ) {
Property prop = ( Property ) iter.next();
@@ -173,6 +175,9 @@
if ( prop.isNaturalIdentifier() ) {
naturalIdNumbers.add( new Integer(i) );
+ if ( prop.isUpdateable() ) {
+ foundUpdateableNaturalIdProperty = true;
+ }
}
if ( "id".equals( prop.getName() ) ) {
@@ -229,9 +234,11 @@
if (naturalIdNumbers.size()==0) {
naturalIdPropertyNumbers = null;
+ hasImmutableNaturalId = false;
}
else {
naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers);
+ hasImmutableNaturalId = !foundUpdateableNaturalIdProperty;
}
hasInsertGeneratedValues = foundInsertGeneratedValue;
@@ -373,6 +380,10 @@
return naturalIdPropertyNumbers!=null;
}
+ public boolean hasImmutableNaturalId() {
+ return hasImmutableNaturalId;
+ }
+
public Set getSubclassEntityNames() {
return subclassEntityNames;
}
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/ImmutableNaturalIdTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/ImmutableNaturalIdTest.java 2007-10-16 11:15:21 UTC (rev 14082)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/ImmutableNaturalIdTest.java 2007-10-16 21:04:09 UTC (rev 14083)
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
package org.hibernate.test.naturalid.immutable;
import junit.framework.Test;
@@ -3,4 +18,9 @@
import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.criterion.Restrictions;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
@@ -24,6 +44,12 @@
return new FunctionalTestClassTestSuite( ImmutableNaturalIdTest.class );
}
+ public void configure(Configuration cfg) {
+ cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "true" );
+ cfg.setProperty( Environment.USE_QUERY_CACHE, "true" );
+ cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
+ }
+
public void testUpdate() {
// prepare some test data...
Session session = openSession();
@@ -31,9 +57,6 @@
User user = new User();
user.setUserName( "steve" );
user.setEmail( "steve(a)hibernate.org" );
- user.setFirstName( "Steve" );
- user.setInitial( null);
- user.setLastName( "Ebersole" );
user.setPassword( "brewhaha" );
session.save( user );
session.getTransaction().commit();
@@ -54,4 +77,82 @@
session.getTransaction().commit();
session.close();
}
+
+ public void testNaturalIdCheck() throws Exception {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ User u = new User( "steve", "superSecret" );
+ s.persist( u );
+ u.setUserName( "Steve" );
+ try {
+ s.flush();
+ fail();
+ }
+ catch ( HibernateException he ) {
+ }
+ u.setUserName( "steve" );
+ s.delete( u );
+ t.commit();
+ s.close();
+ }
+
+ public void testNaturalIdCache() {
+ Session s = openSession();
+ s.beginTransaction();
+ User u = new User( "steve", "superSecret" );
+ s.persist( u );
+ s.getTransaction().commit();
+ s.close();
+
+ getSessions().getStatistics().clear();
+
+ s = openSession();
+ s.beginTransaction();
+ u = ( User ) s.createCriteria( User.class )
+ .add( Restrictions.naturalId().set( "userName", "steve" ) )
+ .setCacheable( true )
+ .uniqueResult();
+ assertNotNull( u );
+ s.getTransaction().commit();
+ s.close();
+
+ assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 1 );
+ assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 0 );
+ assertEquals( getSessions().getStatistics().getQueryCachePutCount(), 1 );
+
+ s = openSession();
+ s.beginTransaction();
+ User v = new User( "gavin", "supsup" );
+ s.persist( v );
+ s.getTransaction().commit();
+ s.close();
+
+ getSessions().getStatistics().clear();
+
+ s = openSession();
+ s.beginTransaction();
+ u = ( User ) s.createCriteria( User.class )
+ .add( Restrictions.naturalId().set( "userName", "steve" ) )
+ .setCacheable( true )
+ .uniqueResult();
+ assertNotNull( u );
+ assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 0 );
+ assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 1 );
+ u = ( User ) s.createCriteria( User.class )
+ .add( Restrictions.naturalId().set( "userName", "steve" ) )
+ .setCacheable( true )
+ .uniqueResult();
+ assertNotNull( u );
+ assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 0 );
+ assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 2 );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ s.createQuery( "delete User" ).executeUpdate();
+ s.getTransaction().commit();
+ s.close();
+ }
}
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/User.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/User.hbm.xml 2007-10-16 11:15:21 UTC (rev 14082)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/User.hbm.xml 2007-10-16 21:04:09 UTC (rev 14083)
@@ -1,11 +1,32 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+
+<!--
+
+ This mapping illustrates use of <natural-id mutable="false"/>
+
+-->
<hibernate-mapping package="org.hibernate.test.naturalid.immutable">
- <class name="User" table="IMM_NAT_ID_USER" lazy="true">
+ <class name="User" table="IMM_NAT_ID_USER" lazy="true">
<comment>Users may bid for or sell auction items.</comment>
<id name="myUserId" type="java.lang.Integer">
<generator class="increment"/>
@@ -16,9 +37,6 @@
<version name="version"/>
<property name="password" not-null="true" length="15" column="`password`"/>
<property name="email"/>
- <property name="firstName" length="50" not-null="true"/>
- <property name="initial" column="`initial`"/>
- <property name="lastName" length="50" not-null="true"/>
</class>
</hibernate-mapping>
\ No newline at end of file
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/User.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/User.java 2007-10-16 11:15:21 UTC (rev 14082)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/User.java 2007-10-16 21:04:09 UTC (rev 14083)
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
package org.hibernate.test.naturalid.immutable;
/**
@@ -12,13 +27,15 @@
private String userName;
private String password;
private String email;
- private String firstName;
- private Character initial;
- private String lastName;
public User() {
}
+ public User(String userName, String password) {
+ this.userName = userName;
+ this.password = password;
+ }
+
public Integer getMyUserId() {
return this.myUserId;
}
@@ -51,30 +68,6 @@
this.email = email;
}
- public String getFirstName() {
- return this.firstName;
- }
-
- public void setFirstName(String firstName) {
- this.firstName = firstName;
- }
-
- public Character getInitial() {
- return this.initial;
- }
-
- public void setInitial(Character initial) {
- this.initial = initial;
- }
-
- public String getLastName() {
- return this.lastName;
- }
-
- public void setLastName(String lastName) {
- this.lastName = lastName;
- }
-
public Integer getVersion() {
return this.version;
}
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/mutable/MutableNaturalIdTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/mutable/MutableNaturalIdTest.java 2007-10-16 11:15:21 UTC (rev 14082)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/mutable/MutableNaturalIdTest.java 2007-10-16 21:04:09 UTC (rev 14083)
@@ -1,4 +1,4 @@
-//$Id: MutableNaturalIdTest.java 10977 2006-12-12 23:28:04Z steve.ebersole(a)jboss.com $
+//$Id: MutableNaturalIdTest.java 11645 2007-06-06 21:33:31Z steve.ebersole(a)jboss.com $
package org.hibernate.test.naturalid.mutable;
import java.lang.reflect.Field;
@@ -8,7 +8,6 @@
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
-import org.hibernate.test.naturalid.mutable.User;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.criterion.Restrictions;
@@ -19,7 +18,7 @@
* @author Gavin King
*/
public class MutableNaturalIdTest extends FunctionalTestCase {
-
+
public MutableNaturalIdTest(String str) {
super(str);
}
@@ -37,98 +36,117 @@
public static Test suite() {
return new FunctionalTestClassTestSuite( MutableNaturalIdTest.class );
}
-
- public void testNaturalIdCheck() throws Exception {
+
+ public void testReattachmentNaturalIdCheck() throws Throwable {
Session s = openSession();
- Transaction t = s.beginTransaction();
-
- User u = new User("gavin", "hb", "secret");
- s.persist(u);
+ s.beginTransaction();
+ User u = new User( "gavin", "hb", "secret" );
+ s.persist( u );
+ s.getTransaction().commit();
+ s.close();
+
Field name = u.getClass().getDeclaredField("name");
name.setAccessible(true);
name.set(u, "Gavin");
+ s = openSession();
+ s.beginTransaction();
try {
- s.flush();
- fail();
+ s.update( u );
+ s.getTransaction().commit();
}
- catch (HibernateException he) {}
- name.set(u, "gavin");
- s.delete(u);
- t.commit();
+ catch( HibernateException expected ) {
+ s.getTransaction().rollback();
+ }
+ catch( Throwable t ) {
+ try {
+ s.getTransaction().rollback();
+ }
+ catch ( Throwable ignore ) {
+ }
+ throw t;
+ }
+ finally {
+ s.close();
+ }
+
+ s = openSession();
+ s.beginTransaction();
+ s.delete( u );
+ s.getTransaction().commit();
s.close();
}
-
+
public void testNonexistentNaturalIdCache() {
getSessions().getStatistics().clear();
Session s = openSession();
Transaction t = s.beginTransaction();
-
+
Object nullUser = s.createCriteria(User.class)
.add( Restrictions.naturalId()
.set("name", "gavin")
- .set("org", "hb")
+ .set("org", "hb")
)
.setCacheable(true)
.uniqueResult();
-
+
assertNull(nullUser);
-
+
t.commit();
s.close();
-
+
assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 1 );
assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 0 );
assertEquals( getSessions().getStatistics().getQueryCachePutCount(), 0 );
-
+
s = openSession();
t = s.beginTransaction();
-
+
User u = new User("gavin", "hb", "secret");
s.persist(u);
-
+
t.commit();
s.close();
-
+
getSessions().getStatistics().clear();
s = openSession();
t = s.beginTransaction();
-
+
u = (User) s.createCriteria(User.class)
.add( Restrictions.naturalId()
.set("name", "gavin")
- .set("org", "hb")
+ .set("org", "hb")
)
.setCacheable(true)
.uniqueResult();
-
+
assertNotNull(u);
-
+
t.commit();
s.close();
assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 1 );
assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 0 );
assertEquals( getSessions().getStatistics().getQueryCachePutCount(), 1 );
-
+
getSessions().getStatistics().clear();
s = openSession();
t = s.beginTransaction();
-
+
u = (User) s.createCriteria(User.class)
.add( Restrictions.naturalId()
.set("name", "gavin")
- .set("org", "hb")
+ .set("org", "hb")
).setCacheable(true)
.uniqueResult();
-
+
s.delete(u);
-
+
t.commit();
s.close();
-
+
assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 0 );
assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 1 );
@@ -136,86 +154,96 @@
s = openSession();
t = s.beginTransaction();
-
+
nullUser = s.createCriteria(User.class)
.add( Restrictions.naturalId()
.set("name", "gavin")
- .set("org", "hb")
+ .set("org", "hb")
)
.setCacheable(true)
.uniqueResult();
-
+
assertNull(nullUser);
-
+
t.commit();
s.close();
-
+
assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 1 );
assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 0 );
assertEquals( getSessions().getStatistics().getQueryCachePutCount(), 0 );
-
+
}
public void testNaturalIdCache() {
Session s = openSession();
Transaction t = s.beginTransaction();
-
+
User u = new User("gavin", "hb", "secret");
s.persist(u);
-
+
t.commit();
s.close();
-
+
getSessions().getStatistics().clear();
s = openSession();
t = s.beginTransaction();
-
+
u = (User) s.createCriteria(User.class)
.add( Restrictions.naturalId()
.set("name", "gavin")
- .set("org", "hb")
+ .set("org", "hb")
)
.setCacheable(true)
.uniqueResult();
-
+
assertNotNull(u);
-
+
t.commit();
s.close();
assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 1 );
assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 0 );
assertEquals( getSessions().getStatistics().getQueryCachePutCount(), 1 );
-
+
s = openSession();
t = s.beginTransaction();
-
+
User v = new User("xam", "hb", "foobar");
s.persist(v);
-
+
t.commit();
s.close();
-
+
getSessions().getStatistics().clear();
s = openSession();
t = s.beginTransaction();
-
- u = (User) s.createCriteria(User.class)
+
+ u = (User) s.createCriteria( User.class)
.add( Restrictions.naturalId()
.set("name", "gavin")
- .set("org", "hb")
+ .set("org", "hb")
).setCacheable(true)
.uniqueResult();
-
+
assertNotNull(u);
-
+ assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 1 );
+ assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 0 );
+
+ u = (User) s.createCriteria( User.class)
+ .add( Restrictions.naturalId()
+ .set("name", "gavin")
+ .set("org", "hb")
+ ).setCacheable(true)
+ .uniqueResult();
+
+ assertNotNull(u);
+ assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 1 );
+ assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 1 );
+
t.commit();
s.close();
-
- assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 0 );
- assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 1 );
s = openSession();
t = s.beginTransaction();
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/mutable/User.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/mutable/User.hbm.xml 2007-10-16 11:15:21 UTC (rev 14082)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/mutable/User.hbm.xml 2007-10-16 21:04:09 UTC (rev 14083)
@@ -1,27 +1,27 @@
<?xml version="1.0"?>
-<!DOCTYPE hibernate-mapping PUBLIC
+<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
- This mapping illustrates use of <natural-id>.
-
+ This mapping illustrates use of <natural-id mutable="true"/>
+
-->
-<hibernate-mapping
+<hibernate-mapping
package="org.hibernate.test.naturalid"
default-access="field">
-
+
<class name="org.hibernate.test.naturalid.mutable.User" table="SystemUserInfo">
<id name="id">
<generator class="increment"/>
</id>
- <natural-id>
+ <natural-id mutable="true">
<property name="name"/>
<property name="org"/>
</natural-id>
<property name="password"/>
</class>
-
+
</hibernate-mapping>
\ No newline at end of file
18 years, 6 months
Hibernate SVN: r14081 - in core/trunk/documentation/manual/zh-CN: src/main and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2007-10-09 16:10:34 -0400 (Tue, 09 Oct 2007)
New Revision: 14081
Added:
core/trunk/documentation/manual/zh-CN/glossary.txt
core/trunk/documentation/manual/zh-CN/src/main/docbook/Hibernate_Reference.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/architecture.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/association_mapping.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/basic_mapping.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/batch.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/best_practices.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/collection_mapping.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/component_mapping.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/configuration.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/events.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/example_mappings.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/example_parentchild.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/example_weblog.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/filters.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/inheritance_mapping.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/performance.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/persistent_classes.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/preface.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/query_criteria.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/query_hql.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/query_sql.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/quickstart.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/session_api.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/toolset_guide.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/transactions.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/tutorial.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/content/xml.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/AuthorWork.png
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/AuthorWork.zargo
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/CustomerOrderProduct.png
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/CustomerOrderProduct.zargo
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/EmployerEmployee.png
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/EmployerEmployee.zargo
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/full_cream.png
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/full_cream.svg
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/hibernate_logo_a.png
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/lite.png
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/lite.svg
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/overview.png
core/trunk/documentation/manual/zh-CN/src/main/docbook/images/overview.svg
core/trunk/documentation/manual/zh-CN/src/main/docbook/legal_notice.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/translators.xml
Removed:
core/trunk/documentation/manual/zh-CN/src/main/docbook/glossary.txt
core/trunk/documentation/manual/zh-CN/src/main/docbook/master.xml
core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/
core/trunk/documentation/manual/zh-CN/src/main/resources/
Log:
new docbook layout (prep for translations migration to PO)
Copied: core/trunk/documentation/manual/zh-CN/glossary.txt (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/glossary.txt)
===================================================================
--- core/trunk/documentation/manual/zh-CN/glossary.txt (rev 0)
+++ core/trunk/documentation/manual/zh-CN/glossary.txt 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,27 @@
+O/R Mapping 对象/关系数据库映射
+identifier property: 标识属性
+discriminator: 辨别标志(不使用"鉴别器")
+
+join-subclass,union-subclass,join: 不翻译
+
+fine-grained 细粒度
+domain model 领域模型
+business object 业务对象(v2的时候翻译为"商业对象",被无数人痛骂....)
+annotations 注解(这个词还比较新,也见到有翻译为"特殊注释"/"标注"的)
+
+Aggregate functions 统计函数 (聚集函数?聚合函数? 还是翻译为统计函数才能让人看懂)
+Criteria Queries 条件查询(标准查询?这里Criteria是"判据"的含义,而非"标准",意译为条件查询更加明白)
+
+session flush session清洗
+lazy fetching 延迟加载(懒加载,翻译很直白,但是却不易理解)
+
+对象状态:
+ persistent class 持久化类
+ persistent object 持久对象 (体现这是与某个持久化设备联系的,掉电之后不消失)
+ transient object 瞬时对象 (其含义是仅在内存中存在的,掉电之后消失,翻译为瞬时对象比较好)
+ detached object 脱管对象(与session脱离的对象)
+
+outer-join fetching 外连接抓取 (fetch一般翻译为"获取",v2翻译的时候,为了突出其主动获取的特点,翻译为"抓取")
+
+class hierarchy 类分层结构 http://www.umlchina.com/xprogrammer/glossary1.htm
+inheritance hierarchy 继承层次 http://www-128.ibm.com/developerworks/cn/java/j-aopwork4/?ca=dwcn-newslet...
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/Hibernate_Reference.xml (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/Hibernate_Reference.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/Hibernate_Reference.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/Hibernate_Reference.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,72 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+ <!ENTITY versionNumber "3.3.0.alpha1">
+ <!ENTITY copyrightYear "2004">
+ <!ENTITY copyrightHolder "Red Hat Middleware, LLC.">
+]>
+
+<book>
+
+ <bookinfo>
+ <title>HIBERNATE - 符合Java习惯的关系数据库持久化</title>
+ <subtitle>Hibernate参考文档</subtitle>
+ <releaseinfo>&versionNumber;</releaseinfo>
+ <productnumber>&versionNumber;</productnumber>
+ <issuenum>1</issuenum>
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/hibernate_logo_a.png" align="center" />
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="images/hibernate_logo_a.png" depth="3cm" />
+ </imageobject>
+ </mediaobject>
+ <copyright>
+ <year>©rightYear;</year>
+ <holder>©rightHolder;</holder>
+ </copyright>
+ <xi:include href="translators.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="legal_notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </bookinfo>
+
+ <toc/>
+
+ <xi:include href="content/preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/tutorial.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/configuration.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/persistent_classes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/basic_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/collection_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/association_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/component_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/inheritance_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/session_api.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/transactions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/events.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/batch.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/query_hql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/query_criteria.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/query_sql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/filters.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/xml.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/performance.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/toolset_guide.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/example_parentchild.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/example_weblog.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/example_mappings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/best_practices.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+</book>
+
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/architecture.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/architecture.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/architecture.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/architecture.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,284 @@
+<chapter id="architecture">
+
+ <title>体系结构(Architecture)</title>
+ <sect1 id="architecture-overview" revision="1">
+ <title>概况(Overview)</title>
+
+ <para>
+ 一个非常简要的Hibernate体系结构的概要图:
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/overview.svg" format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../shared/images/overview.gif" format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ 从这个图可以看出,Hibernate使用数据库和配置信息来为应用程序提供持久化服务(以及持久的对象)。
+ </para>
+
+ <para>
+ 我们来更详细地看一下Hibernate运行时体系结构。由于Hibernate非常灵活,且支持多种应用方案,
+ 所以我们这只描述一下两种极端的情况。“轻型”的体系结构方案,要求应用程序提供自己的JDBC
+ 连接并管理自己的事务。这种方案使用了Hibernate API的最小子集:
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/lite.svg" format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../shared/images/lite.gif" format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ “全面解决”的体系结构方案,将应用层从底层的JDBC/JTA API中抽象出来,而让Hibernate来处理这些细节。
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/full_cream.svg" format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../shared/images/full_cream.gif" format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ 图中各个对象的定义如下:
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>SessionFactory (<literal>org.hibernate.SessionFactory</literal>)</term>
+ <listitem>
+ <para>
+ 针对单个数据库映射关系经过编译后的内存镜像,是线程安全的(不可变)。
+ 它是生成<literal>Session</literal>的工厂,本身要用到<literal>ConnectionProvider</literal>。
+ 该对象可以在进程或集群的级别上,为那些事务之间可以重用的数据提供可选的二级缓存。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Session (<literal>org.hibernate.Session</literal>)</term>
+ <listitem>
+ <para>
+ 表示应用程序与持久储存层之间交互操作的一个单线程对象,此对象生存期很短。
+ 其隐藏了JDBC连接,也是<literal>Transaction</literal>的工厂。
+ 其会持有一个针对持久化对象的必选(第一级)缓存,在遍历对象图或者根据持久化标识查找对象时会用到。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>持久的对象及其集合</term>
+ <listitem>
+ <para>
+ 带有持久化状态的、具有业务功能的单线程对象,此对象生存期很短。
+ 这些对象可能是普通的JavaBeans/POJO,唯一特殊的是他们正与(仅仅一个)<literal>Session</literal>相关联。
+ 一旦这个<literal>Session</literal>被关闭,这些对象就会脱离持久化状态,这样就可被应用程序的任何层自由使用。
+ (例如,用作跟表示层打交道的数据传输对象。)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>瞬态(transient)和脱管(detached)的对象及其集合</term>
+ <listitem>
+ <para>
+ 那些目前没有与session关联的持久化类实例。
+ 他们可能是在被应用程序实例化后,尚未进行持久化的对象。
+ 也可能是因为实例化他们的<literal>Session</literal>已经被关闭而脱离持久化的对象。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>事务Transaction (<literal>org.hibernate.Transaction</literal>)</term>
+ <listitem>
+ <para>
+ (可选的)应用程序用来指定原子操作单元范围的对象,它是单线程的,生命周期很短。
+ 它通过抽象将应用从底层具体的JDBC、JTA以及CORBA事务隔离开。
+ 某些情况下,一个<literal>Session</literal>之内可能包含多个<literal>Transaction</literal>对象。
+ 尽管是否使用该对象是可选的,但无论是使用底层的API还是使用<literal>Transaction</literal>对象,事务边界的开启与关闭是必不可少的。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ConnectionProvider (<literal>org.hibernate.connection.ConnectionProvider</literal>)</term>
+ <listitem>
+ <para>
+ (可选的)生成JDBC连接的工厂(同时也起到连接池的作用)。
+ 它通过抽象将应用从底层的<literal>Datasource</literal>或<literal>DriverManager</literal>隔离开。
+ 仅供开发者扩展/实现用,并不暴露给应用程序使用。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>TransactionFactory (<literal>org.hibernate.TransactionFactory</literal>)</term>
+ <listitem>
+ <para>
+ (可选的)生成<literal>Transaction</literal>对象实例的工厂。
+ 仅供开发者扩展/实现用,并不暴露给应用程序使用。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis>扩展接口</emphasis></term>
+ <listitem>
+ <para>
+ Hibernate提供了很多可选的扩展接口,你可以通过实现它们来定制你的持久层的行为。
+ 具体请参考API文档。
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ 在特定“轻型”的体系结构中,应用程序可能绕过
+ <literal>Transaction</literal>/<literal>TransactionFactory</literal> 以及
+ <literal>ConnectionProvider</literal> 等API直接跟JTA或JDBC打交道。
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-states" revision="1">
+ <title>实例状态</title>
+ <para>
+ 一个持久化类的实例可能处于三种不同状态中的某一种。
+ 这三种状态的定义则与所谓的<emphasis>持久化上下文(persistence context)</emphasis>有关。
+ Hibernate的<literal>Session</literal>对象就是这个所谓的持久化上下文:
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>瞬态(transient)</term>
+ <listitem>
+ <para>
+ 该实例从未与任何持久化上下文关联过。它没有持久化标识(相当于主键值)。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>持久化(persistent)</term>
+ <listitem>
+ <para>
+ 实例目前与某个持久化上下文有关联。
+ 它拥有持久化标识(相当于主键值),并且可能在数据库中有一个对应的行。
+ 对于某一个特定的持久化上下文,Hibernate<emphasis>保证</emphasis>持久化标识与Java标识(其值代表对象在内存中的位置)等价。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>脱管(detached)</term>
+ <listitem>
+ <para>
+ 实例曾经与某个持久化上下文发生过关联,不过那个上下文被关闭了,
+ 或者这个实例是被序列化(serialize)到另外的进程。
+ 它拥有持久化标识,并且在数据库中可能存在一个对应的行。
+ 对于脱管状态的实例,Hibernate不保证任何持久化标识和Java标识的关系。
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 id="architecture-jmx" revision="1">
+ <title>JMX整合</title>
+
+ <para>
+ JMX是管理Java组件(Java components)的J2EE标准。 Hibernate 可以通过一个JMX标准服务来管理。
+ 在这个发行版本中,我们提供了一个MBean接口的实现,即
+ <literal>org.hibernate.jmx.HibernateService</literal>。
+ </para>
+
+ <para>
+ 想要看如何在JBoss应用服务器上将Hibernate部署为一个JMX服务的例子,您可以参考JBoss用户指南。
+ 我们现在说一下在Jboss应用服务器上,使用JMX来部署Hibernate的好处:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Session管理:</emphasis> Hibernate的<literal>Session</literal>对象的生命周期可以
+ 自动跟一个JTA事务边界绑定。这意味着你无需手工开关<literal>Session</literal>了, 这项
+ 工作会由JBoss EJB 拦截器来完成。你再也不用担心你的代码中的事务边界了(除非你想利用Hibernate提供可选
+ 的<literal>Transaction</literal> API来自己写一个便于移植的的持久层)。
+ 你通过调用<literal>HibernateContext</literal>来访问<literal>Session</literal>。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>HAR 部署:</emphasis> 通常情况下,你会使用JBoss的服务部署描述符(在EAR或/和SAR文件中)来部署Hibernate JMX服务。
+ 这种部署方式支持所有常见的Hibernate <literal>SessionFactory</literal>的配置选项。
+ 不过,你仍需在部署描述符中,列出你所有的映射文件的名字。如果你使用HAR部署方式, JBoss
+ 会自动探测出你的HAR文件中所有的映射文件。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 这些选项更多的描述,请参考JBoss 应用程序用户指南。
+ </para>
+
+ <para>
+ 将Hibernate以部署为JMX服务的另一个好处,是可以查看Hibernate的运行时统计信息。参看
+ <xref linkend="configuration-optional-statistics"/>.
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-jca" revision="1">
+ <title>对JCA的支持</title>
+ <para>
+ Hibernate也可以被配置为一个JCA连接器(JCA connector)。更多信息请参看网站。
+ 请注意,Hibernate对JCA的支持,仍处于实验性阶段。
+ </para>
+ </sect1>
+ <sect1 id="architecture-current-session" revision="2">
+ <title>上下文相关的(Contextual)Session</title>
+ <para>
+ 使用Hibernate的大多数应用程序需要某种形式的“上下文相关的” session,特定的session在整个特定的上下文范围内始终有效。然而,对不同类型的应用程序而言,要为什么是组成这种“上下文”下一个定义通常是困难的;不同的上下文对“当前”这个概念定义了不同的范围。在3.0版本之前,使用Hibernate的程序要么采用自行编写的基于<literal>ThreadLocal</literal>的上下文session,要么采用<literal>HibernateUtil</literal>这样的辅助类,要么采用第三方框架(比如Spring或Pico),它们提供了基于代理(proxy)或者基于拦截器(interception)的上下文相关session。
+ </para>
+ <para>
+ 从3.0.1版本开始,Hibernate增加了<literal>SessionFactory.getCurrentSession()</literal>方法。一开始,它假定了采用<literal>JTA</literal>事务,<literal>JTA</literal>事务定义了当前session的范围和上下文(scope and context)。Hibernate开发团队坚信,因为有好几个独立的<literal>JTA TransactionManager</literal>实现稳定可用,不论是否被部署到一个<literal>J2EE</literal>容器中,大多数(假若不是所有的)应用程序都应该采用<literal>JTA</literal>事务管理。基于这一点,采用<literal>JTA</literal>的上下文相关session可以满足你一切需要。
+ </para>
+ <para>
+ 更好的是,从3.1开始,<literal>SessionFactory.getCurrentSession()</literal>的后台实现是可拔插的。因此,我们引入了新的扩展接口(<literal>org.hibernate.context.CurrentSessionContext</literal>)和新的配置参数(<literal>hibernate.current_session_context_class</literal>),以便对什么是“当前session”的范围和上下文(scope and context)的定义进行拔插。
+ </para>
+ <para>
+ 请参阅<literal>org.hibernate.context.CurrentSessionContext</literal>接口的Javadoc,那里有关于它的契约的详细讨论。它定义了单一的方法,<literal>currentSession()</literal>,特定的实现用它来负责跟踪当前的上下文session。Hibernate内置了此接口的三种实现。
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>org.hibernate.context.JTASessionContext</literal> - 当前session根据<literal>JTA</literal>来跟踪和界定。这和以前的仅支持JTA的方法是完全一样的。详情请参阅Javadoc。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>org.hibernate.context.ThreadLocalSessionContext</literal> - 当前session通过当前执行的线程来跟踪和界定。详情也请参阅Javadoc。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>org.hibernate.context.ManagedSessionContext</literal> - 当前session通过当前执行的线程来跟踪和界定。但是,你需要负责使用这个类的静态方法将<literal>Session</literal>实例绑定、或者取消绑定,它并不会打开(open)、flush或者关闭(close)任何<literal>Session</literal>。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 前两种实现都提供了“每数据库事务对应一个session”的编程模型,也称作<emphasis>每次请求一个session</emphasis>。Hibernate session的起始和终结由数据库事务的生存来控制。假若你在纯粹的 Java SE之上采用自行编写代码来管理事务,而不使用JTA,建议你使用Hibernate <literal>Transaction</literal> API来把底层事务实现从你的代码中隐藏掉。如果你使用JTA,请使用JTA借口来管理Transaction。如果你在支持CMT的EJB容器中执行代码,事务边界是声明式定义的,你不需要在代码中进行任何事务或session管理操作。请参阅<xref linkend="transactions"/>一节来阅读更多的内容和示例代码。
+ </para>
+
+ <para>
+ <literal>hibernate.current_session_context_class</literal>配置参数定义了应该采用哪个<literal>org.hibernate.context.CurrentSessionContext</literal>实现。注意,为了向下兼容,如果未配置此参数,但是存在<literal>org.hibernate.transaction.TransactionManagerLookup</literal>的配置,Hibernate会采用<literal>org.hibernate.context.JTASessionContext</literal>。一般而言,此参数的值指明了要使用的实现类的全名,但那三种内置的实现可以使用简写,即"jta"、"thread"和"managed"。
+
+ </para>
+
+ </sect1>
+
+</chapter>
+
+
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/association_mapping.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/association_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/association_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/association_mapping.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,579 @@
+<chapter id="associations">
+
+ <title>关联关系映射</title>
+
+ <sect1 id="assoc-intro" revision="1">
+ <title>介绍</title>
+
+ <para>
+ 关联关系映射通常情况是最难配置正确的。在这个部分中,我们从单向关系映射开始,然后考虑双向关系映射,由浅至深讲述一遍典型的案例。在所有的例子中,我们都使用 <literal>Person</literal>和<literal>Address</literal>。
+ </para>
+
+ <para>
+ 我们根据映射关系是否涉及连接表以及多样性来划分关联类型。
+ </para>
+
+ <para>
+ 在传统的数据建模中,允许为Null值的外键被认为是一种不好的实践,因此我们所有的例子中都使用不允许为Null的外键。这并不是Hibernate的要求,即使你删除掉不允许为Null的约束,Hibernate映射一样可以工作的很好。
+ </para>
+
+ </sect1>
+
+ <sect1 id="assoc-unidirectional" revision="1">
+ <title>单向关联(Unidirectional associations)</title>
+
+ <sect2 id="assoc-unidirectional-m21">
+ <title>多对一(many to one)</title>
+
+ <para>
+ <emphasis>单向many-to-one关联</emphasis>是最常见的单向关联关系。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-121">
+ <title>一对一(one to one)</title>
+
+ <para>
+ <emphasis>基于外键关联的单向一对一关联</emphasis>和<emphasis>单向多对一关联</emphasis>几乎是一样的。唯一的不同就是单向一对一关联中的外键字段具有唯一性约束。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ unique="true"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ <emphasis>基于主键关联的单向一对一关联</emphasis>通常使用一个特定的id生成器。(请注意,在这个例子中我们掉换了关联的方向。)
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+</class>
+
+<class name="Address">
+ <id name="id" column="personId">
+ <generator class="foreign">
+ <param name="property">person</param>
+ </generator>
+ </id>
+ <one-to-one name="person" constrained="true"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( personId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-12m">
+ <title>一对多(one to many)</title>
+
+ <para>
+ <emphasis>基于外键关联的单向一对多关联</emphasis>是一种很少见的情况,并不推荐使用。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses">
+ <key column="personId"
+ not-null="true"/>
+ <one-to-many class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( addressId bigint not null primary key, personId bigint not null )
+ ]]></programlisting>
+
+ <para>
+ 我们认为对于这种关联关系最好使用连接表。
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-unidirectional-join" revision="1">
+ <title>使用连接表的单向关联(Unidirectional associations with join tables)</title>
+
+ <sect2 id="assoc-unidirectional-join-12m">
+ <title>一对多(one to many)</title>
+
+ <para>
+ <emphasis>基于连接表的单向一对多关联</emphasis> 应该优先被采用。请注意,通过指定<literal>unique="true"</literal>,我们可以把多样性从多对多改变为一对多。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ unique="true"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId not null, addressId bigint not null primary key )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-m21">
+ <title>多对一(many to one)</title>
+
+ <para>
+ <emphasis>基于连接表的单向多对一关联</emphasis>在关联关系可选的情况下应用也很普遍。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId" unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-121">
+ <title>一对一(one to one)</title>
+
+ <para>
+ <emphasis>基于连接表的单向一对一关联</emphasis>非常少见,但也是可行的。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId"
+ unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-m2m">
+ <title>多对多(many to many)</title>
+
+ <para>
+ 最后,还有 <emphasis>单向多对多关联</emphasis>.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-bidirectional" revision="1">
+ <title>双向关联(Bidirectional associations)</title>
+
+ <sect2 id="assoc-bidirectional-m21" revision="2">
+ <title>一对多(one to many) / 多对一(many to one)</title>
+
+ <para>
+ <emphasis>双向多对一关联</emphasis> 是最常见的关联关系。(这也是标准的父/子关联关系。)
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <set name="people" inverse="true">
+ <key column="addressId"/>
+ <one-to-many class="Person"/>
+ </set>
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ 如果你使用<literal>List</literal>(或者其他有序集合类),你需要设置外键对应的<literal>key</literal>列为 <literal>not null</literal>,让Hibernate来从集合端管理关联,维护每个元素的索引(通过设置<literal>update="false"</literal> and <literal>insert="false"</literal>来对另一端反向操作)。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id"/>
+ ...
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ insert="false"
+ update="false"/>
+</class>
+
+<class name="Address">
+ <id name="id"/>
+ ...
+ <list name="people">
+ <key column="addressId" not-null="true"/>
+ <list-index column="peopleIdx"/>
+ <one-to-many class="Person"/>
+ </list>
+</class>]]></programlisting>
+
+ <para>
+ 假若集合映射的<literal><key></literal>元素对应的底层外键字段是<literal>NOT NULL</literal>的,那么为这一key元素定义<literal>not-null="true"</literal>是很重要的。不要仅仅为可能的嵌套<literal><column></literal>元素定义<literal>not-null="true"</literal>,<literal><key></literal>元素也是需要的。
+ </para>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-121">
+ <title>一对一(one to one)</title>
+
+ <para>
+ <emphasis>基于外键关联的双向一对一关联</emphasis>也很常见。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ unique="true"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <one-to-one name="person"
+ property-ref="address"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ <emphasis>基于主键关联的一对一关联</emphasis>需要使用特定的id生成器。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <one-to-one name="address"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="personId">
+ <generator class="foreign">
+ <param name="property">person</param>
+ </generator>
+ </id>
+ <one-to-one name="person"
+ constrained="true"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( personId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-bidirectional-join" revision="1">
+ <title>使用连接表的双向关联(Bidirectional associations with join tables)</title>
+
+ <sect2 id="assoc-bidirectional-join-12m">
+ <title>一对多(one to many) /多对一( many to one)</title>
+
+ <para>
+ <emphasis>基于连接表的双向一对多关联</emphasis>。注意<literal>inverse="true"</literal>可以出现在关联的任意一端,即collection端或者join端。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses"
+ table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ unique="true"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ inverse="true"
+ optional="true">
+ <key column="addressId"/>
+ <many-to-one name="person"
+ column="personId"
+ not-null="true"/>
+ </join>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null primary key )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-join-121">
+ <title>一对一(one to one)</title>
+
+ <para>
+ <emphasis>基于连接表的双向一对一关联</emphasis>极为罕见,但也是可行的。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId"
+ unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true"
+ inverse="true">
+ <key column="addressId"
+ unique="true"/>
+ <many-to-one name="person"
+ column="personId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-join-m2m" revision="1">
+ <title>多对多(many to many)</title>
+
+ <para>
+ 最后,还有 <emphasis>双向多对多关联</emphasis>.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <set name="people" inverse="true" table="PersonAddress">
+ <key column="addressId"/>
+ <many-to-many column="personId"
+ class="Person"/>
+ </set>
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+ <sect1 id="assoc-complex">
+ <title>更复杂的关联映射</title>
+
+ <para>
+ 更复杂的关联连接<emphasis>极为</emphasis>罕见。
+ 通过在映射文档中嵌入SQL片断,Hibernate也可以处理更为复杂的情况。比如,假若包含历史帐户数据的表定义了<literal>accountNumber</literal>, <literal>effectiveEndDate</literal> 和<literal>effectiveStartDate</literal>字段,按照下面映射:
+ </para>
+
+ <programlisting><![CDATA[<properties name="currentAccountKey">
+ <property name="accountNumber" type="string" not-null="true"/>
+ <property name="currentAccount" type="boolean">
+ <formula>case when effectiveEndDate is null then 1 else 0 end</formula>
+ </property>
+</properties>
+<property name="effectiveEndDate" type="date"/>
+<property name="effectiveStateDate" type="date" not-null="true"/>]]></programlisting>
+
+ <para>
+ 那么我们可以对<emphasis>目前(current)</emphasis>实例(其<literal>effectiveEndDate</literal>为null)使用这样的关联映射:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="currentAccountInfo"
+ property-ref="currentAccountKey"
+ class="AccountInfo">
+ <column name="accountNumber"/>
+ <formula>'1'</formula>
+</many-to-one>]]></programlisting>
+
+ <para>
+ 更复杂的例子,假想<literal>Employee</literal>和<literal>Organization</literal>之间的关联是通过一个<literal>Employment</literal>中间表维护的,而中间表中填充了很多历史雇员数据。那“雇员的<emphasis>最新</emphasis>雇主”这个关联(最新雇主就是<literal>startDate</literal>最后的那个)可以这样映射:
+ </para>
+
+ <programlisting><![CDATA[<join>
+ <key column="employeeId"/>
+ <subselect>
+ select employeeId, orgId
+ from Employments
+ group by orgId
+ having startDate = max(startDate)
+ </subselect>
+ <many-to-one name="mostRecentEmployer"
+ class="Organization"
+ column="orgId"/>
+</join>]]></programlisting>
+
+ <para>
+ 使用这一功能时可以充满创意,但通常更加实用的是用HQL或条件查询来处理这些情形。
+ </para>
+
+ </sect1>
+
+
+</chapter>
+
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/basic_mapping.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/basic_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/basic_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/basic_mapping.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,2982 @@
+<chapter id="mapping">
+ <title>对象/关系数据库映射基础(Basic O/R Mapping)</title>
+
+ <sect1 id="mapping-declaration" revision="1">
+ <title>映射定义(Mapping declaration)</title>
+
+ <para>
+ 对象和关系数据库之间的映射通常是用一个XML文档(XML document)来定义的。这个映射文档被设计为易读的,
+ 并且可以手工修改。映射语言是以Java为中心,这意味着映射文档是按照持久化类的定义来创建的,
+ 而非表的定义。
+ </para>
+
+
+ <para>
+ 请注意,虽然很多Hibernate用户选择手写XML映射文档,但也有一些工具可以用来生成映射文档,
+ 包括XDoclet,Middlegen和AndroMDA。
+ </para>
+
+ <para>
+ 让我们从一个映射的例子开始:
+ </para>
+
+ <programlisting id="mapping-declaration-ex1" revision="1"><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class name="Cat"
+ table="cats"
+ discriminator-value="C">
+
+ <id name="id">
+ <generator class="native"/>
+ </id>
+
+ <discriminator column="subclass"
+ type="character"/>
+
+ <property name="weight"/>
+
+ <property name="birthdate"
+ type="date"
+ not-null="true"
+ update="false"/>
+
+ <property name="color"
+ type="eg.types.ColorUserType"
+ not-null="true"
+ update="false"/>
+
+ <property name="sex"
+ not-null="true"
+ update="false"/>
+
+ <property name="litterId"
+ column="litterId"
+ update="false"/>
+
+ <many-to-one name="mother"
+ column="mother_id"
+ update="false"/>
+
+ <set name="kittens"
+ inverse="true"
+ order-by="litter_id">
+ <key column="mother_id"/>
+ <one-to-many class="Cat"/>
+ </set>
+
+ <subclass name="DomesticCat"
+ discriminator-value="D">
+
+ <property name="name"
+ type="string"/>
+
+ </subclass>
+
+ </class>
+
+ <class name="Dog">
+ <!-- mapping for Dog could go here -->
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 我们现在开始讨论映射文档的内容。我们只描述Hibernate在运行时用到的文档元素和属性。
+ 映射文档还包括一些额外的可选属性和元素,它们在使用schema导出工具的时候会影响导出的数据库schema结果。
+ (比如,<literal> not-null</literal> 属性。)
+ </para>
+
+
+
+ <sect2 id="mapping-declaration-doctype" revision="3">
+ <title>Doctype</title>
+
+ <para>
+ 所有的XML映射都需要定义如上所示的doctype。DTD可以从上述URL中获取,
+ 也可以从<literal>hibernate-x.x.x/src/net/sf/hibernate</literal>目录中、
+ 或<literal>hibernate.jar</literal>文件中找到。Hibernate总是会首先在它的classptah中搜索DTD文件。
+ 如果你发现它是通过连接Internet查找DTD文件,就对照你的classpath目录检查XML文件里的DTD声明。
+ </para>
+
+ <sect3 id="mapping-declaration-entity-resolution">
+ <title>EntityResolver</title>
+ <para>
+ As mentioned previously, Hibernate will first attempt to resolve DTDs in its classpath. The
+ manner in which it does this is by registering a custom <literal>org.xml.sax.EntityResolver</literal>
+ implementation with the SAXReader it uses to read in the xml files. This custom
+ <literal>EntityResolver</literal> recognizes two different systemId namespaces.
+ 如前所述,Hibernate首先在其classpath中查找DTD。其行为是依靠在系统中注册的<literal>org.xml.sax.EntityResolver</literal>的一个具体实现,SAXReader依靠它来读取xml文件。这一 <literal>EntityResolver</literal> 实现能辨认两种不同的 systenId命名空间。
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ 若resolver遇到了一个以<literal>http://hibernate.sourceforge.net/</literal>为开头的systemId,它会辨认出是<literal>hibernate namespace</literal>,resolver就试图通过加载Hibernate类的classloader来查找这些实体。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+
+ 若resolver遇到了一个使用<literal>classpath://</literal>URL协议的systemId,它会辨认出这是<literal>user namespace</literal>,resolver试图通过(1)当前线程上下文的classloader和(2)加载Hibernate class的classloader来查找这些实体。
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ 使用user namespace(用户命名空间)的例子:
+ </para>
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" [
+ <!ENTITY types SYSTEM "classpath://your/domain/types.xml">
+]>
+
+<hibernate-mapping package="your.domain">
+ <class name="MyEntity">
+ <id name="id" type="my-custom-id-type">
+ ...
+ </id>
+ <class>
+ &types;
+</hibernate-mapping>]]></programlisting>
+ <para>
+ <literal>types.xml</literal>是<literal>your.domain</literal>包中的一个资源,它包含了一个定制的<xref linkend="mapping-types-custom">typedef</xref>。
+ </para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-mapping" revision="3">
+ <title>hibernate-mapping</title>
+
+ <para>
+ 这个元素包括一些可选的属性。<literal>schema</literal>和<literal>catalog</literal>属性,
+ 指明了这个映射所连接(refer)的表所在的schema和/或catalog名称。
+ 假若指定了这个属性,表名会加上所指定的schema和catalog的名字扩展为全限定名。假若没有指定,表名就不会使用全限定名。
+ <literal>default-cascade</literal>指定了未明确注明<literal>cascade</literal>属性的Java属性和
+ 集合类Hibernate会采取什么样的默认级联风格。<literal>auto-import</literal>属性默认让我们在查询语言中可以使用
+ 非全限定名的类名。
+ </para>
+
+
+ <programlistingco>
+ <areaspec>
+ <area id="hm1" coords="2 55"/>
+ <area id="hm2" coords="3 55"/>
+ <area id="hm3" coords="4 55"/>
+ <area id="hm4" coords="5 55"/>
+ <area id="hm5" coords="6 55"/>
+ <area id="hm6" coords="7 55"/>
+ <area id="hm7" coords="8 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<hibernate-mapping
+ schema="schemaName"
+ catalog="catalogName"
+ default-cascade="cascade_style"
+ default-access="field|property|ClassName"
+ default-lazy="true|false"
+ auto-import="true|false"
+ package="package.name"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="hm1">
+ <para>
+ <literal>schema</literal> (可选): 数据库schema的名称。
+ </para>
+ </callout>
+ <callout arearefs="hm2">
+ <para>
+ <literal>catalog</literal> (可选): 数据库catalog的名称。
+ </para>
+ </callout>
+ <callout arearefs="hm3">
+ <para>
+ <literal>default-cascade</literal> (可选 - 默认为 <literal>none</literal>):
+ 默认的级联风格。
+ </para>
+ </callout>
+ <callout arearefs="hm4">
+ <para>
+ <literal>default-access</literal> (可选 - 默认为 <literal>property</literal>):
+ Hibernate用来访问所有属性的策略。可以通过实现<literal>PropertyAccessor</literal>接口
+ 自定义。
+ </para>
+ </callout>
+ <callout arearefs="hm5">
+ <para>
+ <literal>default-lazy</literal> (可选 - 默认为 <literal>true</literal>):
+ 指定了未明确注明<literal>lazy</literal>属性的Java属性和集合类,
+ Hibernate会采取什么样的默认加载风格。
+ </para>
+ </callout>
+ <callout arearefs="hm6">
+ <para>
+ <literal>auto-import</literal> (可选 - 默认为 <literal>true</literal>):
+ 指定我们是否可以在查询语言中使用非全限定的类名(仅限于本映射文件中的类)。
+ </para>
+ </callout>
+ <callout arearefs="hm7">
+ <para>
+ <literal>package</literal> (可选): 指定一个包前缀,如果在映射文档中没有指定全限定的类名,
+ 就使用这个作为包名。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 假若你有两个持久化类,它们的非全限定名是一样的(就是两个类的名字一样,所在的包不一样--译者注),
+ 你应该设置<literal>auto-import="false"</literal>。如果你把一个“import过”的名字同时对应两个类,
+ Hibernate会抛出一个异常。
+ </para>
+
+ <para>
+ 注意<literal>hibernate-mapping</literal> 元素允许你嵌套多个如上所示的
+ <literal><class></literal>映射。但是最好的做法(也许一些工具需要的)是一个
+ 持久化类(或一个类的继承层次)对应一个映射文件,并以持久化的超类名称命名,例如:
+ <literal>Cat.hbm.xml</literal>,
+ <literal>Dog.hbm.xml</literal>,或者如果使用继承,<literal>Animal.hbm.xml</literal>。
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-class" revision="3">
+ <title>class</title>
+
+ <para>
+ 你可以使用<literal>class</literal>元素来定义一个持久化类:
+ </para>
+
+
+ <programlistingco>
+ <areaspec>
+ <area id="class1" coords="2 55"/>
+ <area id="class2" coords="3 55" />
+ <area id="class3" coords="4 55"/>
+ <area id="class4" coords="5 55" />
+ <area id="class5" coords="6 55"/>
+ <area id="class6" coords="7 55" />
+ <area id="class7" coords="8 55"/>
+ <area id="class8" coords="9 55" />
+ <area id="class9" coords="10 55" />
+ <area id="class10" coords="11 55"/>
+ <area id="class11" coords="12 55"/>
+ <area id="class12" coords="13 55"/>
+ <area id="class13" coords="14 55"/>
+ <area id="class14" coords="15 55"/>
+ <area id="class15" coords="16 55"/>
+ <area id="class16" coords="17 55"/>
+ <area id="class17" coords="18 55"/>
+ <area id="class18" coords="19 55"/>
+ <area id="class19" coords="20 55"/>
+ <area id="class20" coords="21 55"/>
+ <area id="class21" coords="22 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<class
+ name="ClassName"
+ table="tableName"
+ discriminator-value="discriminator_value"
+ mutable="true|false"
+ schema="owner"
+ catalog="catalog"
+ proxy="ProxyInterface"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ select-before-update="true|false"
+ polymorphism="implicit|explicit"
+ where="arbitrary sql where condition"
+ persister="PersisterClass"
+ batch-size="N"
+ optimistic-lock="none|version|dirty|all"
+ lazy="true|false"
+ entity-name="EntityName"
+ check="arbitrary sql check condition"
+ rowid="rowid"
+ subselect="SQL expression"
+ abstract="true|false"
+ node="element-name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="class1">
+ <para>
+ <literal>name</literal> (可选): 持久化类(或者接口)的Java全限定名。
+ 如果这个属性不存在,Hibernate将假定这是一个非POJO的实体映射。
+ </para>
+ </callout>
+ <callout arearefs="class2">
+ <para>
+ <literal>table</literal> (可选 - 默认是类的非全限定名): 对应的数据库表名。
+ </para>
+ </callout>
+ <callout arearefs="class3">
+ <para>
+ <literal>discriminator-value</literal> (可选 - 默认和类名一样):
+ 一个用于区分不同的子类的值,在多态行为时使用。它可以接受的值包括
+ <literal>null</literal> 和 <literal>not null</literal>。
+ </para>
+ </callout>
+ <callout arearefs="class4">
+ <para>
+ <literal>mutable</literal> (可选,默认值为<literal>true</literal>):
+ 表明该类的实例是可变的或者不可变的。
+ </para>
+ </callout>
+ <callout arearefs="class5">
+ <para>
+ <literal>schema</literal> (可选):
+ 覆盖在根<literal><hibernate-mapping></literal>元素中指定的schema名字。
+ </para>
+ </callout>
+ <callout arearefs="class6">
+ <para>
+ <literal>catalog</literal> (可选):
+ 覆盖在根<literal><hibernate-mapping></literal>元素中指定的catalog名字。
+ </para>
+ </callout>
+ <callout arearefs="class7">
+ <para>
+ <literal>proxy</literal> (可选): 指定一个接口,在延迟装载时作为代理使用。
+ 你可以在这里使用该类自己的名字。
+ </para>
+ </callout>
+ <callout arearefs="class8">
+ <para>
+ <literal>dynamic-update</literal> (可选, 默认为 <literal>false</literal>):
+ 指定用于<literal>UPDATE</literal> 的SQL将会在运行时动态生成,并且只更新那些改变过的字段。
+ </para>
+ </callout>
+ <callout arearefs="class9">
+ <para>
+ <literal>dynamic-insert</literal> (可选, 默认为 <literal>false</literal>):
+ 指定用于<literal>INSERT</literal>的 SQL 将会在运行时动态生成,并且只包含那些非空值字段。
+ </para>
+ </callout>
+ <callout arearefs="class10">
+ <para>
+ <literal>select-before-update</literal> (可选, 默认为 <literal>false</literal>):
+ 指定Hibernate除非确定对象真正被修改了(如果该值为true-译注),否则<emphasis>不会</emphasis>执行SQL
+ <literal>UPDATE</literal>操作。在特定场合(实际上,它只在一个瞬时对象(transient object)关联到一个
+ 新的session中时执行的update()中生效),这说明Hibernate会在<literal>UPDATE</literal>
+ 之前执行一次额外的SQL <literal>SELECT</literal>操作,来决定是否应该执行
+ <literal>UPDATE</literal>。
+ </para>
+ </callout>
+ <callout arearefs="class11">
+ <para>
+ <literal>polymorphism(多态)</literal> (可选, 默认值为 <literal>implicit (隐式)
+ </literal>): 界定是隐式还是显式的使用多态查询(这只在Hibernate的具体表继承策略中用到-译注)。
+ </para>
+ </callout>
+ <callout arearefs="class12">
+ <para>
+ <literal>where</literal> (可选) 指定一个附加的SQL<literal>WHERE</literal> 条件,
+ 在抓取这个类的对象时会一直增加这个条件。
+ </para>
+ </callout>
+ <callout arearefs="class13">
+ <para>
+ <literal>persister</literal> (可选): 指定一个定制的<literal>ClassPersister</literal>。
+ </para>
+ </callout>
+ <callout arearefs="class14">
+ <para>
+ <literal>batch-size</literal> (可选,默认是<literal>1</literal>) 指定一个用于
+ 根据标识符(identifier)抓取实例时使用的"batch size"(批次抓取数量)。
+ </para>
+ </callout>
+ <callout arearefs="class15">
+ <para>
+ <literal>optimistic-lock(乐观锁定)</literal>
+ (可选,默认是<literal>version</literal>): 决定乐观锁定的策略。
+ </para>
+ </callout>
+ <callout arearefs="class16">
+ <para>
+ <literal>lazy</literal> (可选): 通过设置<literal>lazy="false"</literal>,
+ 所有的延迟加载(Lazy fetching)功能将被全部禁用(disabled)。
+ </para>
+ </callout>
+ <callout arearefs="class17">
+ <para>
+ <literal>entity-name</literal> (可选,默认为类名): Hibernate3允许一个类进行多次映射(
+ 前提是映射到不同的表),并且允许使用Maps或XML代替Java层次的实体映射
+ (也就是实现动态领域模型,不用写持久化类-译注)。
+ 更多信息请看<xref linkend="persistent-classes-dynamicmodels"/> and <xref linkend="xml"/>。
+ </para>
+ </callout>
+ <callout arearefs="class18">
+ <para>
+ <literal>check</literal> (可选): 这是一个SQL表达式,
+ 用于为自动生成的schema添加多行(multi-row)约束<emphasis>检查</emphasis>。
+ </para>
+ </callout>
+ <callout arearefs="class19">
+ <para>
+ <literal>rowid</literal> (可选): Hibernate可以使用数据库支持的所谓的ROWIDs,例如:
+ Oracle数据库,如果你设置这个可选的<literal>rowid</literal>,
+ Hibernate可以使用额外的字段<literal>rowid</literal>实现快速更新。ROWID是这个功能实现的重点,
+ 它代表了一个存储元组(tuple)的物理位置。
+ </para>
+ </callout>
+ <callout arearefs="class20">
+ <para>
+ <literal>subselect</literal> (可选): 它将一个不可变(immutable)并且只读的实体映射到一个数据库的
+ 子查询中。当你想用视图代替一张基本表的时候,这是有用的,但最好不要这样做。更多的介绍请看下面内容。
+ </para>
+ </callout>
+ <callout arearefs="class21">
+ <para>
+ <literal>abstract</literal> (可选): 用于在<literal><union-subclass></literal>的继承结构
+ (hierarchies)中标识抽象超类。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 若指明的持久化类实际上是一个接口,这也是完全可以接受的。
+ 之后你可以用元素<literal><subclass></literal>来指定该接口的实际实现类。
+ 你可以持久化任何<emphasis>static</emphasis>(静态的)内部类。
+ 你应该使用标准的类名格式来指定类名,<literal>比如:Foo$Bar</literal>。
+ </para>
+ <para>
+ 不可变类,<literal>mutable="false"</literal>不可以被应用程序更新或者删除。
+ 这可以让Hibernate做一些小小的性能优化。
+ </para>
+
+ <para>
+ 可选的<literal>proxy</literal>属性允许延迟加载类的持久化实例。
+ Hibernate开始会返回实现了这个命名接口的CGLIB代理。当代理的某个方法被实际调用的时候,
+ 真实的持久化对象才会被装载。参见下面的“用于延迟装载的代理”。
+ </para>
+
+ <para><emphasis>Implicit</emphasis> (隐式)的多态是指,如果查询时给出的是任何超类、该类实现的接口或者该类的
+ 名字,都会返回这个类的实例;如果查询中给出的是子类的名字,则会返回子类的实例。
+ <emphasis>Explicit</emphasis> (显式)的多态是指,只有在查询时给出明确的该类名字时才会返回这个类的实例;
+ 同时只有在这个<literal><class></literal>的定义中作为<literal><subclass></literal>
+ 或者<literal><joined-subclass></literal>出现的子类,才会可能返回。
+ 在大多数情况下,默认的<literal>polymorphism="implicit"</literal>都是合适的。
+ 显式的多态在有两个不同的类映射到同一个表的时候很有用。(允许一个“轻型”的类,只包含部分表字段)。
+ </para>
+
+ <para>
+ <literal>persister</literal>属性可以让你定制这个类使用的持久化策略。
+ 你可以指定你自己实现
+ <literal>org.hibernate.persister.EntityPersister</literal>的子类,你甚至可以完全从头开始编写一个
+ <literal>org.hibernate.persister.ClassPersister</literal>接口的实现,
+ 比如是用储存过程调用、序列化到文件或者LDAP数据库来实现。
+ 参阅<literal>org.hibernate.test.CustomPersister</literal>,这是一个简单的例子
+ (“持久化”到一个<literal>Hashtable</literal>)。
+ </para>
+
+ <para>
+ 请注意<literal>dynamic-update</literal>和<literal>dynamic-insert</literal>的设置并不会继承到子类,
+ 所以在<literal><subclass></literal>或者<literal><joined-subclass></literal>元素中可能
+ 需要再次设置。这些设置是否能够提高效率要视情形而定。请用你的智慧决定是否使用。
+ </para>
+
+ <para>
+ 使用<literal>select-before-update</literal>通常会降低性能。如果你重新连接一个脱管(detache)对象实例
+ 到一个<literal>Session</literal>中时,它可以防止数据库不必要的触发update。
+ 这就很有用了。
+ </para>
+
+ <para>
+ 如果你打开了<literal>dynamic-update</literal>,你可以选择几种乐观锁定的策略:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>version(版本检查)</literal> 检查version/timestamp字段
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>all(全部)</literal> 检查全部字段
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>dirty(脏检查)</literal>只检察修改过的字段
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>none(不检查)</literal>不使用乐观锁定
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ 我们<emphasis>非常</emphasis>强烈建议你在Hibernate中使用version/timestamp字段来进行乐观锁定。
+ 对性能来说,这是最好的选择,并且这也是唯一能够处理在session外进行操作的策略(例如:
+ 在使用<literal>Session.merge()</literal>的时候)。
+ </para>
+
+ <para>
+ 对Hibernate映射来说视图和表是没有区别的,这是因为它们在数据层都是透明的(
+ 注意:一些数据库不支持视图属性,特别是更新的时候)。有时你想使用视图,但却不能在数据库
+ 中创建它(例如:在遗留的schema中)。这样的话,你可以映射一个不可变的(immutable)并且是
+ 只读的实体到一个给定的SQL子查询表达式:
+ </para>
+
+ <programlisting><![CDATA[<class name="Summary">
+ <subselect>
+ select item.name, max(bid.amount), count(*)
+ from item
+ join bid on bid.item_id = item.id
+ group by item.name
+ </subselect>
+ <synchronize table="item"/>
+ <synchronize table="bid"/>
+ <id name="name"/>
+ ...
+</class>]]></programlisting>
+
+ <para>
+ 定义这个实体用到的表为同步(synchronize),确保自动刷新(auto-flush)正确执行,
+ 并且依赖原实体的查询不会返回过期数据。<literal><subselect></literal>在属性元素
+ 和一个嵌套映射元素中都可见。
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-id" revision="4">
+ <title>id</title>
+
+ <para>
+ 被映射的类<emphasis>必须</emphasis>定义对应数据库表主键字段。大多数类有一个JavaBeans风格的属性,
+ 为每一个实例包含唯一的标识。<literal><id></literal> 元素定义了该属性到数据库表主键字段的映射。
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="id1" coords="2 70"/>
+ <area id="id2" coords="3 70" />
+ <area id="id3" coords="4 70"/>
+ <area id="id4" coords="5 70" />
+ <area id="id5" coords="6 70" />
+ </areaspec>
+ <programlisting><![CDATA[<id
+ name="propertyName"
+ type="typename"
+ column="column_name"
+ unsaved-value="null|any|none|undefined|id_value"
+ access="field|property|ClassName"
+ node="element-name|@attribute-name|element/@attribute|.">
+
+ <generator class="generatorClass"/>
+</id>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="id1">
+ <para>
+ <literal>name</literal> (可选): 标识属性的名字。
+ </para>
+ </callout>
+ <callout arearefs="id2">
+ <para>
+ <literal>type</literal> (可选): 标识Hibernate类型的名字。
+ </para>
+ </callout>
+ <callout arearefs="id3">
+ <para>
+ <literal>column</literal> (可选 - 默认为属性名): 主键字段的名字。
+ </para>
+ </callout>
+ <callout arearefs="id4">
+ <para>
+ <literal>unsaved-value</literal> (可选 - 默认为一个切合实际(sensible)的值):
+ 一个特定的标识属性值,用来标志该实例是刚刚创建的,尚未保存。
+ 这可以把这种实例和从以前的session中装载过(可能又做过修改--译者注)
+ 但未再次持久化的实例区分开来。
+ </para>
+ </callout>
+ <callout arearefs="id5">
+ <para>
+ <literal>access</literal> (可选 - 默认为<literal>property</literal>):
+ Hibernate用来访问属性值的策略。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 如果 <literal>name</literal>属性不存在,会认为这个类没有标识属性。
+ </para>
+
+ <para>
+ <literal>unsaved-value</literal> 属性在Hibernate3中几乎不再需要。
+ </para>
+
+ <para>
+ 还有一个另外的<literal><composite-id></literal>定义可以访问旧式的多主键数据。
+ 我们强烈不建议使用这种方式。
+ </para>
+
+ <sect3 id="mapping-declaration-id-generator" revision="2">
+ <title>Generator</title>
+
+ <para>
+ 可选的<literal><generator></literal>子元素是一个Java类的名字,
+ 用来为该持久化类的实例生成唯一的标识。如果这个生成器实例需要某些配置值或者初始化参数,
+ 用<literal><param></literal>元素来传递。
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+ <generator class="org.hibernate.id.TableHiLoGenerator">
+ <param name="table">uid_table</param>
+ <param name="column">next_hi_value_column</param>
+ </generator>
+</id>]]></programlisting>
+
+ <para>
+
+ 所有的生成器都实现<literal>org.hibernate.id.IdentifierGenerator</literal>接口。
+ 这是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。当然,
+ Hibernate提供了很多内置的实现。下面是一些内置生成器的快捷名字:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>increment</literal></term>
+ <listitem>
+ <para>
+ 用于为<literal>long</literal>, <literal>short</literal>或者<literal>int</literal>类型生成
+ 唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。
+ <emphasis>在集群下不要使用。</emphasis>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>identity</literal></term>
+ <listitem>
+ <para>
+ 对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。
+ 返回的标识符是<literal>long</literal>, <literal>short</literal> 或者<literal>int</literal>类型的。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>sequence</literal></term>
+ <listitem>
+ <para>
+ 在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence),
+ 而在Interbase中使用生成器(generator)。返回的标识符是<literal>long</literal>,
+ <literal>short</literal>或者 <literal>int</literal>类型的。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>hilo</literal></term>
+ <listitem>
+ <para id="mapping-declaration-id-hilodescription" revision="1">
+ 使用一个高/低位算法高效的生成<literal>long</literal>, <literal>short</literal>
+ 或者 <literal>int</literal>类型的标识符。给定一个表和字段(默认分别是
+ <literal>hibernate_unique_key</literal> 和<literal>next_hi</literal>)作为高位值的来源。
+ 高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>seqhilo</literal></term>
+ <listitem>
+ <para>
+ 使用一个高/低位算法来高效的生成<literal>long</literal>, <literal>short</literal>
+ 或者 <literal>int</literal>类型的标识符,给定一个数据库序列(sequence)的名字。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>uuid</literal></term>
+ <listitem>
+ <para>
+ 用一个128-bit的UUID算法生成字符串类型的标识符,
+ 这在一个网络中是唯一的(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>guid</literal></term>
+ <listitem>
+ <para>
+ 在MS SQL Server 和 MySQL 中使用数据库生成的GUID字符串。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>native</literal></term>
+ <listitem>
+ <para>
+ 根据底层数据库的能力选择<literal>identity</literal>, <literal>sequence</literal>
+ 或者<literal>hilo</literal>中的一个。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>assigned</literal></term>
+ <listitem>
+ <para>
+ 让应用程序在<literal>save()</literal>之前为对象分配一个标示符。这是
+ <literal><generator></literal>元素没有指定时的默认生成策略。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>select</literal></term>
+ <listitem>
+ <para>
+ 通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>foreign</literal></term>
+ <listitem>
+ <para>
+ 使用另外一个相关联的对象的标识符。通常和<literal><one-to-one></literal>联合起来使用。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>sequence-identity</literal></term>
+ <listitem>
+ <para>
+ 一种特别的序列生成策略,使用数据库序列来生成实际值,但将它和JDBC3的getGeneratedKeys结合在一起,使得在插入语句执行的时候就返回生成的值。目前为止只有面向JDK 1.4的Oracle 10g驱动支持这一策略。注意,因为Oracle驱动程序的一个bug,这些插入语句的注释被关闭了。(原文:Note comments on these insert statements are disabled due to a bug in the Oracle drivers.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-hilo" revision="1">
+ <title>高/低位算法(Hi/Lo Algorithm)</title>
+ <para>
+ <literal>hilo</literal> 和 <literal>seqhilo</literal>生成器给出了两种hi/lo算法的实现,
+ 这是一种很令人满意的标识符生成算法。第一种实现需要一个“特殊”的数据库表来保存下一个可用的“hi”值。
+ 第二种实现使用一个Oracle风格的序列(在被支持的情况下)。
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+ <generator class="hilo">
+ <param name="table">hi_value</param>
+ <param name="column">next_value</param>
+ <param name="max_lo">100</param>
+ </generator>
+</id>]]></programlisting>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+ <generator class="seqhilo">
+ <param name="sequence">hi_value</param>
+ <param name="max_lo">100</param>
+ </generator>
+</id>]]></programlisting>
+
+ <para>
+ 很不幸,你在为Hibernate自行提供<literal>Connection</literal>时无法使用<literal>hilo</literal>。
+ 当Hibernate使用JTA获取应用服务器的数据源连接时,你必须正确地配置
+ <literal>hibernate.transaction.manager_lookup_class</literal>。
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-uuid">
+ <title>UUID算法(UUID Algorithm )</title>
+ <para>
+ UUID包含:IP地址,JVM的启动时间(精确到1/4秒),系统时间和一个计数器值(在JVM中唯一)。
+ 在Java代码中不可能获得MAC地址或者内存地址,所以这已经是我们在不使用JNI的前提下的能做的最好实现了。
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-sequences">
+ <title>标识字段和序列(Identity columns and Sequences)</title>
+ <para>
+ 对于内部支持标识字段的数据库(DB2,MySQL,Sybase,MS SQL),你可以使用<literal>identity</literal>关键字生成。
+ 对于内部支持序列的数据库(DB2,Oracle, PostgreSQL, Interbase, McKoi,SAP DB),
+ 你可以使用<literal>sequence</literal>风格的关键字生成。
+ 这两种方式对于插入一个新的对象都需要两次SQL查询。
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="person_id">
+ <generator class="sequence">
+ <param name="sequence">person_id_sequence</param>
+ </generator>
+</id>]]></programlisting>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="person_id" unsaved-value="0">
+ <generator class="identity"/>
+</id>]]></programlisting>
+ <para>
+ 对于跨平台开发,<literal>native</literal>策略会从<literal>identity</literal>,
+ <literal>sequence</literal> 和<literal>hilo</literal>中进行选择,选择哪一个,这取决于底层数据库的支持能力。
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-assigned">
+ <title>程序分配的标识符(Assigned Identifiers)</title>
+ <para>
+ 如果你需要应用程序分配一个标示符(而非Hibernate来生成),你可以使用<literal>assigned</literal>
+ 生成器。这种特殊的生成器会使用已经分配给对象的标识符属性的标识符值。
+ 这个生成器使用一个自然键(natural key,有商业意义的列-译注)作为主键,而不是使用一个代理键(
+ surrogate key,没有商业意义的列-译注)。这是没有指定<literal><generator></literal>元素时的默认行为
+ </para>
+
+ <para>
+ 当选择<literal>assigned</literal>生成器时,除非有一个version或timestamp属性,或者你定义了
+ <literal>Interceptor.isUnsaved()</literal>,否则需要让Hiberante使用
+ <literal>unsaved-value="undefined"</literal>,强制Hibernatet查询数据库来确定一个实例是瞬时的(transient)
+ 还是脱管的(detached)。
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-select">
+ <title>触发器实现的主键生成器(Primary keys assigned by triggers)</title>
+ <para>
+ 仅仅用于遗留的schema中 (Hibernate不能使用触发器生成DDL)。
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="person_id">
+ <generator class="select">
+ <param name="key">socialSecurityNumber</param>
+ </generator>
+</id>]]></programlisting>
+
+ <para>
+ 在上面的例子中,类定义了一个命名为<literal>socialSecurityNumber</literal>的唯一值属性,
+ 它是一个自然键(natural key),命名为<literal>person_id</literal>的代理键(surrogate key)
+ 的值由触发器生成。
+ </para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-compositeid" revision="3">
+ <title>composite-id</title>
+
+ <programlisting><![CDATA[<composite-id
+ name="propertyName"
+ class="ClassName"
+ mapped="true|false"
+ access="field|property|ClassName"
+ node="element-name|."
+ >
+
+ <key-property name="propertyName" type="typename" column="column_name"/>
+ <key-many-to-one name="propertyName class="ClassName" column="column_name"/>
+ ......
+</composite-id>]]></programlisting>
+
+ <para>
+ 如果表使用联合主键,你可以映射类的多个属性为标识符属性。
+ <literal><composite-id></literal>元素接受<literal><key-property></literal>
+ 属性映射和<literal><key-many-to-one></literal>属性映射作为子元素。
+ </para>
+
+ <programlisting><![CDATA[<composite-id>
+ <key-property name="medicareNumber"/>
+ <key-property name="dependent"/>
+</composite-id>]]></programlisting>
+
+ <para>
+ 你的持久化类<emphasis>必须</emphasis>重载<literal>equals()</literal>和
+ <literal>hashCode()</literal>方法,来实现组合的标识符的相等判断。
+ 实现<literal>Serializable</literal>接口也是必须的。
+ </para>
+
+ <para>
+ 不幸的是,这种组合关键字的方法意味着一个持久化类是它自己的标识。除了对象自己之外,
+ 没有什么方便的“把手”可用。你必须初始化持久化类的实例,填充它的标识符属性,再<literal>load()</literal>
+ 组合关键字关联的持久状态。我们把这种方法称为<emphasis>embedded(嵌入式)</emphasis>的组合标识符,在重要的应用中不鼓励使用这种用法。
+ </para>
+
+ <para>
+ 第二种方法我们称为<emphasis>mapped(映射式)</emphasis>组合标识符 (mapped composite identifier),<literal><composite-id></literal>元素中列出的标识属性不但在持久化类出现,还形成一个独立的标识符类。
+ </para>
+
+ <programlisting><![CDATA[<composite-id class="MedicareId" mapped="true">
+ <key-property name="medicareNumber"/>
+ <key-property name="dependent"/>
+</composite-id>]]></programlisting>
+
+ <para>
+ 在这个例子中,组合标识符类<literal>MedicareId</literal>和实体类都含有<literal>medicareNumber</literal>和<literal>dependent</literal>属性。标识符类必须重载<literal>equals()</literal>和<literal>hashCode()</literal>并且实现<literal>Serializable</literal>接口。这种方法的缺点是出现了明显的代码重复。
+ </para>
+
+ <para>
+ 下面列出的属性是用来指定一个映射式组合标识符的:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>mapped</literal> (可选, 默认为<literal>false</literal>):
+ 指明使用一个映射式组合标识符,其包含的属性映射同时在实体类和组合标识符类中出现。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>class</literal> (可选,但对映射式组合标识符必须指定):
+ 作为组合标识符类使用的类名.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 在<xref linkend="components-compositeid"/>一节中,我们会描述第三种方式,那就是把组合标识符实现为一个组件(component)类,这是更方便的方法。下面的属性仅对第三种方法有效:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>name</literal> (可选,但对这种方法而言必须): 包含此组件标识符的组件类型的名字 (参阅第9章).
+
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>access</literal> (可选 - 默认为<literal>property</literal>):
+ Hibernate应该使用的访问此属性值的策略
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>class</literal> (可选 - 默认会用反射来自动判定属性类型
+ ): 用来作为组合标识符的组件类的类名(参阅下一节)
+
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 第三种方式,被称为<emphasis>identifier component(标识符组件)</emphasis>是我们对几乎所有应用都推荐使用的方式。
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-discriminator" revision="3">
+ <title>鉴别器(discriminator)</title>
+
+ <para>
+ 在"一棵对象继承树对应一个表"的策略中,<literal><discriminator></literal>元素是必需的,
+ 它定义了表的鉴别器字段。鉴别器字段包含标志值,用于告知持久化层应该为某个特定的行创建哪一个子类的实例。
+ 如下这些受到限制的类型可以使用:
+ <literal>string</literal>, <literal>character</literal>, <literal>integer</literal>,
+ <literal>byte</literal>, <literal>short</literal>, <literal>boolean</literal>,
+ <literal>yes_no</literal>, <literal>true_false</literal>.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="discriminator1" coords="2 60"/>
+ <area id="discriminator2" coords="3 60" />
+ <area id="discriminator3" coords="4 60" />
+ <area id="discriminator4" coords="5 60" />
+ <area id="discriminator5" coords="6 60" />
+ </areaspec>
+ <programlisting><![CDATA[<discriminator
+ column="discriminator_column"
+ type="discriminator_type"
+ force="true|false"
+ insert="true|false"
+ formula="arbitrary sql expression"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="discriminator1">
+ <para>
+ <literal>column</literal> (可选 - 默认为 <literal>class</literal>) 鉴别器字段的名字
+ </para>
+ </callout>
+ <callout arearefs="discriminator2">
+ <para>
+ <literal>type</literal> (可选 - 默认为 <literal>string</literal>) 一个Hibernate字段类型的名字
+ </para>
+ </callout>
+ <callout arearefs="discriminator3">
+ <para>
+ <literal>force(强制)</literal> (可选 - 默认为 <literal>false</literal>)
+ "强制"Hibernate指定允许的鉴别器值,即使当取得的所有实例都是根类的。
+ </para>
+ </callout>
+ <callout arearefs="discriminator4">
+ <para>
+ <literal>insert</literal> (可选 - 默认为<literal>true</literal>)
+ 如果你的鉴别器字段也是映射为复合标识(composite identifier)的一部分,则需将
+ 这个值设为<literal>false</literal>。(告诉Hibernate在做SQL <literal>INSERT</literal>
+ 时不包含该列)
+ </para>
+ </callout>
+ <callout arearefs="discriminator5">
+ <para>
+ <literal>formula</literal> (可选)
+ 一个SQL表达式,在类型判断(判断是父类还是具体子类-译注)时执行。可用于基于内容的鉴别器。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 鉴别器字段的实际值是根据<literal><class></literal>和<literal><subclass></literal>元素中
+ 的<literal>discriminator-value</literal>属性得来的。
+ </para>
+
+ <para>
+ <literal>force</literal>属性仅仅在这种情况下有用的:表中包含没有被映射到持久化类的附加辨别器值。
+ 这种情况不会经常遇到。
+ </para>
+
+ <para>
+ 使用<literal>formula</literal>属性你可以定义一个SQL表达式,用来判断一个行数据的类型。
+ </para>
+
+ <programlisting><![CDATA[<discriminator
+ formula="case when CLASS_TYPE in ('a', 'b', 'c') then 0 else 1 end"
+ type="integer"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-version" revision="4">
+ <title>版本(version)(可选)</title>
+
+ <para>
+ <literal><version></literal>元素是可选的,表明表中包含附带版本信息的数据。
+ 这在你准备使用<emphasis> 长事务(long transactions)</emphasis>的时候特别有用。(见后)
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="version1" coords="2 70"/>
+ <area id="version2" coords="3 70"/>
+ <area id="version3" coords="4 70"/>
+ <area id="version4" coords="5 70"/>
+ <area id="version5" coords="6 70"/>
+ <area id="version6" coords="7 70"/>
+ <area id="version7" coords="8 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<version
+ column="version_column"
+ name="propertyName"
+ type="typename"
+ access="field|property|ClassName"
+ unsaved-value="null|negative|undefined"
+ generated="never|always"
+ insert="true|false"
+ node="element-name|@attribute-name|element/@attribute|."
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="version1">
+ <para>
+ <literal>column</literal> (可选 - 默认为属性名): 指定持有版本号的字段名。
+ </para>
+ </callout>
+ <callout arearefs="version2">
+ <para>
+ <literal>name</literal>: 持久化类的属性名。
+ </para>
+ </callout>
+ <callout arearefs="version3">
+ <para>
+ <literal>type</literal> (可选 - 默认是 <literal>integer</literal>): 版本号的类型。
+ </para>
+ </callout>
+ <callout arearefs="version4">
+ <para>
+ <literal>access</literal> (可选 - 默认是 <literal>property</literal>):
+ Hibernate用于访问属性值的策略。
+ </para>
+ </callout>
+ <callout arearefs="version5">
+ <para>
+ <literal>unsaved-value</literal> (可选 - 默认是<literal>undefined</literal>):
+ 用于标明某个实例时刚刚被实例化的(尚未保存)版本属性值,依靠这个值就可以把这种情况
+ 和已经在先前的session中保存或装载的脱管(detached)实例区分开来。
+ (<literal>undefined</literal>指明应被使用的标识属性值。)
+ </para>
+ </callout>
+ <callout arearefs="version6">
+ <para>
+ <literal>generated</literal> (可选 - 默认是 <literal>never</literal>):
+ 表明此版本属性值是否实际上是由数据库生成的。请参阅<xref linkend="mapping-generated">generated properties</xref>部分的讨论。
+ </para>
+ </callout>
+ <callout arearefs="version7">
+ <para>
+ <literal>insert</literal> (可选 - 默认是 <literal>true</literal>):
+ 表明此版本列应该包含在SQL插入语句中。只有当数据库字段有默认值<literal>0</literal>的时候,才可以设置为<literal>false</literal>。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 版本号必须是以下类型:<literal>long</literal>, <literal>integer</literal>,
+ <literal>short</literal>, <literal>timestamp</literal>或者<literal>calendar</literal>。
+ </para>
+
+ <para>
+ 一个脱管(detached)实例的version或timestamp属性不能为空(null),因为Hibernate不管
+ <literal>unsaved-value</literal>被指定为何种策略,它将任何属性为空的version或timestamp
+ 实例看作为瞬时(transient)实例。
+ <emphasis>避免Hibernate中的传递重附(transitive reattachment)问题的一个简单方法是
+ 定义一个不能为空的version或timestamp属性,特别是在人们使用程序分配的标识符(assigned identifiers)
+ 或复合主键时非常有用!</emphasis>
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-declaration-timestamp" revision="4">
+ <title>timestamp (可选)</title>
+
+ <para>
+ 可选的<literal><timestamp></literal>元素指明了表中包含时间戳数据。
+ 这用来作为版本的替代。时间戳本质上是一种对乐观锁定的一种不是特别安全的实现。当然,
+ 有时候应用程序可能在其他方面使用时间戳。
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="timestamp1" coords="2 70"/>
+ <area id="timestamp2" coords="3 70" />
+ <area id="timestamp3" coords="4 70" />
+ <area id="timestamp4" coords="5 70" />
+ <area id="timestamp5" coords="6 70" />
+ <area id="timestamp6" coords="7 70" />
+ </areaspec>
+ <programlisting><![CDATA[<timestamp
+ column="timestamp_column"
+ name="propertyName"
+ access="field|property|ClassName"
+ unsaved-value="null|undefined"
+ source="vm|db"
+ generated="never|always"
+ node="element-name|@attribute-name|element/@attribute|."
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="timestamp1">
+ <para>
+ <literal>column</literal> (可选 - 默认为属性名): 持有时间戳的字段名。
+ </para>
+ </callout>
+ <callout arearefs="timestamp2">
+ <para>
+ <literal>name</literal>: 在持久化类中的JavaBeans风格的属性名,
+ 其Java类型是 <literal>Date</literal> 或者 <literal>Timestamp</literal>的。
+ </para>
+ </callout>
+ <callout arearefs="timestamp3">
+ <para>
+ <literal>access</literal> (可选 - 默认是 <literal>property</literal>):
+ Hibernate用于访问属性值的策略。
+ </para>
+ </callout>
+ <callout arearefs="timestamp4">
+ <para>
+ <literal>unsaved-value</literal> (可选 - 默认是<literal>null</literal>):
+ 用于标明某个实例时刚刚被实例化的(尚未保存)版本属性值,依靠这个值就可以把这种情况和
+ 已经在先前的session中保存或装载的脱管(detached)实例区分开来。(<literal>undefined</literal>
+ 指明使用标识属性值进行这种判断。)
+ </para>
+ </callout>
+ <callout arearefs="timestamp5">
+ <para>
+ <literal>source</literal> (可选 - 默认是 <literal>vm</literal>):
+ Hibernate如何才能获取到时间戳的值呢?从数据库,还是当前JVM?从数据库获取会带来一些负担,因为Hibernate必须访问数据库来获得“下一个值”,但是在集群环境中会更安全些。还要注意,并不是所有的<literal>Dialect(方言)</literal>都支持获得数据库的当前时间戳的,而支持的数据库中又有一部分因为精度不足,用于锁定是不安全的(例如Oracle 8)。
+ </para>
+ </callout>
+ <callout arearefs="timestamp6">
+ <para>
+ <literal>generated</literal> (可选 - 默认是 <literal>never</literal>):
+ 指出时间戳值是否实际上是由数据库生成的.请参阅<xref linkend="mapping-generated">generated properties</xref>的讨论。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 注意,<literal><timestamp></literal> 和<literal><version type="timestamp"></literal>是等价的。并且<literal><timestamp source="db"></literal>和<literal><version type="dbtimestamp"></literal>是等价的。
+ </para>
+ </sect2>
+
+
+ <sect2 id="mapping-declaration-property" revision="4">
+ <title>property</title>
+
+ <para>
+ <literal><property></literal>元素为类定义了一个持久化的,JavaBean风格的属性。
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="property1" coords="2 70"/>
+ <area id="property2" coords="3 70"/>
+ <area id="property3" coords="4 70"/>
+ <areaset id="property4-5" coords="">
+ <area id="property4" coords='5 70'/>
+ <area id="property5" coords='6 70'/>
+ </areaset>
+ <area id="property6" coords="7 70"/>
+ <area id="property7" coords="8 70"/>
+ <area id="property8" coords="9 70"/>
+ <area id="property9" coords="10 70"/>
+ <area id="property10" coords="11 70"/>
+ <area id="property11" coords="12 70"/>
+ <area id="property12" coords="13 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<property
+ name="propertyName"
+ column="column_name"
+ type="typename"
+ update="true|false"
+ insert="true|false"
+ formula="arbitrary SQL expression"
+ access="field|property|ClassName"
+ lazy="true|false"
+ unique="true|false"
+ not-null="true|false"
+ optimistic-lock="true|false"
+ generated="never|insert|always"
+ node="element-name|@attribute-name|element/@attribute|."
+
+ index="index_name"
+ unique_key="unique_key_id"
+ length="L"
+ precision="P"
+ scale="S"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="property1">
+ <para>
+ <literal>name</literal>: 属性的名字,以小写字母开头。
+ </para>
+ </callout>
+ <callout arearefs="property2">
+ <para>
+ <literal>column</literal> (可选 - 默认为属性名字): 对应的数据库字段名。
+ 也可以通过嵌套的<literal><column></literal>元素指定。
+ </para>
+ </callout>
+ <callout arearefs="property3">
+ <para>
+ <literal>type</literal> (可选): 一个Hibernate类型的名字。
+ </para>
+ </callout>
+ <callout arearefs="property4-5">
+ <para>
+ <literal>update, insert</literal> (可选 - 默认为 <literal>true</literal>) :
+ 表明用于<literal>UPDATE</literal> 和/或 <literal>INSERT</literal>
+ 的SQL语句中是否包含这个被映射了的字段。这二者如果都设置为<literal>false</literal>
+ 则表明这是一个“外源性(derived)”的属性,它的值来源于映射到同一个(或多个)
+ 字段的某些其他属性,或者通过一个trigger(触发器)或其他程序生成。
+ </para>
+ </callout>
+ <callout arearefs="property6">
+ <para>
+ <literal>formula</literal> (可选): 一个SQL表达式,定义了这个<emphasis>计算
+ (computed)</emphasis> 属性的值。计算属性没有和它对应的数据库字段。
+ </para>
+ </callout>
+ <callout arearefs="property7">
+ <para>
+ <literal>access</literal> (可选 - 默认值为 <literal>property</literal>):
+ Hibernate用来访问属性值的策略。
+ </para>
+ </callout>
+ <callout arearefs="property8">
+ <para>
+ <literal>lazy</literal> (可选 - 默认为 <literal>false</literal>): 指定
+ 指定实例变量第一次被访问时,这个属性是否延迟抓取(fetched lazily)(
+ 需要运行时字节码增强)。
+ </para>
+ </callout>
+ <callout arearefs="property9">
+ <para>
+ <literal>unique</literal> (可选): 使用DDL为该字段添加唯一的约束。
+ 同样,允许它作为<literal>property-ref</literal>引用的目标。
+ </para>
+ </callout>
+ <callout arearefs="property10">
+ <para>
+ <literal>not-null</literal> (可选): 使用DDL为该字段添加可否为空(nullability)的约束。
+ </para>
+ </callout>
+ <callout arearefs="property11">
+ <para>
+ <literal>optimistic-lock</literal> (可选 - 默认为 <literal>true</literal>):
+ 指定这个属性在做更新时是否需要获得乐观锁定(optimistic lock)。
+ 换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。
+ </para>
+ </callout>
+ <callout arearefs="property12">
+ <para>
+ <literal>generated</literal> (可选 - 默认为 <literal>never</literal>):
+ 表明此属性值是否实际上是由数据库生成的。请参阅<xref linkend="mapping-generated">generated properties</xref>的讨论。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <emphasis>typename</emphasis>可以是如下几种:
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ Hibernate基本类型名(比如:<literal>integer, string, character,date, timestamp,
+ float, binary, serializable, object, blob</literal>)。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 一个Java类的名字,这个类属于一种默认基础类型
+ (比如: <literal>int, float,char, java.lang.String, java.util.Date, java.lang.Integer,
+ java.sql.Clob</literal>)。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 一个可以序列化的Java类的名字。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 一个自定义类型的类的名字。(比如: <literal>com.illflow.type.MyCustomType</literal>)。
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ 如果你没有指定类型,Hibernarte会使用反射来得到这个名字的属性,以此来猜测正确的Hibernate类型。
+ Hibernate会按照规则2,3,4的顺序对属性读取器(getter方法)的返回类进行解释。然而,这还不够。
+ 在某些情况下你仍然需要<literal>type</literal>属性。(比如,为了区别<literal>Hibernate.DATE</literal>
+ 和<literal>Hibernate.TIMESTAMP</literal>,或者为了指定一个自定义类型。)
+ </para>
+
+ <para>
+ <literal>access</literal>属性用来让你控制Hibernate如何在运行时访问属性。在默认情况下,
+ Hibernate会使用属性的get/set方法对(pair)。如果你指明<literal>access="field"</literal>,
+ Hibernate会忽略get/set方法对,直接使用反射来访问成员变量。你也可以指定你自己的策略,
+ 这就需要你自己实现<literal>org.hibernate.property.PropertyAccessor</literal>接口,
+ 再在access中设置你自定义策略类的名字。
+ </para>
+
+ <para>
+ 衍生属性(derive propertie)是一个特别强大的特征。这些属性应该定义为只读,属性值在装载时计算生成。
+ 你用一个SQL表达式生成计算的结果,它会在这个实例转载时翻译成一个SQL查询的<literal>SELECT</literal>
+ 子查询语句。
+ </para>
+
+ <programlisting><![CDATA[
+<property name="totalPrice"
+ formula="( SELECT SUM (li.quantity*p.price) FROM LineItem li, Product p
+ WHERE li.productId = p.productId
+ AND li.customerId = customerId
+ AND li.orderNumber = orderNumber )"/>]]></programlisting>
+
+ <para>
+ 注意,你可以使用实体自己的表,而不用为这个特别的列定义别名(
+ 上面例子中的<literal>customerId</literal>)。同时注意,如果你不喜欢使用属性,
+ 你可以使用嵌套的<literal><formula></literal>映射元素。
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-manytoone" revision="5">
+ <title>多对一(many-to-one)</title>
+
+ <para>
+ 通过<literal>many-to-one</literal>元素,可以定义一种常见的与另一个持久化类的关联。
+ 这种关系模型是多对一关联(实际上是一个对象引用-译注):这个表的一个外键引用目标表的
+ 主键字段。
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="manytoone1" coords="2 70"/>
+ <area id="manytoone2" coords="3 70"/>
+ <area id="manytoone3" coords="4 70"/>
+ <area id="manytoone4" coords="5 70"/>
+ <area id="manytoone5" coords="6 70"/>
+ <areaset id="manytoone6-7" coords="">
+ <area id="manytoone6" coords='7 70'/>
+ <area id="manytoone7" coords='8 70'/>
+ </areaset>
+ <area id="manytoone8" coords="9 70"/>
+ <area id="manytoone9" coords="10 70"/>
+ <area id="manytoone10" coords="11 70"/>
+ <area id="manytoone11" coords="12 70"/>
+ <area id="manytoone12" coords="13 70"/>
+ <area id="manytoone13" coords="14 70"/>
+ <area id="manytoone14" coords="15 70"/>
+ <area id="manytoone15" coords="16 70"/>
+ <area id="manytoone16" coords="17 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<many-to-one
+ name="propertyName"
+ column="column_name"
+ class="ClassName"
+ cascade="cascade_style"
+ fetch="join|select"
+ update="true|false"
+ insert="true|false"
+ property-ref="propertyNameFromAssociatedClass"
+ access="field|property|ClassName"
+ unique="true|false"
+ not-null="true|false"
+ optimistic-lock="true|false"
+ lazy="proxy|no-proxy|false"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ formula="arbitrary SQL expression"
+ node="element-name|@attribute-name|element/@attribute|."
+
+ embed-xml="true|false"
+ index="index_name"
+ unique_key="unique_key_id"
+ foreign-key="foreign_key_name"
+
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="manytoone1">
+ <para>
+ <literal>name</literal>: 属性名。
+ </para>
+ </callout>
+ <callout arearefs="manytoone2">
+ <para>
+ <literal>column</literal> (可选): 外间字段名。它也可以通过嵌套的
+ <literal><column></literal>元素指定。
+ </para>
+ </callout>
+ <callout arearefs="manytoone3">
+ <para>
+ <literal>class</literal> (可选 - 默认是通过反射得到属性类型): 关联的类的名字。
+ </para>
+ </callout>
+ <callout arearefs="manytoone4">
+ <para>
+ <literal>cascade(级联)</literal> (可选): 指明哪些操作会从父对象级联到关联的对象。
+ </para>
+ </callout>
+ <callout arearefs="manytoone5">
+ <para>
+ <literal>fetch</literal> (可选 - 默认为 <literal>select</literal>):
+ 在外连接抓取(outer-join fetching)和序列选择抓取(sequential select fetching)两者中选择其一。
+ </para>
+ </callout>
+ <callout arearefs="manytoone6">
+ <para>
+ <literal>update, insert</literal> (可选 - 默认为 <literal>true</literal>)
+ 指定对应的字段是否包含在用于<literal>UPDATE</literal> 和/或 <literal>INSERT</literal>
+ 的SQL语句中。如果二者都是<literal>false</literal>,则这是一个纯粹的
+ “外源性(derived)”关联,它的值是通过映射到同一个(或多个)字段的某些其他属性得到
+ 或者通过trigger(触发器)、或其他程序生成。
+ </para>
+ </callout>
+ <callout arearefs="manytoone7">
+ <para>
+ <literal>property-ref</literal>: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。
+ 如果没有指定,会使用对方关联类的主键。
+ </para>
+ </callout>
+ <callout arearefs="manytoone8">
+ <para>
+ <literal>access</literal> (可选 - 默认是 <literal>property</literal>):
+ Hibernate用来访问属性的策略。
+ </para>
+ </callout>
+ <callout arearefs="manytoone9">
+ <para>
+ <literal>unique</literal> (可选): 使用DDL为外键字段生成一个唯一约束。此外,
+ 这也可以用作<literal>property-ref</literal>的目标属性。这使关联同时具有
+ 一对一的效果。
+ </para>
+ </callout>
+ <callout arearefs="manytoone10">
+ <para>
+ <literal>not-null</literal> (可选): 使用DDL为外键字段生成一个非空约束。
+ </para>
+ </callout>
+ <callout arearefs="manytoone11">
+ <para>
+ <literal>optimistic-lock</literal> (可选 - 默认为 <literal>true</literal>):
+ 指定这个属性在做更新时是否需要获得乐观锁定(optimistic lock)。
+ 换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。
+ </para>
+ </callout>
+ <callout arearefs="manytoone12">
+ <para>
+ <literal>lazy</literal> (可选 - 默认为 <literal>proxy</literal>):
+ 默认情况下,单点关联是经过代理的。<literal>lazy="no-proxy"</literal>指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。
+ <literal>lazy="false"</literal>指定此关联总是被预先抓取。
+ </para>
+ </callout>
+ <callout arearefs="manytoone13">
+ <para>
+ <literal>not-found</literal> (可选 - 默认为 <literal>exception</literal>):
+ 指定外键引用的数据不存在时如何处理:
+ <literal>ignore</literal>会将行数据不存在视为一个空(null)关联。
+ </para>
+ </callout>
+ <callout arearefs="manytoone14">
+ <para>
+ <literal>entity-name</literal> (可选): 被关联的类的实体名。
+ </para>
+ </callout>
+ <callout arearefs="manytoone15">
+ <para>
+ <literal>formula</literal> (可选):
+ SQL表达式,用于定义<emphasis>computed(计算出的)</emphasis>外键值。
+ </para>
+ </callout>
+
+ </calloutlist>
+ </programlistingco>
+
+
+ <para>
+ <literal>cascade</literal>属性设置为除了<literal>none</literal>以外任何有意义的值,
+ 它将把特定的操作传递到关联对象中。这个值就代表着Hibernate基本操作的名称,
+ <literal>persist, merge, delete, save-update, evict, replicate, lock, refresh</literal>,
+ 以及特别的值<literal>delete-orphan</literal>和<literal>all</literal>,并且可以用逗号分隔符
+ 来组合这些操作,例如,<literal>cascade="persist,merge,evict"</literal>或
+ <literal>cascade="all,delete-orphan"</literal>。更全面的解释请参考<xref linkend="objectstate-transitive"/>. 注意,单值关联 (many-to-one 和
+ one-to-one 关联) 不支持删除孤儿(orphan delete,删除不再被引用的值).
+
+
+ </para>
+
+ <para>
+ 一个典型的简单<literal>many-to-one</literal>定义例子:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="product" class="Product" column="PRODUCT_ID"/>]]></programlisting>
+
+ <para>
+ <literal>property-ref</literal>属性只应该用来对付遗留下来的数据库系统,
+ 可能有外键指向对方关联表的是个非主键字段(但是应该是一个惟一关键字)的情况下。
+ 这是一种十分丑陋的关系模型。比如说,假设<literal>Product</literal>类有一个惟一的序列号,
+ 它并不是主键。(<literal>unique</literal>属性控制Hibernate通过SchemaExport工具进行的DDL生成。)
+ </para>
+
+
+ <programlisting><![CDATA[<property name="serialNumber" unique="true" type="string" column="SERIAL_NUMBER"/>]]></programlisting>
+
+ <para>
+ 那么关于<literal>OrderItem</literal> 的映射可能是:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="product" property-ref="serialNumber" column="PRODUCT_SERIAL_NUMBER"/>]]></programlisting>
+
+ <para>
+ 当然,我们决不鼓励这种用法。
+ </para>
+
+
+ <para>
+ 如果被引用的唯一主键由关联实体的多个属性组成,你应该在名称为<literal><properties></literal>的元素
+ 里面映射所有关联的属性。
+ </para>
+
+ <para>
+ 假若被引用的唯一主键是组件的属性,你可以指定属性路径:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="owner" property-ref="identity.ssn" column="OWNER_SSN"/>]]></programlisting>
+
+ </sect2>
+
+<sect2 id="mapping-declaration-onetoone" revision="3">
+ <title>一对一</title>
+
+ <para>
+ 持久化对象之间一对一的关联关系是通过<literal>one-to-one</literal>元素定义的。
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="onetoone1" coords="2 70"/>
+ <area id="onetoone2" coords="3 70"/>
+ <area id="onetoone3" coords="4 70"/>
+ <area id="onetoone4" coords="5 70"/>
+ <area id="onetoone5" coords="6 70"/>
+ <area id="onetoone6" coords="7 70"/>
+ <area id="onetoone7" coords="8 70"/>
+ <area id="onetoone8" coords="9 70"/>
+ <area id="onetoone9" coords="10 70"/>
+ <area id="onetoone10" coords="11 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<one-to-one
+ name="propertyName"
+ class="ClassName"
+ cascade="cascade_style"
+ constrained="true|false"
+ fetch="join|select"
+ property-ref="propertyNameFromAssociatedClass"
+ access="field|property|ClassName"
+ formula="any SQL expression"
+ lazy="proxy|no-proxy|false"
+ entity-name="EntityName"
+ node="element-name|@attribute-name|element/@attribute|."
+
+ embed-xml="true|false"
+ foreign-key="foreign_key_name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="onetoone1">
+ <para>
+ <literal>name</literal>: 属性的名字。
+ </para>
+ </callout>
+ <callout arearefs="onetoone2">
+ <para>
+ <literal>class</literal> (可选 - 默认是通过反射得到的属性类型):被关联的类的名字。
+ </para>
+ </callout>
+ <callout arearefs="onetoone3">
+ <para>
+ <literal>cascade(级联)</literal> (可选) 表明操作是否从父对象级联到被关联的对象。
+ </para>
+ </callout>
+ <callout arearefs="onetoone4">
+ <para>
+ <literal>constrained(约束)</literal> (可选) 表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。
+ 这个选项影响<literal>save()</literal>和<literal>delete()</literal>在级联执行时的先后顺序以及
+ 决定该关联能否被委托(也在schema export tool中被使用).
+ </para>
+ </callout>
+ <callout arearefs="onetoone5">
+ <para>
+ <literal>fetch</literal> (可选 - 默认设置为<literal>选择</literal>):
+ 在外连接抓取或者序列选择抓取选择其一.
+ </para>
+ </callout>
+ <callout arearefs="onetoone6">
+ <para>
+ <literal>property-ref</literal>: (可选) 指定关联类的属性名,这个属性将会和本类的主键相对应。如果没有指定,会使用对方关联类的主键。
+ </para>
+ </callout>
+ <callout arearefs="onetoone7">
+ <para>
+ <literal>access</literal> (可选 - 默认是 <literal>property</literal>): Hibernate用来访问属性的策略。
+ </para>
+ </callout>
+ <callout arearefs="onetoone8">
+ <para>
+ <literal>formula </literal> (可选):绝大多数一对一的关联都指向其实体的主键。在一些少见的情况中, 你可能会指向其他的一个或多个字段,或者是一个表达式,这些情况下,你可以用一个SQL公式来表示。 (可以在org.hibernate.test.onetooneformula找到例子)
+
+ </para>
+ </callout>
+ <callout arearefs="onetoone9">
+ <para>
+ <literal>lazy</literal> (可选 - 默认为 <literal>proxy</literal>):
+ 默认情况下,单点关联是经过代理的。<literal>lazy="no-proxy"</literal>指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。
+ <literal>lazy="false"</literal>指定此关联总是被预先抓取。<emphasis>注意,如果<literal>constrained="false"</literal>,
+ 不可能使用代理,Hibernate会采取预先抓取!</emphasis>
+ </para>
+ </callout>
+ <callout arearefs="onetoone10">
+ <para>
+ <literal>entity-name</literal> (可选): 被关联的类的实体名。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 有两种不同的一对一关联:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ 主键关联
+ </para></listitem>
+ <listitem>
+ <para>
+ 惟一外键关联
+ </para></listitem>
+ </itemizedlist>
+
+ <para>
+ 主键关联不需要额外的表字段;如果两行是通过这种一对一关系相关联的,那么这两行就共享同样的主关键字值。所以如果你希望两个对象通过主键一对一关联,你必须确认它们被赋予同样的标识值!
+ </para>
+
+ <para>
+ 比如说,对下面的<literal>Employee</literal>和<literal>Person</literal>进行主键一对一关联:
+ </para>
+
+
+ <programlisting><![CDATA[<one-to-one name="person" class="Person"/>]]></programlisting>
+ <programlisting><![CDATA[<one-to-one name="employee" class="Employee" constrained="true"/>]]></programlisting>
+
+ <para>
+ 现在我们必须确保PERSON和EMPLOYEE中相关的字段是相等的。我们使用一个被成为<literal>foreign</literal>的特殊的hibernate标识符生成策略:
+ </para>
+
+ <programlisting><![CDATA[<class name="person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="foreign">
+ <param name="property">employee</param>
+ </generator>
+ </id>
+ ...
+ <one-to-one name="employee"
+ class="Employee"
+ constrained="true"/>
+</class>]]></programlisting>
+
+ <para>
+ 一个刚刚保存的<literal>Person</literal>实例被赋予和该<literal>Person</literal>的<literal>employee</literal>属性所指向的<literal>Employee</literal>实例同样的关键字值。
+ </para>
+
+ <para>
+ 另一种方式是一个外键和一个惟一关键字对应,上面的<literal>Employee</literal>和<literal>Person</literal>的例子,如果使用这种关联方式,可以表达成:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="person" class="Person" column="PERSON_ID" unique="true"/>]]></programlisting>
+
+ <para>
+ 如果在<literal>Person</literal>的映射加入下面几句,这种关联就是双向的:
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="employee" class="Employee" property-ref="person"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-naturalid">
+ <title>自然ID(natural-id)</title>
+
+ <programlisting><![CDATA[<natural-id mutable="true|false"/>
+ <property ... />
+ <many-to-one ... />
+ ......
+</natural-id>]]></programlisting>
+
+ <para>
+ 我们建议使用代用键(键值不具备实际意义)作为主键,我们仍然应该尝试为所有的实体采用自然的键值作为(附加——译者注)标示。自然键(natural key)是单个或组合属性,他们必须唯一且非空。如果它还是不可变的那就更理想了。在<literal><natural-id></literal>元素中列出自然键的属性。Hibernate会帮你生成必须的唯一键值和非空约束,你的映射会更加的明显易懂(原文是self-documenting,自我注解)。
+ </para>
+
+ <para>
+ 我们强烈建议你实现<literal>equals()</literal> 和<literal>hashCode()</literal>方法,来比较实体的自然键属性。
+ </para>
+
+ <para>
+ 这一映射不是为了把自然键作为主键而准备的。
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>mutable</literal> (可选, 默认为<literal>false</literal>):
+ 默认情况下,自然标识属性被假定为不可变的(常量)。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+
+ <sect2 id="mapping-declaration-component" revision="2">
+ <title>组件(component), 动态组件(dynamic-component)</title>
+
+ <para>
+ <literal><component></literal>元素把子对象的一些元素与父类对应的表的一些字段映射起来。 然后组件可以定义它们自己的属性、组件或者集合。参见后面的“Components”一章。
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="component1" coords="2 45"/>
+ <area id="component2" coords="3 45"/>
+ <area id="component3" coords="4 45"/>
+ <area id="component4" coords="5 45"/>
+ <area id="component5" coords="6 45"/>
+ <area id="component6" coords="7 45"/>
+ <area id="component7" coords="8 45"/>
+ <area id="component8" coords="9 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<component
+ name="propertyName"
+ class="className"
+ insert="true|false"
+ update="true|false"
+ access="field|property|ClassName"
+ lazy="true|false"
+ optimistic-lock="true|false"
+ unique="true|false"
+ node="element-name|."
+>
+
+ <property ...../>
+ <many-to-one .... />
+ ........
+</component>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="component1">
+ <para>
+ <literal>name</literal>: 属性名
+ </para>
+
+ </callout>
+ <callout arearefs="component2">
+ <para>
+ <literal>class</literal> (可选 - 默认为通过反射得到的属性类型):组件(子)类的名字。
+ </para>
+ </callout>
+ <callout arearefs="component3">
+ <para>
+ <literal>insert</literal>: 被映射的字段是否出现在SQL的<literal>INSERT</literal>语句中?
+ </para>
+ </callout>
+ <callout arearefs="component4">
+ <para>
+ <literal>update</literal>: 被映射的字段是否出现在SQL的<literal>UPDATE</literal>语句中?
+ </para>
+ </callout>
+ <callout arearefs="component5">
+ <para>
+ <literal>access</literal> (可选 - 默认是 <literal>property</literal>): Hibernate用来访问属性的策略。
+ </para>
+ </callout>
+ <callout arearefs="component6">
+ <para>
+ <literal>lazy</literal> (可选 - 默认是 <literal>false</literal>): 表明此组件应在实例变量第一次被访问的时候延迟加载(需要编译时字节码装置器)
+ </para>
+ </callout>
+ <callout arearefs="component7">
+ <para>
+ <literal>optimistic-lock</literal> (可选 - 默认是 <literal>true</literal>):表明更新此组件是否需要获取乐观锁。换句话说,当这个属性变脏时,是否增加版本号(Version)
+ </para>
+ </callout>
+ <callout arearefs="component8">
+ <para>
+ <literal>unique</literal> (可选 - 默认是 <literal>false</literal>):表明组件映射的所有字段上都有唯一性约束
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 其<literal><property></literal>子标签为子类的一些属性与表字段之间建立映射。
+ </para>
+
+ <para>
+ <literal><component></literal>元素允许加入一个<literal><parent></literal>子元素,在组件类内部就可以有一个指向其容器的实体的反向引用。
+ </para>
+
+ <para>
+ <literal><dynamic-component></literal>元素允许把一个<literal>Map</literal>映射为组件,其属性名对应map的键值。
+ 参见<xref linkend="components-dynamic"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-properties" revision="2">
+ <title>properties</title>
+
+ <para>
+ <literal><properties></literal> 元素允许定义一个命名的逻辑分组(grouping)包含一个类中的多个属性。
+ 这个元素最重要的用处是允许多个属性的组合作为<literal>property-ref</literal>的目标(target)。
+ 这也是定义多字段唯一约束的一种方便途径。
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="properties1" coords="2 45"/>
+ <area id="properties2" coords="3 45"/>
+ <area id="properties3" coords="4 45"/>
+ <area id="properties4" coords="5 45"/>
+ <area id="properties5" coords="6 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<properties
+ name="logicalName"
+ insert="true|false"
+ update="true|false"
+ optimistic-lock="true|false"
+ unique="true|false"
+>
+
+ <property ...../>
+ <many-to-one .... />
+ ........
+</properties>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="properties1">
+ <para>
+ <literal>name</literal>: 分组的逻辑名称 -
+ <emphasis>不是</emphasis> 实际属性的名称.
+ </para>
+ </callout>
+ <callout arearefs="properties2">
+ <para>
+ <literal>insert</literal>: 被映射的字段是否出现在SQL的
+ <literal>INSERT</literal>语句中?
+ </para>
+ </callout>
+ <callout arearefs="properties3">
+ <para>
+ <literal>update</literal>: 被映射的字段是否出现在SQL的
+ <literal>UPDATE</literal>语句中?
+ </para>
+ </callout>
+ <callout arearefs="properties4">
+ <para>
+ <literal>optimistic-lock</literal> (可选 - 默认是 <literal>true</literal>):表明更新此组件是否需要获取乐观锁。换句话说,当这个属性变脏时,是否增加版本号(Version)
+ </para>
+ </callout>
+ <callout arearefs="properties5">
+ <para>
+ <literal>unique</literal> (可选 - 默认是 <literal>false</literal>):表明组件映射的所有字段上都有唯一性约束
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 例如,如果我们有如下的<literal><properties></literal>映射:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="personNumber"/>
+ ...
+ <properties name="name"
+ unique="true" update="false">
+ <property name="firstName"/>
+ <property name="initial"/>
+ <property name="lastName"/>
+ </properties>
+</class>]]></programlisting>
+
+ <para>
+ 然后,我们可能有一些遗留的数据关联,引用 <literal>Person</literal>表的这个唯一键,而不是主键。
+ </para>
+ <programlisting><![CDATA[<many-to-one name="person"
+ class="Person" property-ref="name">
+ <column name="firstName"/>
+ <column name="initial"/>
+ <column name="lastName"/>
+</many-to-one>]]></programlisting>
+
+ <para>
+ 我们并不推荐这样使用,除非在映射遗留数据的情况下。
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-subclass" revision="4">
+ <title>子类(subclass)</title>
+
+ <para>
+ 最后,多态持久化需要为父类的每个子类都进行定义。对于“每一棵类继承树对应一个表”的策略来说,就需要使用<literal><subclass></literal>定义。
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="subclass1" coords="2 55"/>
+ <area id="subclass2" coords="3 55"/>
+ <area id="subclass3" coords="4 55"/>
+ <area id="subclass4" coords="5 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<subclass
+ name="ClassName"
+ discriminator-value="discriminator_value"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ entity-name="EntityName"
+ node="element-name"
+ extends="SuperclassName">
+
+ <property .... />
+ .....
+</subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="subclass1">
+ <para>
+ <literal>name</literal>: 子类的全限定名。
+ </para>
+ </callout>
+ <callout arearefs="subclass2">
+ <para>
+ <literal>discriminator-value(辨别标志)</literal> (可选 - 默认为类名):一个用于区分每个独立的子类的值。
+ </para>
+ </callout>
+ <callout arearefs="subclass3">
+ <para>
+ <literal>proxy(代理)</literal> (可选): 指定一个类或者接口,在延迟装载时作为代理使用。
+ </para>
+ </callout>
+ <callout arearefs="subclass4">
+ <para>
+ <literal>lazy</literal> (可选, 默认是<literal>true</literal>): 设置为
+ <literal>lazy="false"</literal> 禁止使用延迟抓取
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 每个子类都应该定义它自己的持久化属性和子类。
+ <literal><version></literal> 和<literal><id></literal> 属性可以从根父类继承下来。在一棵继承树上的每个子类都必须定义一个唯一的<literal>discriminator-value</literal>。如果没有指定,就会使用Java类的全限定名。
+ </para>
+
+
+ <para>
+ 更多关于继承映射的信息, 参考 <xref linkend="inheritance"/>章节.
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-declaration-joinedsubclass" revision="3">
+ <title>连接的子类(joined-subclass)</title>
+
+ <para>
+ 此外,每个子类可能被映射到他自己的表中(每个子类一个表的策略)。被继承的状态通过和超类的表关联得到。我们使用<literal><joined-subclass></literal>元素。
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="joinedsubclass1" coords="2 45"/>
+ <area id="joinedsubclass2" coords="3 45"/>
+ <area id="joinedsubclass3" coords="4 45"/>
+ <area id="joinedsubclass4" coords="5 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<joined-subclass
+ name="ClassName"
+ table="tablename"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ schema="schema"
+ catalog="catalog"
+ extends="SuperclassName"
+ persister="ClassName"
+ subselect="SQL expression"
+ entity-name="EntityName"
+ node="element-name">
+
+ <key .... >
+
+ <property .... />
+ .....
+</joined-subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="joinedsubclass1">
+ <para>
+ <literal>name</literal>: 子类的全限定名。
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass2">
+ <para>
+ <literal>table</literal>: 子类的表名.
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass3">
+ <para>
+ <literal>proxy</literal> (可选): 指定一个类或者接口,在延迟装载时作为代理使用。
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass4">
+ <para>
+ <literal>lazy</literal> (可选, 默认是 <literal>true</literal>): 设置为
+ <literal>lazy="false"</literal> 禁止使用延迟装载。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 这种映射策略不需要指定辨别标志(discriminator)字段。但是,每一个子类都必须使用<literal><key></literal>元素指定一个表字段来持有对象的标识符。本章开始的映射可以被用如下方式重写:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class name="Cat" table="CATS">
+ <id name="id" column="uid" type="long">
+ <generator class="hilo"/>
+ </id>
+ <property name="birthdate" type="date"/>
+ <property name="color" not-null="true"/>
+ <property name="sex" not-null="true"/>
+ <property name="weight"/>
+ <many-to-one name="mate"/>
+ <set name="kittens">
+ <key column="MOTHER"/>
+ <one-to-many class="Cat"/>
+ </set>
+ <joined-subclass name="DomesticCat" table="DOMESTIC_CATS">
+ <key column="CAT"/>
+ <property name="name" type="string"/>
+ </joined-subclass>
+ </class>
+
+ <class name="eg.Dog">
+ <!-- mapping for Dog could go here -->
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 更多关于继承映射的信息,参考<xref linkend="inheritance"/>。
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-declaration-unionsubclass" revision="2">
+ <title>联合子类(union-subclass)</title>
+
+ <para>
+ 第三种选择是仅仅映射类继承树中具体类部分到表中(每个具体类一张表的策略)。其中,每张表定义了类的所有持久化状态,包括继承的状态。在 Hibernate 中,并不需要完全显式地映射这样的继承树。你可以简单地使用单独的<literal><class></literal>定义映射每个类。然而,如果你想使用多态关联(例如,一个对类继承树中超类的关联),你需要使用<literal><union-subclass></literal>映射。
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="unionsubclass1" coords="2 45"/>
+ <area id="unionsubclass2" coords="3 45"/>
+ <area id="unionsubclass3" coords="4 45"/>
+ <area id="unionsubclass4" coords="5 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<union-subclass
+ name="ClassName"
+ table="tablename"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ schema="schema"
+ catalog="catalog"
+ extends="SuperclassName"
+ abstract="true|false"
+ persister="ClassName"
+ subselect="SQL expression"
+ entity-name="EntityName"
+ node="element-name">
+
+ <property .... />
+ .....
+</union-subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="unionsubclass1">
+ <para>
+ <literal>name</literal>: 子类的全限定名。
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass2">
+ <para>
+ <literal>table</literal>: 子类的表名
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass3">
+ <para>
+ <literal>proxy</literal> (可选): 指定一个类或者接口,在延迟装载时作为代理使用。
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass4">
+ <para>
+ <literal>lazy</literal> (可选, 默认是 <literal>true</literal>): 设置为
+ <literal>lazy="false"</literal> 禁止使用延迟装载。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 这种映射策略不需要指定辨别标志(discriminator)字段。
+ </para>
+ <para>
+ 更多关于继承映射的信息,参考<xref linkend="inheritance"/>。
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-declaration-join" revision="3">
+ <title>连接(join)</title>
+
+ <para>
+ 使用 <literal><join></literal> 元素,假若在表之间存在一对一关联,可以将一个类的属性映射到多张表中。
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="join1" coords="2 50"/>
+ <area id="join2" coords="3 50"/>
+ <area id="join3" coords="4 50"/>
+ <area id="join4" coords="5 50"/>
+ <area id="join5" coords="6 50"/>
+ <area id="join6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<join
+ table="tablename"
+ schema="owner"
+ catalog="catalog"
+ fetch="join|select"
+ inverse="true|false"
+ optional="true|false">
+
+ <key ... />
+
+ <property ... />
+ ...
+</join>]]></programlisting>
+
+ <calloutlist>
+ <callout arearefs="join1">
+ <para>
+ <literal>table</literal>: 被连接表的名称。
+ </para>
+ </callout>
+ <callout arearefs="join2">
+ <para>
+ <literal>schema</literal> (可选):覆盖由根<literal><hibernate-mapping></literal>元素指定的模式名称。
+ </para>
+ </callout>
+ <callout arearefs="join3">
+ <para>
+ <literal>catalog</literal> (可选): 覆盖由根 <literal><hibernate-mapping></literal>元素指定的目录名称。
+ </para>
+ </callout>
+ <callout arearefs="join4">
+ <para>
+ <literal>fetch</literal> (可选 - 默认是 <literal>join</literal>):
+ 如果设置为默认值<literal>join</literal>, Hibernate 将使用一个内连接来得到这个类或其超类定义的<literal><join></literal>,而使用一个外连接来得到其子类定义的<literal><join></literal>。如果设置为<literal>select</literal>,则 Hibernate 将为子类定义的 <literal><join></literal>使用顺序选择。这仅在一行数据表示一个子类的对象的时候才会发生。对这个类和其超类定义的<literal><join></literal>,依然会使用内连接得到。
+ </para>
+ </callout>
+ <callout arearefs="join5">
+ <para>
+ <literal>inverse</literal> (可选 - 默认是 <literal>false</literal>):
+ 如果打开,Hibernate 不会插入或者更新此连接定义的属性。
+ </para>
+ </callout>
+ <callout arearefs="join6">
+ <para>
+ <literal>optional</literal> (可选 - 默认是 <literal>false</literal>):
+ 如果打开,Hibernate 只会在此连接定义的属性非空时插入一行数据,并且总是使用一个外连接来得到这些属性。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 例如,一个人(person)的地址(address)信息可以被映射到单独的表中(并保留所有属性的值类型语义):
+ </para>
+
+ <programlisting><![CDATA[<class name="Person"
+ table="PERSON">
+
+ <id name="id" column="PERSON_ID">...</id>
+
+ <join table="ADDRESS">
+ <key column="ADDRESS_ID"/>
+ <property name="address"/>
+ <property name="zip"/>
+ <property name="country"/>
+ </join>
+ ...]]></programlisting>
+
+ <para>
+ 此特性常常对遗留数据模型有用,我们推荐表个数比类个数少,以及细粒度的领域模型。然而,在单独的继承树上切换继承映射策略是有用的,后面会解释这点。
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-declaration-key">
+ <title>键(key)</title>
+
+ <para>
+ 我们目前已经见到过<literal><key></literal>元素多次了。 这个元素在父映射元素定义了对新表的连接,并且在被连接表中定义了一个外键引用原表的主键的情况下经常使用。
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="key1" coords="2 50"/>
+ <area id="key2" coords="3 50"/>
+ <area id="key3" coords="4 50"/>
+ <area id="key4" coords="5 50"/>
+ <area id="key5" coords="6 50"/>
+ <area id="key6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<key
+ column="columnname"
+ on-delete="noaction|cascade"
+ property-ref="propertyName"
+ not-null="true|false"
+ update="true|false"
+ unique="true|false"
+/>]]></programlisting>
+
+ <calloutlist>
+ <callout arearefs="key1">
+ <para>
+ <literal>column</literal> (可选): 外键字段的名称。也可以通过嵌套的 <literal><column></literal>指定。
+ </para>
+ </callout>
+ <callout arearefs="key2">
+ <para>
+ <literal>on-delete</literal> (可选, 默认是 <literal>noaction</literal>):
+ 表明外键关联是否打开数据库级别的级联删除。
+ </para>
+ </callout>
+ <callout arearefs="key3">
+ <para>
+ <literal>property-ref</literal> (可选): 表明外键引用的字段不是原表的主键(提供给遗留数据)。
+ </para>
+ </callout>
+ <callout arearefs="key4">
+ <para>
+ <literal>not-null</literal> (可选): 表明外键的字段不可为空(这意味着无论何时外键都是主键的一部分)。
+ </para>
+ </callout>
+ <callout arearefs="key5">
+ <para>
+ <literal>update</literal> (可选): 表明外键决不应该被更新(这意味着无论何时外键都是主键的一部分)。
+ </para>
+ </callout>
+ <callout arearefs="key6">
+ <para>
+ <literal>unique</literal> (可选): 表明外键应有唯一性约束 (这意味着无论何时外键都是主键的一部分)。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 对那些看重删除性能的系统,我们推荐所有的键都应该定义为<literal>on-delete="cascade"</literal>,这样 Hibernate 将使用数据库级的<literal>ON CASCADE DELETE</literal>约束,而不是多个<literal>DELETE</literal>语句。 注意,这个特性会绕过 Hibernate 通常对版本数据(versioned data)采用的乐观锁策略。
+ </para>
+ <para>
+ <literal>not-null</literal> 和 <literal>update</literal> 属性在映射单向一对多关联的时候有用。如果你映射一个单向一对多关联到非空的(non-nullable)外键,你<emphasis>必须</emphasis> 用<literal><key not-null="true"></literal>定义此键字段。
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-column" revision="4">
+ <title>字段和规则元素(column and formula elements)</title>
+ <para>
+ 任何接受<literal>column</literal>属性的映射元素都可以选择接受<literal><column></literal> 子元素。同样的,<literal>formula</literal>子元素也可以替换<literal><formula></literal>属性。
+ </para>
+ <programlisting><![CDATA[<column
+ name="column_name"
+ length="N"
+ precision="N"
+ scale="N"
+ not-null="true|false"
+ unique="true|false"
+ unique-key="multicolumn_unique_key_name"
+ index="index_name"
+ sql-type="sql_type_name"
+ check="SQL expression"
+ default="SQL expression"/>]]></programlisting>
+
+ <programlisting><![CDATA[<formula>SQL expression</formula>]]></programlisting>
+ <para>
+ <literal>column</literal> 和 <literal>formula</literal> 属性甚至可以在同一个属性或关联映射中被合并来表达,例如,一些奇异的连接条件。
+ </para>
+ <programlisting><![CDATA[<many-to-one name="homeAddress" class="Address"
+ insert="false" update="false">
+ <column name="person_id" not-null="true" length="10"/>
+ <formula>'MAILING'</formula>
+</many-to-one>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-import">
+ <title>引用(import)</title>
+
+ <para>
+ 假设你的应用程序有两个同样名字的持久化类,但是你不想在Hibernate查询中使用他们的全限定名。除了依赖<literal>auto-import="true"</literal>以外,类也可以被显式地“import(引用)”。你甚至可以引用没有被明确映射的类和接口。
+ </para>
+
+ <programlisting><![CDATA[<import class="java.lang.Object" rename="Universe"/>]]></programlisting>
+
+ <programlistingco>
+ <areaspec>
+ <area id="import1" coords="2 40"/>
+ <area id="import2" coords="3 40"/>
+ </areaspec>
+ <programlisting><![CDATA[<import
+ class="ClassName"
+ rename="ShortName"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="import1">
+ <para>
+ <literal>class</literal>: 任何Java类的全限定名。
+ </para>
+ </callout>
+ <callout arearefs="import2">
+ <para>
+ <literal>rename</literal> (可选 - 默认为类的全限定名):
+ 在查询语句中可以使用的名字。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ </sect2>
+
+ <sect2 id="mapping-types-anymapping" revision="2">
+ <title>any</title>
+ <para>
+ 这是属性映射的又一种类型。<literal><any></literal> 映射元素定义了一种从多个表到类的多态关联。这种类型的映射常常需要多于一个字段。第一个字段持有被关联实体的类型,其他的字段持有标识符。对这种类型的关联来说,不可能指定一个外键约束,所以这当然不是映射(多态)关联的通常的方式。你只应该在非常特殊的情况下使用它(比如,审计log,用户会话数据等等)。
+ </para>
+ <para>
+ <literal>meta-type</literal> 属性使得应用程序能指定一个将数据库字段的值映射到持久化类的自定义类型。这个持久化类包含有用<literal>id-type</literal>指定的标识符属性。
+ 你必须指定从meta-type的值到类名的映射。
+ </para>
+
+ <programlisting><![CDATA[<any name="being" id-type="long" meta-type="string">
+ <meta-value value="TBL_ANIMAL" class="Animal"/>
+ <meta-value value="TBL_HUMAN" class="Human"/>
+ <meta-value value="TBL_ALIEN" class="Alien"/>
+ <column name="table_name"/>
+ <column name="id"/>
+</any>]]></programlisting>
+
+ <programlistingco>
+ <areaspec>
+ <area id="any1" coords="2 50"/>
+ <area id="any2" coords="3 50"/>
+ <area id="any3" coords="4 50"/>
+ <area id="any4" coords="5 50"/>
+ <area id="any5" coords="6 50"/>
+ <area id="any6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<any
+ name="propertyName"
+ id-type="idtypename"
+ meta-type="metatypename"
+ cascade="cascade_style"
+ access="field|property|ClassName"
+ optimistic-lock="true|false"
+>
+ <meta-value ... />
+ <meta-value ... />
+ .....
+ <column .... />
+ <column .... />
+ .....
+</any>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="any1">
+ <para>
+ <literal>name</literal>: 属性名
+ </para>
+ </callout>
+ <callout arearefs="any2">
+ <para>
+ <literal>id-type</literal>: 标识符类型
+ </para>
+ </callout>
+ <callout arearefs="any3">
+ <para>
+ <literal>meta-type</literal> (可选 -默认是 <literal>string</literal>):
+ 允许辨别标志(discriminator)映射的任何类型
+ </para>
+ </callout>
+ <callout arearefs="any4">
+ <para>
+ <literal>cascade</literal> (可选 -默认是<literal>none</literal>):
+ 级联的类型
+ </para>
+ </callout>
+ <callout arearefs="any5">
+ <para>
+ <literal>access</literal> (可选 -默认是 <literal>property</literal>): Hibernate 用来访问属性值的策略。
+ </para>
+ </callout>
+ <callout arearefs="any6">
+ <para>
+ <literal>optimistic-lock</literal> (可选 -默认是 <literal>true</literal>): 表明更新此组件是否需要获取乐观锁。换句话说,当这个属性变脏时,是否增加版本号(Version)
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="mapping-types">
+ <title>Hibernate 的类型</title>
+ <sect2 id="mapping-types-entitiesvalues" revision="1">
+ <title>实体(Entities)和值(values)</title>
+
+ <para>
+ 为了理解很多与持久化服务相关的Java语言级对象的行为,我们需要把它们分为两类:
+ </para>
+
+ <para>
+ <emphasis>实体entity</emphasis> 独立于任何持有实体引用的对象。与通常的Java模型相比,不再被引用的对象会被当作垃圾收集掉。实体必须被显式的保存和删除(除非保存和删除是从父实体向子实体引发的<emphasis>级联</emphasis>)。这和ODMG模型中关于对象通过可触及保持持久性有一些不同——比较起来更加接近应用程序对象通常在一个大系统中的使用方法。实体支持循环引用和交叉引用,它们也可以加上版本信息。
+ </para>
+
+ <para>
+ 一个实体的持久状态包含指向其他实体和<emphasis>值</emphasis>类型实例的引用。值可以是原始类型,集合(不是集合中的对象),组件或者特定的不可变对象。与实体不同,值(特别是集合和组件)是通过可触及性来进行持久化和删除的。因为值对象(和原始类型数据)是随着包含他们的实体而被持久化和删除的,他们不能被独立的加上版本信息。值没有独立的标识,所以他们不能被两个实体或者集合共享。
+ </para>
+
+ <para>
+ 直到现在,我们都一直使用术语“持久类”(persistent class)来代表实体。我们仍然会这么做。 然而严格说来,不是所有的用户自定义的,带有持久化状态的类都是实体。<emphasis>组件</emphasis>就是用户自定义类,却是值语义的。<literal>java.lang.String</literal>类型的java属性也是值语义的。给了这个定义以后,我们可以说所有JDK提供的类型(类)都是值类型的语义,而用于自定义类型可能被映射为实体类型或值类型语义。采用哪种类型的语义取决于开发人员。在领域模型中,寻找实体类的一个好线索是共享引用指向这个类的单一实例,而组合或聚合通常被转化为值类型。
+ </para>
+
+ <para>
+ 我们会在本文档中重复碰到这两个概念。
+ </para>
+
+ <para>
+ 挑战在于将java类型系统(和开发者定义的实体和值类型)映射到 SQL/数据库类型系统。Hibernate提供了连接两个系统之间的桥梁:对于实体类型,我们使用<literal><class></literal>, <literal><subclass></literal> 等等。对于值类型,我们使用 <literal><property></literal>, <literal><component></literal> 及其他,通常跟随着<literal>type</literal>属性。这个属性的值是Hibernate 的<emphasis>映射类型</emphasis>的名字。Hibernate提供了许多现成的映射(标准的JDK值类型)。你也可以编写自己的映射类型并实现自定义的变换策略,随后我们会看到这点。
+ </para>
+ <para>
+ 所有的Hibernate内建类型,除了collections以外,都支持空(null)语义。
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-types-basictypes" revision="3">
+ <title>基本值类型</title>
+
+ <para>
+ 内建的 <emphasis>基本映射类型</emphasis>可以大致分为
+ <variablelist>
+ <varlistentry>
+ <term><literal>integer, long, short, float, double, character, byte,
+ boolean, yes_no, true_false</literal></term>
+ <listitem>
+ <para>
+ 这些类型都对应Java的原始类型或者其封装类,来符合(特定厂商的)SQL 字段类型。<literal>boolean, yes_no</literal> 和 <literal>true_false</literal>都是Java 中<literal>boolean</literal> 或者<literal>java.lang.Boolean</literal>的另外说法。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>string</literal></term>
+ <listitem>
+ <para>
+ 从<literal>java.lang.String</literal> 到
+ <literal>VARCHAR</literal> (或者 Oracle的 <literal>VARCHAR2</literal>)的映射。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>date, time, timestamp</literal></term>
+ <listitem>
+ <para>
+ 从<literal>java.util.Date</literal>和其子类到SQL类型<literal>DATE</literal>, <literal>TIME</literal> 和<literal>TIMESTAMP</literal> (或等价类型)的映射。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>calendar, calendar_date</literal></term>
+ <listitem>
+ <para>
+ 从<literal>java.util.Calendar</literal> 到SQL 类型<literal>TIMESTAMP</literal>和 <literal>DATE</literal>(或等价类型)的映射。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>big_decimal, big_integer</literal></term>
+ <listitem>
+ <para>
+ 从<literal>java.math.BigDecimal</literal>和<literal>java.math.BigInteger</literal>到<literal>NUMERIC</literal> (或者 Oracle 的<literal>NUMBER</literal>类型)的映射。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>locale, timezone, currency</literal></term>
+ <listitem>
+ <para>
+ 从<literal>java.util.Locale</literal>, <literal>java.util.TimeZone</literal> 和<literal>java.util.Currency</literal> 到<literal>VARCHAR</literal> (或者 Oracle 的<literal>VARCHAR2</literal>类型)的映射.
+ <literal>Locale</literal>和 <literal>Currency</literal> 的实例被映射为它们的ISO代码。<literal>TimeZone</literal>的实例被影射为它的<literal>ID</literal>。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>class</literal></term>
+ <listitem>
+ <para>
+ 从<literal>java.lang.Class</literal> 到
+ <literal>VARCHAR</literal> (或者 Oracle 的<literal>VARCHAR2</literal>类型)的映射。<literal>Class</literal>被映射为它的全限定名。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>binary</literal></term>
+ <listitem>
+ <para>
+ 把字节数组(byte arrays)映射为对应的 SQL二进制类型。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>text</literal></term>
+ <listitem>
+ <para>
+ 把长Java字符串映射为SQL的<literal>CLOB</literal>或者<literal>TEXT</literal>类型。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>serializable</literal></term>
+ <listitem>
+ <para>
+ 把可序列化的Java类型映射到对应的SQL二进制类型。你也可以为一个并非默认为基本类型的可序列化Java类或者接口指定Hibernate类型<literal>serializable</literal>。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>clob, blob</literal></term>
+ <listitem>
+ <para>
+ JDBC 类 <literal>java.sql.Clob</literal> 和 <literal>java.sql.Blob</literal>的映射。某些程序可能不适合使用这个类型,因为blob和clob对象可能在一个事务之外是无法重用的。(而且, 驱动程序对这种类型的支持充满着补丁和前后矛盾。)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>imm_date, imm_time, imm_timestamp, imm_calendar, imm_calendar_date,
+ imm_serializable, imm_binary</literal>
+ </term>
+ <listitem>
+ <para>
+ 一般来说,映射类型被假定为是可变的Java类型,只有对不可变Java类型,Hibernate会采取特定的优化措施,应用程序会把这些对象作为不可变对象处理。比如,你不应该对作为<literal>imm_timestamp</literal>映射的Date执行<literal>Date.setTime()</literal>。要改变属性的值,并且保存这一改变,应用程序必须对这一属性重新设置一个新的(不一样的)对象。
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+
+ <para>
+ 实体及其集合的唯一标识可以是除了<literal>binary</literal>、 <literal>blob</literal> 和 <literal>clob</literal>之外的任何基础类型。(联合标识也是允许的,后面会说到。)
+ </para>
+
+ <para>
+ 在<literal>org.hibernate.Hibernate</literal>中,定义了基础类型对应的<literal>Type</literal>常量。比如,<literal>Hibernate.STRING</literal>代表<literal>string</literal> 类型。
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-types-custom" revision="2">
+ <title>自定义值类型</title>
+
+ <para>
+ 开发者创建属于他们自己的值类型也是很容易的。比如说,你可能希望持久化<literal>java.lang.BigInteger</literal>类型的属性,持久化成为<literal>VARCHAR</literal>字段。Hibernate没有内置这样一种类型。自定义类型能够映射一个属性(或集合元素)到不止一个数据库表字段。比如说,你可能有这样的Java属性:<literal>getName()</literal>/<literal>setName()</literal>,这是<literal>java.lang.String</literal>类型的,对应的持久化到三个字段:<literal>FIRST_NAME</literal>, <literal>INITIAL</literal>, <literal>SURNAME</literal>。
+ </para>
+
+ <para>
+ 要实现一个自定义类型,可以实现<literal>org.hibernate.UserType</literal>或<literal>org.hibernate.CompositeUserType</literal>中的任一个,并且使用类型的Java全限定类名来定义属性。请查看<literal>org.hibernate.test.DoubleStringType</literal>这个例子,看看它是怎么做的。
+ </para>
+
+ <programlisting><![CDATA[<property name="twoStrings" type="org.hibernate.test.DoubleStringType">
+ <column name="first_string"/>
+ <column name="second_string"/>
+</property>]]></programlisting>
+
+ <para>
+ 注意使用<literal><column></literal>标签来把一个属性映射到多个字段的做法。
+ </para>
+
+ <para>
+ <literal>CompositeUserType</literal>, <literal>EnhancedUserType</literal>,
+ <literal>UserCollectionType</literal>, 和 <literal>UserVersionType</literal> 接口为更特殊的使用方式提供支持。
+ </para>
+ <para>
+ 你甚至可以在一个映射文件中提供参数给一个<literal>UserType</literal>。 为了这样做,你的<literal>UserType</literal>必须实现<literal>org.hibernate.usertype.ParameterizedType</literal>接口。为了给自定义类型提供参数,你可以在映射文件中使用<literal><type></literal>元素。
+ </para>
+ <programlisting><![CDATA[<property name="priority">
+ <type name="com.mycompany.usertypes.DefaultValueIntegerType">
+ <param name="default">0</param>
+ </type>
+</property>]]></programlisting>
+
+ <para>
+ 现在,<literal>UserType</literal> 可以从传入的<literal>Properties</literal>对象中得到<literal>default</literal> 参数的值。
+ </para>
+ <para>
+ 如果你非常频繁地使用某一<literal>UserType</literal>,可以为他定义一个简称。这可以通过使用 <literal><typedef></literal>元素来实现。Typedefs为一自定义类型赋予一个名称,并且如果此类型是参数化的,还可以包含一系列默认的参数值。
+ </para>
+ <programlisting><![CDATA[<typedef class="com.mycompany.usertypes.DefaultValueIntegerType" name="default_zero">
+ <param name="default">0</param>
+</typedef>]]></programlisting>
+
+ <programlisting><![CDATA[<property name="priority" type="default_zero"/>]]></programlisting>
+
+ <para>
+ 也可以根据具体案例通过属性映射中的类型参数覆盖在typedef中提供的参数。
+ </para>
+ <para>
+ 尽管 Hibernate 内建的丰富的类型和对组件的支持意味着你可能很少 <emphasis>需要</emphasis>使用自定义类型。不过,为那些在你的应用中经常出现的(非实体)类使用自定义类型也是一个好方法。例如,一个<literal>MonetaryAmount</literal>类使用<literal>CompositeUserType</literal>来映射是不错的选择,虽然他可以很容易地被映射成组件。这样做的动机之一是抽象。使用自定义类型,以后假若你改变表示金额的方法时,它可以保证映射文件不需要修改。
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="mapping-entityname">
+ <title>多次映射同一个类</title>
+ <para>
+ 对特定的持久化类,映射多次是允许的。这种情形下,你必须指定<emphasis>entity name</emphasis>来区别不同映射实体的对象实例。(默认情况下,实体名字和类名是相同的。)
+ Hibernate在操作持久化对象、编写查询条件,或者把关联映射到指定实体时,允许你指定这个entity name(实体名字)。
+ </para>
+
+ <programlisting><![CDATA[<class name="Contract" table="Contracts"
+ entity-name="CurrentContract">
+ ...
+ <set name="history" inverse="true"
+ order-by="effectiveEndDate desc">
+ <key column="currentContractId"/>
+ <one-to-many entity-name="HistoricalContract"/>
+ </set>
+</class>
+
+<class name="Contract" table="ContractHistory"
+ entity-name="HistoricalContract">
+ ...
+ <many-to-one name="currentContract"
+ column="currentContractId"
+ entity-name="CurrentContract"/>
+</class>]]></programlisting>
+
+ <para>
+ 注意这里关联是如何用<literal>entity-name</literal>来代替<literal>class</literal>的。
+ </para>
+
+ </sect1>
+
+ <sect1 id="mapping-quotedidentifiers">
+ <title>SQL中引号包围的标识符</title>
+ <para>
+ 你可通过在映射文档中使用反向引号(`)把表名或者字段名包围起来,以强制Hibernate在生成的SQL中把标识符用引号包围起来。Hibernate会使用相应的SQL<literal>Dialect</literal>(方言)来使用正确的引号风格(通常是双引号,但是在SQL Server中是括号,MySQL中是反向引号)。
+ </para>
+
+ <programlisting><![CDATA[<class name="LineItem" table="`Line Item`">
+ <id name="id" column="`Item Id`"/><generator class="assigned"/></id>
+ <property name="itemNumber" column="`Item #`"/>
+ ...
+</class>]]></programlisting>
+
+ </sect1>
+
+
+ <sect1 id="mapping-alternatives">
+ <title>其他元数据(Metadata)</title>
+
+ <para>
+ XML 并不适用于所有人, 因此有其他定义Hibernate O/R 映射元数据(metadata)的方法。
+ </para>
+
+ <sect2 id="mapping-xdoclet">
+ <title>使用 XDoclet 标记</title>
+
+ <para>
+ 很多Hibernate使用者更喜欢使用XDoclet<literal>@hibernate.tags</literal>将映射信息直接嵌入到源代码中。我们不会在本文档中涉及这个方法,因为严格说来,这属于XDoclet的一部分。然而,我们包含了如下使用XDoclet映射的<literal>Cat</literal>类的例子。
+ </para>
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+import java.util.Date;
+
+/**
+ * @hibernate.class
+ * table="CATS"
+ */
+public class Cat {
+ private Long id; // identifier
+ private Date birthdate;
+ private Cat mother;
+ private Set kittens
+ private Color color;
+ private char sex;
+ private float weight;
+
+ /*
+ * @hibernate.id
+ * generator-class="native"
+ * column="CAT_ID"
+ */
+ public Long getId() {
+ return id;
+ }
+ private void setId(Long id) {
+ this.id=id;
+ }
+
+ /**
+ * @hibernate.many-to-one
+ * column="PARENT_ID"
+ */
+ public Cat getMother() {
+ return mother;
+ }
+ void setMother(Cat mother) {
+ this.mother = mother;
+ }
+
+ /**
+ * @hibernate.property
+ * column="BIRTH_DATE"
+ */
+ public Date getBirthdate() {
+ return birthdate;
+ }
+ void setBirthdate(Date date) {
+ birthdate = date;
+ }
+ /**
+ * @hibernate.property
+ * column="WEIGHT"
+ */
+ public float getWeight() {
+ return weight;
+ }
+ void setWeight(float weight) {
+ this.weight = weight;
+ }
+
+ /**
+ * @hibernate.property
+ * column="COLOR"
+ * not-null="true"
+ */
+ public Color getColor() {
+ return color;
+ }
+ void setColor(Color color) {
+ this.color = color;
+ }
+ /**
+ * @hibernate.set
+ * inverse="true"
+ * order-by="BIRTH_DATE"
+ * @hibernate.collection-key
+ * column="PARENT_ID"
+ * @hibernate.collection-one-to-many
+ */
+ public Set getKittens() {
+ return kittens;
+ }
+ void setKittens(Set kittens) {
+ this.kittens = kittens;
+ }
+ // addKitten not needed by Hibernate
+ public void addKitten(Cat kitten) {
+ kittens.add(kitten);
+ }
+
+ /**
+ * @hibernate.property
+ * column="SEX"
+ * not-null="true"
+ * update="false"
+ */
+ public char getSex() {
+ return sex;
+ }
+ void setSex(char sex) {
+ this.sex=sex;
+ }
+}]]></programlisting>
+
+ <para>
+ 参考Hibernate网站更多的Xdoclet和Hibernate的例子
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-annotations" revision="2">
+ <title>使用 JDK 5.0 的注解(Annotation)</title>
+
+ <para>
+ JDK 5.0 在语言级别引入了 XDoclet 风格的标注,并且是类型安全的,在编译期进行检查。这一机制比XDoclet的注解更为强大,有更好的工具和IDE支持。例如, IntelliJ IDEA,支持JDK 5.0注解的自动完成和语法高亮 。EJB规范的新修订版(JSR-220)使用 JDK 5.0的注解作为entity beans的主要元数据(metadata)机制。Hibernate 3 实现了JSR-220 (the persistence API)的<literal>EntityManager</literal>,支持通过<emphasis>Hibernate Annotations</emphasis>包定义映射元数据。这个包作为单独的部分下载,支持EJB3 (JSR-220)和Hibernate3的元数据。
+ </para>
+ <para>
+ 这是一个被注解为EJB entity bean 的POJO类的例子
+ </para>
+ <programlisting><![CDATA[@Entity(access = AccessType.FIELD)
+public class Customer implements Serializable {
+
+ @Id;
+ Long id;
+
+ String firstName;
+ String lastName;
+ Date birthday;
+
+ @Transient
+ Integer age;
+
+ @Embedded
+ private Address homeAddress;
+
+ @OneToMany(cascade=CascadeType.ALL)
+ @JoinColumn(name="CUSTOMER_ID")
+ Set<Order> orders;
+
+ // Getter/setter and business methods
+}]]></programlisting>
+
+ <para>
+ 注意:对 JDK 5.0 注解 (和 JSR-220)支持的工作仍然在进行中,并未完成。更多细节请参阅Hibernate Annotations 模块。
+ </para>
+ </sect2>
+ </sect1>
+ <sect1 id="mapping-generated" revision="1">
+ <title>数据库生成属性(Generated Properties)</title>
+ <para>
+ Generated properties指的是其值由数据库生成的属性。一般来说,如果对象有任何属性由数据库生成值,Hibernate应用程序需要进行<literal>刷新(refresh)</literal>。但如果把属性标明为generated,就可以转由Hibernate来负责这个动作。实际上。对定义了generated properties的实体,每当Hibernate执行一条SQL INSERT或者UPDATE语句,会立刻执行一条select来获得生成的值。
+ </para>
+ <para>
+ 被标明为generated的属性还必须是 non-insertable和 non-updateable的。只有<xref linkend="mapping-declaration-version">versions</xref>,<xref linkend="mapping-declaration-timestamp">timestamps</xref>和<xref linkend="mapping-declaration-property">简单属性(simple properties)</xref>可以被标明为generated。
+ </para>
+ <para>
+ <literal>never</literal> (默认) 标明此属性值不是从数据库中生成。
+ </para>
+ <para>
+ <literal>insert</literal> - 标明此属性值在insert的时候生成,但是不会在随后的update时重新生成。比如说创建日期就归属于这类。注意虽然<xref linkend="mapping-declaration-version">version</xref>和<xref linkend="mapping-declaration-timestamp">timestamp</xref>属性可以被标注为generated,但是不适用这个选项...
+ </para>
+ <para>
+ <literal>always</literal> - 标明此属性值在insert和update时都会被生成。
+ </para>
+ </sect1>
+
+ <sect1 id="mapping-database-object">
+ <title>辅助数据库对象(Auxiliary Database Objects)</title>
+ <para>
+ Allows CREATE and DROP of arbitrary database objects, in conjunction with
+ Hibernate's schema evolution tools, to provide the ability to fully define
+ a user schema within the Hibernate mapping files. Although designed specifically
+ for creating and dropping things like triggers or stored procedures, really any
+ SQL command that can be run via a <literal>java.sql.Statement.execute()</literal>
+ method is valid here (ALTERs, INSERTS, etc). There are essentially two modes for
+ defining auxiliary database objects...
+ 帮助CREATE和DROP任意数据库对象,与Hibernate的schema交互工具组合起来,可以提供在Hibernate映射文件中完全定义用户schema的能力。虽然这是为创建和销毁trigger(触发器)或stored procedure(存储过程)等特别设计的,实际上任何可以在<literal>java.sql.Statement.execute()</literal>方法中执行的SQL命令都可以在此使用(比如ALTER, INSERT,等等)。本质上有两种模式来定义辅助数据库对象...
+ </para>
+ <para>
+ 第一种模式是在映射文件中显式声明CREATE和DROP命令:
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <create>CREATE TRIGGER my_trigger ...</create>
+ <drop>DROP TRIGGER my_trigger</drop>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ <para>
+ 第二种模式是提供一个类,这个类知道如何组织CREATE和DROP命令。这个特别类必须实现<literal>org.hibernate.mapping.AuxiliaryDatabaseObject</literal>接口。
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <definition class="MyTriggerDefinition"/>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ <para>
+ 还有,这些数据库对象可以特别指定为仅在特定的方言中才使用。
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <definition class="MyTriggerDefinition"/>
+ <dialect-scope name="org.hibernate.dialect.Oracle9Dialect"/>
+ <dialect-scope name="org.hibernate.dialect.OracleDialect"/>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/batch.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/batch.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/batch.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/batch.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,282 @@
+<chapter id="batch">
+ <title>批量处理(Batch processing)</title>
+ <para>
+ 使用Hibernate将 100 000 条记录插入到数据库的一个很自然的做法可能是这样的
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+for ( int i=0; i<100000; i++ ) {
+ Customer customer = new Customer(.....);
+ session.save(customer);
+}
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ 这段程序大概运行到 50 000 条记录左右会失败并抛出 <literal>内存溢出异常(OutOfMemoryException)</literal> 。
+ 这是因为 Hibernate 把所有新插入的 <literal>客户(Customer)</literal>实例在 session级别的缓存区进行了缓存的缘故。
+ </para>
+
+ <para>
+ 我们会在本章告诉你如何避免此类问题。首先,如果你要执行批量处理并且想要达到一个理想的性能,
+ 那么使用JDBC的批量(batching)功能是至关重要。将JDBC的批量抓取数量(batch size)参数设置到一个合适值
+ (比如,10-50之间):
+ </para>
+
+<programlisting><![CDATA[hibernate.jdbc.batch_size 20]]></programlisting>
+
+ <para id="disablebatching" revision="1">
+ 注意,假若你使用了<literal>identiy</literal>标识符生成器,Hibernate在JDBC级别透明的关闭插入语句的批量执行。
+ </para>
+
+ <para>
+ 你也可能想在执行批量处理时关闭二级缓存:
+ </para>
+
+<programlisting><![CDATA[hibernate.cache.use_second_level_cache false]]></programlisting>
+ <para>
+ 但是,这不是绝对必须的,因为我们可以显式设置<literal>CacheMode</literal>来关闭与二级缓存的交互。
+ </para>
+
+
+ <sect1 id="batch-inserts">
+ <title>批量插入(Batch inserts)</title>
+
+ <para>
+ 如果要将很多对象持久化,你必须通过经常的调用 <literal>flush()</literal> 以及稍后调用
+ <literal>clear()</literal> 来控制第一级缓存的大小。
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+for ( int i=0; i<100000; i++ ) {
+ Customer customer = new Customer(.....);
+ session.save(customer);
+ if ( i % 20 == 0 ) { //20, same as the JDBC batch size //20,与JDBC批量设置相同
+ //flush a batch of inserts and release memory:
+ //将本批插入的对象立即写入数据库并释放内存
+ session.flush();
+ session.clear();
+ }
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="batch-update" >
+ <title>批量更新(Batch updates)</title>
+
+ <para>
+ 此方法同样适用于检索和更新数据。此外,在进行会返回很多行数据的查询时,
+ 你需要使用 <literal>scroll()</literal> 方法以便充分利用服务器端游标所带来的好处。
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+ScrollableResults customers = session.getNamedQuery("GetCustomers")
+ .setCacheMode(CacheMode.IGNORE)
+ .scroll(ScrollMode.FORWARD_ONLY);
+int count=0;
+while ( customers.next() ) {
+ Customer customer = (Customer) customers.get(0);
+ customer.updateStuff(...);
+ if ( ++count % 20 == 0 ) {
+ //flush a batch of updates and release memory:
+ session.flush();
+ session.clear();
+ }
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="batch-statelesssession">
+ <title>StatelessSession (无状态session)接口</title>
+ <para>
+ 作为选择,Hibernate提供了基于命令的API,可以用detached object的形式把数据以流的方法加入到数据库,或从数据库输出。<literal>StatelessSession</literal>没有持久化上下文,也不提供多少高层的生命周期语义。特别是,无状态session不实现第一级cache,也不和第二级缓存,或者查询缓存交互。它不实现事务化写,也不实现脏数据检查。用stateless session进行的操作甚至不级联到关联实例。stateless session忽略集合类(Collections)。通过stateless session进行的操作不触发Hibernate的事件模型和拦截器。无状态session对数据的混淆现象免疫,因为它没有第一级缓存。无状态session是低层的抽象,和低层JDBC相当接近。
+ </para>
+
+<programlisting><![CDATA[StatelessSession session = sessionFactory.openStatelessSession();
+Transaction tx = session.beginTransaction();
+
+ScrollableResults customers = session.getNamedQuery("GetCustomers")
+ .scroll(ScrollMode.FORWARD_ONLY);
+while ( customers.next() ) {
+ Customer customer = (Customer) customers.get(0);
+ customer.updateStuff(...);
+ session.update(customer);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ 注意在上面的例子中,查询返回的<literal>Customer</literal>实例立即被脱管(detach)。它们与任何持久化上下文都没有关系。
+ </para>
+
+ <para>
+ <literal>StatelessSession</literal> 接口定义的<literal>insert(), update()</literal> 和 <literal>delete()</literal>操作是直接的数据库行级别操作,其结果是立刻执行一条<literal>INSERT, UPDATE</literal> 或 <literal>DELETE</literal> 语句。因此,它们的语义和<literal>Session</literal> 接口定义的<literal>save(), saveOrUpdate()</literal> 和<literal>delete()</literal> 操作有很大的不同。
+ </para>
+
+ </sect1>
+
+ <sect1 id="batch-direct" revision="3">
+ <title>DML(数据操作语言)风格的操作(DML-style operations)</title>
+
+ <para>
+ hence manipulating (using the SQL <literal>Data Manipulation Language</literal>
+ (DML) statements: <literal>INSERT</literal>, <literal>UPDATE</literal>, <literal>DELETE</literal>)
+ data directly in the database will not affect in-memory state. However, Hibernate provides methods
+ for bulk SQL-style DML statement execution which are performed through the
+ Hibernate Query Language (<xref linkend="queryhql">HQL</xref>).
+
+
+ 就像已经讨论的那样,自动和透明的 对象/关系 映射(object/relational mapping)关注于管理对象的状态。
+ 这就意味着对象的状态存在于内存,因此直接操作 (使用 SQL <literal>Data Manipulation Language</literal>(DML,数据操作语言)语句 :<literal>INSERT</literal> ,<literal>UPDATE</literal> 和
+ <literal>DELETE</literal>) 数据库中的数据将不会影响内存中的对象状态和对象数据。
+ 不过,Hibernate提供通过Hibernate查询语言(<xref linkend="queryhql">HQL</xref>)来执行大批
+ 量SQL风格的DML语句的方法。
+ </para>
+
+ <para>
+ <literal>UPDATE</literal> 和 <literal>DELETE</literal>语句的语法为:
+ <literal>( UPDATE | DELETE ) FROM? EntityName (WHERE where_conditions)?</literal>
+ 有几点说明:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 在FROM子句(from-clause)中,FROM关键字是可选的
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 在FROM子句(from-clause)中只能有一个实体名,它可以是别名。如果实体名是别名,那么任何被引用的属性都必须加上此别名的前缀;如果不是别名,那么任何有前缀的属性引用都是非法的。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 不能在大批量HQL语句中使用<xref linkend="queryhql-joins-forms">连接(join)</xref>(显式或者隐式的都不行)。不过在WHERE子句中可以使用子查询。可以在where子句中使用子查询,子查询本身可以包含join。
+
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 整个WHERE子句是可选的。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 举个例子,使用<literal>Query.executeUpdate()</literal>方法执行一个HQL
+ <literal>UPDATE</literal>语句(:
+ (方法命名是来源于JDBC's <literal>PreparedStatement.executeUpdate()</literal>):
+ </para>
+
+ <programlisting><![CDATA[Session session = sessionFactory.openSession();
+ Transaction tx = session.beginTransaction();
+
+ String hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName";
+ // or String hqlUpdate = "update Customer set name = :newName where name = :oldName";
+ int updatedEntities = s.createQuery( hqlUpdate )
+ .setString( "newName", newName )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+ tx.commit();
+ session.close();]]></programlisting>
+
+ <para>
+ HQL <literal>UPDATE</literal>语句,默认不会影响更新实体的<xref linkend="mapping-declaration-version">version</xref>或者<xref linkend="mapping-declaration-timestamp">timestamp</xref>属性值。这和EJB3规范是一致的。但是,通过使用<literal>versioned update</literal>,你可以强制Hibernate正确的重置<literal>version</literal>或者<literal>timestamp</literal>属性值。这通过在<literal>UPDATE</literal>关键字后面增加<literal>VERSIONED</literal>关键字来实现的。
+ </para>
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+String hqlVersionedUpdate = "update versioned Customer set name = :newName where name = :oldName";
+int updatedEntities = s.createQuery( hqlUpdate )
+ .setString( "newName", newName )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ 注意,自定义的版本类型(<literal>org.hibernate.usertype.UserVersionType</literal>)不允许和<literal>update versioned</literal>语句联用。
+ </para>
+
+ <para>
+ 执行一个HQL <literal>DELETE</literal>,同样使用 <literal>Query.executeUpdate()</literal> 方法:
+ </para>
+
+ <programlisting><![CDATA[Session session = sessionFactory.openSession();
+ Transaction tx = session.beginTransaction();
+
+ String hqlDelete = "delete Customer c where c.name = :oldName";
+ // or String hqlDelete = "delete Customer where name = :oldName";
+ int deletedEntities = s.createQuery( hqlDelete )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+ tx.commit();
+ session.close();]]></programlisting>
+
+ <para>
+ 由<literal>Query.executeUpdate()</literal>方法返回的<literal>整型</literal>值表明了受此操作影响的记录数量。
+ 注意这个数值可能与数据库中被(最后一条SQL语句)影响了的“行”数有关,也可能没有。一个大批量HQL操作可能导致多条实际的SQL语句被执行,
+ 举个例子,对joined-subclass映射方式的类进行的此类操作。这个返回值代表了实际被语句影响了的记录数量。在那个joined-subclass的例子中,
+ 对一个子类的删除实际上可能不仅仅会删除子类映射到的表而且会影响“根”表,还有可能影响与之有继承关系的joined-subclass映射方式的子类的表。
+ </para>
+
+ <para>
+ <literal>INSERT</literal>语句的伪码是:
+ <literal>INSERT INTO EntityName properties_list select_statement</literal>.
+ 要注意的是:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 只支持INSERT INTO ... SELECT ...形式,不支持INSERT INTO ... VALUES ...形式.
+ </para>
+ <para>
+ properties_list和SQL <literal>INSERT</literal>语句中的<literal>字段定义(column speficiation)</literal>类似。对参与继承树映射的实体而言,只有直接定义在给定的类级别的属性才能直接在properties_list中使用。超类的属性不被支持;子类的属性无意义。换句话说,<literal>INSERT</literal>天生不支持多态。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ select_statement可以是任何合法的HQL选择查询,不过要保证返回类型必须和要插入的类型完全匹配。目前,这一检查是在查询编译的时候进行的,而不是把它交给数据库。注意,在Hibernate<literal>Type</literal>间如果只是<emphasis>等价(equivalent)</emphasis>而非<emphasis>相等(equal)</emphasis>,会导致问题。定义为<literal>org.hibernate.type.DateType</literal>和<literal>org.hibernate.type.TimestampType</literal>的两个属性可能会产生类型不匹配错误,虽然数据库级可能不加区分或者可以处理这种转换。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 对id属性来说,insert语句给你两个选择。你可以明确地在properties_list表中指定id属性(这样它的值是从对应的select表达式中获得),或者在properties_list中省略它(此时使用生成指)。后一种选择只有当使用在数据库中生成值的id产生器时才能使用;如果是“内存”中计算的类型生成器,在解析时会抛出一个异常。注意,为了说明这一问题,数据库产生值的生成器是<literal>org.hibernate.id.SequenceGenerator</literal>(和它的子类),以及任何<literal>org.hibernate.id.PostInsertIdentifierGenerator</literal>接口的实现。这儿最值得注意的意外是<literal>org.hibernate.id.TableHiLoGenerator</literal>,它不能在此使用,因为它没有得到其值的途径。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 对映射为<literal>version</literal> 或 <literal>timestamp</literal>的属性来说,insert语句也给你两个选择,你可以在properties_list表中指定(此时其值从对应的select表达式中获得),或者在properties_list中省略它(此时,使用在<literal>org.hibernate.type.VersionType</literal> 中定义的<literal>seed value(种子值)</literal>)。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 执行HQL <literal>INSERT</literal>语句的例子如下:
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlInsert = "insert into DelinquentAccount (id, name) select c.id, c.name from Customer c where ...";
+int createdEntities = s.createQuery( hqlInsert )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/best_practices.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/best_practices.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/best_practices.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/best_practices.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,175 @@
+<chapter id="best-practices" revision="2">
+ <title>最佳实践(Best Practices)</title>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>设计细颗粒度的持久类并且使用<literal><component></literal>来实现映射。</term>
+ <listitem>
+ <para>
+ 使用一个<literal>Address</literal>持久类来封装 <literal>street</literal>,
+ <literal>suburb</literal>, <literal>state</literal>, <literal>postcode</literal>.
+ 这将有利于代码重用和简化代码重构(refactoring)的工作。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>对持久类声明标识符属性( identifier properties)。</term>
+ <listitem>
+ <para>
+ Hibernate中标识符属性是可选的,不过有很多原因来说明你应该使用标识符属性。我们建议标识符应该是“人造”的(自动生成,不涉及业务含义)。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>使用自然键(natural keys)标识</term>
+ <listitem>
+ <para>
+ 对所有的实体都标识出自然键,用<literal><natural-id></literal>进行映射。实现<literal>equals()</literal>和<literal>hashCode()</literal>,在其中用组成自然键的属性进行比较。
+ </para>
+ </listitem>
+ Y00008051221000980 2.7,89,100万
+ </varlistentry>
+
+ <varlistentry>
+ <term>为每个持久类写一个映射文件</term>
+ <listitem>
+ <para>
+ 不要把所有的持久类映射都写到一个大文件中。把 <literal>com.eg.Foo</literal> 映射到<literal>com/eg/Foo.hbm.xml</literal>中, 在团队开发环境中,这一点显得特别有意义。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>把映射文件作为资源加载</term>
+ <listitem>
+ <para>
+ 把映射文件和他们的映射类放在一起进行部署。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>考虑把查询字符串放在程序外面</term>
+ <listitem>
+ <para>
+ 如果你的查询中调用了非ANSI标准的SQL函数,那么这条实践经验对你适用。把查询字符串放在映射文件中可以让程序具有更好的可移植性。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>使用绑定变量</term>
+ <listitem>
+ <para>
+ 就像在JDBC编程中一样,应该总是用占位符"?"来替换非常量值,不要在查询中用字符串值来构造非常量值!更好的办法是在查询中使用命名参数。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>不要自己来管理JDBC connections</term>
+ <listitem>
+ <para>
+ Hibernate允许应用程序自己来管理JDBC connections,但是应该作为最后没有办法的办法。如果你不能使用Hibernate内建的connections providers,那么考虑实现自己来实现<literal>org.hibernate.connection.ConnectionProvider</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>考虑使用用户自定义类型(custom type)</term>
+ <listitem>
+ <para>
+ 假设你有一个Java类型,来自某些类库,需要被持久化,但是该类没有提供映射操作需要的存取方法。那么你应该考虑实现<literal>org.hibernate.UserType</literal>接口。这种办法使程序代码写起来更加自如,不再需要考虑类与Hibernate type之间的相互转换。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>在性能瓶颈的地方使用硬编码的JDBC</term>
+ <listitem>
+ <para>
+ In performance-critical areas of the system, some kinds of operations might benefit from
+ direct JDBC. But please, wait until you <emphasis>know</emphasis> something is a bottleneck.
+ And don't assume that direct JDBC is necessarily faster. If you need to use direct JDBC, it might
+ be worth opening a Hibernate <literal>Session</literal> and using that JDBC connection. That
+ way you can still use the same transaction strategy and underlying connection provider.
+
+ 在系统中对性能要求很严格的一些部分,某些操作也许直接使用JDBC会更好。但是请先<emphasis>确认</emphasis>这的确是一个瓶颈,并且不要想当然认为JDBC一定会更快。如果确实需要直接使用JDBC,那么最好打开一个
+Hibernate <literal>Session</literal> 然后从 <literal>Session</literal>获得connection,按照这种办法你仍然可以使用同样的transaction策略和底层的connection provider。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>理解<literal>Session</literal>清洗( flushing)</term>
+ <listitem>
+ <para>
+ Session会不时的向数据库同步持久化状态,如果这种操作进行的过于频繁,性能会受到一定的影响。有时候你可以通过禁止自动flushing,尽量最小化非必要的flushing操作,或者更进一步,在一个特定的transaction中改变查询和其它操作的顺序。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>在三层结构中,考虑使用托管对象(detached object)</term>
+ <listitem>
+ <para>
+ 当使用一个servlet / session bean 类型的架构的时候, 你可以把已加载的持久对象在session bean层和servlet / JSP 层之间来回传递。使用新的session来为每个请求服务,使用 <literal>Session.merge()</literal> 或者<literal>Session.saveOrUpdate()</literal>来与数据库同步。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>在两层结构中,考虑使用长持久上下文(long persistence contexts).</term>
+ <listitem>
+ <para>
+ 为了得到最佳的可伸缩性,数据库事务(Database Transaction)应该尽可能的短。但是,程序常常需要实现长时间运行的<emphasis>“应用程序事务(Application Transaction)”</emphasis>,包含一个从用户的观点来看的原子操作。这个应用程序事务可能跨越多次从用户请求到得到反馈的循环。用脱管对象(与session脱离的对象)来实现应用程序事务是常见的。或者,尤其在两层结构中,把Hibernate Session从JDBC连接中脱离开,下次需要用的时候再连接上。绝不要把一个Session用在多个应用程序事务(Application Transaction)中,否则你的数据可能会过期失效。
+ </para>
+
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>不要把异常看成可恢复的</term>
+ <listitem>
+ <para>
+ 这一点甚至比“最佳实践”还要重要,这是“必备常识”。当异常发生的时候,必须要回滚 <literal>Transaction</literal> ,关闭<literal>Session</literal>。如果你不这样做的话,Hibernate无法保证内存状态精确的反应持久状态。尤其不要使用<literal>Session.load()</literal>来判断一个给定标识符的对象实例在数据库中是否存在,应该使用<literal>Session.get()</literal>或者进行一次查询.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>对于关联优先考虑lazy fetching </term>
+ <listitem>
+ <para>
+ 谨慎的使用主动抓取(eager fetching)。对于关联来说,若其目标是无法在第二级缓存中完全缓存所有实例的类,应该使用代理(proxies)与/或具有延迟加载属性的集合(lazy collections)。若目标是可以被缓存的,尤其是缓存的命中率非常高的情况下,应该使用<literal>lazy="false"</literal>,明确的禁止掉eager fetching。如果那些特殊的确实适合使用join fetch 的场合,请在查询中使用<literal>left join fetch</literal>。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ 使用<emphasis>open session in view</emphasis>模式,或者执行严格的<emphasis>装配期(assembly phase)</emphasis>策略来避免再次抓取数据带来的问题
+ </term>
+ <listitem>
+ <para>
+
+ Hibernate让开发者们摆脱了繁琐的<emphasis>Data Transfer Objects</emphasis> (DTO)。在传统的EJB结构中,DTO有双重作用:首先,他们解决了entity bean无法序列化的问题;其次,他们隐含地定义了一个装配期,在此期间,所有在view层需要用到的数据,都被抓取、集中到了DTO中,然后控制才被装到表示层。Hibernate终结了第一个作用。然而,除非你做好了在整个渲染过程中都维护一个打开的持久化上下文(session)的准备,你仍然需要一个装配期(想象一下,你的业务方法与你的表示层有严格的契约,数据总是被放置到托管对象中)。这并非是Hibernate的限制!这是实现安全的事务化数据访问的基本需求。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>考虑把Hibernate代码从业务逻辑代码中抽象出来</term>
+ <listitem>
+ <para>
+ 把Hibernate的数据存取代码隐藏到接口(interface)的后面,组合使用<emphasis>DAO</emphasis>和<emphasis>Thread Local Session</emphasis>模式。通过Hibernate的<literal>UserType</literal>,你甚至可以用硬编码的JDBC来持久化那些本该被Hibernate持久化的类。 (该建议更适用于规模足够大应用软件中,对于那些只有5张表的应用程序并不适合。)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>不要用怪异的连接映射</term>
+ <listitem>
+ <para>
+ 多对多连接用得好的例子实际上相当少见。大多数时候你在“连接表”中需要保存额外的信息。这种情况下,用两个指向中介类的一对多的连接比较好。实际上,我们认为绝大多数的连接是一对多和多对一的,你应该谨慎使用其它连接风格,用之前问自己一句,是否真的必须这么做。
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>偏爱双向关联</term>
+ <listitem>
+ <para>
+ 单向关联更加难于查询。在大型应用中,几乎所有的关联必须在查询中可以双向导航。
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/collection_mapping.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/collection_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/collection_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/collection_mapping.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,1081 @@
+ <chapter id="collections">
+ <title>集合类(Collections)映射</title>
+
+
+ <sect1 id="collections-persistent" revision="3">
+ <title>持久化集合类(Persistent collections)</title>
+
+ <para id="collections-persistent-translate-comment">
+ (译者注:在阅读本章的时候,以后整个手册的阅读过程中,我们都会面临一个名词方面的问题,那就是“集合”。"Collections"和"Set"在中文里对应都被翻译为“集合”,但是他们的含义很不一样。Collections是一个超集,Set是其中的一种。大部分情况下,本译稿中泛指的未加英文注明的“集合”,都应当理解为“Collections”。在有些二者同时出现,可能造成混淆的地方,我们用“集合类”来特指“Collecions”,“集合(Set)”来指"Set",一般都会在后面的括号中给出英文。希望大家在阅读时联系上下文理解,不要造成误解。
+ 与此同时,“元素”一词对应的英文“element”,也有两个不同的含义。其一为集合的元素,是内存中的一个变量;另一含义则是XML文档中的一个标签所代表的元素。也请注意区别。
+ 本章中,特别是后半部分是需要反复阅读才能理解清楚的。如果遇到任何疑问,请记住,英文版本的reference是惟一标准的参考资料。)
+ </para>
+
+ <para>
+ Hibernate要求持久化集合值字段必须声明为接口,比如:
+ </para>
+
+ <programlisting><![CDATA[public class Product {
+ private String serialNumber;
+ private Set parts = new HashSet();
+
+ public Set getParts() { return parts; }
+ void setParts(Set parts) { this.parts = parts; }
+ public String getSerialNumber() { return serialNumber; }
+ void setSerialNumber(String sn) { serialNumber = sn; }
+}]]></programlisting>
+
+ <para>
+ 实际的接口可能是<literal>java.util.Set</literal>,
+ <literal>java.util.Collection</literal>, <literal>java.util.List</literal>,
+ <literal>java.util.Map</literal>, <literal>java.util.SortedSet</literal>,
+ <literal>java.util.SortedMap</literal> 或者...任何你喜欢的类型!("任何你喜欢的类型" 代表你需要编写 <literal>org.hibernate.usertype.UserCollectionType</literal>的实现.)
+ </para>
+
+ <para>
+ 注意我们是如何用一个<literal>HashSet</literal>实例来初始化实例变量的.这是用于初始化新创建(尚未持久化)的类实例中集合值属性的最佳方法。当你持久化这个实例时——比如通过调用<literal>persist()</literal>——Hibernate 会自动把<literal>HashSet</literal>替换为Hibernate自己的<literal>Set</literal>实现。观察下面的错误:
+ </para>
+
+
+ <programlisting><![CDATA[Cat cat = new DomesticCat();
+Cat kitten = new DomesticCat();
+....
+Set kittens = new HashSet();
+kittens.add(kitten);
+cat.setKittens(kittens);
+session.persist(cat);
+kittens = cat.getKittens(); //Okay, kittens collection is a Set
+(HashSet) cat.getKittens(); //Error!]]></programlisting>
+
+ <para>
+ 根据不同的接口类型,被Hibernate注射的持久化集合类的表现类似<literal>HashMap</literal>, <literal>HashSet</literal>,
+ <literal>TreeMap</literal>, <literal>TreeSet</literal> or
+ <literal>ArrayList</literal>。
+ </para>
+
+ <para>
+ 集合类实例具有值类型的通常行为。当被持久化对象引用后,他们会自动被持久化,当不再被引用后,自动被删除。假若实例被从一个持久化对象传递到另一个,它的元素可能从一个表转移到另一个表。两个实体不能共享同一个集合类实例的引用。因为底层关系数据库模型的原因,集合值属性无法支持空值语义;Hibernate对空的集合引用和空集合不加区别。
+ </para>
+
+ <para>
+ 你不需要过多的为此担心。就如同你平时使用普通的Java集合类一样来使用持久化集合类。只是要确认你理解了双向关联的语义(后文讨论)。
+ </para>
+
+ </sect1>
+
+ <sect1 id="collections-mapping" revision="4">
+ <title>集合映射( Collection mappings )</title>
+
+ <para>
+ 用于映射集合类的Hibernate映射元素取决于接口的类型。比如, <literal><set></literal> 元素用来映射<literal>Set</literal>类型的属性。
+ </para>
+
+ <programlisting><![CDATA[<class name="Product">
+ <id name="serialNumber" column="productSerialNumber"/>
+ <set name="parts">
+ <key column="productSerialNumber" not-null="true"/>
+ <one-to-many class="Part"/>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ 除了<literal><set></literal>,还有<literal><list></literal>, <literal><map></literal>, <literal><bag></literal>, <literal><array></literal> 和
+ <literal><primitive-array></literal> 映射元素。<literal><map></literal>具有代表性:
+ </para>
+
+
+ <programlistingco>
+ <areaspec>
+ <area id="mappingcollection1" coords="2 65"/>
+ <area id="mappingcollection2" coords="3 65"/>
+ <area id="mappingcollection3" coords="4 65"/>
+ <area id="mappingcollection4" coords="5 65"/>
+ <area id="mappingcollection5" coords="6 65"/>
+ <area id="mappingcollection6" coords="7 65"/>
+ <area id="mappingcollection7" coords="8 65"/>
+ <area id="mappingcollection8" coords="9 65"/>
+ <area id="mappingcollection9" coords="10 65"/>
+ <area id="mappingcollection10" coords="11 65"/>
+ <area id="mappingcollection11" coords="12 65"/>
+ <area id="mappingcollection12" coords="13 65"/>
+ <area id="mappingcollection13" coords="14 65"/>
+ <area id="mappingcollection14" coords="15 65"/>
+
+ </areaspec>
+ <programlisting><![CDATA[<map
+ name="propertyName"
+ table="table_name"
+ schema="schema_name"
+ lazy="true|extra|false"
+ inverse="true|false"
+ cascade="all|none|save-update|delete|all-delete-orphan|delete-orphan"
+ sort="unsorted|natural|comparatorClass"
+ order-by="column_name asc|desc"
+ where="arbitrary sql where condition"
+ fetch="join|select|subselect"
+ batch-size="N"
+ access="field|property|ClassName"
+ optimistic-lock="true|false"
+ mutable="true|false"
+ node="element-name|."
+ embed-xml="true|false"
+>
+
+ <key .... />
+ <map-key .... />
+ <element .... />
+</map>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="mappingcollection1">
+ <para>
+ <literal>name</literal> 集合属性的名称
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection2">
+ <para>
+ <literal>table</literal> (可选——默认为属性的名称)这个集合表的名称(不能在一对多的关联关系中使用)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection3">
+ <para>
+ <literal>schema</literal> (可选) 表的schema的名称, 他将覆盖在根元素中定义的schema
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection4">
+ <para>
+ <literal>lazy</literal> (可选--默认为true) 可以用来关闭延迟加载(false),指定一直使用预先抓取,或者打开"extra-lazy" 抓取,此时大多数操作不会初始化集合类(适用于非常大的集合)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection5">
+ <para>
+ <literal>inverse</literal> (可选——默认为<literal>false</literal>)
+ 标记这个集合作为双向关联关系中的方向一端。
+
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection6">
+ <para>
+ <literal>cascade</literal> (可选——默认为<literal>none</literal>)
+ 让操作级联到子实体
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection7">
+ <para>
+ <literal>sort</literal>(可选)指定集合的排序顺序, 其可以为自然的(<literal>natural</literal>)或者给定一个用来比较的类。
+
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection8">
+ <para>
+ <literal>order-by</literal> (可选, 仅用于jdk1.4) 指定表的字段(一个或几个)再加上asc或者desc(可选), 定义Map,Set和Bag的迭代顺序
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection9">
+ <para>
+ <literal>where</literal> (可选) 指定任意的SQL where条件, 该条件将在重新载入或者删除这个集合时使用(当集合中的数据仅仅是所有可用数据的一个子集时这个条件非常有用)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection10">
+ <para>
+ <literal>fetch</literal> (可选, 默认为<literal>select</literal>) 用于在外连接抓取、通过后续select抓取和通过后续subselect抓取之间选择。
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection11">
+ <para>
+ <literal>batch-size</literal> (可选, 默认为<literal>1</literal>) 指定通过延迟加载取得集合实例的批处理块大小("batch size")。
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection12">
+ <para>
+ <literal>access</literal>(可选-默认为属性property):Hibernate取得集合属性值时使用的策略
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection13">
+ <para>
+ <literal>乐观锁</literal> (可选 - 默认为 <literal>true</literal>):
+ 对集合的状态的改变会是否导致其所属的实体的版本增长。 (对一对多关联来说,关闭这个属性常常是有理的)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection14">
+ <para>
+ <literal>mutable(可变)</literal> (可选 - 默认为<literal>true</literal>):
+ 若值为<literal>false</literal>,表明集合中的元素不会改变(在某些情况下可以进行一些小的性能优化)。
+ </para>
+ </callout>
+
+ </calloutlist>
+ </programlistingco>
+
+ <sect2 id="collections-foreignkeys" >
+ <title>集合外键(Collection foreign keys)</title>
+
+ <para>
+ 集合实例在数据库中依靠持有集合的实体的外键加以辨别。此外键作为<emphasis>集合关键字段(collection key column)</emphasis>(或多个字段)加以引用。集合关键字段通过<literal><key></literal> 元素映射。
+ </para>
+
+ <para>
+ 在外键字段上可能具有非空约束。对于大多数集合来说,这是隐含的。对单向一对多关联来说,外键字段默认是可以为空的,因此你可能需要指明 <literal>not-null="true"</literal>。
+ </para>
+
+ <programlisting><![CDATA[<key column="productSerialNumber" not-null="true"/>]]></programlisting>
+
+ <para>
+ 外键约束可以使用<literal>ON DELETE CASCADE</literal>。
+ </para>
+
+ <programlisting><![CDATA[<key column="productSerialNumber" on-delete="cascade"/>]]></programlisting>
+
+ <para>
+ 对<literal><key></literal> 元素的完整定义,请参阅前面的章节。
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-elements" >
+ <title>集合元素(Collection elements)</title>
+
+ <para>
+ 集合几乎可以包含任何其他的Hibernate类型,包括所有的基本类型、自定义类型、组件,当然还有对其他实体的引用。存在一个重要的区别:位于集合中的对象可能是根据“值”语义来操作(其声明周期完全依赖于集合持有者),或者它可能是指向另一个实体的引用,具有其自己的生命周期。在后者的情况下,被作为集合持有的状态考虑的,只有两个对象之间的“连接”。
+ </para>
+
+
+ <para>
+ 被包容的类型被称为<emphasis>集合元素类型(collection element type)</emphasis>。集合元素通过<literal><element></literal>或<literal><composite-element></literal>映射,或在其是实体引用的时候,通过<literal><one-to-many></literal> 或<literal><many-to-many></literal>映射。前两种用于使用值语义映射元素,后两种用于映射实体关联。
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-indexed">
+ <title>索引集合类(Indexed collections)</title>
+
+
+ <para>
+ 所有的集合映射,除了set和bag语义的以外,都需要指定一个集合表的<emphasis>索引字段(index column)</emphasis>——用于对应到数组索引,或者<literal>List</literal>的索引,或者<literal>Map</literal>的关键字。通过<literal><map-key></literal>,<literal>Map</literal> 的索引可以是任何基础类型;若通过<literal><map-key-many-to-many></literal>,它也可以是一个实体引用;若通过<literal><composite-map-key></literal>,它还可以是一个组合类型。数组或列表的索引必须是<literal>integer</literal>类型,并且使用 <literal><list-index></literal>元素定义映射。被映射的字段包含有顺序排列的整数(默认从0开始)。
+ </para>
+
+
+ <programlistingco>
+ <areaspec>
+ <area id="mapkey1" coords="2 45"/>
+ <area id="mapkey2" coords="3 45"/>
+ <area id="mapkey3" coords="4 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<map-key
+ column="column_name"
+ formula="any SQL expression"
+ type="type_name"
+ node="@attribute-name"
+ length="N"/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="mapkey1">
+ <para>
+ <literal>column</literal>(可选):保存集合索引值的字段名。
+ </para>
+ </callout>
+ <callout arearefs="mapkey2">
+ <para>
+ <literal>formula</literal> (可选): 用于计算map关键字的SQL公式
+ </para>
+ </callout>
+
+ <callout arearefs="mapkey3">
+ <para>
+ <literal>type</literal> (必须):映射键(map key)的类型。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <programlistingco>
+ <areaspec>
+ <area id="indexmanytomany1" coords="2 45"/>
+ <area id="indexmanytomany2" coords="3 45"/>
+ <area id="indexmanytomany3" coords="3 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<map-key-many-to-many
+ column="column_name"
+ formula="any SQL expression"
+ class="ClassName"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="indexmanytomany1">
+ <para>
+ <literal>column</literal>(可选):集合索引值中外键字段的名称
+ </para>
+ </callout>
+ <callout arearefs="indexmanytomany2">
+ <para>
+ <literal>formula</literal> (可选): 用于计算map关键字的外键的SQL公式
+ </para>
+ </callout>
+ <callout arearefs="indexmanytomany3">
+ <para>
+ <literal>class</literal> (必需):映射的键(map key)使用的实体类。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 假若你的表没有一个索引字段,当你仍然希望使用<literal>List</literal>作为属性类型,你应该把此属性映射为Hibernate <emphasis><bag></emphasis>。从数据库中获取的时候,bag不维护其顺序,但也可选择性的进行排序。
+ </para>
+
+ </sect2>
+
+
+ <para>
+ 从集合类可以产生很大一部分映射,覆盖了很多常见的关系模型。我们建议你试验schema生成工具,来体会一下不同的映射声明是如何被翻译为数据库表的。
+ </para>
+
+ <sect2 id="collections-ofvalues" revision="2">
+ <title>值集合于多对多关联(Collections of values and many-to-many associations)</title>
+
+
+ <para>
+ 任何值集合或者多对多关联需要专用的具有一个或多个外键字段的<emphasis>collection table</emphasis>、一个或多个<emphasis>collection element column</emphasis>,以及还可能有一个或多个索引字段。
+ </para>
+
+
+ <para>
+ 对于一个值集合, 我们使用<literal><element></literal>标签。
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="element1b" coords="2 50"/>
+ <area id="element2b" coords="3 50"/>
+ <area id="element3b" coords="4 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<element
+ column="column_name"
+ formula="any SQL expression"
+ type="typename"
+ length="L"
+ precision="P"
+ scale="S"
+ not-null="true|false"
+ unique="true|false"
+ node="element-name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="element1b">
+ <para>
+ <literal>column</literal>(可选):保存集合元素值的字段名。
+ </para>
+ </callout>
+ <callout arearefs="element2b">
+ <para>
+ <literal>formula</literal> (可选): 用于计算元素的SQL公式
+ </para>
+ </callout>
+ <callout arearefs="element3b">
+ <para>
+ <literal>type</literal> (必需):集合元素的类型
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <emphasis>多对多关联(many-to-many association)</emphasis> 使用
+ <literal><many-to-many></literal>元素定义.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="manytomany1" coords="2 60"/>
+ <area id="manytomany2" coords="3 60"/>
+ <area id="manytomany3" coords="4 60"/>
+ <area id="manytomany4" coords="5 60"/>
+ <area id="manytomany5" coords="6 60"/>
+ <area id="manytomany6" coords="7 60"/>
+ <area id="manytomany7" coords="8 60"/>
+ <area id="manytomany8" coords="9 60"/>
+ </areaspec>
+ <programlisting><![CDATA[<many-to-many
+ column="column_name"
+ formula="any SQL expression"
+ class="ClassName"
+ fetch="select|join"
+ unique="true|false"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ property-ref="propertyNameFromAssociatedClass"
+ node="element-name"
+ embed-xml="true|false"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="manytomany1">
+ <para>
+ <literal>column</literal>(可选): 这个元素的外键关键字段名
+ </para>
+ </callout>
+ <callout arearefs="manytomany2">
+ <para>
+ <literal>formula</literal> (可选): 用于计算元素外键值的SQL公式.
+ </para>
+ </callout>
+
+ <callout arearefs="manytomany3">
+ <para>
+ <literal>class</literal> (必需): 关联类的名称
+ </para>
+ </callout>
+ <callout arearefs="manytomany3">
+ <para>
+ <literal>outer-join</literal> (可选 - 默认为<literal>auto</literal>):
+ 在Hibernate系统参数中<literal>hibernate.use_outer_join</literal>被打开的情况下,该参数用来允许使用outer join来载入此集合的数据。
+ </para>
+ </callout>
+ <callout arearefs="manytomany4">
+ <para>
+ 为此关联打开外连接抓取或者后续select抓取。这是特殊情况;对于一个实体及其指向其他实体的多对多关联进全预先抓取(使用一条单独的<literal>SELECT</literal>),你不仅需要对集合自身打开<literal>join</literal>,也需要对<literal><many-to-many></literal>这个内嵌元素打开此属性。
+ </para>
+ </callout>
+ <callout arearefs="manytomany5">
+ <para>
+ 对外键字段允许DDL生成的时候生成一个惟一约束。这使关联变成了一个高效的一对多关联。(此句存疑:原文为This makes the association multiplicity effectively one to many.)
+ </para>
+ </callout>
+ <callout arearefs="manytomany6">
+ <para>
+ <literal>not-found</literal> (可选 - 默认为 <literal>exception</literal>): 指明引用的外键中缺少某些行该如何处理:
+ <literal>ignore</literal> 会把缺失的行作为一个空引用处理。
+ </para>
+
+ </callout>
+ <callout arearefs="manytomany7">
+ <para>
+ <literal>entity-name</literal> (可选): 被关联的类的实体名,作为<literal>class</literal>的替代。
+ </para>
+ </callout>
+ <callout arearefs="manytomany8">
+ <para>
+ <literal>property-ref</literal>: (可选) 被关联到此外键(foreign key)的类中的对应属性的名字。若未指定,使用被关联类的主键。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 例子:首先, 一组字符串:
+ </para>
+
+ <programlisting><![CDATA[<set name="names" table="NAMES">
+ <key column="GROUPID"/>
+ <element column="NAME" type="string"/>
+</set>]]></programlisting>
+
+ <para>
+ 包含一组整数的bag(还设置了<literal>order-by</literal>参数指定了迭代的顺序):
+ </para>
+
+ <programlisting><![CDATA[<bag name="sizes"
+ table="item_sizes"
+ order-by="size asc">
+ <key column="item_id"/>
+ <element column="size" type="integer"/>
+</bag>]]></programlisting>
+
+ <para>
+ 一个实体数组,在这个案例中是一个多对多的关联(注意这里的实体是自动管理生命周期的对象(life cycle objects),<literal>cascade="all"</literal>):
+ </para>
+
+
+ <programlisting><![CDATA[<array name="addresses"
+ table="PersonAddress"
+ cascade="persist">
+ <key column="personId"/>
+ <list-index column="sortOrder"/>
+ <many-to-many column="addressId" class="Address"/>
+</array>]]></programlisting>
+
+ <para>
+ 一个map,通过字符串的索引来指明日期:
+ </para>
+
+
+ <programlisting><![CDATA[<map name="holidays"
+ table="holidays"
+ schema="dbo"
+ order-by="hol_name asc">
+ <key column="id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ 一个组件的列表:(下一章讨论)
+ </para>
+
+ <programlisting><![CDATA[<list name="carComponents"
+ table="CarComponents">
+ <key column="carId"/>
+ <list-index column="sortOrder"/>
+ <composite-element class="CarComponent">
+ <property name="price"/>
+ <property name="type"/>
+ <property name="serialNumber" column="serialNum"/>
+ </composite-element>
+</list>]]></programlisting>
+
+
+ </sect2>
+
+
+ <sect2 id="collections-onetomany">
+ <title>一对多关联(One-to-many Associations)</title>
+
+
+ <para>
+ <emphasis>一对多关联</emphasis><emphasis>通过外键</emphasis>连接两个类对应的表,而没有中间集合表。 这个关系模型失去了一些Java集合的语义:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 一个被包含的实体的实例只能被包含在一个集合的实例中
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 一个被包含的实体的实例只能对应于集合索引的一个值中
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ 一个从<literal>Product</literal>到<literal>Part</literal>的关联需要关键字字段,可能还有一个索引字段指向<literal>Part</literal>所对应的表。 <literal><one-to-many></literal>标记指明了一个一对多的关联。
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="onetomany1" coords="2 60"/>
+ <area id="onetomany2" coords="3 60"/>
+ <area id="onetomany3" coords="4 60"/>
+ </areaspec>
+ <programlisting><![CDATA[<one-to-many
+ class="ClassName"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ node="element-name"
+ embed-xml="true|false"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="onetomany1">
+ <para>
+ <literal>class</literal>(必须):被关联类的名称。
+ </para>
+ </callout>
+ <callout arearefs="onetomany2">
+ <para>
+ <literal>not-found</literal> (可选 - 默认为<literal>exception</literal>):
+ 指明若缓存的标示值关联的行缺失,该如何处理:
+ <literal>ignore</literal> 会把缺失的行作为一个空关联处理。
+ </para>
+ </callout>
+ <callout arearefs="onetomany3">
+ <para>
+ <literal>entity-name</literal> (可选): 被关联的类的实体名,作为<literal>class</literal>的替代。
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+
+ <para>
+ 例子
+ </para>
+
+ <programlisting><![CDATA[<set name="bars">
+ <key column="foo_id"/>
+ <one-to-many class="org.hibernate.Bar"/>
+</set>]]></programlisting>
+
+ <para>
+ 注意:<literal><one-to-many></literal>元素不需要定义任何字段。 也不需要指定表名。
+
+ </para>
+
+ <para>
+ <emphasis>重要提示</emphasis>:如果<literal>一对多</literal>关联中的外键字段定义成<literal>NOT NULL</literal>,你必须把<literal><key></literal>映射声明为<literal>not-null="true"</literal>,或者使用<emphasis>双向关联</emphasis>,并且标明<literal>inverse="true"</literal>。参阅本章后面关于双向关联的讨论。
+ </para>
+
+ <para>
+ 下面的例子展示一个<literal>Part</literal>实体的map,把name作为关键字。( <literal>partName</literal> 是<literal>Part</literal>的持久化属性)。注意其中的基于公式的索引的用法。
+ </para>
+
+ <programlisting><![CDATA[<map name="parts"
+ cascade="all">
+ <key column="productId" not-null="true"/>
+ <map-key formula="partName"/>
+ <one-to-many class="Part"/>
+</map>]]></programlisting>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="collections-advancedmappings">
+ <title>高级集合映射(Advanced collection mappings)</title>
+
+ <sect2 id="collections-sorted" revision="2">
+ <title>有序集合(Sorted collections)</title>
+
+ <para>
+ Hibernate支持实现<literal>java.util.SortedMap</literal>和<literal>java.util.SortedSet</literal>的集合。
+你必须在映射文件中指定一个比较器:
+ </para>
+
+ <programlisting><![CDATA[<set name="aliases"
+ table="person_aliases"
+ sort="natural">
+ <key column="person"/>
+ <element column="name" type="string"/>
+</set>
+
+<map name="holidays" sort="my.custom.HolidayComparator">
+ <key column="year_id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ <literal>sort</literal>属性中允许的值包括<literal>unsorted</literal>,<literal>natural</literal>和某个实现了<literal>java.util.Comparator</literal>的类的名称。
+ </para>
+
+ <para>
+ 分类集合的行为事实上象<literal>java.util.TreeSet</literal>或者<literal>java.util.TreeMap</literal>。
+ </para>
+
+ <para>
+ 如果你希望数据库自己对集合元素排序,可以利用<literal>set</literal>,<literal>bag</literal>或者<literal>map</literal>映射中的<literal>order-by</literal>属性。这个解决方案只能在jdk1.4或者更高的jdk版本中才可以实现(通过LinkedHashSet或者
+LinkedHashMap实现)。 它是在SQL查询中完成排序,而不是在内存中。
+ </para>
+
+ <programlisting><![CDATA[<set name="aliases" table="person_aliases" order-by="lower(name) asc">
+ <key column="person"/>
+ <element column="name" type="string"/>
+</set>
+
+<map name="holidays" order-by="hol_date, hol_name">
+ <key column="year_id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ 注意: 这个<literal>order-by</literal>属性的值是一个SQL排序子句而不是HQL的!
+ </para>
+
+ <para>
+ 关联还可以在运行时使用集合<literal>filter()</literal>根据任意的条件来排序。
+ </para>
+
+ <programlisting><![CDATA[sortedUsers = s.createFilter( group.getUsers(), "order by this.name" ).list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="collections-bidirectional" revision="1">
+ <title>双向关联(Bidirectional associations)</title>
+
+ <para>
+ <emphasis>双向关联</emphasis>允许通过关联的任一端访问另外一端。在Hibernate中, 支持两种类型的双向关联:
+
+ <variablelist>
+ <varlistentry>
+ <term>一对多(one-to-many)</term>
+ <listitem>
+ <para>
+ Set或者bag值在一端, 单独值(非集合)在另外一端
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>多对多(many-to-many)</term>
+ <listitem>
+ <para>
+ 两端都是set或bag值
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+
+ <para>
+ 要建立一个双向的多对多关联,只需要映射两个many-to-many关联到同一个数据库表中,并再定义其中的一端为<emphasis>inverse</emphasis>(使用哪一端要根据你的选择,但它不能是一个索引集合)。
+ </para>
+
+
+
+ <para>
+ 这里有一个many-to-many的双向关联的例子;每一个category都可以有很多items,每一个items可以属于很多categories:
+ </para>
+
+
+ <programlisting><![CDATA[<class name="Category">
+ <id name="id" column="CATEGORY_ID"/>
+ ...
+ <bag name="items" table="CATEGORY_ITEM">
+ <key column="CATEGORY_ID"/>
+ <many-to-many class="Item" column="ITEM_ID"/>
+ </bag>
+</class>
+
+<class name="Item">
+ <id name="id" column="ITEM_ID"/>
+ ...
+
+ <!-- inverse end -->
+ <bag name="categories" table="CATEGORY_ITEM" inverse="true">
+ <key column="ITEM_ID"/>
+ <many-to-many class="Category" column="CATEGORY_ID"/>
+ </bag>
+</class>]]></programlisting>
+
+ <para>
+ 如果只对关联的反向端进行了改变,这个改变<emphasis>不会</emphasis>被持久化。
+ 这表示Hibernate为每个双向关联在内存中存在两次表现,一个从A连接到B,另一个从B连接到A。如果你回想一下Java对象模型,我们是如何在Java中创建多对多关系的,这可以让你更容易理解:
+
+ </para>
+
+ <programlisting><![CDATA[
+category.getItems().add(item); // The category now "knows" about the relationship
+item.getCategories().add(category); // The item now "knows" about the relationship
+
+session.persist(item); // The relationship won''t be saved!
+session.persist(category); // The relationship will be saved]]></programlisting>
+
+ <para>
+ 非反向端用于把内存中的表示保存到数据库中。
+ </para>
+
+ <para>
+ 要建立一个一对多的双向关联,你可以通过把一个一对多关联,作为一个多对一关联映射到到同一张表的字段上,并且在"多"的那一端定义<literal>inverse="true"</literal>。
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ not-null="true"/>
+</class>]]></programlisting>
+
+
+
+ <para>
+ 在“一”这一端定义<literal>inverse="true"</literal>不会影响级联操作,二者是正交的概念!
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-indexedbidirectional">
+ <title>双向关联,涉及有序集合类</title>
+ <para>
+ 对于有一端是<literal><list></literal>或者<literal><map></literal>的双向关联,需要加以特别考虑。假若子类中的一个属性映射到索引字段,没问题,我们仍然可以在集合类映射上使用<literal>inverse="true"</literal>:
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <map name="children" inverse="true">
+ <key column="parent_id"/>
+ <map-key column="name"
+ type="string"/>
+ <one-to-many class="Child"/>
+ </map>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <property name="name"
+ not-null="true"/>
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ 但是,假若子类中没有这样的属性存在,我们不能认为这个关联是真正的双向关联(信息不对称,在关联的一端有一些另外一端没有的信息)。在这种情况下,我们不能使用<literal>inverse="true"</literal>。我们需要这样用:
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <map name="children">
+ <key column="parent_id"
+ not-null="true"/>
+ <map-key column="name"
+ type="string"/>
+ <one-to-many class="Child"/>
+ </map>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ insert="false"
+ update="false"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ 注意在这个映射中,关联中集合类"值"一端负责来更新外键.TODO: Does this really result in some unnecessary update statements?
+ </para>
+
+ </sect2>
+
+
+ <sect2 id="collections-ternary">
+ <title>三重关联(Ternary associations)</title>
+
+ <para>
+ 有三种可能的途径来映射一个三重关联。第一种是使用一个<literal>Map</literal>,把一个关联作为其索引:
+ </para>
+
+ <programlisting><![CDATA[<map name="contracts">
+ <key column="employer_id" not-null="true"/>
+ <map-key-many-to-many column="employee_id" class="Employee"/>
+ <one-to-many class="Contract"/>
+</map>]]></programlisting>
+
+ <programlisting><![CDATA[<map name="connections">
+ <key column="incoming_node_id"/>
+ <map-key-many-to-many column="outgoing_node_id" class="Node"/>
+ <many-to-many column="connection_id" class="Connection"/>
+</map>]]></programlisting>
+
+ <para>
+ 第二种方法是简单的把关联重新建模为一个实体类。这使我们最经常使用的方法。
+ </para>
+ <para>
+ 最后一种选择是使用复合元素,我们会在后面讨论
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-idbag" revision="1">
+ <title><literal>使用<idbag></literal></title>
+ <para>
+ 如果你完全信奉我们对于“联合主键(composite keys)是个坏东西”,和“实体应该使用(无机的)自己生成的代用标识符(surrogate keys)”的观点,也许你会感到有一些奇怪,我们目前为止展示的多对多关联和值集合都是映射成为带有联合主键的表的!现在,这一点非常值得争辩;看上去一个单纯的关联表并不能从代用标识符中获得什么好处(虽然使用组合值的集合<emphasis>可能</emphasis>会获得一点好处)。不过,Hibernate提供了一个(一点点试验性质的)功能,让你把多对多关联和值集合应得到一个使用代用标识符的表去。
+ </para>
+
+ <para>
+ <literal><idbag></literal> 属性让你使用bag语义来映射一个<literal>List</literal> (或<literal>Collection</literal>)。
+ </para>
+
+<programlisting><![CDATA[<idbag name="lovers" table="LOVERS">
+ <collection-id column="ID" type="long">
+ <generator class="sequence"/>
+ </collection-id>
+ <key column="PERSON1"/>
+ <many-to-many column="PERSON2" class="Person" fetch="join"/>
+</idbag>]]></programlisting>
+
+ <para>
+ 你可以理解,<literal><idbag></literal>人工的id生成器,就好像是实体类一样!集合的每一行都有一个不同的人造关键字。但是,Hibernate没有提供任何机制来让你取得某个特定行的人造关键字。
+ </para>
+
+ <para>
+ 注意<literal><idbag></literal>的更新性能要比普通的<literal><bag></literal>高得多!Hibernate可以有效的定位到不同的行,分别进行更新或删除工作,就如同处理一个list, map或者set一样。
+
+ </para>
+
+ <para>
+ 在目前的实现中,还不支持使用<literal>identity</literal>标识符生成器策略来生成<literal><idbag></literal>集合的标识符。
+ </para>
+
+ </sect2>
+
+ </sect1>
+ <!--undocumenting this stuff -->
+ <!--sect1 id="collections-heterogeneous">
+ <title>异类关联(Heterogeneous Associations)</title>
+
+ <para>
+ <literal><many-to-any></literal>和<literal><index-many-to-any></literal>元素提供真正的异类关联。这些元素和<literal><any></literal>元素工作方式是同样的,他们都应该很少用到。
+ </para>
+ </sect1-->
+
+ <sect1 id="collections-example" revision="1">
+ <title>集合例子(Collection example)</title>
+
+ <para>
+ 在前面的几个章节的确非常令人迷惑。 因此让我们来看一个例子。这个类:
+ </para>
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+
+public class Parent {
+ private long id;
+ private Set children;
+
+ public long getId() { return id; }
+ private void setId(long id) { this.id=id; }
+
+ private Set getChildren() { return children; }
+ private void setChildren(Set children) { this.children=children; }
+
+ ....
+ ....
+}]]></programlisting>
+
+ <para>
+ 这个类有一个<literal>Child</literal>的实例集合。如果每一个子实例至多有一个父实例, 那么最自然的映射是一个one-to-many的关联关系:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 在以下的表定义中反应了这个映射关系:
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null primary key, name varchar(255), parent_id bigint )
+alter table child add constraint childfk0 (parent_id) references parent]]></programlisting>
+
+ <para>
+ 如果父亲是<emphasis>必须</emphasis>的, 那么就可以使用双向one-to-many的关联了:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ <many-to-one name="parent" class="Parent" column="parent_id" not-null="true"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 请注意<literal>NOT NULL</literal>的约束:
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null
+ primary key,
+ name varchar(255),
+ parent_id bigint not null )
+alter table child add constraint childfk0 (parent_id) references parent]]></programlisting>
+
+
+ <para>
+ 另外,如果你绝对坚持这个关联应该是单向的,你可以对<literal><key></literal>映射声明<literal>NOT NULL</literal>约束:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children">
+ <key column="parent_id" not-null="true"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 另外一方面,如果一个子实例可能有多个父实例, 那么就应该使用many-to-many关联:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children" table="childset">
+ <key column="parent_id"/>
+ <many-to-many class="Child" column="child_id"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+ <para>
+ 表定义:
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null primary key, name varchar(255) )
+create table childset ( parent_id bigint not null,
+ child_id bigint not null,
+ primary key ( parent_id, child_id ) )
+alter table childset add constraint childsetfk0 (parent_id) references parent
+alter table childset add constraint childsetfk1 (child_id) references child]]></programlisting>
+
+ <para>
+ 更多的例子,以及一个完整的父/子关系映射的排练,请参阅<xref linkend="example-parentchild"/>.
+ </para>
+
+ <para>
+ 甚至可能出现更加复杂的关联映射,我们会在下一章中列出所有可能性。
+ </para>
+
+ </sect1>
+
+ </chapter>
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/component_mapping.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/component_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/component_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/component_mapping.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,339 @@
+<chapter id="components">
+ <title>组件(Component)映射</title>
+
+ <para>
+ <emphasis>组件</emphasis>(Component)这个概念在Hibernate中几处不同的地方为了不同的目的被重复使用.
+ </para>
+
+ <sect1 id="components-dependentobjects" revision="2">
+ <title>依赖对象(Dependent objects)</title>
+
+ <para>
+ 组件(Component)是一个被包含的对象,在持久化的过程中,它被当作值类型,而并非一个实体的引用。在这篇文档中,组件这一术语指的是面向对象的合成概念(而并不是系统构架层次上的组件的概念)。举个例子, 你对人(Person)这个概念可以像下面这样来建模:
+ </para>
+
+ <programlisting><![CDATA[public class Person {
+ private java.util.Date birthday;
+ private Name name;
+ private String key;
+ public String getKey() {
+ return key;
+ }
+ private void setKey(String key) {
+ this.key=key;
+ }
+ public java.util.Date getBirthday() {
+ return birthday;
+ }
+ public void setBirthday(java.util.Date birthday) {
+ this.birthday = birthday;
+ }
+ public Name getName() {
+ return name;
+ }
+ public void setName(Name name) {
+ this.name = name;
+ }
+ ......
+ ......
+}]]></programlisting>
+
+ <programlisting><![CDATA[public class Name {
+ char initial;
+ String first;
+ String last;
+ public String getFirst() {
+ return first;
+ }
+ void setFirst(String first) {
+ this.first = first;
+ }
+ public String getLast() {
+ return last;
+ }
+ void setLast(String last) {
+ this.last = last;
+ }
+ public char getInitial() {
+ return initial;
+ }
+ void setInitial(char initial) {
+ this.initial = initial;
+ }
+}]]></programlisting>
+
+ <para>
+ 在持久化的过程中,<literal>姓名(Name)</literal>可以作为<literal>人(Person)</literal>的一个组件。需要注意的是:你应该为<literal>姓名</literal>的持久化属性定义getter和setter方法,但是你不需要实现任何的接口或申明标识符字段。
+ </para>
+
+ <para>
+ 以下是这个例子的Hibernate映射文件:
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Person" table="person">
+ <id name="Key" column="pid" type="string">
+ <generator class="uuid"/>
+ </id>
+ <property name="birthday" type="date"/>
+ <component name="Name" class="eg.Name"> <!-- class attribute optional -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </component>
+</class>]]></programlisting>
+
+ <para>
+ 人员(Person)表中将包括<literal>pid</literal>,
+ <literal>birthday</literal>,
+ <literal>initial</literal>,
+ <literal>first</literal>和
+ <literal>last</literal>等字段。</para>
+
+ <para>
+ 就像所有的值类型一样, 组件不支持共享引用。
+ 换句话说,两个人可能重名,但是两个Person对象应该包含两个独立的Name对象,只不过这两个Name对象具有“同样”的值。
+ 组件的值可以为空,其定义如下。
+ 每当Hibernate重新加载一个包含组件的对象,如果该组件的所有字段为空,Hibernate将假定整个组件为空。
+ 在大多数情况下,这样假定应该是没有问题的。
+ </para>
+
+ <para>
+ 组件的属性可以是任意一种Hibernate类型(包括集合, 多对多关联,
+ 以及其它组件等等)。嵌套组件不应该被当作一种特殊的应用(Nested components should not be considered an
+ exotic usage)。 Hibernate倾向于支持细致的(fine-grained)对象模型。
+ </para>
+
+ <para>
+ <literal><component></literal> 元素还允许有 <literal><parent></literal>子元素,用来表明component类中的一个属性是指向包含它的实体的引用。
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Person" table="person">
+ <id name="Key" column="pid" type="string">
+ <generator class="uuid"/>
+ </id>
+ <property name="birthday" type="date">
+ <component name="Name" class="eg.Name" unique="true">
+ <parent name="namedPerson"/> <!-- reference back to the Person -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </component>
+</class>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="components-incollections" revision="1">
+ <title>在集合中出现的依赖对象 (Collections of dependent objects)</title>
+
+ <para>
+ Hibernate支持组件的集合(例如: 一个元素是姓名(Name)这种类型的数组)。
+ 你可以使用<literal><composite-element></literal>标签替代<literal><element></literal>标签来定义你的组件集合。
+ </para>
+
+ <programlisting><![CDATA[<set name="someNames" table="some_names" lazy="true">
+ <key column="id"/>
+ <composite-element class="eg.Name"> <!-- class attribute required -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>;
+ </composite-element>
+</set>]]></programlisting>
+
+ <para>
+ 注意,如果你定义的Set包含组合元素(composite-element),正确地实现<literal>equals()</literal>和<literal>hashCode()</literal>是非常重要的。
+ </para>
+
+ <para>
+ 组合元素可以包含组件,但是不能包含集合。如果你的组合元素自身包含组件, 你必须使用<literal><nested-composite-element></literal>标签。这是一个相当特殊的案例 - 在一个组件的集合里,那些组件本身又可以包含其他的组件。这个时候你就应该考虑一下使用one-to-many关联是否会更恰当。
+ 尝试对这个组合元素重新建模为一个实体-但是需要注意的是,虽然Java模型和重新建模前是一样的,关系模型和持久性语义会有细微的变化。
+ </para>
+
+ <para>
+ 请注意如果你使用<literal><set></literal>标签,一个组合元素的映射不支持可能为空的属性. 当删除对象时, Hibernate必须使用每一个字段的值来确定一条记录(在组合元素表中,没有单独的关键字段),
+ 如果有为null的字段,这样做就不可能了。你必须作出一个选择,要么在组合元素中使用不能为空的属性,要么选择使用<literal><list></literal>,<literal><map></literal>,<literal><bag></literal> 或者 <literal><idbag></literal>而不是 <literal><set></literal>。
+ </para>
+
+ <para>
+ 组合元素有个特别的用法是它可以包含一个<literal><many-to-one></literal>元素。类似这样的映射允许你将一个many-to-many关联表映射为组合元素的集合。(A mapping like this allows you to map extra columns of a many-to-many association table to the composite element class.) 接下来的的例子是从<literal>Order</literal>到<literal>Item</literal>的一个多对多的关联关系, 关联属性是 <literal>purchaseDate</literal>, <literal>price</literal> 和 <literal>quantity</literal> 。
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Order" .... >
+ ....
+ <set name="purchasedItems" table="purchase_items" lazy="true">
+ <key column="order_id">
+ <composite-element class="eg.Purchase">
+ <property name="purchaseDate"/>
+ <property name="price"/>
+ <property name="quantity"/>
+ <many-to-one name="item" class="eg.Item"/> <!-- class attribute is optional -->
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+ <para>
+ 当然,当你定义Item时,你无法引用这些purchase,因此你无法实现双向关联查询。记住组件是值类型,并且不允许共享引用。某一个特定的<literal>Purchase</literal> 可以放在<literal>Order</literal>的集合中,但它不能同时被<literal>Item</literal>所引用。
+ </para>
+
+ <para>其实组合元素的这个用法可以扩展到三重或多重关联:</para>
+
+ <programlisting><![CDATA[<class name="eg.Order" .... >
+ ....
+ <set name="purchasedItems" table="purchase_items" lazy="true">
+ <key column="order_id">
+ <composite-element class="eg.OrderLine">
+ <many-to-one name="purchaseDetails" class="eg.Purchase"/>
+ <many-to-one name="item" class="eg.Item"/>
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ 在查询中,表达组合元素的语法和关联到其他实体的语法是一样的。
+ </para>
+
+ </sect1>
+
+ <sect1 id="components-asmapindex">
+ <title>组件作为Map的索引(Components as Map indices )</title>
+
+ <para>
+ <literal><composite-map-key></literal>元素允许你映射一个组件类作为一个<literal>Map</literal>的key,前提是你必须正确的在这个类中重写了<literal>hashCode()</literal> 和 <literal>equals()</literal>方法。
+ </para>
+ </sect1>
+
+ <sect1 id="components-compositeid" revision="1">
+ <title>组件作为联合标识符(Components as composite identifiers)</title>
+
+ <para>
+ 你可以使用一个组件作为一个实体类的标识符。 你的组件类必须满足以下要求:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 它必须实现<literal>java.io.Serializable</literal>接口
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 它必须重新实现<literal>equals()</literal>和<literal>hashCode()</literal>方法, 始终和组合关键字在数据库中的概念保持一致
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <emphasis>注意:在Hibernate3中,第二个要求并非是Hibernate强制必须的。但最好这样做。</emphasis>
+ </para>
+
+ <para>
+ 你不能使用一个<literal>IdentifierGenerator</literal>产生组合关键字。一个应用程序必须分配它自己的标识符。
+ </para>
+
+ <para>
+ 使用<literal><composite-id></literal> 标签(并且内嵌<literal><key-property></literal>元素)代替通常的<literal><id></literal>标签。比如,<literal>OrderLine</literal>类具有一个主键,这个主键依赖于<literal>Order</literal>的(联合)主键。
+ </para>
+
+ <programlisting><![CDATA[<class name="OrderLine">
+
+ <composite-id name="id" class="OrderLineId">
+ <key-property name="lineId"/>
+ <key-property name="orderId"/>
+ <key-property name="customerId"/>
+ </composite-id>
+
+ <property name="name"/>
+
+ <many-to-one name="order" class="Order"
+ insert="false" update="false">
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </many-to-one>
+ ....
+
+</class>]]></programlisting>
+
+ <para>
+ 现在,任何指向<literal>OrderLine</literal>的外键都是复合的。在你的映射文件中,必须为其他类也这样声明。例如,一个指向<literal>OrderLine</literal>的关联可能被这样映射:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="orderLine" class="OrderLine">
+<!-- the "class" attribute is optional, as usual -->
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+</many-to-one>]]></programlisting>
+
+ <para>
+ (注意在各个地方<literal><column></literal>标签都是<literal>column</literal>属性的替代写法。)
+ </para>
+
+ <para>
+ 指向<literal>OrderLine</literal>的<literal>多对多</literal>关联也使用联合外键:
+ </para>
+
+ <programlisting><![CDATA[<set name="undeliveredOrderLines">
+ <key column name="warehouseId"/>
+ <many-to-many class="OrderLine">
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </many-to-many>
+</set>]]></programlisting>
+
+ <para>
+ 在<literal>Order</literal>中,<literal>OrderLine</literal>的集合则是这样:
+ </para>
+
+ <programlisting><![CDATA[<set name="orderLines" inverse="true">
+ <key>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </key>
+ <one-to-many class="OrderLine"/>
+</set>]]></programlisting>
+
+ <para>
+ (与通常一样,<literal><one-to-many></literal>元素不声明任何列.)
+ </para>
+
+ <para>
+ 假若<literal>OrderLine</literal>本身拥有一个集合,它也具有组合外键。
+ </para>
+
+ <programlisting><![CDATA[<class name="OrderLine">
+ ....
+ ....
+ <list name="deliveryAttempts">
+ <key> <!-- a collection inherits the composite key type -->
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </key>
+ <list-index column="attemptId" base="1"/>
+ <composite-element class="DeliveryAttempt">
+ ...
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="components-dynamic" revision="1">
+ <title>动态组件 (Dynamic components)</title>
+
+ <para>
+ 你甚至可以映射<literal>Map</literal>类型的属性:
+ </para>
+
+ <programlisting><![CDATA[<dynamic-component name="userAttributes">
+ <property name="foo" column="FOO" type="string"/>
+ <property name="bar" column="BAR" type="integer"/>
+ <many-to-one name="baz" class="Baz" column="BAZ_ID"/>
+</dynamic-component>]]></programlisting>
+
+ <para>
+ 从<literal><dynamic-component></literal>映射的语义上来讲,它和<literal><component></literal>是相同的。
+ 这种映射类型的优点在于通过修改映射文件,就可以具有在部署时检测真实属性的能力。利用一个DOM解析器,也可以在程序运行时操作映射文件。
+ 更好的是,你可以通过<literal>Configuration</literal>对象来访问(或者修改)Hibernate的运行时元模型。
+ </para>
+ </sect1>
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/configuration.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/configuration.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/configuration.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/configuration.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,1694 @@
+<chapter id="session-configuration" revision="1">
+
+ <title>
+ 配置
+ </title>
+
+ <para>
+ 由于Hibernate是为了能在各种不同环境下工作而设计的, 因此存在着大量的配置参数. 幸运的是多数配置参数都
+ 有比较直观的默认值, 并有随Hibernate一同分发的配置样例<literal>hibernate.properties</literal>
+ (位于<literal>etc/</literal>)来展示各种配置选项. 所需做的仅仅是将这个样例文件复制到类路径
+ (classpath)下并做一些自定义的修改.
+ </para>
+
+ <sect1 id="configuration-programmatic" revision="1">
+ <title>
+ 可编程的配置方式
+ </title>
+
+ <para>
+ 一个<literal>org.hibernate.cfg.Configuration</literal>实例代表了一个应用程序中Java类型
+ 到SQL数据库映射的完整集合. <literal>Configuration</literal>被用来构建一个(不可变的
+ (immutable))<literal>SessionFactory</literal>. 映射定义则由不同的XML映射定义文件编译而来.
+ </para>
+
+ <para>
+ 你可以直接实例化<literal>Configuration</literal>来获取一个实例,并为它指定XML映射定义
+ 文件. 如果映射定
+ 义文件在类路径(classpath)中, 请使用<literal>addResource()</literal>:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addResource("Item.hbm.xml")
+ .addResource("Bid.hbm.xml");]]></programlisting>
+
+ <para>
+ 一个替代方法(有时是更好的选择)是,指定被映射的类,让Hibernate帮你寻找映射定义文件:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addClass(org.hibernate.auction.Item.class)
+ .addClass(org.hibernate.auction.Bid.class);]]></programlisting>
+
+ <para>
+ Hibernate将会在类路径(classpath)中寻找名字为
+ <literal>/org/hibernate/auction/Item.hbm.xml</literal>和
+ <literal>/org/hibernate/auction/Bid.hbm.xml</literal>映射定义文件.
+ 这种方式消除了任何对文件名的硬编码(hardcoded).
+ </para>
+
+ <para>
+ <literal>Configuration</literal>也允许你指定配置属性:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addClass(org.hibernate.auction.Item.class)
+ .addClass(org.hibernate.auction.Bid.class)
+ .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
+ .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
+ .setProperty("hibernate.order_updates", "true");]]></programlisting>
+
+ <para>
+ 当然这不是唯一的传递Hibernate配置属性的方式, 其他可选方式还包括:
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ 传一个<literal>java.util.Properties</literal>实例给
+ <literal>Configuration.setProperties()</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 将<literal>hibernate.properties</literal>放置在类路径(classpath)的根目录下
+ (root directory).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 通过<literal>java -Dproperty=value</literal>来设置系统
+ (<literal>System</literal>)属性.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 在<literal>hibernate.cfg.xml</literal>中加入元素
+ <literal><property></literal> (稍后讨论).
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ 如果想尽快体验Hibernate, <literal>hibernate.properties</literal>是最简单的方式.
+ </para>
+
+ <para>
+ <literal>Configuration</literal>实例被设计成启动期间(startup-time)对象,
+ 一旦<literal>SessionFactory</literal>创建完成它就被丢弃了.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-sessionfactory">
+ <title>
+ 获得SessionFactory
+ </title>
+
+
+ <para>
+ 当所有映射定义被<literal>Configuration</literal>解析后,
+ 应用程序必须获得一个用于构造<literal>Session</literal>实例的工厂.
+ 这个工厂将被应用程序的所有线程共享:
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sessions = cfg.buildSessionFactory();]]></programlisting>
+
+ <para>
+ Hibernate允许你的应用程序创建多个<literal>SessionFactory</literal>实例. 这对
+ 使用多个数据库的应用来说很有用.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-hibernatejdbc" revision="1">
+ <title>
+ JDBC连接
+ </title>
+
+ <para>
+ 通常你希望<literal>SessionFactory</literal>来为你创建和缓存(pool)JDBC连接. 如果你采用这种方式,
+ 只需要如下例所示那样,打开一个<literal>Session</literal>:
+ </para>
+
+ <programlisting><![CDATA[Session session = sessions.openSession(); // open a new Session]]></programlisting>
+
+ <para>
+ 一旦你需要进行数据访问时, 就会从连接池(connection pool)获得一个JDBC连接.
+ </para>
+
+ <para>
+ 为了使这种方式工作起来, 我们需要向Hibernate传递一些JDBC连接的属性.
+ 所有Hibernate属性的名字和语义都在<literal>org.hibernate.cfg.Environment</literal>中定义.
+ 我们现在将描述JDBC连接配置中最重要的设置.
+ </para>
+
+ <para>
+ 如果你设置如下属性,Hibernate将使用<literal>java.sql.DriverManager</literal>来获得(和缓存)JDBC连接 :
+ </para>
+
+ <table frame="topbot">
+ <title>
+ Hibernate JDBC属性
+ </title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>
+ 属性名
+ </entry>
+ <entry>
+ 用途
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.connection.driver_class</literal>
+ </entry>
+ <entry>
+ <emphasis>jdbc驱动类</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.url</literal>
+ </entry>
+ <entry>
+ <emphasis>jdbc URL</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.username</literal>
+ </entry>
+ <entry>
+ <emphasis>数据库用户</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.password</literal>
+ </entry>
+ <entry>
+ <emphasis>数据库用户密码</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.pool_size</literal>
+ </entry>
+ <entry>
+ <emphasis>连接池容量上限数目</emphasis>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 但Hibernate自带的连接池算法相当不成熟.
+ 它只是为了让你快些上手<emphasis>,并不适合用于产品系统</emphasis>或性能测试中。
+ 出于最佳性能和稳定性考虑你应该使用第三方的连接池。只需要用特定连接池的设置替换
+ <literal>hibernate.connection.pool_size</literal>即可。这将关闭Hibernate自带的连接池.
+ 例如, 你可能会想用C3P0.
+ </para>
+
+ <para>
+ C3P0是一个随Hibernate一同分发的开源的JDBC连接池, 它位于<literal>lib</literal>目录下。
+ 如果你设置了<literal>hibernate.c3p0.*</literal>相关的属性, Hibernate将使用
+ <literal>C3P0ConnectionProvider</literal>来缓存JDBC连接. 如果你更原意使用Proxool, 请参考发
+ 行包中的<literal>hibernate.properties</literal>并到Hibernate网站获取更多的信息.
+ </para>
+
+ <para>
+ 这是一个使用C3P0的<literal>hibernate.properties</literal>样例文件:
+ </para>
+
+ <programlisting id="c3p0-configuration" revision="1"><![CDATA[hibernate.connection.driver_class = org.postgresql.Driver
+hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
+hibernate.connection.username = myuser
+hibernate.connection.password = secret
+hibernate.c3p0.min_size=5
+hibernate.c3p0.max_size=20
+hibernate.c3p0.timeout=1800
+hibernate.c3p0.max_statements=50
+hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
+
+ <para>
+ 为了能在应用程序服务器(application server)中使用Hibernate, 应当总是将Hibernate
+ 配置成从注册在JNDI中的<literal>Datasource</literal>处获得连接,你至少需要设置下列属性中的一个:
+ </para>
+
+ <table frame="topbot">
+ <title>
+ Hibernate数据源属性
+ </title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>
+ 属性名
+ </entry>
+ <entry>
+ 用途
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.connection.datasource</literal>
+ </entry>
+ <entry>
+ <emphasis>数据源JNDI名字</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.url</literal>
+ </entry>
+ <entry>
+ <emphasis>JNDI提供者的URL</emphasis> (可选)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.class</literal>
+ </entry>
+ <entry>
+ <emphasis>JNDI <literal>InitialContextFactory</literal>类</emphasis> (可选)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.username</literal>
+ </entry>
+ <entry>
+ <emphasis>数据库用户</emphasis> (可选)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.password</literal>
+ </entry>
+ <entry>
+ <emphasis>数据库用户密码</emphasis> (可选)
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 这是一个使用应用程序服务器提供的JNDI数据源的<literal>hibernate.properties</literal>样例文件:
+ </para>
+
+ <programlisting><![CDATA[hibernate.connection.datasource = java:/comp/env/jdbc/test
+hibernate.transaction.factory_class = \
+ org.hibernate.transaction.JTATransactionFactory
+hibernate.transaction.manager_lookup_class = \
+ org.hibernate.transaction.JBossTransactionManagerLookup
+hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
+
+ <para>
+ 从JNDI数据源获得的JDBC连接将自动参与到应用程序服务器中容器管理的事务(container-managed transactions)中去.
+ </para>
+
+ <para>
+ 任何连接(connection)属性的属性名都要以"<literal>hibernate.connnection</literal>"开头.
+ 例如, 你可能会使用<literal>hibernate.connection.charSet</literal>来指定字符集<literal>charSet</literal>.
+ </para>
+
+ <para>
+ 通过实现<literal>org.hibernate.connection.ConnectionProvider</literal>接口,你可以定义属于
+ 你自己的获得JDBC连接的插件策略。通过设置<literal>hibernate.connection.provider_class</literal>,
+ 你可以选择一个自定义的实现.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-optional" revision="1">
+ <title>
+ 可选的配置属性
+ </title>
+
+ <para>
+ 有大量属性能用来控制Hibernate在运行期的行为. 它们都是可选的, 并拥有适当的默认值.
+ </para>
+
+ <para>
+ <emphasis>警告: 其中一些属性是"系统级(system-level)的".</emphasis>
+ 系统级属性只能通过<literal>java -Dproperty=value</literal>或
+ <literal>hibernate.properties</literal>来设置, 而<emphasis>不能</emphasis>用上面描述的其他方法来设置.
+ </para>
+
+ <table frame="topbot" id="configuration-optional-properties" revision="8">
+ <title>
+ Hibernate配置属性
+ </title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>
+ 属性名
+ </entry>
+ <entry>
+ 用途
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.dialect</literal>
+ </entry>
+ <entry>
+ 一个Hibernate <literal>Dialect</literal>类名允许Hibernate针对特定的关系数据库生成优化的SQL.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>full.classname.of.Dialect</literal>
+
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.show_sql</literal>
+ </entry>
+ <entry>
+ 输出所有SQL语句到控制台.
+ 有一个另外的选择是把<literal>org.hibernate.SQL</literal>这个log category设为<literal>debug</literal>。
+ <para>
+ <emphasis role="strong">eg.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.format_sql</literal>
+ </entry>
+ <entry>
+ 在log和console中打印出更漂亮的SQL。
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_schema</literal>
+ </entry>
+ <entry>
+ 在生成的SQL中, 将给定的schema/tablespace附加于非全限定名的表名上.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>SCHEMA_NAME</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_catalog</literal>
+ </entry>
+ <entry>
+ 在生成的SQL中, 将给定的catalog附加于非全限定名的表名上.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>CATALOG_NAME</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.session_factory_name</literal>
+ </entry>
+ <entry>
+ <literal>SessionFactory</literal>创建后,将自动使用这个名字绑定到JNDI中.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>jndi/composite/name</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.max_fetch_depth</literal>
+ </entry>
+ <entry>
+ 为单向关联(一对一, 多对一)的外连接抓取(outer join fetch)树设置最大深度.
+ 值为<literal>0</literal>意味着将关闭默认的外连接抓取.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ 建议在<literal>0</literal>到<literal>3</literal>之间取值
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_batch_fetch_size</literal>
+ </entry>
+ <entry>
+ 为Hibernate关联的批量抓取设置默认数量.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ 建议的取值为<literal>4</literal>, <literal>8</literal>,
+ 和<literal>16</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_entity_mode</literal>
+ </entry>
+ <entry>
+ 为由这个<literal>SessionFactory</literal>打开的所有Session指定默认的实体表现模式.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>dynamic-map</literal>, <literal>dom4j</literal>,
+ <literal>pojo</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.order_updates</literal>
+ </entry>
+ <entry>
+ 强制Hibernate按照被更新数据的主键,为SQL更新排序。这么做将减少在高并发系统中事务的死锁。
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.generate_statistics</literal>
+ </entry>
+ <entry>
+ 如果开启, Hibernate将收集有助于性能调节的统计数据.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.use_identifer_rollback</literal>
+ </entry>
+ <entry>
+ 如果开启, 在对象被删除时生成的标识属性将被重设为默认值.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.use_sql_comments</literal>
+ </entry>
+ <entry>
+ 如果开启, Hibernate将在SQL中生成有助于调试的注释信息, 默认值为<literal>false</literal>.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-jdbc-properties" revision="8">
+ <title>
+ Hibernate JDBC和连接(connection)属性
+ </title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>
+ 属性名
+ </entry>
+ <entry>
+ 用途
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.fetch_size</literal>
+ </entry>
+ <entry>
+ 非零值,指定JDBC抓取数量的大小 (调用<literal>Statement.setFetchSize()</literal>).
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.batch_size</literal>
+ </entry>
+ <entry>
+ 非零值,允许Hibernate使用JDBC2的批量更新.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ 建议取<literal>5</literal>到<literal>30</literal>之间的值
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.batch_versioned_data</literal>
+ </entry>
+ <entry>
+ 如果你想让你的JDBC驱动从<literal>executeBatch()</literal>返回正确的行计数 ,
+ 那么将此属性设为<literal>true</literal>(开启这个选项通常是安全的).
+ 同时,Hibernate将为自动版本化的数据使用批量DML. 默认值为<literal>false</literal>.
+ <para>
+ <emphasis role="strong">eg.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.factory_class</literal>
+ </entry>
+ <entry>
+ 选择一个自定义的<literal>Batcher</literal>. 多数应用程序不需要这个配置属性.
+ <para>
+ <emphasis role="strong">eg.</emphasis>
+ <literal>classname.of.BatcherFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.use_scrollable_resultset</literal>
+ </entry>
+ <entry>
+ 允许Hibernate使用JDBC2的可滚动结果集.
+ 只有在使用用户提供的JDBC连接时,这个选项才是必要的,
+ 否则Hibernate会使用连接的元数据.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.use_streams_for_binary</literal>
+ </entry>
+ <entry>
+ 在JDBC读写<literal>binary (二进制)</literal>或<literal>serializable (可序列化)</literal>
+ 的类型时使用流(stream)(系统级属性).
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.use_get_generated_keys</literal>
+ </entry>
+ <entry>
+ 在数据插入数据库之后,允许使用JDBC3 <literal>PreparedStatement.getGeneratedKeys()</literal>
+ 来获取数据库生成的key(键)。需要JDBC3+驱动和JRE1.4+, 如果你的数据库驱动在使用Hibernate的标
+ 识生成器时遇到问题,请将此值设为false. 默认情况下将使用连接的元数据来判定驱动的能力.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.provider_class</literal>
+ </entry>
+ <entry>
+ 自定义<literal>ConnectionProvider</literal>的类名, 此类用来向Hibernate提供JDBC连接.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>classname.of.ConnectionProvider</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.isolation</literal>
+ </entry>
+ <entry>
+ 设置JDBC事务隔离级别. 查看<literal>java.sql.Connection</literal>来了解各个值的具体意义,
+ 但请注意多数数据库都不支持所有的隔离级别.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>1, 2, 4, 8</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.autocommit</literal>
+ </entry>
+ <entry>
+ 允许被缓存的JDBC连接开启自动提交(autocommit) (不建议).
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.release_mode</literal>
+ </entry>
+ <entry>
+ 指定Hibernate在何时释放JDBC连接. 默认情况下,直到Session被显式关闭或被断开连接时,才会释放JDBC连接.
+ 对于应用程序服务器的JTA数据源, 你应当使用<literal>after_statement</literal>, 这样在每次JDBC调用后,都会主动的释放连接.
+ 对于非JTA的连接, 使用<literal>after_transaction</literal>在每个事务结束时释放连接是合理的.
+ <literal>auto</literal>将为JTA和CMT事务策略选择<literal>after_statement</literal>,
+ 为JDBC事务策略选择<literal>after_transaction</literal>.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>auto</literal> (默认) | <literal>on_close</literal> |
+ <literal>after_transaction</literal> | <literal>after_statement</literal>
+ </para>
+ <para>
+
+ 注意,这些设置仅对通过<literal>SessionFactory.openSession</literal>得到的<literal>Session</literal>起作用。对于通过<literal>SessionFactory.getCurrentSession</literal>得到的<literal>Session</literal>,所配置的<literal>CurrentSessionContext</literal>实现控制这些<literal>Session</literal>的连接释放模式。请参阅<xref linkend="architecture-current-session"/>。
+ </para>
+
+
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.<emphasis><propertyName></emphasis></literal>
+ </entry>
+ <entry>
+ 将JDBC属性<literal>propertyName</literal>传递到<literal>DriverManager.getConnection()</literal>中去.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.<emphasis><propertyName></emphasis></literal>
+ </entry>
+ <entry>
+ 将属性<literal>propertyName</literal>传递到JNDI <literal>InitialContextFactory</literal>中去.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-cache-properties" revision="7">
+ <title>
+ Hibernate缓存属性
+ </title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>
+ 属性名
+ </entry>
+ <entry>
+ 用途
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.cache.provider_class</literal>
+ </entry>
+ <entry>
+ 自定义的<literal>CacheProvider</literal>的类名.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>classname.of.CacheProvider</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_minimal_puts</literal>
+ </entry>
+ <entry>
+ 以频繁的读操作为代价, 优化二级缓存来最小化写操作. 在Hibernate3中,这个设置对的集群缓存非常有用,
+ 对集群缓存的实现而言,默认是开启的.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_query_cache</literal>
+ </entry>
+ <entry>
+ 允许查询缓存, 个别查询仍然需要被设置为可缓存的.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_second_level_cache</literal>
+ </entry>
+ <entry>
+ 能用来完全禁止使用二级缓存. 对那些在类的映射定义中指定<literal><cache></literal>的类,会默认开启二级缓存.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.query_cache_factory</literal>
+ </entry>
+ <entry>
+ 自定义实现<literal>QueryCache</literal>接口的类名,
+ 默认为内建的<literal>StandardQueryCache</literal>.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>classname.of.QueryCache</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.region_prefix</literal>
+ </entry>
+ <entry>
+ 二级缓存区域名的前缀.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>prefix</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_structured_entries</literal>
+ </entry>
+ <entry>
+ 强制Hibernate以更人性化的格式将数据存入二级缓存.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-transaction-properties" revision="9">
+ <title>
+ Hibernate事务属性
+ </title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>
+ 属性名
+ </entry>
+ <entry>
+ 用途
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.factory_class</literal>
+ </entry>
+ <entry>
+ 一个<literal>TransactionFactory</literal>的类名, 用于Hibernate <literal>Transaction</literal> API
+ (默认为<literal>JDBCTransactionFactory</literal>).
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>classname.of.TransactionFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>jta.UserTransaction</literal>
+ </entry>
+ <entry>
+ 一个JNDI名字,被<literal>JTATransactionFactory</literal>用来从应用服务器获取JTA <literal>UserTransaction</literal>.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>jndi/composite/name</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.manager_lookup_class</literal>
+ </entry>
+ <entry>
+ 一个<literal>TransactionManagerLookup</literal>的类名
+ - 当使用JVM级缓存,或在JTA环境中使用hilo生成器的时候需要该类.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>classname.of.TransactionManagerLookup</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.flush_before_completion</literal>
+ </entry>
+ <entry>
+ 如果开启, session在事务完成后将被自动清洗(flush)。 现在更好的方法是使用自动session上下文管理。请参见<xref linkend="architecture-current-session"/>。
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.auto_close_session</literal>
+ </entry>
+ <entry>
+ 如果开启, session在事务完成后将被自动关闭。 现在更好的方法是使用自动session上下文管理。请参见<xref linkend="architecture-current-session"/>。
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-misc-properties" revision="10">
+ <title>
+ 其他属性
+ </title>
+
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>
+ 属性名
+ </entry>
+ <entry>
+ 用途
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.current_session_context_class</literal>
+ </entry>
+ <entry>
+ 为"当前"
+ <literal>Session</literal>指定一个(自定义的)策略。关于内置策略的详情,请参见<xref linkend="architecture-current-session"/> 。
+ <para>
+ <emphasis role="strong">eg.</emphasis>
+ <literal>jta</literal> | <literal>thread</literal> |
+ <literal>managed</literal> | <literal>custom.Class</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.query.factory_class</literal>
+ </entry>
+ <entry>
+ 选择HQL解析器的实现.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>org.hibernate.hql.ast.ASTQueryTranslatorFactory</literal> or
+ <literal>org.hibernate.hql.classic.ClassicQueryTranslatorFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.query.substitutions</literal>
+ </entry>
+ <entry>
+ 将Hibernate查询中的符号映射到SQL查询中的符号
+ (符号可能是函数名或常量名字).
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.hbm2ddl.auto</literal>
+ </entry>
+ <entry>
+ 在<literal>SessionFactory</literal>创建时,自动检查数据库结构,或者将数据库schema的DDL导出到数据库. 使用
+ <literal>create-drop</literal>时,在显式关闭<literal>SessionFactory</literal>时,将drop掉数据库schema.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>validate</literal> | <literal>update</literal> |
+ <literal>create</literal> | <literal>create-drop</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cglib.use_reflection_optimizer</literal>
+ </entry>
+ <entry>
+ 开启CGLIB来替代运行时反射机制(系统级属性). 反射机制有时在除错时比较有用.
+ 注意即使关闭这个优化, Hibernate还是需要CGLIB. 你不能在<literal>hibernate.cfg.xml</literal>中设置此属性.
+ <para>
+ <emphasis role="strong">取值</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="configuration-optional-dialects" revision="1">
+ <title>
+ SQL方言
+ </title>
+
+ <para>
+ 你应当总是为你的数据库将<literal>hibernate.dialect</literal>属性设置成正确的
+ <literal>org.hibernate.dialect.Dialect</literal>子类. 如果你指定一种方言,
+ Hibernate将为上面列出的一些属性使用合理的默认值, 为你省去了手工指定它们的功夫.
+ </para>
+
+ <table frame="topbot" id="sql-dialects" revision="2">
+ <title>
+ Hibernate SQL方言 (<literal>hibernate.dialect</literal>)
+ </title>
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>RDBMS</entry>
+ <entry>
+ 方言
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>DB2</entry> <entry><literal>org.hibernate.dialect.DB2Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>DB2 AS/400</entry> <entry><literal>org.hibernate.dialect.DB2400Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>DB2 OS390</entry> <entry><literal>org.hibernate.dialect.DB2390Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>PostgreSQL</entry> <entry><literal>org.hibernate.dialect.PostgreSQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL</entry> <entry><literal>org.hibernate.dialect.MySQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL with InnoDB</entry> <entry><literal>org.hibernate.dialect.MySQLInnoDBDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL with MyISAM</entry> <entry><literal>org.hibernate.dialect.MySQLMyISAMDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Oracle (any version)</entry> <entry><literal>org.hibernate.dialect.OracleDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Oracle 9i/10g</entry> <entry><literal>org.hibernate.dialect.Oracle9Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>Sybase</entry> <entry><literal>org.hibernate.dialect.SybaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Sybase Anywhere</entry> <entry><literal>org.hibernate.dialect.SybaseAnywhereDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Microsoft SQL Server</entry> <entry><literal>org.hibernate.dialect.SQLServerDialect</literal></entry>
+ </row>
+ <row>
+ <entry>SAP DB</entry> <entry><literal>org.hibernate.dialect.SAPDBDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Informix</entry> <entry><literal>org.hibernate.dialect.InformixDialect</literal></entry>
+ </row>
+ <row>
+ <entry>HypersonicSQL</entry> <entry><literal>org.hibernate.dialect.HSQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Ingres</entry> <entry><literal>org.hibernate.dialect.IngresDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Progress</entry> <entry><literal>org.hibernate.dialect.ProgressDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Mckoi SQL</entry> <entry><literal>org.hibernate.dialect.MckoiDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Interbase</entry> <entry><literal>org.hibernate.dialect.InterbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Pointbase</entry> <entry><literal>org.hibernate.dialect.PointbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>FrontBase</entry> <entry><literal>org.hibernate.dialect.FrontbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Firebird</entry> <entry><literal>org.hibernate.dialect.FirebirdDialect</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-outerjoin" revision="4">
+ <title>
+ 外连接抓取(Outer Join Fetching)
+ </title>
+
+ <para>
+ 如果你的数据库支持ANSI, Oracle或Sybase风格的外连接, <emphasis>外连接抓取</emphasis>通常能通过限制往返数据库次数
+ (更多的工作交由数据库自己来完成)来提高效率. 外连接抓取允许在单个<literal>SELECT</literal>SQL语句中,
+ 通过many-to-one, one-to-many, many-to-many和one-to-one关联获取连接对象的整个对象图.
+ </para>
+
+ <para>
+ 将<literal>hibernate.max_fetch_depth</literal>设为<literal>0</literal>能在<emphasis>全局</emphasis>
+ 范围内禁止外连接抓取. 设为<literal>1</literal>或更高值能启用one-to-one和many-to-oneouter关联的外连接抓取, 它们通过
+ <literal>fetch="join"</literal>来映射.
+ </para>
+
+ <para>
+ 参见<xref linkend="performance-fetching"/>获得更多信息.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-binarystreams" revision="1">
+ <title>
+ 二进制流 (Binary Streams)
+ </title>
+
+ <para>
+ Oracle限制那些通过JDBC驱动传输的<literal>字节</literal>数组的数目. 如果你希望使用<literal>二进值 (binary)</literal>或
+ <literal>可序列化的 (serializable)</literal>类型的大对象, 你应该开启
+ <literal>hibernate.jdbc.use_streams_for_binary</literal>属性.
+ <emphasis>这是系统级属性.</emphasis>
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-cacheprovider" revision="2">
+ <title>
+ 二级缓存与查询缓存
+ </title>
+
+ <para>
+ 以<literal>hibernate.cache</literal>为前缀的属性允许你在Hibernate中,使用进程或群集范围内的二级缓存系统.
+ 参见<xref linkend="performance-cache"/>获取更多的详情.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-querysubstitution">
+ <title>
+ 查询语言中的替换
+ </title>
+
+ <para>
+ 你可以使用<literal>hibernate.query.substitutions</literal>在Hibernate中定义新的查询符号.
+ 例如:
+ </para>
+
+ <programlisting>hibernate.query.substitutions true=1, false=0</programlisting>
+
+ <para>
+ 将导致符号<literal>true</literal>和<literal>false</literal>在生成的SQL中被翻译成整数常量.
+ </para>
+
+ <programlisting>hibernate.query.substitutions toLowercase=LOWER</programlisting>
+
+ <para>
+ 将允许你重命名SQL中的<literal>LOWER</literal>函数.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-statistics" revision="2">
+ <title>
+ Hibernate的统计(statistics)机制
+ </title>
+
+ <para>
+ 如果你开启<literal>hibernate.generate_statistics</literal>, 那么当你通过
+ <literal>SessionFactory.getStatistics()</literal>调整正在运行的系统时,Hibernate将导出大量有用的数据.
+ Hibernate甚至能被配置成通过JMX导出这些统计信息. 参考<literal>org.hibernate.stats</literal>中接口的Javadoc,以获得更多信息.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="configuration-logging">
+ <title>
+ 日志
+ </title>
+
+ <para>
+ Hibernate使用Apache commons-logging来为各种事件记录日志.
+ </para>
+
+ <para>
+ commons-logging将直接输出到Apache Log4j(如果在类路径中包括<literal>log4j.jar</literal>)或
+ JDK1.4 logging (如果运行在JDK1.4或以上的环境下). 你可以从<literal>http://jakarta.apache.org</literal>
+ 下载Log4j. 要使用Log4j,你需要将<literal>log4j.properties</literal>文件放置在类路径下, 随Hibernate
+ 一同分发的样例属性文件在<literal>src/</literal>目录下.
+ </para>
+
+ <para>
+ 我们强烈建议你熟悉一下Hibernate的日志消息. 在不失可读性的前提下,
+ 我们做了很多工作,使Hibernate的日志可能地详细. 这是必要的查错利器.
+ 最令人感兴趣的日志分类有如下这些:
+ </para>
+
+ <table frame="topbot" id="log-categories" revision="2">
+ <title>
+ Hibernate日志类别
+ </title>
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>
+ 类别
+ </entry>
+ <entry>
+ 功能
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>org.hibernate.SQL</literal></entry>
+ <entry>
+ 在所有SQL DML语句被执行时为它们记录日志
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.type</literal></entry>
+ <entry>
+ 为所有JDBC参数记录日志
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.tool.hbm2ddl</literal></entry>
+ <entry>
+ 在所有SQL DDL语句执行时为它们记录日志
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.pretty</literal></entry>
+ <entry>
+ 在session清洗(flush)时,为所有与其关联的实体(最多20个)的状态记录日志
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.cache</literal></entry>
+ <entry>
+ 为所有二级缓存的活动记录日志
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction</literal></entry>
+ <entry>
+ 为事务相关的活动记录日志
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.jdbc</literal></entry>
+ <entry>
+ 为所有JDBC资源的获取记录日志
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.hql.AST</literal></entry>
+ <entry>
+ 在解析查询的时候,记录HQL和SQL的AST分析日志
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.secure</literal></entry>
+ <entry>
+ 为JAAS认证请求做日志
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate</literal></entry>
+ <entry>
+ 为任何Hibernate相关信息做日志 (信息量较大, 但对查错非常有帮助)
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 在使用Hibernate开发应用程序时, 你应当总是为<literal>org.hibernate.SQL</literal>
+ 开启<literal>debug</literal>级别的日志记录,或者开启<literal>hibernate.show_sql</literal>属性。
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-namingstrategy">
+ <title>
+ 实现<literal>NamingStrategy</literal>
+ </title>
+
+ <para>
+ <literal>org.hibernate.cfg.NamingStrategy</literal>接口允许你为数据库中的对象和schema
+ 元素指定一个“命名标准”.
+ </para>
+
+ <para>
+ 你可能会提供一些通过Java标识生成数据库标识或将映射定义文件中"逻辑"表/列名处理成"物理"表/列名的规则.
+ 这个特性有助于减少冗长的映射定义文件.
+ </para>
+
+ <para>
+ 在加入映射定义前,你可以调用
+ <literal>Configuration.setNamingStrategy()</literal>指定一个不同的命名策略:
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration()
+ .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
+ .addFile("Item.hbm.xml")
+ .addFile("Bid.hbm.xml")
+ .buildSessionFactory();]]></programlisting>
+
+ <para>
+ <literal>org.hibernate.cfg.ImprovedNamingStrategy</literal>是一个内建的命名策略, 对
+ 一些应用程序而言,可能是非常有用的起点.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-xmlconfig" revision="2">
+ <title>
+ XML配置文件
+ </title>
+
+ <para>
+ 另一个配置方法是在<literal>hibernate.cfg.xml</literal>文件中指定一套完整的配置.
+ 这个文件可以当成<literal>hibernate.properties</literal>的替代。 若两个文件同时存在,它将覆盖前者的属性.
+ </para>
+
+ <para>
+ XML配置文件被默认是放在<literal>CLASSPATH</literal>的根目录下. 这是一个例子:
+ </para>
+ <para>
+
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <!-- 以/jndi/name绑定到JNDI的SessionFactory实例 -->
+ <session-factory
+ name="java:hibernate/SessionFactory">
+
+ <!-- 属性 -->
+ <property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
+ <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
+ <property name="show_sql">false</property>
+ <property name="transaction.factory_class">
+ org.hibernate.transaction.JTATransactionFactory
+ </property>
+ <property name="jta.UserTransaction">java:comp/UserTransaction</property>
+
+ <!-- 映射定义文件 -->
+ <mapping resource="org/hibernate/auction/Item.hbm.xml"/>
+ <mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
+
+ <!-- 缓存设置 -->
+ <class-cache class="org.hibernate.auction.Item" usage="read-write"/>
+ <class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
+ <collection-cache collection="org.hibernate.auction.Item.bids" usage="read-write"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ 如你所见, 这个方法优势在于,在配置文件中指出了映射定义文件的名字. 一旦你需要调整Hibernate的缓存,
+ <literal>hibernate.cfg.xml</literal>也是更方便. 注意,使用<literal>hibernate.properties</literal>还是
+ <literal>hibernate.cfg.xml</literal>完全是由你来决定, 除了上面提到的XML语法的优势之外, 两者是等价的.
+ </para>
+
+ <para>
+ 使用XML配置,使得启动Hibernate变的异常简单, 如下所示,一行代码就可以搞定:
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration().configure().buildSessionFactory();]]></programlisting>
+
+ <para>
+ 你可以使用如下代码来添加一个不同的XML配置文件
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration()
+ .configure("catdb.cfg.xml")
+ .buildSessionFactory();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="configuration-j2ee" revision="1">
+ <title>
+ J2EE应用程序服务器的集成
+ </title>
+
+ <para>
+ 针对J2EE体系,Hibernate有如下几个集成的方面:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>容器管理的数据源(Container-managed datasources)</emphasis>:
+ Hibernate能使用通过容器管理,并由JNDI提供的JDBC连接. 通常, 特别是当处理多个数据源的分布式事务的时候,
+ 由一个JTA兼容的<literal>TransactionManager</literal>和一个
+ <literal>ResourceManager</literal>来处理事务管理(CMT, 容器管理的事务). 当然你可以通过
+ 编程方式来划分事务边界(BMT, Bean管理的事务). 或者为了代码的可移植性,你也也许会想使用可选的
+ Hibernate <literal>Transaction</literal> API.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>自动JNDI绑定</emphasis>: Hibernate可以在启动后将
+ <literal>SessionFactory</literal>绑定到JNDI.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>JTA Session绑定:</emphasis> Hibernate <literal>Session</literal>
+ 可以自动绑定到JTA事务作用的范围. 只需简单地从JNDI查找<literal>SessionFactory</literal>并获得当前的
+ <literal>Session</literal>. 当JTA事务完成时, 让Hibernate来处理
+ <literal>Session</literal>的清洗(flush)与关闭. 事务的划分可以是声明式的(CMT),也可以是编程式的(BMT/UserTransaction).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>JMX部署:</emphasis> 如果你使用支持JMX应用程序服务器(如, JBoss AS), 那么你可以选择将Hibernate部署成托管MBean.
+ 这将为你省去一行从<literal>Configuration</literal>构建<literal>SessionFactory</literal>的启动代码.
+ 容器将启动你的<literal>HibernateService</literal>, 并完美地处理好服务间的依赖关系 (在Hibernate启动前,数据源必须是可用的,等等).
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ 如果应用程序服务器抛出"connection containment"异常, 根据你的环境,也许该将配置属性
+ <literal>hibernate.connection.release_mode</literal>设为<literal>after_statement</literal>.
+ </para>
+ <sect2 id="configuration-optional-transactionstrategy" revision="3">
+ <title>
+ 事务策略配置
+ </title>
+
+ <para>
+ 在你的架构中,Hibernate的<literal>Session</literal> API是独立于任何事务分界系统的.
+ 如果你让Hibernate通过连接池直接使用JDBC, 你需要调用JDBC API来打开和关闭你的事务.
+ 如果你运行在J2EE应用程序服务器中, 你也许想用Bean管理的事务并在需要的时候调用JTA API和<literal>UserTransaction</literal>.
+ </para>
+
+ <para>
+ 为了让你的代码在两种(或其他)环境中可以移植,我们建议使用可选的Hibernate <literal>Transaction</literal> API,
+ 它包装并隐藏了底层系统. 你必须通过设置Hibernate配置属性<literal>hibernate.transaction.factory_class</literal>来指定
+ 一个<literal>Transaction</literal>实例的工厂类.
+ </para>
+
+ <para>
+ 有三个标准(内建)的选择:
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term><literal>org.hibernate.transaction.JDBCTransactionFactory</literal></term>
+ <listitem>
+ <para>
+ 委托给数据库(JDBC)事务(默认)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>org.hibernate.transaction.JTATransactionFactory</literal></term>
+ <listitem>
+ <para>
+ 如果在上下文环境中存在运行着的事务(如, EJB会话Bean的方法), 则委托给容器管
+ 理的事务, 否则,将启动一个新的事务,并使用Bean管理的事务.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>org.hibernate.transaction.CMTTransactionFactory</literal></term>
+ <listitem>
+ <para>
+ 委托给容器管理的JTA事务
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ 你也可以定义属于你自己的事务策略 (如, 针对CORBA的事务服务)
+ </para>
+
+ <para>
+ Hibernate的一些特性 (比如二级缓存, Contextual Sessions with JTA等等)需要访问在托管环境中的JTA <literal>TransactionManager</literal>.
+ 由于J2EE没有标准化一个单一的机制,Hibernate在应用程序服务器中,你必须指定Hibernate如何获得<literal>TransactionManager</literal>的引用:
+ </para>
+
+ <table frame="topbot" id="jtamanagerlookup" revision="1">
+ <title>JTA TransactionManagers</title>
+ <tgroup cols="2">
+ <colspec colwidth="2.5*"/>
+ <colspec colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>
+ Transaction工厂类
+ </entry>
+ <entry align="center">
+ 应用程序服务器
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>org.hibernate.transaction.JBossTransactionManagerLookup</literal></entry>
+ <entry align="center">JBoss</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.WeblogicTransactionManagerLookup</literal></entry>
+ <entry align="center">Weblogic</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.WebSphereTransactionManagerLookup</literal></entry>
+ <entry align="center">WebSphere</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</literal></entry>
+ <entry align="center">WebSphere 6</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.OrionTransactionManagerLookup</literal></entry>
+ <entry align="center">Orion</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.ResinTransactionManagerLookup</literal></entry>
+ <entry align="center">Resin</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.JOTMTransactionManagerLookup</literal></entry>
+ <entry align="center">JOTM</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.JOnASTransactionManagerLookup</literal></entry>
+ <entry align="center">JOnAS</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.JRun4TransactionManagerLookup</literal></entry>
+ <entry align="center">JRun4</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.BESTransactionManagerLookup</literal></entry>
+ <entry align="center">Borland ES</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-jndi" revision="3">
+ <title>
+ JNDI绑定的<literal>SessionFactory</literal>
+ </title>
+
+
+ <para>
+ 与JNDI绑定的Hibernate的<literal>SessionFactory</literal>能简化工厂的查询,简化创建新的<literal>Session</literal>.
+ 需要注意的是这与JNDI绑定<literal>Datasource</literal>没有关系, 它们只是恰巧用了相同的注册表!
+ </para>
+
+ <para>
+ 如果你希望将<literal>SessionFactory</literal>绑定到一个JNDI的名字空间,
+ 用属性<literal>hibernate.session_factory_name</literal>指定一个名字(如, <literal>java:hibernate/SessionFactory</literal>).
+ 如果不设置这个属性, <literal>SessionFactory</literal>将不会被绑定到JNDI中. (在以只读JNDI为默认实现的环境中,这个设置尤其有用, 如Tomcat.)
+ </para>
+
+ <para>
+ 在将<literal>SessionFactory</literal>绑定至JNDI时, Hibernate将使用<literal>hibernate.jndi.url</literal>,
+ 和<literal>hibernate.jndi.class</literal>的值来实例化初始环境(initial context).
+ 如果它们没有被指定, 将使用默认的<literal>InitialContext</literal>.
+ </para>
+
+ <para>
+ 在你调用<literal>cfg.buildSessionFactory()</literal>后, Hibernate会自动将<literal>SessionFactory</literal>注册到JNDI.
+ 这意味这你至少需要在你应用程序的启动代码(或工具类)中完成这个调用, 除非你使用<literal>HibernateService</literal>来做JMX部署 (见后面讨论).
+ </para>
+
+ <para>
+ 假若你使用JNDI <literal>SessionFactory</literal>,EJB或者任何其它类都可以从JNDI中找到此<literal>SessionFactory</literal>。
+ </para>
+
+ <para>
+ 我们建议,在受管理的环境中,把<literal>SessionFactory</literal>绑定到JNDI,在其它情况下,使用一个<literal>static(静态的)</literal>singleton。为了在你的应用程序代码中隐藏这些细节,我们还建议你用一个helper类把实际查找<literal>SessionFactory</literal>的代码隐藏起来,比如<literal>HibernateUtil.getSessionFactory()</literal>。注意,这个类也就可以方便地启动Hibernate,参见第一章。
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-j2ee-currentsession" revision="4">
+ <title>在JTA环境下使用Current Session context (当前session上下文)管理</title>
+
+ <para>
+ 在Hibernate中,管理<literal>Session</literal>和transaction最好的方法是自动的"当前"<literal>Session</literal>管理。请参见<xref linkend="architecture-current-session">contextual sessions</xref>一节的讨论。使用<literal>"jta"</literal>session上下文,假若在当前JTA事务中还没有Hibernate<literal>Session</literal>关联,第一次<literal>sessionFactory.getCurrentSession()</literal>调用会启动一个Session,并关联到当前的JTA事务。在<literal>"jta"</literal>上下文中调用<literal>getCurrentSession()</literal>获得的<literal>Session</literal>,会被设置为在transaction关闭的时候自动flush(清洗)、在transaction关闭之后自动关闭,每句语句之后主动释放JDBC连接。这就可以根据JTA事务的生命周期来管理与之关联的<literal>Session</literal>,用户代码中就可以不再考虑这些管理。你的代码也可以通过<literal>UserTransaction</literal>用编�!
�方式使用JTA,或者(我们建议,为了便于移植代码)使用Hibernate的<literal>Transaction</literal> API来设置transaction边界。如果你的代码运行在EJB容器中,建议对CMT使用声明式事务声明。
+
+ </para>
+ </sect2>
+ <sect2 id="configuration-j2ee-jmx" revision="1">
+ <title>
+ JMX部署
+ </title>
+
+ <para>
+ 为了将<literal>SessionFactory</literal>注册到JNDI中,<literal>cfg.buildSessionFactory()</literal>这行代码仍需在某处被执行.
+ 你可在一个<literal>static</literal>初始化块(像<literal>HibernateUtil</literal>中的那样)中执行它或将Hibernate部署为一个<emphasis>托管的服务</emphasis>.
+ </para>
+
+ <para>
+ 为了部署在一个支持JMX的应用程序服务器上,Hibernate和
+ <literal>org.hibernate.jmx.HibernateService</literal>一同分发,如Jboss AS。
+ 实际的部署和配置是由应用程序服务器提供者指定的. 这里是JBoss 4.0.x的<literal>jboss-service.xml</literal>样例:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<server>
+
+<mbean code="org.hibernate.jmx.HibernateService"
+ name="jboss.jca:service=HibernateFactory,name=HibernateFactory">
+
+ <!-- 必须的服务 -->
+ <depends>jboss.jca:service=RARDeployer</depends>
+ <depends>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>
+
+ <!-- 将Hibernate服务绑定到JNDI -->
+ <attribute name="JndiName">java:/hibernate/SessionFactory</attribute>
+
+ <!-- 数据源设置 -->
+ <attribute name="Datasource">java:HsqlDS</attribute>
+ <attribute name="Dialect">org.hibernate.dialect.HSQLDialect</attribute>
+
+ <!-- 事务集成 -->
+ <attribute name="TransactionStrategy">
+ org.hibernate.transaction.JTATransactionFactory</attribute>
+ <attribute name="TransactionManagerLookupStrategy">
+ org.hibernate.transaction.JBossTransactionManagerLookup</attribute>
+ <attribute name="FlushBeforeCompletionEnabled">true</attribute>
+ <attribute name="AutoCloseSessionEnabled">true</attribute>
+
+ <!-- 抓取选项 -->
+ <attribute name="MaximumFetchDepth">5</attribute>
+
+ <!-- 二级缓存 -->
+ <attribute name="SecondLevelCacheEnabled">true</attribute>
+ <attribute name="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>
+ <attribute name="QueryCacheEnabled">true</attribute>
+
+ <!-- 日志 -->
+ <attribute name="ShowSqlEnabled">true</attribute>
+
+ <!-- 映射定义文件 -->
+ <attribute name="MapResources">auction/Item.hbm.xml,auction/Category.hbm.xml</attribute>
+
+</mbean>
+
+</server>]]></programlisting>
+
+ <para>
+ 这个文件是部署在<literal>META-INF</literal>目录下的, 并会被打包到以<literal>.sar</literal> (service archive)为扩展名的JAR文件中.
+ 同时,你需要将Hibernate、它所需要的第三方库、你编译好的持久化类以及你的映射定义文件打包进同一个文档.
+ 你的企业Bean(一般为会话Bean)可能会被打包成它们自己的JAR文件, 但你也许会将EJB JAR文件一同包含进能独立(热)部署的主服务文档.
+ 参考JBoss AS文档以了解更多的JMX服务与EJB部署的信息.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/events.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/events.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/events.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/events.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,247 @@
+<chapter id="events">
+ <title>
+ 拦截器与事件(Interceptors and events)
+ </title>
+
+ <para>
+ 应用程序能够响应Hibernate内部产生的特定事件是非常有用的。这样就允许实现某些通用的功能
+ 以及允许对Hibernate功能进行扩展。
+ </para>
+
+ <sect1 id="objectstate-interceptors" revision="3">
+ <title>
+ 拦截器(Interceptors)
+ </title>
+
+ <para>
+ <literal>Interceptor</literal>接口提供了从会话(session)回调(callback)应用程序(application)的机制,
+ 这种回调机制可以允许应用程序在持久化对象被保存、更新、删除或是加载之前,检查并(或)修改其
+ 属性。一个可能的用途,就是用来跟踪审核(auditing)信息。例如:下面的这个<literal>拦截器</literal>,会在一个实现了
+ <literal>Auditable</literal>接口的对象被创建时自动地设置<literal>createTimestamp</literal>属性,并在实现了
+ <literal>Auditable</literal>接口的对象被更新时,同步更新<literal>lastUpdateTimestamp</literal>属性。
+ </para>
+
+ <para>
+ 你可以直接实现<literal>Interceptor</literal>接口,也可以(最好)继承自<literal>EmptyInterceptor</literal>。
+ </para>
+
+ <programlisting><![CDATA[package org.hibernate.test;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.Transaction;
+import org.hibernate.type.Type;
+
+public class AuditInterceptor extends EmptyInterceptor {
+
+ private int updates;
+ private int creates;
+ private int loads;
+
+ public void onDelete(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+ // do nothing
+ }
+
+ public boolean onFlushDirty(Object entity,
+ Serializable id,
+ Object[] currentState,
+ Object[] previousState,
+ String[] propertyNames,
+ Type[] types) {
+
+ if ( entity instanceof Auditable ) {
+ updates++;
+ for ( int i=0; i < propertyNames.length; i++ ) {
+ if ( "lastUpdateTimestamp".equals( propertyNames[i] ) ) {
+ currentState[i] = new Date();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean onLoad(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+ if ( entity instanceof Auditable ) {
+ loads++;
+ }
+ return false;
+ }
+
+ public boolean onSave(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if ( entity instanceof Auditable ) {
+ creates++;
+ for ( int i=0; i<propertyNames.length; i++ ) {
+ if ( "createTimestamp".equals( propertyNames[i] ) ) {
+ state[i] = new Date();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void afterTransactionCompletion(Transaction tx) {
+ if ( tx.wasCommitted() ) {
+ System.out.println("Creations: " + creates + ", Updates: " + updates, "Loads: " + loads);
+ }
+ updates=0;
+ creates=0;
+ loads=0;
+ }
+
+}]]></programlisting>
+
+
+ <para>
+ 拦截器可以有两种:<literal>Session</literal>范围内的,和<literal>SessionFactory</literal>范围内的。
+ </para>
+
+ <para>
+ 当使用某个重载的SessionFactory.openSession()使用<literal>Interceptor</literal>作为参数调用打开一个session的时候,就指定了<literal>Session</literal>范围内的拦截器。
+
+ </para>
+
+ <programlisting><![CDATA[Session session = sf.openSession( new AuditInterceptor() );]]></programlisting>
+
+ <para>
+ <literal>SessionFactory</literal>范围内的拦截器要通过<literal>Configuration</literal>中注册,而这必须在创建<literal>SessionFactory</literal>之前。在这种情况下,给出的拦截器会被这个<literal>SessionFactory</literal>所打开的所有session使用了;除非session打开时明确指明了使用的拦截器。<literal>SessionFactory</literal>范围内的拦截器,必须是线程安全的,因为多个session可能并发使用这个拦截器,要因此小心不要保存与session相关的状态。
+ </para>
+
+ <programlisting><![CDATA[new Configuration().setInterceptor( new AuditInterceptor() );]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="objectstate-events" revision="4">
+ <title>
+ 事件系统(Event system)
+ </title>
+
+ <para>
+ 如果需要响应持久层的某些特殊事件,你也可以使用Hibernate3的事件框架。
+ 该事件系统可以用来替代拦截器,也可以作为拦截器的补充来使用。
+
+ </para>
+
+ <para>
+ 基本上,<literal>Session</literal>接口的每个方法都有相对应的事件。比如
+ <literal>LoadEvent</literal>,<literal>FlushEvent</literal>,等等(查阅XML配置文件
+ 的DTD,以及<literal>org.hibernate.event</literal>包来获得所有已定义的事件的列表)。当某个方
+ 法被调用时,Hibernate <literal>Session</literal>会生成一个相对应的事件并激活所
+ 有配置好的事件监听器。系统预设的监听器实现的处理过程就是被监听的方法要做的(被监听的方法所做的其实仅仅是激活监听器,
+ “实际”的工作是由监听器完成的)。不过,你可以自由地选择实现
+ 一个自己定制的监听器(比如,实现并注册用来处理处理<literal>LoadEvent</literal>的<literal>LoadEventListener</literal>接口),
+ 来负责处理所有的调用<literal>Session</literal>的<literal>load()</literal>方法的请求。
+ </para>
+
+ <para>
+ 监听器应该被看作是单例(singleton)对象,也就是说,所有同类型的事件的处理共享同一个监听器实例,因此监听器
+ 不应该保存任何状态(也就是不应该使用成员变量)。
+ </para>
+
+ <para>
+ 用户定制的监听器应该实现与所要处理的事件相对应的接口,或者从一个合适的基类继承(甚至是从Hibernate自带的默认事件监听器类继承,
+ 为了方便你这样做,这些类都被声明成non-final的了)。用户定制的监听器可以通过编程使用<literal>Configuration</literal>对象
+ 来注册,也可以在Hibernate的XML格式的配置文件中进行声明(不支持在Properties格式的配置文件声明监听器)。
+ 下面是一个用户定制的加载事件(load event)的监听器:
+ </para>
+
+ <programlisting><![CDATA[public class MyLoadListener implements LoadEventListener {
+ // this is the single method defined by the LoadEventListener interface
+ public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType)
+ throws HibernateException {
+ if ( !MySecurity.isAuthorized( event.getEntityClassName(), event.getEntityId() ) ) {
+ throw MySecurityException("Unauthorized access");
+ }
+ }
+}]]></programlisting>
+
+ <para>
+ 你还需要修改一处配置,来告诉Hibernate,除了默认的监听器,还要附加选定的监听器。
+ </para>
+
+<programlisting><![CDATA[<hibernate-configuration>
+ <session-factory>
+ ...
+ <event type="load">
+ <listener class="com.eg.MyLoadListener"/>
+ <listener class="org.hibernate.event.def.DefaultLoadEventListener"/>
+ </event>
+ </session-factory>
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ 看看用另一种方式,通过编程的方式来注册它。
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration();
+LoadEventListener[] stack = { new MyLoadListener(), new DefaultLoadEventListener() };
+cfg.EventListeners().setLoadEventListeners(stack);]]></programlisting>
+
+ <para>
+ 通过在XML配置文件声明而注册的监听器不能共享实例。如果在多个<literal><listener/></literal>节点中使用
+ 了相同的类的名字,则每一个引用都将会产生一个独立的实例。如果你需要在多个监听器类型之间共享
+ 监听器的实例,则你必须使用编程的方式来进行注册。
+ </para>
+
+ <para>
+ 为什么我们实现了特定监听器的接口,在注册的时候还要明确指出我们要注册哪个事件的监听器呢?
+ 这是因为一个类可能实现多个监听器的接口。在注册的时候明确指定要监听的事件,可以让启用或者禁用对某个事件的监听的配置工作简单些。
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-decl-security" revision="2">
+ <title>
+ Hibernate的声明式安全机制
+ </title>
+ <para>
+ 通常,Hibernate应用程序的声明式安全机制由会话外观层(session facade)所管理。
+ 现在,Hibernate3允许某些特定的行为由JACC进行许可管理,由JAAS进行授权管理。
+ 本功能是一个建立在事件框架之上的可选的功能。
+ </para>
+
+ <para>
+ 首先,你必须要配置适当的事件监听器(event listener),来激活使用JAAS管理授权的功能。
+ </para>
+
+ <programlisting><![CDATA[<listener type="pre-delete" class="org.hibernate.secure.JACCPreDeleteEventListener"/>
+<listener type="pre-update" class="org.hibernate.secure.JACCPreUpdateEventListener"/>
+<listener type="pre-insert" class="org.hibernate.secure.JACCPreInsertEventListener"/>
+<listener type="pre-load" class="org.hibernate.secure.JACCPreLoadEventListener"/>]]></programlisting>
+
+ <para>
+ 注意,<literal><listener type="..." class="..."/></literal>只是<literal><event type="..."><listener class="..."/></event></literal>的简写,对每一个事件类型都必须严格的有一个监听器与之对应。
+ </para>
+
+ <para>
+ 接下来,仍然在<literal>hibernate.cfg.xml</literal>文件中,绑定角色的权限:
+ </para>
+
+ <programlisting><![CDATA[<grant role="admin" entity-name="User" actions="insert,update,read"/>
+<grant role="su" entity-name="User" actions="*"/>]]></programlisting>
+
+ <para>
+ 这些角色的名字就是你的JACC provider所定义的角色的名字。
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/example_mappings.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/example_mappings.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/example_mappings.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/example_mappings.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,650 @@
+<chapter id="example-mappings">
+ <title>示例:复杂映射实例</title>
+ <para>
+ 本章展示了一些较为复杂的关系映射。
+ </para>
+
+ <sect1 id="example-mappings-emp">
+ <title>Employer(雇主)/Employee(雇员)</title>
+
+ <para>
+ 下面关于<literal>Employer</literal> 和 <literal>Employee</literal>的关系模型使用了一个真实的实体类
+ (<literal>Employment</literal>)来表述,这是因为对于相同的雇员和雇主可能会有多个雇佣时间段。
+ 对于金额和雇员姓名,用Components建模。
+
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/EmployerEmployee.gif" format="GIF" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../shared/images/EmployerEmployee.gif" format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ 映射文件可能是这样:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Employer" table="employers">
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employer_id_seq</param>
+ </generator>
+ </id>
+ <property name="name"/>
+ </class>
+
+ <class name="Employment" table="employment_periods">
+
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employment_id_seq</param>
+ </generator>
+ </id>
+ <property name="startDate" column="start_date"/>
+ <property name="endDate" column="end_date"/>
+
+ <component name="hourlyRate" class="MonetaryAmount">
+ <property name="amount">
+ <column name="hourly_rate" sql-type="NUMERIC(12, 2)"/>
+ </property>
+ <property name="currency" length="12"/>
+ </component>
+
+ <many-to-one name="employer" column="employer_id" not-null="true"/>
+ <many-to-one name="employee" column="employee_id" not-null="true"/>
+
+ </class>
+
+ <class name="Employee" table="employees">
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employee_id_seq</param>
+ </generator>
+ </id>
+ <property name="taxfileNumber"/>
+ <component name="name" class="Name">
+ <property name="firstName"/>
+ <property name="initial"/>
+ <property name="lastName"/>
+ </component>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 用<literal>SchemaExport</literal>生成表结构。
+ </para>
+
+ <programlisting><![CDATA[create table employers (
+ id BIGINT not null,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+create table employment_periods (
+ id BIGINT not null,
+ hourly_rate NUMERIC(12, 2),
+ currency VARCHAR(12),
+ employee_id BIGINT not null,
+ employer_id BIGINT not null,
+ end_date TIMESTAMP,
+ start_date TIMESTAMP,
+ primary key (id)
+)
+
+create table employees (
+ id BIGINT not null,
+ firstName VARCHAR(255),
+ initial CHAR(1),
+ lastName VARCHAR(255),
+ taxfileNumber VARCHAR(255),
+ primary key (id)
+)
+
+alter table employment_periods
+ add constraint employment_periodsFK0 foreign key (employer_id) references employers
+alter table employment_periods
+ add constraint employment_periodsFK1 foreign key (employee_id) references employees
+create sequence employee_id_seq
+create sequence employment_id_seq
+create sequence employer_id_seq]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-mappings-authorwork">
+ <title>Author(作家)/Work(作品)</title>
+
+ <para>
+
+ 考虑下面的<literal>Work</literal>,<literal>Author</literal> 和 <literal>Person</literal>模型的关系。
+ 我们用多对多关系来描述<literal>Work</literal> 和 <literal>Author</literal>,
+ 用一对一关系来描述<literal>Author</literal> 和 <literal>Person</literal>,
+ 另一种可能性是<literal>Author</literal>继承<literal>Person</literal>。
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/AuthorWork.gif" format="GIF" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../shared/images/AuthorWork.gif" format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ 下面的映射文件正确的描述了这些关系:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Work" table="works" discriminator-value="W">
+
+ <id name="id" column="id">
+ <generator class="native"/>
+ </id>
+ <discriminator column="type" type="character"/>
+
+ <property name="title"/>
+ <set name="authors" table="author_work">
+ <key column name="work_id"/>
+ <many-to-many class="Author" column name="author_id"/>
+ </set>
+
+ <subclass name="Book" discriminator-value="B">
+ <property name="text"/>
+ </subclass>
+
+ <subclass name="Song" discriminator-value="S">
+ <property name="tempo"/>
+ <property name="genre"/>
+ </subclass>
+
+ </class>
+
+ <class name="Author" table="authors">
+
+ <id name="id" column="id">
+ <!-- The Author must have the same identifier as the Person -->
+ <generator class="assigned"/>
+ </id>
+
+ <property name="alias"/>
+ <one-to-one name="person" constrained="true"/>
+
+ <set name="works" table="author_work" inverse="true">
+ <key column="author_id"/>
+ <many-to-many class="Work" column="work_id"/>
+ </set>
+
+ </class>
+
+ <class name="Person" table="persons">
+ <id name="id" column="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+
+ 映射中有4个表。<literal>works</literal>, <literal>authors</literal> 和 <literal>persons</literal>
+ 分别保存着work,author和person的数据。<literal>author_work</literal>是authors和works的关联表。
+ 表结构是由<literal>SchemaExport</literal>生成的。
+ </para>
+
+ <programlisting><![CDATA[create table works (
+ id BIGINT not null generated by default as identity,
+ tempo FLOAT,
+ genre VARCHAR(255),
+ text INTEGER,
+ title VARCHAR(255),
+ type CHAR(1) not null,
+ primary key (id)
+)
+
+create table author_work (
+ author_id BIGINT not null,
+ work_id BIGINT not null,
+ primary key (work_id, author_id)
+)
+
+create table authors (
+ id BIGINT not null generated by default as identity,
+ alias VARCHAR(255),
+ primary key (id)
+)
+
+create table persons (
+ id BIGINT not null generated by default as identity,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+alter table authors
+ add constraint authorsFK0 foreign key (id) references persons
+alter table author_work
+ add constraint author_workFK0 foreign key (author_id) references authors
+alter table author_work
+ add constraint author_workFK1 foreign key (work_id) references works]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-mappings-customerorderproduct">
+ <title>Customer(客户)/Order(订单)/Product(产品)</title>
+
+ <para>
+
+ 现在来考虑<literal>Customer</literal>,<literal>Order</literal> , <literal>LineItem</literal>
+ 和 <literal>Product</literal>关系的模型。<literal>Customer</literal> 和 <literal>Order</literal>之间
+ 是一对多的关系,但是我们怎么来描述<literal>Order</literal> / <literal>LineItem</literal> / <literal>Product</literal>呢?
+ 我可以把<literal>LineItem</literal>作为描述<literal>Order</literal> 和 <literal>Product</literal>
+ 多对多关系的关联类,在Hibernate,这叫做组合元素。
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/CustomerOrderProduct.gif" format="GIF" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../shared/images/CustomerOrderProduct.gif" format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ 映射文件如下:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Customer" table="customers">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ <set name="orders" inverse="true">
+ <key column="customer_id"/>
+ <one-to-many class="Order"/>
+ </set>
+ </class>
+
+ <class name="Order" table="orders">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="date"/>
+ <many-to-one name="customer" column="customer_id"/>
+ <list name="lineItems" table="line_items">
+ <key column="order_id"/>
+ <list-index column="line_number"/>
+ <composite-element class="LineItem">
+ <property name="quantity"/>
+ <many-to-one name="product" column="product_id"/>
+ </composite-element>
+ </list>
+ </class>
+
+ <class name="Product" table="products">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="serialNumber"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>customers</literal>, <literal>orders</literal>, <literal>line_items</literal> 和
+ <literal>products</literal> 分别保存着customer, order, order line item 和 product的数据。
+ <literal>line_items</literal>也作为连接orders 和 products的关联表。
+ </para>
+
+ <programlisting><![CDATA[create table customers (
+ id BIGINT not null generated by default as identity,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+create table orders (
+ id BIGINT not null generated by default as identity,
+ customer_id BIGINT,
+ date TIMESTAMP,
+ primary key (id)
+)
+
+create table line_items (
+ line_number INTEGER not null,
+ order_id BIGINT not null,
+ product_id BIGINT,
+ quantity INTEGER,
+ primary key (order_id, line_number)
+)
+
+create table products (
+ id BIGINT not null generated by default as identity,
+ serialNumber VARCHAR(255),
+ primary key (id)
+)
+
+alter table orders
+ add constraint ordersFK0 foreign key (customer_id) references customers
+alter table line_items
+ add constraint line_itemsFK0 foreign key (product_id) references products
+alter table line_items
+ add constraint line_itemsFK1 foreign key (order_id) references orders]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="misc">
+ <title>杂例</title>
+
+ <para>
+ 这些例子全部来自于Hibernate的test suite,同时你也可以找到其他有用的例子。
+ 可以参考Hibernate的<literal>test</literal>目录。
+ </para>
+
+ <para>TODO: put words around this stuff</para>
+
+ <sect2 id="example-mappings-typed-onetone">
+ <title>"Typed" one-to-one association</title>
+<programlisting><![CDATA[<class name="Person">
+ <id name="name"/>
+ <one-to-one name="address"
+ cascade="all">
+ <formula>name</formula>
+ <formula>'HOME'</formula>
+ </one-to-one>
+ <one-to-one name="mailingAddress"
+ cascade="all">
+ <formula>name</formula>
+ <formula>'MAILING'</formula>
+ </one-to-one>
+</class>
+
+<class name="Address" batch-size="2"
+ check="addressType in ('MAILING', 'HOME', 'BUSINESS')">
+ <composite-id>
+ <key-many-to-one name="person"
+ column="personName"/>
+ <key-property name="type"
+ column="addressType"/>
+ </composite-id>
+ <property name="street" type="text"/>
+ <property name="state"/>
+ <property name="zip"/>
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-composite-key">
+ <title>Composite key example</title>
+<programlisting><![CDATA[<class name="Customer">
+
+ <id name="customerId"
+ length="10">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="name" not-null="true" length="100"/>
+ <property name="address" not-null="true" length="200"/>
+
+ <list name="orders"
+ inverse="true"
+ cascade="save-update">
+ <key column="customerId"/>
+ <index column="orderNumber"/>
+ <one-to-many class="Order"/>
+ </list>
+
+</class>
+
+<class name="Order" table="CustomerOrder" lazy="true">
+ <synchronize table="LineItem"/>
+ <synchronize table="Product"/>
+
+ <composite-id name="id"
+ class="Order$Id">
+ <key-property name="customerId" length="10"/>
+ <key-property name="orderNumber"/>
+ </composite-id>
+
+ <property name="orderDate"
+ type="calendar_date"
+ not-null="true"/>
+
+ <property name="total">
+ <formula>
+ ( select sum(li.quantity*p.price)
+ from LineItem li, Product p
+ where li.productId = p.productId
+ and li.customerId = customerId
+ and li.orderNumber = orderNumber )
+ </formula>
+ </property>
+
+ <many-to-one name="customer"
+ column="customerId"
+ insert="false"
+ update="false"
+ not-null="true"/>
+
+ <bag name="lineItems"
+ fetch="join"
+ inverse="true"
+ cascade="save-update">
+ <key>
+ <column name="customerId"/>
+ <column name="orderNumber"/>
+ </key>
+ <one-to-many class="LineItem"/>
+ </bag>
+
+</class>
+
+<class name="LineItem">
+
+ <composite-id name="id"
+ class="LineItem$Id">
+ <key-property name="customerId" length="10"/>
+ <key-property name="orderNumber"/>
+ <key-property name="productId" length="10"/>
+ </composite-id>
+
+ <property name="quantity"/>
+
+ <many-to-one name="order"
+ insert="false"
+ update="false"
+ not-null="true">
+ <column name="customerId"/>
+ <column name="orderNumber"/>
+ </many-to-one>
+
+ <many-to-one name="product"
+ insert="false"
+ update="false"
+ not-null="true"
+ column="productId"/>
+
+</class>
+
+<class name="Product">
+ <synchronize table="LineItem"/>
+
+ <id name="productId"
+ length="10">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="description"
+ not-null="true"
+ length="200"/>
+ <property name="price" length="3"/>
+ <property name="numberAvailable"/>
+
+ <property name="numberOrdered">
+ <formula>
+ ( select sum(li.quantity)
+ from LineItem li
+ where li.productId = productId )
+ </formula>
+ </property>
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-composite-key-manytomany">
+ <title>共有组合键属性的多对多(Many-to-many with shared composite key attribute)</title>
+
+<programlisting><![CDATA[<class name="User" table="`User`">
+ <composite-id>
+ <key-property name="name"/>
+ <key-property name="org"/>
+ </composite-id>
+ <set name="groups" table="UserGroup">
+ <key>
+ <column name="userName"/>
+ <column name="org"/>
+ </key>
+ <many-to-many class="Group">
+ <column name="groupName"/>
+ <formula>org</formula>
+ </many-to-many>
+ </set>
+</class>
+
+<class name="Group" table="`Group`">
+ <composite-id>
+ <key-property name="name"/>
+ <key-property name="org"/>
+ </composite-id>
+ <property name="description"/>
+ <set name="users" table="UserGroup" inverse="true">
+ <key>
+ <column name="groupName"/>
+ <column name="org"/>
+ </key>
+ <many-to-many class="User">
+ <column name="userName"/>
+ <formula>org</formula>
+ </many-to-many>
+ </set>
+</class>
+]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-content-discrimination">
+ <title>Content based discrimination</title>
+<programlisting><![CDATA[<class name="Person"
+ discriminator-value="P">
+
+ <id name="id"
+ column="person_id"
+ unsaved-value="0">
+ <generator class="native"/>
+ </id>
+
+
+ <discriminator
+ type="character">
+ <formula>
+ case
+ when title is not null then 'E'
+ when salesperson is not null then 'C'
+ else 'P'
+ end
+ </formula>
+ </discriminator>
+
+ <property name="name"
+ not-null="true"
+ length="80"/>
+
+ <property name="sex"
+ not-null="true"
+ update="false"/>
+
+ <component name="address">
+ <property name="address"/>
+ <property name="zip"/>
+ <property name="country"/>
+ </component>
+
+ <subclass name="Employee"
+ discriminator-value="E">
+ <property name="title"
+ length="20"/>
+ <property name="salary"/>
+ <many-to-one name="manager"/>
+ </subclass>
+
+ <subclass name="Customer"
+ discriminator-value="C">
+ <property name="comments"/>
+ <many-to-one name="salesperson"/>
+ </subclass>
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-association-alternatekeys" revision="2">
+ <title>Associations on alternate keys</title>
+<programlisting><![CDATA[<class name="Person">
+
+ <id name="id">
+ <generator class="hilo"/>
+ </id>
+
+ <property name="name" length="100"/>
+
+ <one-to-one name="address"
+ property-ref="person"
+ cascade="all"
+ fetch="join"/>
+
+ <set name="accounts"
+ inverse="true">
+ <key column="userId"
+ property-ref="userId"/>
+ <one-to-many class="Account"/>
+ </set>
+
+ <property name="userId" length="8"/>
+
+</class>
+
+<class name="Address">
+
+ <id name="id">
+ <generator class="hilo"/>
+ </id>
+
+ <property name="address" length="300"/>
+ <property name="zip" length="5"/>
+ <property name="country" length="25"/>
+ <many-to-one name="person" unique="true" not-null="true"/>
+
+</class>
+
+<class name="Account">
+ <id name="accountId" length="32">
+ <generator class="uuid"/>
+ </id>
+
+ <many-to-one name="user"
+ column="userId"
+ property-ref="userId"/>
+
+ <property name="type" not-null="true"/>
+
+</class>]]></programlisting>
+ </sect2>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/example_parentchild.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/example_parentchild.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/example_parentchild.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/example_parentchild.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,306 @@
+<chapter id="example-parentchild">
+ <title>示例:父子关系(Parent Child Relationships)</title>
+ <para>
+ 刚刚接触Hibernate的人大多是从父子关系(parent / child type relationship)的建模入手的。父子关系的建模有两种方法。由于种种原因,最方便的方法是把<literal>Parent</literal>和<literal>Child</literal>都建模成实体类,并创建一个从<literal>Parent</literal>指向<literal>Child</literal>的<one-to-many>关联,对新手来说尤其如此。还有一种方法,就是将<literal>Child</literal>声明为一个<literal><composite-element></literal>(组合元素)。 事实上在Hibernate中one to many关联的默认语义远没有composite element贴近parent / child关系的通常语义。下面我们会阐述如何使用<emphasis>带有级联的双向一对多关联(bidirectional one to many association with cascades)</emphasis>去建立有效、优美的parent / child关系。这一点也不难!
+ </para>
+
+ <sect1 id="example-parentchild-collections">
+ <title>关于collections需要注意的一点</title>
+ <para>
+ Hibernate collections被当作其所属实体而不是其包含实体的一个逻辑部分。这非常重要!它主要体现为以下几点:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ 当删除或增加collection中对象的时候,collection所属者的版本值会递增。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 如果一个从collection中移除的对象是一个值类型(value type)的实例,比如composite element,那么这个对象的持久化状态将会终止,其在数据库中对应的记录会被删除。同样的,向collection增加一个value type的实例将会使之立即被持久化。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 另一方面,如果从一对多或多对多关联的collection中移除一个实体,在缺省情况下这个对象并不会被删除。这个行为是完全合乎逻辑的--改变一个实体的内部状态不应该使与它关联的实体消失掉!同样的,向collection增加一个实体不会使之被持久化。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 实际上,向Collection增加一个实体的缺省动作只是在两个实体之间创建一个连接而已,同样移除的时候也只是删除连接。这种处理对于所有的情况都是合适的。对于父子关系则是完全不适合的,在这种关系下,子对象的生存绑定于父对象的生存周期。
+ </para>
+
+ </sect1>
+ <sect1 id="example-parentchild-bidir">
+ <title>双向的一对多关系(Bidirectional one-to-many)</title>
+
+ <para>
+ 假设我们要实现一个简单的从Parent到Child的<one-to-many>关联。
+ </para>
+
+ <programlisting><![CDATA[<set name="children">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ 如果我们运行下面的代码
+ </para>
+
+ <programlisting><![CDATA[Parent p = .....;
+Child c = new Child();
+p.getChildren().add(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ <para>
+ Hibernate会产生两条SQL语句:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>一条<literal>INSERT</literal>语句,为<literal>c</literal>创建一条记录</para>
+ </listitem>
+ <listitem>
+ <para>
+ 一条<literal>UPDATE</literal>语句,创建从<literal>p</literal>到<literal>c</literal>的连接
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 这样做不仅效率低,而且违反了列<literal>parent_id</literal>非空的限制。我们可以通过在集合类映射上指定<literal>not-null="true"</literal>来解决违反非空约束的问题:
+ </para>
+
+ <programlisting><![CDATA[<set name="children">
+ <key column="parent_id" not-null="true"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ 然而,这并非是推荐的解决方法。
+ </para>
+
+ <para> 这种现象的根本原因是从<literal>p</literal>到<literal>c</literal>的连接(外键parent_id)没有被当作<literal>Child</literal>对象状态的一部分,因而没有在INSERT语句中被创建。因此解决的办法就是把这个连接添加到Child的映射中。
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="parent" column="parent_id" not-null="true"/>]]></programlisting>
+
+ <para>
+ (我们还需要为类<literal>Child</literal>添加<literal>parent</literal>属性)
+ </para>
+
+ <para>
+ 现在实体<literal>Child</literal>在管理连接的状态,为了使collection不更新连接,我们使用<literal>inverse</literal>属性。
+ </para>
+
+ <programlisting><![CDATA[<set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ 下面的代码是用来添加一个新的<literal>Child</literal>
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+c.setParent(p);
+p.getChildren().add(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ <para>
+ 现在,只会有一条<literal>INSERT</literal>语句被执行!
+ </para>
+
+ <para>
+ 为了让事情变得井井有条,可以为<literal>Parent</literal>加一个<literal>addChild()</literal>方法。
+ </para>
+
+ <programlisting><![CDATA[public void addChild(Child c) {
+ c.setParent(this);
+ children.add(c);
+}]]></programlisting>
+
+ <para>
+ 现在,添加<literal>Child</literal>的代码就是这样
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+p.addChild(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-cascades">
+ <title>级联生命周期(Cascading life cycle)</title>
+ <para>
+ 需要显式调用<literal>save()</literal>仍然很麻烦,我们可以用级联来解决这个问题。
+ </para>
+
+ <programlisting><![CDATA[<set name="children" inverse="true" cascade="all">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ 这样上面的代码可以简化为:
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+p.addChild(c);
+session.flush();]]></programlisting>
+
+ <para>
+ 同样的,保存或删除<literal>Parent</literal>对象的时候并不需要遍历其子对象。
+ 下面的代码会删除对象<literal>p</literal>及其所有子对象对应的数据库记录。
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+session.delete(p);
+session.flush();]]></programlisting>
+
+ <para>
+ 然而,这段代码
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = (Child) p.getChildren().iterator().next();
+p.getChildren().remove(c);
+c.setParent(null);
+session.flush();]]></programlisting>
+
+ <para>
+ 不会从数据库删除<literal>c</literal>;它只会删除与<literal>p</literal>之间的连接(并且会导致违反<literal>NOT NULL</literal>约束,在这个例子中)。你需要显式调用<literal>delete()</literal>来删除<literal>Child</literal>。 <!--,因为Hibernate并没有设计垃圾回收器!代码如下:-->
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = (Child) p.getChildren().iterator().next();
+p.getChildren().remove(c);
+session.delete(c);
+session.flush();]]></programlisting>
+
+
+ <para>
+ 在我们的例子中,如果没有父对象,子对象就不应该存在,如果将子对象从collection中移除,实际上我们是想删除它。要实现这种要求,就必须使用<literal>cascade="all-delete-orphan"</literal>。
+ </para>
+
+
+ <programlisting><![CDATA[<set name="children" inverse="true" cascade="all-delete-orphan">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ 注意:即使在collection一方的映射中指定<literal>inverse="true"</literal>,级联仍然是通过遍历collection中的元素来处理的。如果你想要通过级联进行子对象的插入、删除、更新操作,就必须把它加到collection中,只调用<literal>setParent()</literal>是不够的。
+ </para>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-update">
+ <title>级联与<literal>未保存值</literal>(Cascades and <literal>unsaved-value</literal>)</title>
+
+ <para>
+ 假设我们从<literal>Session</literal>中装入了一个<literal>Parent</literal>对象,用户界面对其进行了修改,然后希望在一个新的Session里面调用<literal>update()</literal>来保存这些修改。对象<literal>Parent</literal>包含了子对象的集合,由于打开了级联更新,Hibernate需要知道哪些Child对象是新实例化的,哪些代表数据库中已经存在的记录。我们假设<literal>Parent</literal>和<literal>Child</literal>对象的标识属性都是自动生成的,类型为<literal>java.lang.Long</literal>。Hibernate会使用标识属性的值,和version 或 timestamp 属性,来判断哪些子对象是新的。(参见<xref linkend="objectstate-saveorupdate"/>.) <emphasis>在 Hibernate3 中,显式指定<literal>unsaved-value</literal>不再是必须的了。</emphasis>
+ </para>
+
+ <para>
+ 下面的代码会更新<literal>parent</literal>和<literal>child</literal>对象,并且插入<literal>newChild</literal>对象。
+ </para>
+
+ <programlisting><![CDATA[//parent and child were both loaded in a previous session
+parent.addChild(child);
+Child newChild = new Child();
+parent.addChild(newChild);
+session.update(parent);
+session.flush();]]></programlisting>
+
+ <para>
+ Well, that's all very well for the case of a generated identifier, but what about assigned identifiers
+ and composite identifiers? This is more difficult, since Hibernate can't use the identifier property to
+ distinguish between a newly instantiated object (with an identifier assigned by the user) and an
+ object loaded in a previous session. In this case, Hibernate will either use the timestamp or version
+ property, or will actually query the second-level cache or, worst case, the database, to see if the
+ row exists.
+ </para>
+ <para>
+ 这对于自动生成标识的情况是非常好的,但是自分配的标识和复合标识怎么办呢?这是有点麻烦,因为Hibernate没有办法区分新实例化的对象(标识被用户指定了)和前一个Session装入的对象。在这种情况下,Hibernate会使用timestamp或version属性,或者查询第二级缓存,或者最坏的情况,查询数据库,来确认是否此行存在。</para>
+
+ <!-- undocumenting
+
+ <para>
+ 还有一种可能情况,有一个名为<literal>isUnsaved()</literal>的<literal>新的拦截器(Interceptor)</literal>方法,它允许应用程序自己实现新实例的判断。比如,你可以自己定义一个持久类的祖先类:
+ </para>
+
+ <programlisting><![CDATA[public class Persistent {
+ private boolean _saved = false;
+ public void onSave() {
+ _saved=true;
+ }
+ public void onLoad() {
+ _saved=true;
+ }
+ ......
+ public boolean isSaved() {
+ return _saved;
+ }
+}]]></programlisting>
+
+ <para>
+ (<literal>saved</literal>属性是不会被持久化的。)
+ 现在在<literal>onLoad()</literal>和<literal>onSave()</literal>外,还要实现<literal>isUnsaved()</literal>。
+ </para>
+
+ <programlisting><![CDATA[public Boolean isUnsaved(Object entity) {
+ if (entity instanceof Persistent) {
+ return new Boolean( !( (Persistent) entity ).isSaved() );
+ }
+ else {
+ return null;
+ }
+}
+
+public boolean onLoad(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if (entity instanceof Persistent) ( (Persistent) entity ).onLoad();
+ return false;
+}
+
+public boolean onSave(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if (entity instanceof Persistent) ( (Persistent) entity ).onSave();
+ return false;
+}]]></programlisting>
+
+ <para>
+ Don't worry; in Hibernate3 you don't need to write any of this kind of code if you don't want to.
+ 别担心,在Hibernate3中,假若你不愿意,你不需要编写任何这类代码。
+ </para>
+ -->
+
+ </sect1>
+
+
+ <sect1 id="example-parentchild-conclusion">
+ <title>结论</title>
+ <para> 这里有不少东西需要融会贯通,可能会让新手感到迷惑。但是在实践中它们都工作地非常好。大部分Hibernate应用程序都会经常用到父子对象模式。
+ </para>
+ <para>
+ 在第一段中我们曾经提到另一个方案。上面的这些问题都不会出现在<literal><composite-element></literal>映射中,它准确地表达了父子关系的语义。很不幸复合元素还有两个重大限制:复合元素不能拥有collections,并且,除了用于惟一的父对象外,它们不能再作为其它任何实体的子对象。
+ </para>
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/example_weblog.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/example_weblog.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/example_weblog.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/example_weblog.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,424 @@
+<chapter id="example-weblog">
+ <title>示例:Weblog 应用程序</title>
+
+ <sect1 id="example-weblog-classes">
+ <title>持久化类</title>
+
+ <para> 下面的持久化类表示一个weblog和在其中张贴的一个贴子。他们是标准的父/子关系模型,但是我们会用一个有序包(ordered bag)而非集合(set)。
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+import java.util.List;
+
+public class Blog {
+ private Long _id;
+ private String _name;
+ private List _items;
+
+ public Long getId() {
+ return _id;
+ }
+ public List getItems() {
+ return _items;
+ }
+ public String getName() {
+ return _name;
+ }
+ public void setId(Long long1) {
+ _id = long1;
+ }
+ public void setItems(List list) {
+ _items = list;
+ }
+ public void setName(String string) {
+ _name = string;
+ }
+}]]></programlisting>
+
+ <programlisting><![CDATA[package eg;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+
+public class BlogItem {
+ private Long _id;
+ private Calendar _datetime;
+ private String _text;
+ private String _title;
+ private Blog _blog;
+
+ public Blog getBlog() {
+ return _blog;
+ }
+ public Calendar getDatetime() {
+ return _datetime;
+ }
+ public Long getId() {
+ return _id;
+ }
+ public String getText() {
+ return _text;
+ }
+ public String getTitle() {
+ return _title;
+ }
+ public void setBlog(Blog blog) {
+ _blog = blog;
+ }
+ public void setDatetime(Calendar calendar) {
+ _datetime = calendar;
+ }
+ public void setId(Long long1) {
+ _id = long1;
+ }
+ public void setText(String string) {
+ _text = string;
+ }
+ public void setTitle(String string) {
+ _title = string;
+ }
+}]]></programlisting>
+
+ </sect1>
+ <sect1 id="example-weblog-mappings">
+ <title>Hibernate 映射</title>
+
+ <para>
+ 下列的XML映射应该是很直白的。
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+ <class
+ name="Blog"
+ table="BLOGS" >
+
+ <id
+ name="id"
+ column="BLOG_ID">
+
+ <generator class="native"/>
+
+ </id>
+
+ <property
+ name="name"
+ column="NAME"
+ not-null="true"
+ unique="true"/>
+
+ <bag
+ name="items"
+ inverse="true"
+ order-by="DATE_TIME"
+ cascade="all">
+
+ <key column="BLOG_ID"/>
+ <one-to-many class="BlogItem"/>
+
+ </bag>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class
+ name="BlogItem"
+ table="BLOG_ITEMS"
+ dynamic-update="true">
+
+ <id
+ name="id"
+ column="BLOG_ITEM_ID">
+
+ <generator class="native"/>
+
+ </id>
+
+ <property
+ name="title"
+ column="TITLE"
+ not-null="true"/>
+
+ <property
+ name="text"
+ column="TEXT"
+ not-null="true"/>
+
+ <property
+ name="datetime"
+ column="DATE_TIME"
+ not-null="true"/>
+
+ <many-to-one
+ name="blog"
+ column="BLOG_ID"
+ not-null="true"/>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-weblog-code">
+ <title>Hibernate 代码</title>
+
+ <para>
+ 下面的类演示了我们可以使用Hibernate对这些类进行的一些操作。
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.tool.hbm2ddl.SchemaExport;
+
+public class BlogMain {
+
+ private SessionFactory _sessions;
+
+ public void configure() throws HibernateException {
+ _sessions = new Configuration()
+ .addClass(Blog.class)
+ .addClass(BlogItem.class)
+ .buildSessionFactory();
+ }
+
+ public void exportTables() throws HibernateException {
+ Configuration cfg = new Configuration()
+ .addClass(Blog.class)
+ .addClass(BlogItem.class);
+ new SchemaExport(cfg).create(true, true);
+ }
+
+ public Blog createBlog(String name) throws HibernateException {
+
+ Blog blog = new Blog();
+ blog.setName(name);
+ blog.setItems( new ArrayList() );
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.persist(blog);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return blog;
+ }
+
+ public BlogItem createBlogItem(Blog blog, String title, String text)
+ throws HibernateException {
+
+ BlogItem item = new BlogItem();
+ item.setTitle(title);
+ item.setText(text);
+ item.setBlog(blog);
+ item.setDatetime( Calendar.getInstance() );
+ blog.getItems().add(item);
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.update(blog);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return item;
+ }
+
+ public BlogItem createBlogItem(Long blogid, String title, String text)
+ throws HibernateException {
+
+ BlogItem item = new BlogItem();
+ item.setTitle(title);
+ item.setText(text);
+ item.setDatetime( Calendar.getInstance() );
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ Blog blog = (Blog) session.load(Blog.class, blogid);
+ item.setBlog(blog);
+ blog.getItems().add(item);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return item;
+ }
+
+ public void updateBlogItem(BlogItem item, String text)
+ throws HibernateException {
+
+ item.setText(text);
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.update(item);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ }
+
+ public void updateBlogItem(Long itemid, String text)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ BlogItem item = (BlogItem) session.load(BlogItem.class, itemid);
+ item.setText(text);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ }
+
+ public List listAllBlogNamesAndItemCounts(int max)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ List result = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "select blog.id, blog.name, count(blogItem) " +
+ "from Blog as blog " +
+ "left outer join blog.items as blogItem " +
+ "group by blog.name, blog.id " +
+ "order by max(blogItem.datetime)"
+ );
+ q.setMaxResults(max);
+ result = q.list();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return result;
+ }
+
+ public Blog getBlogAndAllItems(Long blogid)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ Blog blog = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "from Blog as blog " +
+ "left outer join fetch blog.items " +
+ "where blog.id = :blogid"
+ );
+ q.setParameter("blogid", blogid);
+ blog = (Blog) q.uniqueResult();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return blog;
+ }
+
+ public List listBlogsAndRecentItems() throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ List result = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "from Blog as blog " +
+ "inner join blog.items as blogItem " +
+ "where blogItem.datetime > :minDate"
+ );
+
+ Calendar cal = Calendar.getInstance();
+ cal.roll(Calendar.MONTH, false);
+ q.setCalendar("minDate", cal);
+
+ result = q.list();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return result;
+ }
+}]]></programlisting>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/filters.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/filters.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/filters.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/filters.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,140 @@
+<chapter id="filters">
+ <title>过滤数据</title>
+ <para>
+
+ Hibernate3 提供了一种创新的方式来处理具有“显性(visibility)”规则的数据,那就是使用<emphasis>Hibernate filter</emphasis>。
+ <emphasis>Hibernate filter</emphasis>是全局有效的、具有名字、可以带参数的过滤器,
+ 对于某个特定的Hibernate session您可以选择是否启用(或禁用)某个过滤器。
+ </para>
+
+ <sect1 id="objectstate-filters" revision="1">
+ <title>Hibernate 过滤器(filters)</title>
+
+ <para>
+ Hibernate3新增了对某个类或者集合使用预先定义的过滤器条件(filter criteria)的功能。过滤器条件相当于定义一个
+ 非常类似于类和各种集合上的“where”属性的约束子句,但是过滤器条件可以带参数。
+ 应用程序可以在运行时决定是否启用给定的过滤器,以及使用什么样的参数值。
+ 过滤器的用法很像数据库视图,只不过是在应用程序中确定使用什么样的参数的。
+
+ </para>
+
+ <para>
+
+ 要使用过滤器,必须首先在相应的映射节点中定义。而定义一个过滤器,要用到位于<literal><hibernate-mapping/></literal>
+ 节点之内的<literal><filter-def/></literal>节点:
+ </para>
+
+ <programlisting><![CDATA[<filter-def name="myFilter">
+ <filter-param name="myFilterParam" type="string"/>
+</filter-def>]]></programlisting>
+
+ <para>
+ 定义好之后,就可以在某个类中使用这个过滤器:
+ </para>
+
+ <programlisting><![CDATA[<class name="myClass" ...>
+ ...
+ <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/>
+</class>]]></programlisting>
+
+ <para>
+ 也可以在某个集合使用它:
+ </para>
+
+ <programlisting><![CDATA[<set ...>
+ <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/>
+</set>]]></programlisting>
+
+ <para>
+ 可以在多个类或集合中使用某个过滤器;某个类或者集合中也可以使用多个过滤器。
+ </para>
+
+ <para>
+
+ <literal>Session</literal>对象中会用到的方法有:<literal>enableFilter(String filterName)</literal>,
+ <literal>getEnabledFilter(String filterName)</literal>, 和 <literal>disableFilter(String filterName)</literal>.
+ Session中默认是<emphasis>不</emphasis>启用过滤器的,必须通过<literal>Session.enabledFilter()</literal>方法显式的启用。
+ 该方法返回被启用的<literal>Filter</literal>的实例。以上文定义的过滤器为例:
+ </para>
+
+ <programlisting><![CDATA[session.enableFilter("myFilter").setParameter("myFilterParam", "some-value");]]></programlisting>
+
+ <para>
+ 注意,org.hibernate.Filter的方法允许链式方法调用。(类似上面例子中启用Filter之后设定Filter参数这个“方法链”)
+ Hibernate的其他部分也大多有这个特性。
+ </para>
+
+ <para>
+ 下面是一个比较完整的例子,使用了记录生效日期模式过滤有时效的数据:
+ </para>
+
+ <programlisting><![CDATA[<filter-def name="effectiveDate">
+ <filter-param name="asOfDate" type="date"/>
+</filter-def>
+
+<class name="Employee" ...>
+...
+ <many-to-one name="department" column="dept_id" class="Department"/>
+ <property name="effectiveStartDate" type="date" column="eff_start_dt"/>
+ <property name="effectiveEndDate" type="date" column="eff_end_dt"/>
+...
+ <!--
+ Note that this assumes non-terminal records have an eff_end_dt set to
+ a max db date for simplicity-sake
+
+ 注意,为了简单起见,此处假设雇用关系生效期尚未结束的记录的eff_end_dt字段的值等于数据库最大的日期
+ -->
+ <filter name="effectiveDate"
+ condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
+</class>
+
+<class name="Department" ...>
+...
+ <set name="employees" lazy="true">
+ <key column="dept_id"/>
+ <one-to-many class="Employee"/>
+ <filter name="effectiveDate"
+ condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ 定义好后,如果想要保证取回的都是目前处于生效期的记录,只需在获取雇员数据的操作之前先开启过滤器即可:
+ </para>
+
+<programlisting><![CDATA[Session session = ...;
+session.enabledFilter("effectiveDate").setParameter("asOfDate", new Date());
+List results = session.createQuery("from Employee as e where e.salary > :targetSalary")
+ .setLong("targetSalary", new Long(1000000))
+ .list();
+]]></programlisting>
+
+ <para>
+
+ 在上面的HQL中,虽然我们仅仅显式的使用了一个薪水条件,但因为启用了过滤器,查询将仅返回那些目前雇用
+ 关系处于生效期的,并且薪水高于一百万美刀的雇员的数据。
+
+ </para>
+
+ <para>
+
+ 注意:如果你打算在使用外连接(或者通过HQL或load fetching)的同时使用过滤器,要注意条件表达式的方向(左还是右)。
+ 最安全的方式是使用左外连接(left outer joining)。并且通常来说,先写参数,
+ 然后是操作符,最后写数据库字段名。
+ </para>
+
+ <para>
+ 在Filter定义之后,它可能被附加到多个实体和/或集合类,每个都有自己的条件。假若这些条件都是一样的,每次都要定义就显得很繁琐。因此,<literal><filter-def/></literal>被用来定义一个默认条件,它可能作为属性或者CDATA出现:
+ </para>
+
+ <programlisting><![CDATA[<filter-def name="myFilter" condition="abc > xyz">...</filter-def>
+<filter-def name="myOtherFilter">abc=xyz</filter-def>]]></programlisting>
+
+ <para>
+ 当这个filter被附加到任何目的地,而又没有指明条件时,这个条件就会被使用。注意,换句话说,你可以通过给filter附加特别的条件来重载默认条件。
+ </para>
+
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/inheritance_mapping.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/inheritance_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/inheritance_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/inheritance_mapping.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,467 @@
+ <chapter id="inheritance">
+ <title>继承映射(Inheritance Mappings)</title>
+
+ <sect1 id="inheritance-strategies" revision="3">
+ <title> 三种策略</title>
+
+
+ <para>
+ Hibernate支持三种基本的继承映射策略:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ 每个类分层结构一张表(table per class hierarchy)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 每个子类一张表(table per subclass)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 每个具体类一张表(table per concrete class)
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ 此外,Hibernate还支持第四种稍有不同的多态映射策略:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ 隐式多态(implicit polymorphism)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 对于同一个继承层次内的不同分支,可以采用不同的映射策略,然后用隐式多
+ 态来完成跨越整个层次的多态。但是在同一个<literal><class></literal>根元素
+ 下,Hibernate不支持混合了元素<literal><subclass></literal>、
+ <literal><joined-subclass></literal>和<literal><union-subclass></literal>
+ 的映射。在同一个<literal><class></literal>元素下,可以混合使用
+ “每个类分层结构一张表”(table per hierarchy) 和“每个子类一张表”(table per subclass)
+ 这两种映射策略,这是通过结合元素<literal><subclass></literal>和
+ <literal><join></literal>来实现的(见后)。
+
+ </para>
+
+ <para>
+ 在多个映射文件中,可以直接在<literal>hibernate-mapping</literal>根下定义<literal>subclass</literal>,<literal>union-subclass</literal>和<literal>joined-subclass</literal>。也就是说,你可以仅加入一个新的映射文件来扩展类层次。你必须在subclass的映射中指明<literal>extends</literal>属性,给出一个之前定义的超类的名字。注意,在以前,这一功能对映射文件的顺序有严格的要求,从Hibernate 3开始,使用extends关键字的时侯,对映射文件的顺序不再有要求;但在每个映射文件里,超类必须在子类之前定义。
+ </para>
+
+ <programlisting><![CDATA[
+ <hibernate-mapping>
+ <subclass name="DomesticCat" extends="Cat" discriminator-value="D">
+ <property name="name" type="string"/>
+ </subclass>
+ </hibernate-mapping>]]></programlisting>
+
+ <sect2 id="inheritance-tableperclass" >
+ <title>每个类分层结构一张表(Table per class hierarchy)</title>
+
+
+ <para>
+ 假设我们有接口<literal>Payment</literal>和它的几个实现类:
+ <literal>CreditCardPayment</literal>, <literal>CashPayment</literal>,
+ 和<literal>ChequePayment</literal>。则“每个类分层结构一张表”(Table per
+ class hierarchy)的映射代码如下所示:
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ ...
+ </subclass>
+ <subclass name="ChequePayment" discriminator-value="CHEQUE">
+ ...
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ 采用这种策略只需要一张表即可。它有一个很大的限制:要求那些由子类定义的字段,
+ 如<literal>CCTYPE</literal>,不能有<literal>非空(NOT NULL)</literal>约束。
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tablepersubclass">
+
+ <title>每个子类一张表(Table per subclass)</title>
+
+
+ <para>
+ 对于上例中的几个类而言,采用“每个子类一张表”的映射策略,代码如下所示:
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="CashPayment" table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </joined-subclass>
+</class>]]></programlisting>
+ <para>
+ 需要四张表。三个子类表通过主键关联到超类表(因而关系模型实际上是一对一关联)。
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tablepersubclass-discriminator" revision="2">
+
+ <title>每个子类一张表(Table per subclass),使用辨别标志(Discriminator)</title>
+
+ <para>
+ 注意,对“每个子类一张表”的映射策略,Hibernate的实现不需要辨别字段,而其他
+ 的对象/关系映射工具使用了一种不同于Hibernate的实现方法,该方法要求在超类
+ 表中有一个类型辨别字段(type discriminator column)。Hibernate采用的方法更
+ 难实现,但从关系(数据库)的角度来看,按理说它更正确。若你愿意使用带有辨别字
+ 段的“每个子类一张表”的策略,你可以结合使用<literal><subclass></literal>
+ 与<literal><join></literal>,如下所示:
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+ <join table="CREDIT_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ <join table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="ChequePayment" discriminator-value="CHEQUE">
+ <join table="CHEQUE_PAYMENT" fetch="select">
+ <key column="PAYMENT_ID"/>
+ ...
+ </join>
+ </subclass>
+</class>]]></programlisting>
+
+
+ <para>
+ 可选的声明<literal>fetch="select"</literal>,是用来告诉Hibernate,在查询超类时,
+ 不要使用外部连接(outer join)来抓取子类<literal>ChequePayment</literal>的数据。
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-mixing-tableperclass-tablepersubclass">
+ <title>混合使用“每个类分层结构一张表”和“每个子类一张表”</title>
+
+ <para>
+ 你甚至可以采取如下方法混和使用“每个类分层结构一张表”和“每个子类一张表”这两种策略:
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+ <join table="CREDIT_PAYMENT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ ...
+ </subclass>
+ <subclass name="ChequePayment" discriminator-value="CHEQUE">
+ ...
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ 对上述任何一种映射策略而言,指向根类<literal>Payment</literal>的
+ 关联是使用<literal><many-to-one></literal>进行映射的。
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="payment" column="PAYMENT_ID" class="Payment"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="inheritance-tableperconcrete" revision="2">
+ <title>每个具体类一张表(Table per concrete class)</title>
+
+ <para>
+ 对于“每个具体类一张表”的映射策略,可以采用两种方法。第一种方法是使用
+ <literal><union-subclass></literal>。
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="sequence"/>
+ </id>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </union-subclass>
+ <union-subclass name="CashPayment" table="CASH_PAYMENT">
+ ...
+ </union-subclass>
+ <union-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+ ...
+ </union-subclass>
+</class>]]></programlisting>
+
+ <para>
+ 这里涉及三张与子类相关的表。每张表为对应类的所有属性(包括从超类继承的属性)定义相应字段。
+ </para>
+
+ <para>
+ 这种方式的局限在于,如果一个属性在超类中做了映射,其字段名必须与所有子类
+ 表中定义的相同。(我们可能会在Hibernate的后续发布版本中放宽此限制。)
+ 不允许在联合子类(union subclass)的继承层次中使用标识生成器策略(identity generator strategy),
+ 实际上, 主键的种子(primary key seed)不得不为同一继承层次中的全部被联合子类所共用.
+ </para>
+
+ <para>
+ 假若超类是抽象类,请使用<literal>abstract="true"</literal>。当然,假若它不是抽象的,需要一个额外的表(上面的例子中,默认是<literal>PAYMENT</literal>),来保存超类的实例。
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tableperconcreate-polymorphism">
+ <title>Table per concrete class, using implicit polymorphism</title>
+ <title>每个具体类一张表,使用隐式多态</title>
+
+ <para>
+ 另一种可供选择的方法是采用隐式多态:
+ </para>
+
+ <programlisting><![CDATA[<class name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <id name="id" type="long" column="CREDIT_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CREDIT_AMOUNT"/>
+ ...
+</class>
+
+<class name="CashPayment" table="CASH_PAYMENT">
+ <id name="id" type="long" column="CASH_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CASH_AMOUNT"/>
+ ...
+</class>
+
+<class name="ChequePayment" table="CHEQUE_PAYMENT">
+ <id name="id" type="long" column="CHEQUE_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CHEQUE_AMOUNT"/>
+ ...
+</class>]]></programlisting>
+
+ <para>
+ 注意,我们没有在任何地方明确的提及接口<literal>Payment</literal>。同时注意
+ <literal>Payment</literal>的属性在每个子类中都进行了映射。如果你想避免重复,
+ 可以考虑使用XML实体(例如:位于<literal>DOCTYPE</literal>声明内的
+ <literal>[ <!ENTITY allproperties SYSTEM "allproperties.xml"> ]</literal>
+ 和映射中的<literal>&allproperties;</literal>)。
+ </para>
+
+ <para>
+ 这种方法的缺陷在于,在Hibernate执行多态查询时(polymorphic queries)无法生成带
+ <literal>UNION</literal>的SQL语句。
+ </para>
+
+ <para>
+ 对于这种映射策略而言,通常用<literal><any></literal>来实现到
+ <literal>Payment</literal>的多态关联映射。
+ </para>
+
+ <programlisting><![CDATA[<any name="payment" meta-type="string" id-type="long">
+ <meta-value value="CREDIT" class="CreditCardPayment"/>
+ <meta-value value="CASH" class="CashPayment"/>
+ <meta-value value="CHEQUE" class="ChequePayment"/>
+ <column name="PAYMENT_CLASS"/>
+ <column name="PAYMENT_ID"/>
+</any>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="inheritace-mixingpolymorphism">
+ <title>隐式多态和其他继承映射混合使用</title>
+
+ <para>
+ 对这一映射还有一点需要注意。因为每个子类都在各自独立的元素<literal><class></literal>
+ 中映射(并且<literal>Payment</literal>只是一个接口),每个子类可以很容易的成为另一
+ 个继承体系中的一部分!(你仍然可以对接口<literal>Payment</literal>使用多态查询。)
+ </para>
+
+ <programlisting><![CDATA[<class name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <id name="id" type="long" column="CREDIT_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="CREDIT_CARD" type="string"/>
+ <property name="amount" column="CREDIT_AMOUNT"/>
+ ...
+ <subclass name="MasterCardPayment" discriminator-value="MDC"/>
+ <subclass name="VisaPayment" discriminator-value="VISA"/>
+</class>
+
+<class name="NonelectronicTransaction" table="NONELECTRONIC_TXN">
+ <id name="id" type="long" column="TXN_ID">
+ <generator class="native"/>
+ </id>
+ ...
+ <joined-subclass name="CashPayment" table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="amount" column="CASH_AMOUNT"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="amount" column="CHEQUE_AMOUNT"/>
+ ...
+ </joined-subclass>
+</class>]]></programlisting>
+
+ <para>
+ 我们还是没有明确的提到<literal>Payment</literal>。
+ 如果我们针对接口<literal>Payment</literal>执行查询
+ ——如<literal>from Payment</literal>—— Hibernate
+ 自动返回<literal>CreditCardPayment</literal>(和它的子类,因为
+ 它们也实现了接口<literal>Payment</literal>)、
+ <literal>CashPayment</literal>和<literal>Chequepayment</literal>的实例,
+ 但不返回<literal>NonelectronicTransaction</literal>的实例。
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="inheritance-limitations">
+ <title>限制</title>
+
+ <para>
+ 对“每个具体类映射一张表”(table per concrete-class)的映射策略而言,隐式多态的
+ 方式有一定的限制。而<literal><union-subclass></literal>映射的限制则没有那
+ 么严格。
+ </para>
+
+ <para>
+ 下面表格中列出了在Hibernte中“每个具体类一张表”的策略和隐式多态的限制。
+ </para>
+
+ <table frame="topbot">
+ <title>继承映射特性(Features of inheritance mappings) </title>
+ <tgroup cols='8' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="1*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <colspec colname='c6' colwidth="1*"/>
+ <colspec colname='c7' colwidth="1*"/>
+ <colspec colname='c8' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>继承策略(Inheritance strategy)</entry>
+ <entry>多态多对一</entry>
+ <entry>多态一对一</entry>
+ <entry>多态一对多</entry>
+ <entry>多态多对多</entry>
+ <entry>多态 <literal>load()/get()</literal></entry>
+ <entry>多态查询</entry>
+ <entry>多态连接(join)</entry>
+ <entry>外连接(Outer join)读取</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+
+ <entry>每个类分层结构一张表</entry>
+ <entry><literal><many-to-one></literal></entry>
+ <entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal></entry>
+ <entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class, id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment p</literal></entry>
+ <entry><emphasis>支持</emphasis></entry>
+ </row>
+ <row>
+ <entry>每个子类一张表</entry>
+ <entry><literal><many-to-one></literal></entry>
+ <entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal></entry>
+ <entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class, id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment p</literal></entry>
+ <entry><emphasis>支持</emphasis></entry>
+ </row>
+ <row>
+
+ <entry>每个具体类一张表(union-subclass)</entry>
+ <entry><literal><many-to-one></literal></entry>
+ <entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal> (仅对于<literal>inverse="true"</literal>的情况)</entry>
+ <entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class, id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment p</literal></entry>
+ <entry><emphasis>支持</emphasis></entry>
+ </row>
+ <row>
+
+ <entry>每个具体类一张表(隐式多态)</entry>
+ <entry><literal><any></literal></entry>
+ <entry><emphasis>不支持</emphasis></entry>
+ <entry><emphasis>不支持</emphasis></entry>
+ <entry><literal><many-to-any></literal></entry>
+ <entry><literal>s.createCriteria(Payment.class).add( Restrictions.idEq(id) ).uniqueResult()</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><emphasis>不支持</emphasis></entry>
+ <entry><emphasis>不支持</emphasis></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ </chapter>
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/performance.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/performance.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/performance.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/performance.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,1315 @@
+<chapter id="performance">
+ <title>提升性能
+ </title>
+ <sect1 id="performance-fetching" revision="2">
+ <title>
+ 抓取策略(Fetching strategies)
+ </title>
+
+ <para>
+
+ <emphasis>抓取策略(fetching strategy)</emphasis> 是指:当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候,
+ Hibernate如何获取关联对象的策略。抓取策略可以在O/R映射的元数据中声明,也可以在特定的HQL
+ 或<literal>条件查询(Criteria Query)</literal>中重载声明。
+ </para>
+
+ <para>
+ Hibernate3 定义了如下几种抓取策略:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+
+ <emphasis>连接抓取(Join fetching)</emphasis> - Hibernate通过
+ 在<literal>SELECT</literal>语句使用<literal>OUTER JOIN</literal>(外连接)来
+ 获得对象的关联实例或者关联集合。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+
+ <emphasis>查询抓取(Select fetching)</emphasis> - 另外发送一条 <literal>SELECT</literal>
+ 语句抓取当前对象的关联实体或集合。除非你显式的指定<literal>lazy="false"</literal>禁止
+ 延迟抓取(lazy fetching),否则只有当你真正访问关联关系的时候,才会执行第二条select语句。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>子查询抓取(Subselect fetching)</emphasis> - 另外发送一条<literal>SELECT</literal>
+ 语句抓取在前面查询到(或者抓取到)的所有实体对象的关联集合。除非你显式的指定<literal>lazy="false"</literal>
+ 禁止延迟抓取(lazy fetching),否则只有当你真正访问关联关系的时候,才会执行第二条select语句。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+
+ <emphasis>批量抓取(Batch fetching)</emphasis> - 对查询抓取的优化方案,
+ 通过指定一个主键或外键列表,Hibernate使用单条<literal>SELECT</literal>语句获取一批对象实例或集合。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate会区分下列各种情况:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Immediate fetching,立即抓取</emphasis> - 当宿主被加载时,关联、集合或属性被立即抓取。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Lazy collection fetching,延迟集合抓取</emphasis>- 直到应用程序对集合进行了一次操作时,集合才被抓取。(对集合而言这是默认行为。)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>"Extra-lazy" collection fetching,"Extra-lazy"集合抓取</emphasis> -对集合类中的每个元素而言,都是直到需要时才去访问数据库。除非绝对必要,Hibernate不会试图去把整个集合都抓取到内存里来(适用于非常大的集合)。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Proxy fetching,代理抓取</emphasis> - 对返回单值的关联而言,当其某个方法被调用,而非对其关键字进行get操作时才抓取。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>"No-proxy" fetching,非代理抓取</emphasis> - 对返回单值的关联而言,当实例变量被访问的时候进行抓取。与上面的代理抓取相比,这种方法没有那么“延迟”得厉害(就算只访问标识符,也会导致关联抓取)但是更加透明,因为对应用程序来说,不再看到proxy。这种方法需要在编译期间进行字节码增强操作,因此很少需要用到。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Lazy attribute fetching,属性延迟加载</emphasis> - 对属性或返回单值的关联而言,当其实例变量被访问的时候进行抓取。需要编译期字节码强化,因此这一方法很少是必要的。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 这里有两个正交的概念:关联<emphasis>何时</emphasis>被抓取,以及被<emphasis>如何</emphasis>抓取(会采用什么样的SQL语句)。不要混淆它们!我们使用<literal>抓取</literal>来改善性能。我们使用<literal>延迟</literal>来定义一些契约,对某特定类的某个脱管的实例,知道有哪些数据是可以使用的。
+ </para>
+
+ <sect2 id="performance-fetching-lazy">
+ <title>操作延迟加载的关联</title>
+
+ <para>
+ 默认情况下,Hibernate 3对集合使用延迟select抓取,对返回单值的关联使用延迟代理抓取。对几乎是所有的应用而言,其绝大多数的关联,这种策略都是有效的。
+ </para>
+
+ <para>
+ <emphasis>注意:</emphasis>假若你设置了<literal>hibernate.default_batch_fetch_size</literal>,Hibernate会对延迟加载采取批量抓取优化措施(这种优化也可能会在更细化的级别打开)。
+ </para>
+
+ <para>
+ 然而,你必须了解延迟抓取带来的一个问题。在一个打开的Hibernate session上下文之外调用延迟集合会导致一次意外。比如:
+ </para>
+
+ <programlisting><![CDATA[s = sessions.openSession();
+Transaction tx = s.beginTransaction();
+
+User u = (User) s.createQuery("from User u where u.name=:userName")
+ .setString("userName", userName).uniqueResult();
+Map permissions = u.getPermissions();
+
+tx.commit();
+s.close();
+
+Integer accessLevel = (Integer) permissions.get("accounts"); // Error!]]></programlisting>
+
+ <para>
+ 在<literal>Session</literal>关闭后,permessions集合将是未实例化的、不再可用,因此无法正常载入其状态。
+ <emphasis>Hibernate对脱管对象不支持延迟实例化</emphasis>. 这里的修改方法是:将permissions读取数据的代码
+ 移到tx.commit()之前。
+ </para>
+
+ <para>
+ 除此之外,通过对关联映射指定<literal>lazy="false"</literal>,我们也可以使用非延迟的集合或关联。但是,
+ 对绝大部分集合来说,更推荐使用延迟方式抓取数据。如果在你的对象模型中定义了太多的非延迟关联,Hibernate最终几乎需要在每个事务中载入整个数据库到内存中!
+ </para>
+
+ <para>
+
+ 但是,另一方面,在一些特殊的事务中,我们也经常需要使用到连接抓取(它本身上就是非延迟的),以代替查询抓取。
+ 下面我们将会很快明白如何具体的定制Hibernate中的抓取策略。在Hibernate3中,具体选择哪种抓取策略的机制是和选择
+ 单值关联或集合关联相一致的。
+ </para>
+ </sect2>
+
+
+ <sect2 id="performance-fetching-custom" revision="4">
+ <title>
+
+ 调整抓取策略(Tuning fetch strategies)
+ </title>
+
+ <para>
+
+ 查询抓取(默认的)在N+1查询的情况下是极其脆弱的,因此我们可能会要求在映射文档中定义使用连接抓取:
+ </para>
+ <programlisting><![CDATA[<set name="permissions"
+ fetch="join">
+ <key column="userId"/>
+ <one-to-many class="Permission"/>
+</set]]></programlisting>
+
+ <programlisting><![CDATA[<many-to-one name="mother" class="Cat" fetch="join"/>]]></programlisting>
+
+ <para>
+ 在映射文档中定义的<literal>抓取</literal>策略将会对以下列表条目产生影响:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+
+ 通过<literal>get()</literal>或<literal>load()</literal>方法取得数据。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 只有在关联之间进行导航时,才会隐式的取得数据。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>条件查询</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 使用了<literal>subselect</literal>抓取的HQL查询
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 不管你使用哪种抓取策略,定义为非延迟的类图会被保证一定装载入内存。注意这可能意味着在一条HQL查询后紧跟着一系列的查询。
+ </para>
+
+ <para>
+ 通常情况下,我们并不使用映射文档进行抓取策略的定制。更多的是,保持其默认值,然后在特定的事务中,
+ 使用HQL的<literal>左连接抓取(left join fetch)</literal> 对其进行重载。这将通知
+ Hibernate在第一次查询中使用外部关联(outer join),直接得到其关联数据。
+ 在<literal>条件查询</literal> API中,应该调用 <literal>setFetchMode(FetchMode.JOIN)</literal>语句。
+ </para>
+
+ <para>
+ 也许你喜欢仅仅通过条件查询,就可以改变<literal>get()</literal>
+ 或 <literal>load()</literal>语句中的数据抓取策略。例如:
+ </para>
+
+ <programlisting><![CDATA[User user = (User) session.createCriteria(User.class)
+ .setFetchMode("permissions", FetchMode.JOIN)
+ .add( Restrictions.idEq(userId) )
+ .uniqueResult();]]></programlisting>
+
+ <para>
+
+ (这就是其他ORM解决方案的“抓取计划(fetch plan)”在Hibernate中的等价物。)
+ </para>
+
+
+ <para>
+ 截然不同的一种避免N+1次查询的方法是,使用二级缓存。
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-proxies" revision="2">
+ <title>单端关联代理(Single-ended association proxies)
+ </title>
+
+ <para>
+ 在Hinerbate中,对集合的延迟抓取的采用了自己的实现方法。但是,对于单端关联的延迟抓取,则需要采用
+ 其他不同的机制。单端关联的目标实体必须使用代理,Hihernate在运行期二进制级(通过优异的CGLIB库),
+ 为持久对象实现了延迟载入代理。
+ </para>
+
+ <para>
+ 默认的,Hibernate3将会为所有的持久对象产生代理(在启动阶段),然后使用他们实现
+ <literal>多对一(many-to-one)</literal>关联和<literal>一对一(one-to-one)</literal>
+ 关联的延迟抓取。
+ </para>
+
+ <para>
+ 在映射文件中,可以通过设置<literal>proxy</literal>属性为目标class声明一个接口供代理接口使用。
+ 默认的,Hibernate将会使用该类的一个子类。
+ <emphasis>注意:被代理的类必须实现一个至少包可见的默认构造函数,我们建议所有的持久类都应拥有这样的构造函数</emphasis>
+ </para>
+
+ <para>
+ 在如此方式定义一个多态类的时候,有许多值得注意的常见性的问题,例如:
+ </para>
+
+ <programlisting><![CDATA[<class name="Cat" proxy="Cat">
+ ......
+ <subclass name="DomesticCat">
+ .....
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ 首先,<literal>Cat</literal>实例永远不可以被强制转换为<literal>DomesticCat</literal>,
+ 即使它本身就是<literal>DomesticCat</literal>实例。
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(Cat.class, id); // instantiate a proxy (does not hit the db)
+if ( cat.isDomesticCat() ) { // hit the db to initialize the proxy
+ DomesticCat dc = (DomesticCat) cat; // Error!
+ ....
+}]]></programlisting>
+
+ <para>
+ 其次,代理的“<literal>==</literal>”可能不再成立。
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(Cat.class, id); // instantiate a Cat proxy
+DomesticCat dc =
+ (DomesticCat) session.load(DomesticCat.class, id); // acquire new DomesticCat proxy!
+System.out.println(cat==dc); // false]]></programlisting>
+
+ <para>
+ 虽然如此,但实际情况并没有看上去那么糟糕。虽然我们现在有两个不同的引用,分别指向这两个不同的代理对象,
+ 但实际上,其底层应该是同一个实例对象:
+ </para>
+
+ <programlisting><![CDATA[cat.setWeight(11.0); // hit the db to initialize the proxy
+System.out.println( dc.getWeight() ); // 11.0]]></programlisting>
+
+ <para>
+ 第三,你不能对“final类”或“具有final方法的类”使用CGLIB代理。
+ </para>
+
+ <para>
+ 最后,如果你的持久化对象在实例化时需要某些资源(例如,在实例化方法、默认构造方法中),
+ 那么代理对象也同样需要使用这些资源。实际上,代理类是持久化类的子类。
+ </para>
+
+ <para>
+
+ 这些问题都源于Java的单根继承模型的天生限制。如果你希望避免这些问题,那么你的每个持久化类必须实现一个接口,
+ 在此接口中已经声明了其业务方法。然后,你需要在映射文档中再指定这些接口。例如:
+ </para>
+
+ <programlisting><![CDATA[<class name="CatImpl" proxy="Cat">
+ ......
+ <subclass name="DomesticCatImpl" proxy="DomesticCat">
+ .....
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+
+ 这里<literal>CatImpl</literal>实现了<literal>Cat</literal>接口,
+ <literal>DomesticCatImpl</literal>实现<literal>DomesticCat</literal>接口。
+ 在<literal>load()</literal>、<literal>iterate()</literal>方法中就会返回
+ <literal>Cat</literal>和<literal>DomesticCat</literal>的代理对象。
+ (注意<literal>list()</literal>并不会返回代理对象。)
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(CatImpl.class, catid);
+Iterator iter = session.createQuery("from CatImpl as cat where cat.name='fritz'").iterate();
+Cat fritz = (Cat) iter.next();]]></programlisting>
+
+ <para>
+
+ 这里,对象之间的关系也将被延迟载入。这就意味着,你应该将属性声明为<literal>Cat</literal>,而不是<literal>CatImpl</literal>。
+ </para>
+
+ <para>
+
+ 但是,在有些方法中是<emphasis>不需要</emphasis>使用代理的。例如:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>equals()</literal>方法,如果持久类没有重载<literal>equals()</literal>方法。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>hashCode()</literal>方法,如果持久类没有重载<literal>hashCode()</literal>方法。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 标志符的getter方法。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate将会识别出那些重载了<literal>equals()</literal>、或<literal>hashCode()</literal>方法的持久化类。
+ </para>
+ <para>
+ 若选择<literal>lazy="no-proxy"</literal>而非默认的<literal>lazy="proxy"</literal>,我们可以避免类型转换带来的问题。然而,这样我们就需要编译期字节码增强,并且所有的操作都会导致立刻进行代理初始化。
+
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-initialization" revision="1">
+ <title>实例化集合和代理(Initializing collections and proxies)
+ </title>
+
+ <para>
+ 在<literal>Session</literal>范围之外访问未初始化的集合或代理,Hibernate将会抛出<literal>LazyInitializationException</literal>异常。
+ 也就是说,在分离状态下,访问一个实体所拥有的集合,或者访问其指向代理的属性时,会引发此异常。
+ </para>
+
+ <para>
+
+ 有时候我们需要保证某个代理或者集合在Session关闭前就已经被初始化了。
+ 当然,我们可以通过强行调用<literal>cat.getSex()</literal>或者<literal>cat.getKittens().size()</literal>之类的方法来确保这一点。
+ 但是这样的程序会造成读者的疑惑,也不符合通常的代码规范。
+ </para>
+
+ <para>
+
+ 静态方法<literal>Hibernate.initialized()</literal>
+ 为你的应用程序提供了一个便捷的途径来延迟加载集合或代理。
+ 只要它的Session处于open状态,<literal>Hibernate.initialize(cat)</literal> 将会为cat强制对代理实例化。
+ 同样,<literal>Hibernate.initialize( cat.getKittens() )</literal> 对kittens的集合具有同样的功能。
+ </para>
+
+ <para>
+
+ 还有另外一种选择,就是保持<literal>Session</literal>一直处于open状态,直到所有需要的集合或代理都被载入。
+ 在某些应用架构中,特别是对于那些使用Hibernate进行数据访问的代码,以及那些在不同应用层和不同物理进程中使用Hibernate的代码。
+ 在集合实例化时,如何保证<literal>Session</literal>处于open状态经常会是一个问题。有两种方法可以解决此问题:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ 在一个基于Web的应用中,可以利用servlet过滤器(filter),在用户请求(request)结束、页面生成
+ 结束时关闭<literal>Session</literal>(这里使用了<emphasis>在展示层保持打开Session模式(Open Session in View)</emphasis>),
+ 当然,这将依赖于应用框架中异常需要被正确的处理。在返回界面给用户之前,乃至在生成界面过程中发生异常的情况下,
+ 正确关闭<literal>Session</literal>和结束事务将是非常重要的,
+ 请参见Hibernate wiki上的"Open Session in View"模式,你可以找到示例。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+
+ 在一个拥有单独业务层的应用中,业务层必须在返回之前,为web层“准备”好其所需的数据集合。这就意味着
+ 业务层应该载入所有表现层/web层所需的数据,并将这些已实例化完毕的数据返回。通常,应用程序应该
+ 为web层所需的每个集合调用<literal>Hibernate.initialize()</literal>(这个调用必须发生咱session关闭之前);
+ 或者使用带有<literal>FETCH</literal>从句,或<literal>FetchMode.JOIN</literal>的Hibernate查询,
+ 事先取得所有的数据集合。如果你在应用中使用了<emphasis>Command</emphasis>模式,代替<emphasis>Session Facade</emphasis> ,
+ 那么这项任务将会变得简单的多。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 你也可以通过<literal>merge()</literal>或<literal>lock()</literal>方法,在访问未实例化的集合(或代理)之前,
+ 为先前载入的对象绑定一个新的<literal>Session</literal>。
+ 显然,Hibernate将不会,也不<emphasis>应该</emphasis>自动完成这些任务,因为这将引入一个特殊的事务语义。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 有时候,你并不需要完全实例化整个大的集合,仅需要了解它的部分信息(例如其大小)、或者集合的部分内容。
+ </para>
+
+ <para>
+
+ 你可以使用集合过滤器得到其集合的大小,而不必实例化整个集合:
+ </para>
+
+ <programlisting><![CDATA[( (Integer) s.createFilter( collection, "select count(*)" ).list().get(0) ).intValue()]]></programlisting>
+
+ <para>
+ 这里的<literal>createFilter()</literal>方法也可以被用来有效的抓取集合的部分内容,而无需实例化整个集合:
+ </para>
+
+ <programlisting><![CDATA[s.createFilter( lazyCollection, "").setFirstResult(0).setMaxResults(10).list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-batch">
+ <title>使用批量抓取(Using batch fetching)
+ </title>
+
+ <para>
+ Hibernate可以充分有效的使用批量抓取,也就是说,如果仅一个访问代理(或集合),那么Hibernate将不载入其他未实例化的代理。
+ 批量抓取是延迟查询抓取的优化方案,你可以在两种批量抓取方案之间进行选择:在类级别和集合级别。
+ </para>
+
+ <para>
+
+ 类/实体级别的批量抓取很容易理解。假设你在运行时将需要面对下面的问题:你在一个<literal>Session</literal>中载入了25个
+ <literal>Cat</literal>实例,每个<literal>Cat</literal>实例都拥有一个引用成员<literal>owner</literal>,
+ 其指向<literal>Person</literal>,而<literal>Person</literal>类是代理,同时<literal>lazy="true"</literal>。
+ 如果你必须遍历整个cats集合,对每个元素调用<literal>getOwner()</literal>方法,Hibernate将会默认的执行25次<literal>SELECT</literal>查询,
+ 得到其owner的代理对象。这时,你可以通过在映射文件的<literal>Person</literal>属性,显式声明<literal>batch-size</literal>,改变其行为:
+
+ </para>
+
+ <programlisting><![CDATA[<class name="Person" batch-size="10">...</class>]]></programlisting>
+
+ <para>
+ 随之,Hibernate将只需要执行三次查询,分别为10、10、 5。
+ </para>
+
+ <para>
+ 你也可以在集合级别定义批量抓取。例如,如果每个<literal>Person</literal>都拥有一个延迟载入的<literal>Cats</literal>集合,
+ 现在,<literal>Sesssion</literal>中载入了10个person对象,遍历person集合将会引起10次<literal>SELECT</literal>查询,
+ 每次查询都会调用<literal>getCats()</literal>方法。如果你在<literal>Person</literal>的映射定义部分,允许对<literal>cats</literal>批量抓取,
+ 那么,Hibernate将可以预先抓取整个集合。请看例子:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <set name="cats" batch-size="3">
+ ...
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ 如果整个的<literal>batch-size</literal>是3(笔误?),那么Hibernate将会分四次执行<literal>SELECT</literal>查询,
+ 按照3、3、3、1的大小分别载入数据。这里的每次载入的数据量还具体依赖于当前<literal>Session</literal>中未实例化集合的个数。
+ </para>
+
+ <para>
+ 如果你的模型中有嵌套的树状结构,例如典型的帐单-原料结构(bill-of-materials pattern),集合的批量抓取是非常有用的。
+ (尽管在更多情况下对树进行读取时,<emphasis>嵌套集合(nested set)</emphasis>或<emphasis>原料路径(materialized path)</emphasis>(××)
+ 是更好的解决方法。)
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-subselect">
+ <title>使用子查询抓取(Using subselect fetching)
+ </title>
+ <para>
+ 假若一个延迟集合或单值代理需要抓取,Hibernate会使用一个subselect重新运行原来的查询,一次性读入所有的实例。这和批量抓取的实现方法是一样的,不会有破碎的加载。
+ </para>
+
+ <!-- TODO: Write more about this -->
+ </sect2>
+
+ <sect2 id="performance-fetching-lazyproperties">
+ <title>使用延迟属性抓取(Using lazy property fetching)
+ </title>
+
+ <para>
+ Hibernate3对单独的属性支持延迟抓取,这项优化技术也被称为<emphasis>组抓取(fetch groups)</emphasis>。
+ 请注意,该技术更多的属于市场特性。在实际应用中,优化行读取比优化列读取更重要。但是,仅载入类的部分属性在某些特定情况下会有用,例如在原有表中拥有几百列数据、数据模型无法改动的情况下。
+ </para>
+
+ <para>
+
+ 可以在映射文件中对特定的属性设置<literal>lazy</literal>,定义该属性为延迟载入。
+ </para>
+
+ <programlisting><![CDATA[<class name="Document">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name" not-null="true" length="50"/>
+ <property name="summary" not-null="true" length="200" lazy="true"/>
+ <property name="text" not-null="true" length="2000" lazy="true"/>
+</class>]]></programlisting>
+
+ <para>
+
+ 属性的延迟载入要求在其代码构建时加入二进制指示指令(bytecode instrumentation),如果你的持久类代码中未含有这些指令,
+ Hibernate将会忽略这些属性的延迟设置,仍然将其直接载入。
+ </para>
+
+ <para>
+ 你可以在Ant的Task中,进行如下定义,对持久类代码加入“二进制指令。”
+ </para>
+
+ <programlisting><![CDATA[<target name="instrument" depends="compile">
+ <taskdef name="instrument" classname="org.hibernate.tool.instrument.InstrumentTask">
+ <classpath path="${jar.path}"/>
+ <classpath path="${classes.dir}"/>
+ <classpath refid="lib.class.path"/>
+ </taskdef>
+
+ <instrument verbose="true">
+ <fileset dir="${testclasses.dir}/org/hibernate/auction/model">
+ <include name="*.class"/>
+ </fileset>
+ </instrument>
+</target>]]></programlisting>
+
+ <para>
+
+ 还有一种可以优化的方法,它使用HQL或条件查询的投影(projection)特性,可以避免读取非必要的列,
+ 这一点至少对只读事务是非常有用的。它无需在代码构建时“二进制指令”处理,因此是一个更加值得选择的解决方法。
+ </para>
+
+ <para>
+ 有时你需要在HQL中通过<literal>抓取所有属性</literal>,强行抓取所有内容。
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="performance-cache" revision="1">
+ <title>二级缓存(The Second Level Cache)
+ </title>
+
+ <para>
+ Hibernate的<literal>Session</literal>在事务级别进行持久化数据的缓存操作。
+ 当然,也有可能分别为每个类(或集合),配置集群、或JVM级别(<literal>SessionFactory级别</literal>)的缓存。
+ 你甚至可以为之插入一个集群的缓存。注意,缓存永远不知道其他应用程序对持久化仓库(数据库)可能进行的修改
+ (即使可以将缓存数据设定为定期失效)。
+ </para>
+
+ <para revision="1">
+ 通过在<literal>hibernate.cache.provider_class</literal>属性中指定<literal>org.hibernate.cache.CacheProvider</literal>的某个实现的类名,你可以选择让Hibernate使用哪个缓存实现。Hibernate打包一些开源缓存实现,提供对它们的内置支持(见下表)。除此之外,你也可以实现你自己的实现,将它们插入到系统中。注意,在3.2版本之前,默认使用EhCache 作为缓存实现,但从3.2起就不再这样了。
+ </para>
+
+ <table frame="topbot" id="cacheproviders" revision="1">
+ <title>
+ 缓存策略提供商(Cache Providers)
+ </title>
+ <tgroup cols='5' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="3*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Cache</entry>
+ <entry>Provider class</entry>
+ <entry>Type</entry>
+ <entry>Cluster Safe</entry>
+ <entry>Query Cache Supported</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Hashtable (not intended for production use)</entry>
+ <entry><literal>org.hibernate.cache.HashtableCacheProvider</literal></entry>
+ <entry>memory</entry>
+ <entry></entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry>EHCache</entry>
+ <entry><literal>org.hibernate.cache.EhCacheProvider</literal></entry>
+ <entry>memory, disk</entry>
+ <entry></entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry>OSCache</entry>
+ <entry><literal>org.hibernate.cache.OSCacheProvider</literal></entry>
+ <entry>memory, disk</entry>
+ <entry>yes (clustered invalidation)</entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry>SwarmCache</entry>
+ <entry><literal>org.hibernate.cache.SwarmCacheProvider</literal></entry>
+ <entry>clustered (ip multicast)</entry>
+ <entry>yes (clustered invalidation)</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>JBoss TreeCache</entry>
+ <entry><literal>org.hibernate.cache.TreeCacheProvider</literal></entry>
+ <entry>clustered (ip multicast), transactional</entry>
+ <entry>yes (replication)</entry>
+ <entry>yes (clock sync req.)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="performance-cache-mapping" revision="2">
+ <title>缓存映射(Cache mappings)
+ </title>
+
+ <para>
+ 类或者集合映射的“<literal><cache></literal>元素”可以有下列形式:
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="cache1" coords="2 70"/>
+ <area id="cache2" coords="3 70"/>
+ <area id="cache3" coords="4 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<cache
+ usage="transactional|read-write|nonstrict-read-write|read-only"
+ region="RegionName"
+ include="all|non-lazy"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="cache1">
+ <para>
+
+ <literal>usage</literal>(必须)说明了缓存的策略:
+ <literal>transactional</literal>、
+ <literal>read-write</literal>、
+ <literal>nonstrict-read-write</literal>或
+ <literal>read-only</literal>。
+ </para>
+ </callout>
+ <callout arearefs="cache2">
+ <para>
+ <literal>region</literal> (可选, 默认为类或者集合的名字(class or
+ collection role name)) 指定第二级缓存的区域名(name of the second level cache
+ region)
+
+ </para>
+ </callout>
+ <callout arearefs="cache3">
+ <para>
+ <literal>include</literal> (可选,默认为 <literal>all</literal>)
+ <literal>non-lazy</literal> 当属性级延迟抓取打开时, 标记为<literal>lazy="true"</literal>的实体的属性可能无法被缓存
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 另外(首选?), 你可以在hibernate.cfg.xml中指定<literal><class-cache></literal>和
+ <literal><collection-cache></literal> 元素。
+ </para>
+
+ <para>
+
+ 这里的<literal>usage</literal> 属性指明了<emphasis>缓存并发策略(cache concurrency strategy)</emphasis>。
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-cache-readonly">
+ <title>策略:只读缓存(Strategy: read only)
+ </title>
+
+ <para>
+ 如果你的应用程序只需读取一个持久化类的实例,而无需对其修改,
+ 那么就可以对其进行<literal>只读</literal> 缓存。这是最简单,也是实用性最好的方法。甚至在集群中,它也能完美地运作。
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Immutable" mutable="false">
+ <cache usage="read-only"/>
+ ....
+</class>]]></programlisting>
+
+ </sect2>
+
+
+ <sect2 id="performance-cache-readwrite">
+ <title>
+ 策略:读/写缓存(Strategy: read/write)
+ </title>
+
+ <para>
+
+ 如果应用程序需要更新数据,那么使用<literal>读/写缓存</literal> 比较合适。
+ 如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolation level),那么就决不能使用这种缓存策略。
+ 如果在JTA环境中使用缓存,你必须指定<literal>hibernate.transaction.manager_lookup_class</literal>属性的值,
+ 通过它,Hibernate才能知道该应用程序中JTA的<literal>TransactionManager</literal>的具体策略。
+ 在其它环境中,你必须保证在<literal>Session.close()</literal>、或<literal>Session.disconnect()</literal>调用前,
+ 整个事务已经结束。 如果你想在集群环境中使用此策略,你必须保证底层的缓存实现支持锁定(locking)。Hibernate内置的缓存策略并不支持锁定功能。
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Cat" .... >
+ <cache usage="read-write"/>
+ ....
+ <set name="kittens" ... >
+ <cache usage="read-write"/>
+ ....
+ </set>
+</class>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-cache-nonstrict">
+ <title>
+ 策略:非严格读/写缓存(Strategy: nonstrict read/write)
+ </title>
+
+ <para>
+
+ 如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离,
+ 那么比较适合使用<literal>非严格读/写缓存</literal>策略。如果在JTA环境中使用该策略,
+ 你必须为其指定<literal>hibernate.transaction.manager_lookup_class</literal>属性的值,
+ 在其它环境中,你必须保证在<literal>Session.close()</literal>、或<literal>Session.disconnect()</literal>调用前,
+ 整个事务已经结束。
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-cache-transactional">
+ <title>
+
+ 策略:事务缓存(transactional)
+ </title>
+
+ <para>
+ Hibernate的<literal>事务缓存</literal>策略提供了全事务的缓存支持,
+ 例如对JBoss TreeCache的支持。这样的缓存只能用于JTA环境中,你必须指定
+ 为其<literal>hibernate.transaction.manager_lookup_class</literal>属性。
+ </para>
+
+ </sect2>
+
+ <para>
+ 没有一种缓存提供商能够支持上列的所有缓存并发策略。下表中列出了各种提供器、及其各自适用的并发策略。
+ </para>
+
+ <table frame="topbot">
+ <title>
+ 各种缓存提供商对缓存并发策略的支持情况(Cache Concurrency Strategy Support)
+ </title>
+ <tgroup cols='5' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="1*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Cache</entry>
+ <entry>read-only</entry>
+ <entry>nonstrict-read-write</entry>
+ <entry>read-write</entry>
+ <entry>transactional</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Hashtable (not intended for production use)</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>EHCache</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>OSCache</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>SwarmCache</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>JBoss TreeCache</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>yes</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="performance-sessioncache" revision="2">
+ <title>
+ 管理缓存(Managing the caches)
+ </title>
+
+ <para>
+ 无论何时,当你给<literal>save()</literal>、<literal>update()</literal>或
+ <literal>saveOrUpdate()</literal>方法传递一个对象时,或使用<literal>load()</literal>、
+ <literal>get()</literal>、<literal>list()</literal>、<literal>iterate()</literal>
+ 或<literal>scroll()</literal>方法获得一个对象时,
+ 该对象都将被加入到<literal>Session</literal>的内部缓存中。
+ </para>
+ <para>
+ 当随后flush()方法被调用时,对象的状态会和数据库取得同步。
+ 如果你不希望此同步操作发生,或者你正处理大量对象、需要对有效管理内存时,你可以调用<literal>evict()</literal>
+ 方法,从一级缓存中去掉这些对象及其集合。
+ </para>
+
+ <programlisting><![CDATA[ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set
+while ( cats.next() ) {
+ Cat cat = (Cat) cats.get(0);
+ doSomethingWithACat(cat);
+ sess.evict(cat);
+}]]></programlisting>
+
+ <para>
+ Session还提供了一个<literal>contains()</literal>方法,用来判断某个实例是否处于当前session的缓存中。
+ </para>
+
+ <para>
+ 如若要把所有的对象从session缓存中彻底清除,则需要调用<literal>Session.clear()</literal>。
+ </para>
+
+ <para>
+ 对于二级缓存来说,在<literal>SessionFactory</literal>中定义了许多方法,
+ 清除缓存中实例、整个类、集合实例或者整个集合。
+ </para>
+
+ <programlisting><![CDATA[sessionFactory.evict(Cat.class, catId); //evict a particular Cat
+sessionFactory.evict(Cat.class); //evict all Cats
+sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
+sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections]]></programlisting>
+
+ <para>
+ <literal>CacheMode</literal>参数用于控制具体的Session如何与二级缓存进行交互。
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>CacheMode.NORMAL</literal> - 从二级缓存中读、写数据。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.GET</literal> - 从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.PUT</literal> - 仅向二级缓存写数据,但不从二级缓存中读数据。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.REFRESH</literal> - 仅向二级缓存写数据,但不从二级缓存中读数据。通过
+ <literal>hibernate.cache.use_minimal_puts</literal>的设置,强制二级缓存从数据库中读取数据,刷新缓存内容。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 如若需要查看二级缓存或查询缓存区域的内容,你可以使用<literal>统计(Statistics)</literal> API。
+ </para>
+
+ <programlisting><![CDATA[Map cacheEntries = sessionFactory.getStatistics()
+ .getSecondLevelCacheStatistics(regionName)
+ .getEntries();]]></programlisting>
+
+ <para>
+ 此时,你必须手工打开统计选项。可选的,你可以让Hibernate更人工可读的方式维护缓存内容。
+ </para>
+
+ <programlisting><![CDATA[hibernate.generate_statistics true
+hibernate.cache.use_structured_entries true]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="performance-querycache" revision="1">
+ <title>查询缓存(The Query Cache)
+ </title>
+
+ <para>
+ 查询的结果集也可以被缓存。只有当经常使用同样的参数进行查询时,这才会有些用处。
+ 要使用查询缓存,首先你必须打开它:
+ </para>
+
+ <programlisting><![CDATA[hibernate.cache.use_query_cache true]]></programlisting>
+
+ <para>
+
+ 该设置将会创建两个缓存区域 - 一个用于保存查询结果集(<literal>org.hibernate.cache.StandardQueryCache</literal>);
+ 另一个则用于保存最近查询的一系列表的时间戳(<literal>org.hibernate.cache.UpdateTimestampsCache</literal>)。
+ 请注意:在查询缓存中,它并不缓存结果集中所包含的实体的确切状态;它只缓存这些实体的标识符属性的值、以及各值类型的结果。
+ 所以查询缓存通常会和二级缓存一起使用。
+ </para>
+
+ <para>
+
+ 绝大多数的查询并不能从查询缓存中受益,所以Hibernate默认是不进行查询缓存的。如若需要进行缓存,请调用
+ <literal>Query.setCacheable(true)</literal>方法。这个调用会让查询在执行过程中时先从缓存中查找结果,
+ 并将自己的结果集放到缓存中去。
+ </para>
+
+ <para>
+
+ 如果你要对查询缓存的失效政策进行精确的控制,你必须调用<literal>Query.setCacheRegion()</literal>方法,
+ 为每个查询指定其命名的缓存区域。
+ </para>
+
+ <programlisting><![CDATA[List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger")
+ .setEntity("blogger", blogger)
+ .setMaxResults(15)
+ .setCacheable(true)
+ .setCacheRegion("frontpages")
+ .list();]]></programlisting>
+
+ <para>
+ 如果查询需要强行刷新其查询缓存区域,那么你应该调用<literal>Query.setCacheMode(CacheMode.REFRESH)</literal>方法。
+ 这对在其他进程中修改底层数据(例如,不通过Hibernate修改数据),或对那些需要选择性更新特定查询结果集的情况特别有用。
+ 这是对<literal>SessionFactory.evictQueries()</literal>的更为有效的替代方案,同样可以清除查询缓存区域。
+ </para>
+
+ </sect1>
+
+ <sect1 id="performance-collections">
+ <title>
+ 理解集合性能(Understanding Collection performance)
+ </title>
+
+ <para>
+ 前面我们已经对集合进行了足够的讨论。本段中,我们将着重讲述集合在运行时的事宜。
+ </para>
+
+ <sect2 id="performance-collections-taxonomy">
+ <title>
+
+ 分类(Taxonomy)
+ </title>
+
+ <para>
+
+ Hibernate定义了三种基本类型的集合:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+
+ 值数据集合
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+
+ 一对多关联
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+
+ 多对多关联
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 这个分类是区分了不同的表和外键关系类型,但是它没有告诉我们关系模型的所有内容。
+ 要完全理解他们的关系结构和性能特点,我们必须同时考虑“用于Hibernate更新或删除集合行数据的主键的结构”。
+ 因此得到了如下的分类:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+
+ 有序集合类
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+
+ 集合(sets)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+
+ 包(bags)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+
+ 所有的有序集合类(maps, lists, arrays)都拥有一个由<literal><key></literal>和
+ <literal><index></literal>组成的主键。
+ 这种情况下集合类的更新是非常高效的——主键已经被有效的索引,因此当Hibernate试图更新或删除一行时,可以迅速找到该行数据。
+ </para>
+
+ <para>
+
+ 集合(sets)的主键由<literal><key></literal>和其他元素字段构成。
+ 对于有些元素类型来说,这很低效,特别是组合元素或者大文本、大二进制字段;
+ 数据库可能无法有效的对复杂的主键进行索引。
+ 另一方面,对于一对多、多对多关联,特别是合成的标识符来说,集合也可以达到同样的高效性能。(
+ 附注:如果你希望<literal>SchemaExport</literal>为你的<literal><set></literal>创建主键,
+ 你必须把所有的字段都声明为<literal>not-null="true"</literal>。)
+ </para>
+
+ <para>
+
+ <literal><idbag></literal>映射定义了代理键,因此它总是可以很高效的被更新。事实上,
+ <literal><idbag></literal>拥有着最好的性能表现。
+ </para>
+
+ <para>
+ Bag是最差的。因为bag允许重复的元素值,也没有索引字段,因此不可能定义主键。
+ Hibernate无法判断出重复的行。当这种集合被更改时,Hibernate将会先完整地移除
+ (通过一个(in a single <literal>DELETE</literal>))整个集合,然后再重新创建整个集合。
+ 因此Bag是非常低效的。
+ </para>
+
+ <para>
+ 请注意:对于一对多关联来说,“主键”很可能并不是数据库表的物理主键。
+ 但就算在此情况下,上面的分类仍然是有用的。(它仍然反映了Hibernate在集合的各数据行中是如何进行“定位”的。)
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-collections-mostefficientupdate">
+ <title>
+ Lists, maps 和sets用于更新效率最高
+ </title>
+
+ <para>
+
+ 根据我们上面的讨论,显然有序集合类型和大多数set都可以在增加、删除、修改元素中拥有最好的性能。
+ </para>
+
+ <para>
+ 可论证的是对于多对多关联、值数据集合而言,有序集合类比集合(set)有一个好处。因为<literal>Set</literal>的内在结构,
+ 如果“改变”了一个元素,Hibernate并不会<literal>更新(UPDATE)</literal>这一行。
+ 对于<literal>Set</literal>来说,只有在<literal>插入(INSERT)</literal>和<literal>删除(DELETE)</literal>
+ 操作时“改变”才有效。再次强调:这段讨论对“一对多关联”并不适用。
+ </para>
+
+ <para>
+ 注意到数组无法延迟载入,我们可以得出结论,list, map和idbags是最高效的(非反向)集合类型,set则紧随其后。
+ 在Hibernate中,set应该时最通用的集合类型,这时因为“set”的语义在关系模型中是最自然的。
+ </para>
+
+ <para>
+ 但是,在设计良好的Hibernate领域模型中,我们通常可以看到更多的集合事实上是带有<literal>inverse="true"</literal>
+ 的一对多的关联。对于这些关联,更新操作将会在多对一的这一端进行处理。因此对于此类情况,无需考虑其集合的更新性能。
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-collections-mostefficentinverse">
+ <title>
+ Bag和list是反向集合类中效率最高的
+ </title>
+
+ <para>
+ 在把bag扔进水沟之前,你必须了解,在一种情况下,bag的性能(包括list)要比set高得多:
+ 对于指明了<literal>inverse="true"</literal>的集合类(比如说,标准的双向的一对多关联),
+ 我们可以在未初始化(fetch)包元素的情况下直接向bag或list添加新元素!
+ 这是因为<literal>Collection.add()</literal>)或者<literal>Collection.addAll()</literal> 方法
+ 对bag或者List总是返回true(这点与与Set不同)。因此对于下面的相同代码来说,速度会快得多。
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) sess.load(Parent.class, id);
+ Child c = new Child();
+ c.setParent(p);
+ p.getChildren().add(c); //no need to fetch the collection!
+ sess.flush();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-collections-oneshotdelete">
+ <title>
+ 一次性删除(One shot delete)
+ </title>
+
+ <para>
+ 偶尔的,逐个删除集合类中的元素是相当低效的。Hibernate并没那么笨,
+ 如果你想要把整个集合都删除(比如说调用list.clear()),Hibernate只需要一个DELETE就搞定了。
+ </para>
+
+ <para>
+ 假设我们在一个长度为20的集合类中新增加了一个元素,然后再删除两个。
+ Hibernate会安排一条<literal>INSERT</literal>语句和两条<literal>DELETE</literal>语句(除非集合类是一个bag)。
+ 这当然是显而易见的。
+ </para>
+
+ <para>
+ 但是,假设我们删除了18个数据,只剩下2个,然后新增3个。则有两种处理方式:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ 逐一的删除这18个数据,再新增三个;
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 删除整个集合类(只用一句DELETE语句),然后增加5个数据。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate还没那么聪明,知道第二种选择可能会比较快。
+ (也许让Hibernate不这么聪明也是好事,否则可能会引发意外的“数据库触发器”之类的问题。)
+ </para>
+
+ <para>
+ 幸运的是,你可以强制使用第二种策略。你需要取消原来的整个集合类(解除其引用),
+ 然后再返回一个新的实例化的集合类,只包含需要的元素。有些时候这是非常有用的。
+ </para>
+
+ <para>
+ 显然,一次性删除并不适用于被映射为<literal>inverse="true"</literal>的集合。
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="performance-monitoring" revision="1">
+ <title>
+ 监测性能(Monitoring performance)
+ </title>
+
+ <para>
+ 没有监测和性能参数而进行优化是毫无意义的。Hibernate为其内部操作提供了一系列的示意图,因此可以从
+ 每个<literal>SessionFactory</literal>抓取其统计数据。
+ </para>
+
+ <sect2 id="performance-monitoring-sf" revision="2">
+ <title>
+ 监测SessionFactory
+ </title>
+
+ <para>
+ 你可以有两种方式访问<literal>SessionFactory</literal>的数据记录,第一种就是自己直接调用
+ <literal>sessionFactory.getStatistics()</literal>方法读取、显示<literal>统计</literal>数据。
+ </para>
+
+ <para>
+ 此外,如果你打开<literal>StatisticsService</literal> MBean选项,那么Hibernate则可以使用JMX技术
+ 发布其数据记录。你可以让应用中所有的<literal>SessionFactory</literal>同时共享一个MBean,也可以每个
+ SessionFactory分配一个MBean。下面的代码即是其演示代码:
+ </para>
+
+ <programlisting><![CDATA[// MBean service registration for a specific SessionFactory
+Hashtable tb = new Hashtable();
+tb.put("type", "statistics");
+tb.put("sessionFactory", "myFinancialApp");
+ObjectName on = new ObjectName("hibernate", tb); // MBean object name
+
+StatisticsService stats = new StatisticsService(); // MBean implementation
+stats.setSessionFactory(sessionFactory); // Bind the stats to a SessionFactory
+server.registerMBean(stats, on); // Register the Mbean on the server]]></programlisting>
+
+
+<programlisting><![CDATA[// MBean service registration for all SessionFactory's
+Hashtable tb = new Hashtable();
+tb.put("type", "statistics");
+tb.put("sessionFactory", "all");
+ObjectName on = new ObjectName("hibernate", tb); // MBean object name
+
+StatisticsService stats = new StatisticsService(); // MBean implementation
+server.registerMBean(stats, on); // Register the MBean on the server]]></programlisting>
+
+ <para>
+
+ TODO:仍需要说明的是:在第一个例子中,我们直接得到和使用MBean;而在第二个例子中,在使用MBean之前
+ 我们则需要给出SessionFactory的JNDI名,使用<literal>hibernateStatsBean.setSessionFactoryJNDIName("my/JNDI/Name")</literal>
+ 得到SessionFactory,然后将MBean保存于其中。
+ </para>
+ <para>
+ 你可以通过以下方法打开或关闭<literal>SessionFactory</literal>的监测功能:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+
+ 在配置期间,将<literal>hibernate.generate_statistics</literal>设置为<literal>true</literal>或<literal>false</literal>;
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>
+
+ 在运行期间,则可以可以通过<literal>sf.getStatistics().setStatisticsEnabled(true)</literal>
+ 或<literal>hibernateStatsBean.setStatisticsEnabled(true)</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 你也可以在程序中调用<literal>clear()</literal>方法重置统计数据,调用<literal>logSummary()</literal>
+ 在日志中记录(info级别)其总结。
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-monitoring-metrics" revision="1">
+ <title>
+ 数据记录(Metrics)
+ </title>
+
+ <para>
+ Hibernate提供了一系列数据记录,其记录的内容包括从最基本的信息到与具体场景的特殊信息。所有的测量值都可以由
+ <literal>Statistics</literal>接口进行访问,主要分为三类:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ 使用<literal>Session</literal>的普通数据记录,例如打开的Session的个数、取得的JDBC的连接数等;
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 实体、集合、查询、缓存等内容的统一数据记录
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 和具体实体、集合、查询、缓存相关的详细数据记录
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 例如:你可以检查缓存的命中成功次数,缓存的命中失败次数,实体、集合和查询的使用概率,查询的平均时间等。请注意
+ Java中时间的近似精度是毫秒。Hibernate的数据精度和具体的JVM有关,在有些平台上其精度甚至只能精确到10秒。
+ </para>
+
+ <para>
+ 你可以直接使用getter方法得到全局数据记录(例如,和具体的实体、集合、缓存区无关的数据),你也可以在具体查询中通过标记实体名、
+ 或HQL、SQL语句得到某实体的数据记录。请参考<literal>Statistics</literal>、<literal>EntityStatistics</literal>、
+ <literal>CollectionStatistics</literal>、<literal>SecondLevelCacheStatistics</literal>、
+ 和<literal>QueryStatistics</literal>的API文档以抓取更多信息。下面的代码则是个简单的例子:
+ </para>
+
+ <programlisting><![CDATA[Statistics stats = HibernateUtil.sessionFactory.getStatistics();
+
+double queryCacheHitCount = stats.getQueryCacheHitCount();
+double queryCacheMissCount = stats.getQueryCacheMissCount();
+double queryCacheHitRatio =
+ queryCacheHitCount / (queryCacheHitCount + queryCacheMissCount);
+
+log.info("Query Hit ratio:" + queryCacheHitRatio);
+
+EntityStatistics entityStats =
+ stats.getEntityStatistics( Cat.class.getName() );
+long changes =
+ entityStats.getInsertCount()
+ + entityStats.getUpdateCount()
+ + entityStats.getDeleteCount();
+log.info(Cat.class.getName() + " changed " + changes + "times" );]]></programlisting>
+
+ <para>
+ 如果你想得到所有实体、集合、查询和缓存区的数据,你可以通过以下方法获得实体、集合、查询和缓存区列表:
+ <literal>getQueries()</literal>、<literal>getEntityNames()</literal>、
+ <literal>getCollectionRoleNames()</literal>和
+ <literal>getSecondLevelCacheRegionNames()</literal>。
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/persistent_classes.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/persistent_classes.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/persistent_classes.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/persistent_classes.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,493 @@
+<chapter id="persistent-classes" revision="2">
+ <title>持久化类(Persistent Classes)</title>
+
+ <para>
+ 在应用程序中,用来实现业务问题实体的(如,在电子商务应用程序中的Customer和Order)
+ 类就是持久化类。不能认为所有的持久化类的实例都是持久的状态——一个实例的状态也可能
+ 是瞬时的或脱管的。
+ </para>
+
+
+
+ <para>
+ 如果这些持久化类遵循一些简单的规则,Hibernate能够工作得更好,这些规则也被称作
+ 简单传统Java对象(POJO:Plain Old Java Object)编程模型。但是这些规则并不是必需的。
+ 实际上,Hibernate3对于你的持久化类几乎不做任何设想。你可以用其他的方法来表达领域模型:
+ 比如,使用<literal>Map</literal>实例的树型结构。
+ </para>
+
+
+ <sect1 id="persistent-classes-pojo">
+ <title>一个简单的POJO例子</title>
+ <para>
+ 大多数Java程序需要用一个持久化类来表示猫科动物。
+ </para>
+
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+import java.util.Date;
+
+public class Cat {
+ private Long id; // identifier
+
+ private Date birthdate;
+ private Color color;
+ private char sex;
+ private float weight;
+ private int litterId;
+
+ private Cat mother;
+ private Set kittens = new HashSet();
+
+ private void setId(Long id) {
+ this.id=id;
+ }
+ public Long getId() {
+ return id;
+ }
+
+ void setBirthdate(Date date) {
+ birthdate = date;
+ }
+ public Date getBirthdate() {
+ return birthdate;
+ }
+
+ void setWeight(float weight) {
+ this.weight = weight;
+ }
+ public float getWeight() {
+ return weight;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+ void setColor(Color color) {
+ this.color = color;
+ }
+
+ void setSex(char sex) {
+ this.sex=sex;
+ }
+ public char getSex() {
+ return sex;
+ }
+
+ void setLitterId(int id) {
+ this.litterId = id;
+ }
+ public int getLitterId() {
+ return litterId;
+ }
+
+ void setMother(Cat mother) {
+ this.mother = mother;
+ }
+ public Cat getMother() {
+ return mother;
+ }
+ void setKittens(Set kittens) {
+ this.kittens = kittens;
+ }
+ public Set getKittens() {
+ return kittens;
+ }
+
+ // addKitten not needed by Hibernate
+ public void addKitten(Cat kitten) {
+ kitten.setMother(this);
+ kitten.setLitterId( kittens.size() );
+ kittens.add(kitten);
+ }
+}]]></programlisting>
+
+ <para>
+ 这里要遵循四条主要的规则:
+ </para>
+
+
+ <sect2 id="persistent-classes-pojo-constructor" revision="1">
+ <title>实现一个默认的(即无参数的)构造方法(constructor)</title>
+
+ <para>
+ <literal>Cat</literal>有一个无参数的构造方法。所有的持久化类都必须有一个
+ 默认的构造方法(可以不是public的),这样的话Hibernate就可以使用
+ <literal>Constructor.newInstance()</literal>来实例化它们。
+ 我们强烈建议,在Hibernate中,为了运行期代理的生成,构造方法至少是
+ <emphasis>包(package)</emphasis>内可见的。
+ </para>
+
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-identifier" revision="2">
+ <title>提供一个标识属性(identifier property)(可选) </title>
+
+ <para>
+ <literal>Cat</literal>有一个属性叫做<literal>id</literal>。这个属性映射数据库表的主
+ 键字段。这个属性可以叫任何名字,其类型可以是任何的原始类型、原始类型的包装类型、
+ <literal>java.lang.String</literal> 或者是 <literal>java.util.Date</literal>。
+ (如果你的遗留数据库表有联合主键,你甚至可以用一个用户自定义的类,该类拥有这些类型
+ 的属性。参见后面的关于联合标识符的章节。)
+ </para>
+
+
+ <para>
+ 标识符属性是可选的。可以不用管它,让Hibernate内部来追踪对象的识别。
+ 但是我们并不推荐这样做。
+ </para>
+
+ <para>
+ 实际上,一些功能只对那些声明了标识符属性的类起作用:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+
+ <para>
+ 托管对象的传播性再连接(级联更新或级联合并)
+ ——参阅 <xref linkend="objectstate-transitive"/>
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.saveOrUpdate()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.merge()</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+
+ <para>
+ 我们建议你对持久化类声明命名一致的标识属性。我们还建议你使用一
+ 个可以为空(也就是说,不是原始类型)的类型。
+ </para>
+
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-final">
+ <title>使用非final的类 (可选)</title>
+ <para>
+ <emphasis>代理(proxies)</emphasis>是Hibernate的一个重要的功能,它依赖的条件是,持久
+ 化类或者是非final的,或者是实现了一个所有方法都声明为public的接口。
+ </para>
+
+
+ <para>
+ 你可以用Hibernate持久化一个没有实现任何接口的<literal>final</literal>类,但是你
+ 不能使用代理来延迟关联加载,这会限制你进行性能优化的选择。
+ </para>
+
+
+ <para>
+ 你也应该避免在非final类中声明 <literal>public final</literal>的方法。如果你想使用一
+ 个有<literal>public final</literal>方法的类,你必须通过设置<literal>lazy="false"</literal>
+ 来明确地禁用代理。
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-accessors" revision="2">
+ <title>为持久化字段声明访问器(accessors)和是否可变的标志(mutators)(可选)</title>
+
+ <para>
+ <literal>Cat</literal>为它的所有持久化字段声明了访问方法。很多其他ORM工具直接对
+ 实例变量进行持久化。我们相信,在关系数据库schema和类的内部数据结构之间引入间接层(原文为"非直接",indirection)会好一些。默认情况下Hibernate持久化JavaBeans风格的属性,认可
+ <literal>getFoo</literal>,<literal>isFoo</literal> 和 <literal>setFoo</literal>这种形式的方法名。
+ 如果需要,你可以对某些特定属性实行直接字段访问。
+ </para>
+
+
+ <para>
+ 属性<emphasis>不需要</emphasis>要声明为public的。Hibernate可以持久化一个有
+ <literal>default</literal>、<literal>protected</literal>或<literal>private</literal>的get/set方法对
+ 的属性进行持久化。
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="persistent-classes-inheritance">
+ <title>实现继承(Inheritance)</title>
+
+ <para>
+ 子类也必须遵守第一条和第二条规则。它从超类<literal>Cat</literal>继承了标识属性。
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+public class DomesticCat extends Cat {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+ protected void setName(String name) {
+ this.name=name;
+ }
+}]]></programlisting>
+ </sect1>
+
+ <sect1 id="persistent-classes-equalshashcode" revision="1">
+ <title>实现<literal>equals()</literal>和<literal>hashCode()</literal></title>
+
+ <para>
+ 如果你有如下需求,你必须重载
+ <literal>equals()</literal> 和 <literal>hashCode()</literal>方法:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 想把持久类的实例放入<literal>Set</literal>中(当表示多值关联时,推荐这么做)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 想重用脱管实例
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate保证,仅在特定会话范围内,持久化标识(数据库的行)和Java标识是等价的。因此,一旦
+ 我们混合了从不同会话中获取的实例,如果希望<literal>Set</literal>有明确的语义,就必
+ 须实现<literal>equals()</literal> 和<literal>hashCode()</literal>。
+ </para>
+
+ <para>
+ 实现<literal>equals()</literal>/<literal>hashCode()</literal>最显而易见的方法是比较两个对象
+ 标识符的值。如果值相同,则两个对象对应于数据库的同一行,因此它们是相等的(如果都被添加到
+ <literal>Set</literal>,则在<literal>Set</literal>中只有一个元素)。不幸的是,对生成的标识不能
+ 使用这种方法。Hibernate仅对那些持久化对象赋标识值,一个新创建的实例将不会有任何标识值。此外,
+ 如果一个实例没有被保存(unsaved),并且它当前正在一个<literal>Set</literal>中,保存它将会给这个对象
+ 赋一个标识值。如果<literal>equals()</literal> 和 <literal>hashCode()</literal>是基于标识值
+ 实现的,则其哈希码将会改变,这违反了<literal>Set</literal>的契约。建议去Hibernate的站点阅读关于这个
+ 问题的全部讨论。注意,这不是Hibernate的问题,而是一般的Java对象标识和Java对象等价的语义问题。
+ </para>
+ <para>
+ 我们建议使用<emphasis>业务键值相等(Business key equality)</emphasis>来实现<literal>equals()</literal>
+ 和 <literal>hashCode()</literal>。业务键值相等的意思是,<literal>equals()</literal>方法
+ 仅仅比较形成业务键的属性,它能在现实世界里标识我们的实例(是一个<emphasis>自然的</emphasis>候选码)。
+ </para>
+ <programlisting><![CDATA[public class Cat {
+
+ ...
+ public boolean equals(Object other) {
+ if (this == other) return true;
+ if ( !(other instanceof Cat) ) return false;
+
+ final Cat cat = (Cat) other;
+
+ if ( !cat.getLitterId().equals( getLitterId() ) ) return false;
+ if ( !cat.getMother().equals( getMother() ) ) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = getMother().hashCode();
+ result = 29 * result + getLitterId();
+ return result;
+ }
+
+}]]></programlisting>
+
+ <para>
+ 注意,业务键不必像数据库的主键那样固定不变(参见<xref linkend="transactions-basics-identity"/>)。
+ 对业务键而言,不可变或唯一的属性是不错的选择。
+ </para>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-dynamicmodels">
+ <title>动态模型(Dynamic models)</title>
+ <para>
+ <emphasis>注意,以下特性在当前处于试验阶段,将来可能会有变化。</emphasis>
+ </para>
+
+ <para>
+ 运行期的持久化实体没有必要一定表示为像POJO类或JavaBean对象那样的形式。Hibernate也支持动态模型
+ (在运行期使用<literal>Map</literal>的<literal>Map</literal>)和象DOM4J的树模型那
+ 样的实体表示。使用这种方法,你不用写持久化类,只写映射文件就行了。
+ </para>
+
+
+ <para>
+ Hibernate默认工作在普通POJO模式。你可以使用配置选项<literal>default_entity_mode</literal>,
+ 对特定的<literal>SessionFactory</literal>,设置一个默认的实体表示模式。
+ (参见<xref linkend="configuration-optional-properties"/>。)
+ </para>
+
+ <para>
+ 下面是用<literal>Map</literal>来表示的例子。首先,在映射文件中,要声明
+ <literal>entity-name</literal>来代替一个类名(或作为一种附属)。
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class entity-name="Customer">
+
+ <id name="id"
+ type="long"
+ column="ID">
+ <generator class="sequence"/>
+ </id>
+
+ <property name="name"
+ column="NAME"
+ type="string"/>
+
+ <property name="address"
+ column="ADDRESS"
+ type="string"/>
+
+ <many-to-one name="organization"
+ column="ORGANIZATION_ID"
+ class="Organization"/>
+
+ <bag name="orders"
+ inverse="true"
+ lazy="false"
+ cascade="all">
+ <key column="CUSTOMER_ID"/>
+ <one-to-many class="Order"/>
+ </bag>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 注意,虽然是用目标类名来声明关联的,但是关联的目标类型除了是POJO之外,也可以
+ 是一个动态的实体。
+ </para>
+
+ <para>
+ 在使用<literal>dynamic-map</literal>为<literal>SessionFactory</literal>
+ 设置了默认的实体模式之后,可以在运行期使用<literal>Map</literal>的
+ <literal>Map</literal>。
+ </para>
+
+ <programlisting><![CDATA[Session s = openSession();
+Transaction tx = s.beginTransaction();
+Session s = openSession();
+
+// Create a customer
+Map david = new HashMap();
+david.put("name", "David");
+
+// Create an organization
+Map foobar = new HashMap();
+foobar.put("name", "Foobar Inc.");
+
+// Link both
+david.put("organization", foobar);
+
+// Save both
+s.save("Customer", david);
+s.save("Organization", foobar);
+
+tx.commit();
+s.close();]]></programlisting>
+
+ <para>
+ 动态映射的好处是,变化所需要的时间少了,因为原型不需要实现实体类。然而,你无法进行
+ 编译期的类型检查,并可能由此会处理很多的运行期异常。幸亏有了Hibernate映射,它使得数
+ 据库的schema能容易的规格化和合理化,并允许稍后在此之上添加合适的领域模型实现。
+ </para>
+
+
+ <para>
+ 实体表示模式也能在每个<literal>Session</literal>的基础上设置:
+ </para>
+ <programlisting><![CDATA[Session dynamicSession = pojoSession.getSession(EntityMode.MAP);
+
+// Create a customer
+Map david = new HashMap();
+david.put("name", "David");
+dynamicSession.save("Customer", david);
+...
+dynamicSession.flush();
+dynamicSession.close()
+...
+// Continue on pojoSession
+]]></programlisting>
+
+
+
+ <para>
+ 请注意,用<literal>EntityMode</literal>调用<literal>getSession()</literal>是在
+ <literal>Session</literal>的API中,而不是<literal>SessionFactory</literal>。
+ 这样,新的<literal>Session</literal>共享底层的JDBC连接,事务,和其他的上下文信
+ 息。这意味着,你不需要在第二个<literal>Session</literal>中调用
+ <literal>flush()</literal>和<literal>close()</literal>,同样的,把事务和连接的处理
+ 交给原来的工作单元。
+ </para>
+
+
+ <para>
+ 关于XML表示能力的更多信息可以在<xref linkend="xml"/>中找到。
+ </para>
+ </sect1>
+
+ <sect1 id="persistent-classes-tuplizers" revision="1">
+ <title>元组片断映射(Tuplizers)</title>
+
+ <para>
+ <literal>org.hibernate.tuple.Tuplizer</literal>,以及其子接口,负责根据给定的<literal>org.hibernate.EntityMode</literal>,来复现片断数据。如果给定的片断数据被认为其是一种数据结构,"tuplizer"就是一个知道如何创建这样的数据结构,以及如何给这个数据结构赋值的东西。比如说,对于POJO这种Entity Mode,对应的tuplizer知道通过其构造方法来创建一个POJO,再通过其属性访问器来访问POJO属性。有两大类高层Tuplizer,分别是<literal>org.hibernate.tuple.entity.EntityTuplizer</literal> 和<literal>org.hibernate.tuple.entity.ComponentTuplizer</literal>接口。<literal>EntityTuplizer</literal>负责管理上面提到的实体的契约,而<literal>ComponentTuplizer</literal>则是针对组件的。
+ </para>
+
+ <para>
+ 用户也可以插入其自定义的tuplizer。或许您需要一种不同于dynamic-map entity-mode中使用的<literal>java.util.HashMap</literal>的<literal>java.util.Map</literal>实现;或许您需要与默认策略不同的代理生成策略(proxy generation strategy)。通过自定义tuplizer实现,这两个目标您都可以达到。Tuplizer定义被附加到它们期望管理的entity或者component映射中。回到我们的customer entity例子:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+ <class entity-name="Customer">
+ <!--
+ Override the dynamic-map entity-mode
+ tuplizer for the customer entity
+ -->
+ <tuplizer entity-mode="dynamic-map"
+ class="CustomMapTuplizerImpl"/>
+
+ <id name="id" type="long" column="ID">
+ <generator class="sequence"/>
+ </id>
+
+ <!-- other properties -->
+ ...
+ </class>
+</hibernate-mapping>
+
+
+public class CustomMapTuplizerImpl
+ extends org.hibernate.tuple.entity.DynamicMapEntityTuplizer {
+ // override the buildInstantiator() method to plug in our custom map...
+ protected final Instantiator buildInstantiator(
+ org.hibernate.mapping.PersistentClass mappingInfo) {
+ return new CustomMapInstantiator( mappingInfo );
+ }
+
+ private static final class CustomMapInstantiator
+ extends org.hibernate.tuple.DynamicMapInstantitor {
+ // override the generateMap() method to return our custom map...
+ protected final Map generateMap() {
+ return new CustomMap();
+ }
+ }
+}]]></programlisting>
+
+
+ </sect1>
+
+ <para>
+ TODO:property和proxy包里的用户扩展框架文档。
+ </para>
+
+</chapter>
+
Added: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/preface.xml
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/preface.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/preface.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,70 @@
+<?xml version='1.0' encoding="UTF-8"?>
+
+<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<preface id="preface" revision="2">
+ <title>前言</title>
+
+ <para>
+ 在今日的企业环境中,把面向对象的软件和关系数据库一起使用可能是相当麻烦、浪费时间的。Hibernate是一个面向Java环境的对象/关系数据库映射工具。对象/关系数据库映射(object/relational mapping (ORM))这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去。
+ </para>
+
+ <para>
+ Hibernate不仅仅管理Java类到数据库表的映射(包括Java数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用SQL和JDBC处理数据的时间。
+ </para>
+
+ <para>
+ Hibernate的目标是对于开发者通常的数据持久化相关的编程任务,解放其中的95%。对于以数据为中心的程序来说,它们往往只在数据库中使用存储过程来实现商业逻辑,Hibernate可能不是最好的解决方案;对于那些在基于Java的中间层应用中,它们实现面向对象的业务模型和商业逻辑的应用,Hibernate是最有用的。不管怎样,Hibernate一定可以帮助你消除或者包装那些针对特定厂商的SQL代码,并且帮你把结果集从表格式的表示形式转换到一系列的对象去。
+ </para>
+
+ <para>
+ 如果你对Hibernate和对象/关系数据库映射还是个新手,或者甚至对Java也不熟悉,请按照下面的步骤来学习。
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ 阅读<xref linkend="tutorial"/>,这是一篇包含详细的逐步指导的指南。本指南的源代码包含在发行包中,你可以在<literal>doc/reference/tutorial/</literal>目录下找到。 </para>
+ </listitem>
+ <listitem>
+ <para>
+ 阅读<xref linkend="architecture"/>来理解Hibernate可以使用的环境。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 查看Hibernate发行包中的<literal>eg/</literal>目录,里面有一个简单的独立运行的程序。把你的JDBC驱动拷贝到<literal>lib/</literal>目录下,修改一下<literal>src/hibernate.properties</literal>,指定其中你的数据库的信息。进入命令行,切换到你的发行包的目录,输入<literal>ant eg</literal>(使用了Ant),或者在Windows操作系统中使用<literal>build eg</literal>。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 把这份参考文档作为你学习的主要信息来源。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 在Hibernate 的网站上可以找到经常提问的问题与解答(FAQ)。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 在Hibernate网站上还有第三方的演示、示例和教程的链接。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Hibernate网站的“社区(Community Area)”是讨论关于设计模式以及很多整合方案(Tomcat, JBoss AS, Struts, EJB,等等)的好地方。
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ 如果你有问题,请使用Hibernate网站上链接的用户论坛。我们也提供一个JIRA问题追踪系统,来搜集bug报告和新功能请求。如果你对开发Hibernate有兴趣,请加入开发者的邮件列表。(Hibernate网站上的用户论坛有一个中文版面,JavaEye也有Hibernate中文版面,您可以在那里交流问题与经验。)
+ </para>
+
+ <para>
+ 商业开发、产品支持和Hibernate培训可以通过JBoss Inc.获得。(请查阅:http://www.hibernate.org/SupportTraining/)。
+ Hibernate是一个专业的开放源代码项目(Professional Open Source project),也是JBoss Enterprise Middleware System(JEMS),JBoss企业级中间件系统的一个核心组件。
+ </para>
+
+</preface>
\ No newline at end of file
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/query_criteria.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/query_criteria.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/query_criteria.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/query_criteria.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,424 @@
+<chapter id="querycriteria">
+ <title>
+ 条件查询(Criteria Queries)
+ </title>
+ <para>
+ 具有一个直观的、可扩展的条件查询API是Hibernate的特色。
+ </para>
+
+ <sect1 id="querycriteria-creating">
+ <title>创建一个<literal>Criteria</literal> 实例</title>
+
+ <para>
+ <literal>org.hibernate.Criteria</literal>接口表示特定持久类的一个查询。<literal>Session</literal>是
+ <literal>Criteria</literal>实例的工厂。
+ </para>
+
+ <programlisting><![CDATA[Criteria crit = sess.createCriteria(Cat.class);
+crit.setMaxResults(50);
+List cats = crit.list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-narrowing">
+ <title>限制结果集内容</title>
+
+ <para>
+ 一个单独的查询条件是<literal>org.hibernate.criterion.Criterion</literal>
+ 接口的一个实例。<literal>org.hibernate.criterion.Restrictions</literal>类
+ 定义了获得某些内置<literal>Criterion</literal>类型的工厂方法。
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .add( Restrictions.between("weight", minWeight, maxWeight) )
+ .list();]]></programlisting>
+
+ <para>
+ 约束可以按逻辑分组。
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .add( Restrictions.or(
+ Restrictions.eq( "age", new Integer(0) ),
+ Restrictions.isNull("age")
+ ) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
+ .add( Restrictions.disjunction()
+ .add( Restrictions.isNull("age") )
+ .add( Restrictions.eq("age", new Integer(0) ) )
+ .add( Restrictions.eq("age", new Integer(1) ) )
+ .add( Restrictions.eq("age", new Integer(2) ) )
+ ) )
+ .list();]]></programlisting>
+
+ <para>
+ Hibernate提供了相当多的内置criterion类型(<literal>Restrictions</literal>
+ 子类), 但是尤其有用的是可以允许你直接使用SQL。
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.sqlRestriction("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) )
+ .list();]]></programlisting>
+
+ <para>
+ <literal>{alias}</literal>占位符应当被替换为被查询实体的列别名。
+ </para>
+
+ <para>
+
+ <literal>Property</literal>实例是获得一个条件的另外一种途径。你可以通过调用<literal>Property.forName()</literal>
+ 创建一个<literal>Property</literal>。
+
+ </para>
+
+ <programlisting><![CDATA[
+Property age = Property.forName("age");
+List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.disjunction()
+ .add( age.isNull() )
+ .add( age.eq( new Integer(0) ) )
+ .add( age.eq( new Integer(1) ) )
+ .add( age.eq( new Integer(2) ) )
+ ) )
+ .add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-ordering">
+ <title>结果集排序</title>
+
+ <para>
+ 你可以使用<literal>org.hibernate.criterion.Order</literal>来为查询结果排序。
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "F%")
+ .addOrder( Order.asc("name") )
+ .addOrder( Order.desc("age") )
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Property.forName("name").like("F%") )
+ .addOrder( Property.forName("name").asc() )
+ .addOrder( Property.forName("age").desc() )
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-associations" revision="2">
+ <title>关联</title>
+
+ <para>
+ 你可以使用<literal>createCriteria()</literal>非常容易的在互相关联的实体间建立
+ 约束。
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "F%") )
+ .createCriteria("kittens")
+ .add( Restrictions.like("name", "F%") )
+ .list();]]></programlisting>
+
+ <para>
+ 注意第二个 <literal>createCriteria()</literal>返回一个新的
+ <literal>Criteria</literal>实例,该实例引用<literal>kittens</literal> 集合中的元素。
+ </para>
+
+ <para>
+ 接下来,替换形态在某些情况下也是很有用的。
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .createAlias("kittens", "kt")
+ .createAlias("mate", "mt")
+ .add( Restrictions.eqProperty("kt.name", "mt.name") )
+ .list();]]></programlisting>
+
+ <para>
+
+ (<literal>createAlias()</literal>并不创建一个新的
+ <literal>Criteria</literal>实例。)
+ </para>
+
+ <para>
+ <literal>Cat</literal>实例所保存的之前两次查询所返回的kittens集合是
+ <emphasis>没有</emphasis>被条件预过滤的。如果你希望只获得符合条件的kittens,
+ 你必须使用<literal>ResultTransformer</literal>。
+
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .createCriteria("kittens", "kt")
+ .add( Restrictions.eq("name", "F%") )
+ .setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP)
+ .list();
+Iterator iter = cats.iterator();
+while ( iter.hasNext() ) {
+ Map map = (Map) iter.next();
+ Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
+ Cat kitten = (Cat) map.get("kt");
+}]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-dynamicfetching" revision="1">
+ <title>动态关联抓取</title>
+
+ <para>
+ 你可以使用<literal>setFetchMode()</literal>在运行时定义动态关联抓取的语义。
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .setFetchMode("mate", FetchMode.EAGER)
+ .setFetchMode("kittens", FetchMode.EAGER)
+ .list();]]></programlisting>
+
+ <para>
+ 这个查询可以通过外连接抓取<literal>mate</literal>和<literal>kittens</literal>。
+ 查看<xref linkend="performance-fetching"/>可以获得更多信息。
+ </para>
+
+ </sect1>
+
+ <sect1 id="querycriteria-examples">
+ <title>查询示例</title>
+
+ <para>
+ <literal>org.hibernate.criterion.Example</literal>类允许你通过一个给定实例
+ 构建一个条件查询。
+ </para>
+
+ <programlisting><![CDATA[Cat cat = new Cat();
+cat.setSex('F');
+cat.setColor(Color.BLACK);
+List results = session.createCriteria(Cat.class)
+ .add( Example.create(cat) )
+ .list();]]></programlisting>
+
+ <para>
+ 版本属性、标识符和关联被忽略。默认情况下值为null的属性将被排除。
+ </para>
+
+ <para>
+ 你可以自行调整<literal>Example</literal>使之更实用。
+ </para>
+
+ <programlisting><![CDATA[Example example = Example.create(cat)
+ .excludeZeroes() //exclude zero valued properties
+ .excludeProperty("color") //exclude the property named "color"
+ .ignoreCase() //perform case insensitive string comparisons
+ .enableLike(); //use like for string comparisons
+List results = session.createCriteria(Cat.class)
+ .add(example)
+ .list();]]></programlisting>
+
+ <para>
+ 你甚至可以使用examples在关联对象上放置条件。
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .add( Example.create(cat) )
+ .createCriteria("mate")
+ .add( Example.create( cat.getMate() ) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-projection">
+ <title>投影(Projections)、聚合(aggregation)和分组(grouping)</title>
+ <para>
+ <literal>org.hibernate.criterion.Projections</literal>是
+ <literal>Projection</literal> 的实例工厂。我们通过调用
+ <literal>setProjection()</literal>应用投影到一个查询。
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.rowCount() )
+ .add( Restrictions.eq("color", Color.BLACK) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount() )
+ .add( Projections.avg("weight") )
+ .add( Projections.max("weight") )
+ .add( Projections.groupProperty("color") )
+ )
+ .list();]]></programlisting>
+
+ <para>
+ 在一个条件查询中没有必要显式的使用 "group by" 。某些投影类型就是被定义为<emphasis>
+ 分组投影</emphasis>,他们也出现在SQL的<literal>group by</literal>子句中。
+ </para>
+
+ <para>
+ 你可以选择把一个别名指派给一个投影,这样可以使投影值被约束或排序所引用。下面是两种不同的实现方式:
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
+ .addOrder( Order.asc("colr") )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.groupProperty("color").as("colr") )
+ .addOrder( Order.asc("colr") )
+ .list();]]></programlisting>
+
+ <para>
+ <literal>alias()</literal>和<literal>as()</literal>方法简便的将一个投影实例包装到另外一个
+ 别名的<literal>Projection</literal>实例中。简而言之,当你添加一个投影到一个投影列表中时
+ 你可以为它指定一个别名:
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount(), "catCountByColor" )
+ .add( Projections.avg("weight"), "avgWeight" )
+ .add( Projections.max("weight"), "maxWeight" )
+ .add( Projections.groupProperty("color"), "color" )
+ )
+ .addOrder( Order.desc("catCountByColor") )
+ .addOrder( Order.desc("avgWeight") )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Domestic.class, "cat")
+ .createAlias("kittens", "kit")
+ .setProjection( Projections.projectionList()
+ .add( Projections.property("cat.name"), "catName" )
+ .add( Projections.property("kit.name"), "kitName" )
+ )
+ .addOrder( Order.asc("catName") )
+ .addOrder( Order.asc("kitName") )
+ .list();]]></programlisting>
+
+ <para>
+ 你也可以使用<literal>Property.forName()</literal>来表示投影:
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Property.forName("name") )
+ .add( Property.forName("color").eq(Color.BLACK) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount().as("catCountByColor") )
+ .add( Property.forName("weight").avg().as("avgWeight") )
+ .add( Property.forName("weight").max().as("maxWeight") )
+ .add( Property.forName("color").group().as("color" )
+ )
+ .addOrder( Order.desc("catCountByColor") )
+ .addOrder( Order.desc("avgWeight") )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-detachedqueries">
+ <title>离线(detached)查询和子查询</title>
+ <para>
+ <literal>DetachedCriteria</literal>类使你在一个session范围之外创建一个查询,并且可以使用任意的
+ <literal>Session</literal>来执行它。
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria query = DetachedCriteria.forClass(Cat.class)
+ .add( Property.forName("sex").eq('F') );
+
+Session session = ....;
+Transaction txn = session.beginTransaction();
+List results = query.getExecutableCriteria(session).setMaxResults(100).list();
+txn.commit();
+session.close();]]></programlisting>
+
+ <para>
+ <literal>DetachedCriteria</literal>也可以用以表示子查询。条件实例包含子查询可以通过
+ <literal>Subqueries</literal>或者<literal>Property</literal>获得。
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)
+ .setProjection( Property.forName("weight").avg() );
+session.createCriteria(Cat.class)
+ .add( Property.forName("weight").gt(avgWeight) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)
+ .setProjection( Property.forName("weight") );
+session.createCriteria(Cat.class)
+ .add( Subqueries.geAll("weight", weights) )
+ .list();]]></programlisting>
+
+ <para>
+ 甚至相互关联的子查询也是有可能的:
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")
+ .setProjection( Property.forName("weight").avg() )
+ .add( Property.forName("cat2.sex").eqProperty("cat.sex") );
+session.createCriteria(Cat.class, "cat")
+ .add( Property.forName("weight").gt(avgWeightForSex) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+
+ <!--TODO: ResultSetTransformer + aliasing. AliasToBeanTransformer allow returning arbitrary
+ user objects - similar to setResultClass in JDO2. General use of ResultTransformer
+ could also be explained. -->
+
+ <sect1 id="query-criteria-naturalid">
+ <title>根据自然标识查询(Queries by natural identifier)</title>
+
+
+ <para>
+ 对大多数查询,包括条件查询而言,因为查询缓存的失效(invalidation)发生得太频繁,查询缓存不是非常高效。然而,有一种特别的查询,可以通过不变的自然键优化缓存的失效算法。在某些应用中,这种类型的查询比较常见。条件查询API对这种用例提供了特别规约。
+ </para>
+
+ <para>
+ 首先,你应该对你的entity使用<literal><natural-id></literal>来映射自然键,然后打开第二级缓存。
+ </para>
+
+ <programlisting><![CDATA[<class name="User">
+ <cache usage="read-write"/>
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <natural-id>
+ <property name="name"/>
+ <property name="org"/>
+ </natural-id>
+ <property name="password"/>
+</class>]]></programlisting>
+
+ <para>
+ 注意,此功能对具有<emphasis>mutable</emphasis>自然键的entity并不适用。
+ </para>
+
+ <para>
+ 然后,打开Hibernate 查询缓存。
+ </para>
+
+ <para>
+ 现在,我们可以用<literal>Restrictions.naturalId()</literal>来使用更加高效的缓存算法。
+ </para>
+
+ <programlisting><![CDATA[session.createCriteria(User.class)
+ .add( Restrictions.naturalId()
+ .set("name", "gavin")
+ .set("org", "hb")
+ ).setCacheable(true)
+ .uniqueResult();]]></programlisting>
+
+ </sect1>
+
+
+</chapter>
+
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/query_hql.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/query_hql.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/query_hql.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/query_hql.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,1088 @@
+<chapter id="queryhql">
+ <title>HQL: Hibernate查询语言</title>
+ <para>
+ Hibernate配备了一种非常强大的查询语言,这种语言看上去很像SQL。但是不要被语法结构
+ 上的相似所迷惑,HQL是非常有意识的被设计为完全面向对象的查询,它可以理解如继承、多态
+ 和关联之类的概念。
+ </para>
+
+ <sect1 id="queryhql-casesensitivity">
+ <title>大小写敏感性问题</title>
+
+ <para>
+ 除了Java类与属性的名称外,查询语句对大小写并不敏感。
+ 所以 <literal>SeLeCT</literal> 与
+ <literal>sELEct</literal> 以及
+ <literal>SELECT</literal> 是相同的,但是
+ <literal>org.hibernate.eg.FOO</literal> 并不等价于
+ <literal>org.hibernate.eg.Foo</literal> 并且
+ <literal>foo.barSet</literal> 也不等价于
+ <literal>foo.BARSET</literal>。
+ </para>
+
+ <para>
+ 本手册中的HQL关键字将使用小写字母. 很多用户发现使用完全大写的关键字会使查询语句
+ 的可读性更强, 但我们发现,当把查询语句嵌入到Java语句中的时候使用大写关键字比较难看。
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-from">
+ <title>from子句</title>
+
+ <para>
+ Hibernate中最简单的查询语句的形式如下:
+ </para>
+
+ <programlisting><![CDATA[from eg.Cat]]></programlisting>
+
+ <para>
+ 该子句简单的返回<literal>eg.Cat</literal>类的所有实例。
+ 通常我们不需要使用类的全限定名, 因为 <literal>auto-import</literal>(自动引入)
+ 是缺省的情况。 所以我们几乎只使用如下的简单写法:
+ </para>
+
+ <programlisting><![CDATA[from Cat]]></programlisting>
+
+ <para>
+ 大多数情况下, 你需要指定一个<emphasis>别名</emphasis>, 原因是你可能需要
+ 在查询语句的其它部分引用到<literal>Cat</literal>
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat]]></programlisting>
+
+ <para>
+ 这个语句把别名<literal>cat</literal>指定给类<literal>Cat</literal>
+ 的实例, 这样我们就可以在随后的查询中使用此别名了。 关键字<literal>as</literal>
+ 是可选的,我们也可以这样写:
+ </para>
+
+ <programlisting><![CDATA[from Cat cat]]></programlisting>
+
+ <para>
+ 子句中可以同时出现多个类, 其查询结果是产生一个笛卡儿积或产生跨表的连接。
+ </para>
+
+ <programlisting><![CDATA[from Formula, Parameter]]></programlisting>
+ <programlisting><![CDATA[from Formula as form, Parameter as param]]></programlisting>
+
+ <para>
+ 查询语句中别名的开头部分小写被认为是实践中的好习惯,
+ 这样做与Java变量的命名标准保持了一致
+ (比如,<literal>domesticCat</literal>)。
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-joins" revision="2">
+ <title>关联(Association)与连接(Join)</title>
+
+ <para>
+ 我们也可以为相关联的实体甚至是对一个集合中的全部元素指定一个别名, 这时要使用关键字<literal>join</literal>。
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join cat.mate as mate
+ left outer join cat.kittens as kitten]]></programlisting>
+
+ <programlisting><![CDATA[from Cat as cat left join cat.mate.kittens as kittens]]></programlisting>
+
+ <programlisting><![CDATA[from Formula form full join form.parameter param]]></programlisting>
+
+ <para>
+ 受支持的连接类型是从ANSI SQL中借鉴来的。
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>inner join</literal>(内连接)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>left outer join</literal>(左外连接)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>right outer join</literal>(右外连接)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>full join</literal> (全连接,并不常用)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 语句<literal>inner join</literal>, <literal>left outer join</literal> 以及
+ <literal>right outer join</literal> 可以简写。
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ join cat.mate as mate
+ left join cat.kittens as kitten]]></programlisting>
+
+ <para>
+ 通过HQL的<literal>with</literal>关键字,你可以提供额外的join条件。
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ left join cat.kittens as kitten
+ with kitten.bodyWeight > 10.0]]></programlisting>
+
+ <para>
+ 还有,一个"fetch"连接允许仅仅使用一个选择语句就将相关联的对象或一组值的集合随着他们的父对象的初始化而被初始化,这种方法在使用到集合的情况下尤其有用,对于关联和集合来说,它有效的代替了映射文件中的外联接
+ 与延迟声明(lazy declarations). 查看
+ <xref linkend="performance-fetching"/> 以获得等多的信息。
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join fetch cat.mate
+ left join fetch cat.kittens]]></programlisting>
+
+ <para>
+ 一个fetch连接通常不需要被指定别名, 因为相关联的对象不应当被用在
+ <literal>where</literal> 子句 (或其它任何子句)中。同时,相关联的对象
+ 并不在查询的结果中直接返回,但可以通过他们的父对象来访问到他们。
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join fetch cat.mate
+ left join fetch cat.kittens child
+ left join fetch child.kittens]]></programlisting>
+
+
+ <para>
+ 假若使用<literal>iterate()</literal>来调用查询,请注意<literal>fetch</literal>构造是不能使用的(<literal>scroll()</literal> 可以使用)。<literal>fetch</literal>也不应该与<literal>setMaxResults()</literal> 或<literal>setFirstResult()</literal>共用,这是因为这些操作是基于结果集的,而在预先抓取集合类时可能包含重复的数据,也就是说无法预先知道精确的行数。<literal>fetch</literal>还不能与独立的 <literal>with</literal>条件一起使用。通过在一次查询中fetch多个集合,可以制造出笛卡尔积,因此请多加注意。对bag映射来说,同时join fetch多个集合角色可能在某些情况下给出并非预期的结果,也请小心。最后注意,使用<literal>full join fetch</literal> 与 <literal>right join fetch</literal>是没有意义的。
+ </para>
+
+ <para>
+ 如果你使用属性级别的延迟获取(lazy fetching)(这是通过重新编写字节码实现的),可以使用 <literal>fetch
+all properties</literal>
+ 来强制Hibernate立即取得那些原本需要延迟加载的属性(在第一个查询中)。
+
+ </para>
+
+ <programlisting><![CDATA[from Document fetch all properties order by name]]></programlisting>
+ <programlisting><![CDATA[from Document doc fetch all properties where lower(doc.name) like '%cats%']]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-joins-forms">
+ <title>join 语法的形式</title>
+
+ <para>
+ HQL支持两种关联join的形式:<literal>implicit(隐式)</literal> 与<literal>explicit(显式)</literal>。
+ </para>
+
+ <para>
+ 上一节中给出的查询都是使用<literal>explicit(显式)</literal>形式的,其中form子句中明确给出了join关键字。这是建议使用的方式。
+ </para>
+
+ <para>
+ <literal>implicit(隐式)</literal>形式不使用join关键字。关联使用"点号"来进行“引用”。<literal>implicit</literal> join可以在任何HQL子句中出现.<literal>implicit</literal> join在最终的SQL语句中以inner join的方式出现。
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.mate.name like '%s%']]></programlisting>
+ </sect1>
+
+ <sect1 id="queryhql-select">
+ <title>select子句</title>
+
+ <para>
+ <literal>select</literal> 子句选择将哪些对象与属性返
+ 回到查询结果集中. 考虑如下情况:
+ </para>
+
+ <programlisting><![CDATA[select mate
+from Cat as cat
+ inner join cat.mate as mate]]></programlisting>
+
+ <para>
+ 该语句将选择<literal>mate</literal>s of other <literal>Cat</literal>s。(其他猫的配偶)
+ 实际上, 你可以更简洁的用以下的查询语句表达相同的含义:
+ </para>
+
+ <programlisting><![CDATA[select cat.mate from Cat cat]]></programlisting>
+
+ <para>
+ 查询语句可以返回值为任何类型的属性,包括返回类型为某种组件(Component)的属性:
+ </para>
+
+ <programlisting><![CDATA[select cat.name from DomesticCat cat
+where cat.name like 'fri%']]></programlisting>
+
+ <programlisting><![CDATA[select cust.name.firstName from Customer as cust]]></programlisting>
+
+ <para>
+ 查询语句可以返回多个对象和(或)属性,存放在
+ <literal>Object[]</literal>队列中,
+ </para>
+
+ <programlisting><![CDATA[select mother, offspr, mate.name
+from DomesticCat as mother
+ inner join mother.mate as mate
+ left outer join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ 或存放在一个<literal>List</literal>对象中,
+ </para>
+
+ <programlisting><![CDATA[select new list(mother, offspr, mate.name)
+from DomesticCat as mother
+ inner join mother.mate as mate
+ left outer join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ 也可能直接返回一个实际的类型安全的Java对象,
+ </para>
+
+ <programlisting><![CDATA[select new Family(mother, mate, offspr)
+from DomesticCat as mother
+ join mother.mate as mate
+ left join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ 假设类<literal>Family</literal>有一个合适的构造函数.
+ </para>
+
+ <para>
+ 你可以使用关键字<literal>as</literal>给“被选择了的表达式”指派别名:
+ </para>
+
+ <programlisting><![CDATA[select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n
+from Cat cat]]></programlisting>
+
+ <para>
+ 这种做法在与子句<literal>select new map</literal>一起使用时最有用:
+ </para>
+
+ <programlisting><![CDATA[select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n )
+from Cat cat]]></programlisting>
+
+ <para>
+ 该查询返回了一个<literal>Map</literal>的对象,内容是别名与被选择的值组成的名-值映射。
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-aggregation">
+ <title>聚集函数</title>
+
+ <para>
+ HQL查询甚至可以返回作用于属性之上的聚集函数的计算结果:
+ </para>
+
+ <programlisting><![CDATA[select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)
+from Cat cat]]></programlisting>
+
+<!-- 已经不再被继续支持
+ <para>
+ 在<literal>select</literal>子句中,集合(Collections)也可以出现在聚集函数的内部。
+ </para>
+
+ <programlisting><![CDATA[select cat, count( elements(cat.kittens) )
+from Cat cat group by cat]]></programlisting>
+-->
+
+ <para>
+ 受支持的聚集函数如下:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>avg(...), sum(...), min(...), max(...)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>count(*)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>count(...), count(distinct ...), count(all...)</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 你可以在选择子句中使用数学操作符、连接以及经过验证的SQL函数:
+ </para>
+
+ <programlisting><![CDATA[select cat.weight + sum(kitten.weight)
+from Cat cat
+ join cat.kittens kitten
+group by cat.id, cat.weight]]></programlisting>
+
+ <programlisting><![CDATA[select firstName||' '||initial||' '||upper(lastName) from Person]]></programlisting>
+
+ <para>
+ 关键字<literal>distinct</literal>与<literal>all</literal> 也可以使用,它们具有与SQL相同的语义.
+ </para>
+
+ <programlisting><![CDATA[select distinct cat.name from Cat cat
+
+select count(distinct cat.name), count(cat) from Cat cat]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-polymorphism">
+ <title>多态查询</title>
+
+ <para>
+ 一个如下的查询语句:
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat]]></programlisting>
+
+ <para>
+ 不仅返回<literal>Cat</literal>类的实例, 也同时返回子类
+ <literal>DomesticCat</literal>的实例. Hibernate 可以在<literal>from</literal>子句中指定<emphasis>任何</emphasis>
+ Java 类或接口. 查询会返回继承了该类的所有持久化子类
+ 的实例或返回声明了该接口的所有持久化类的实例。下面的查询语句返回所有的被持久化的对象:
+ </para>
+
+ <programlisting><![CDATA[from java.lang.Object o]]></programlisting>
+
+ <para>
+ 接口<literal>Named</literal> 可能被各种各样的持久化类声明:
+ </para>
+
+ <programlisting><![CDATA[from Named n, Named m where n.name = m.name]]></programlisting>
+
+ <para>
+ 注意,最后的两个查询将需要超过一个的SQL <literal>SELECT</literal>.这表明<literal>order by</literal>子句
+ 没有对整个结果集进行正确的排序.
+ (这也说明你不能对这样的查询使用<literal>Query.scroll()</literal>方法.)
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-where">
+ <title>where子句</title>
+
+ <para>
+ <literal>where</literal>子句允许你将返回的实例列表的范围缩小.
+ 如果没有指定别名,你可以使用属性名来直接引用属性:
+ </para>
+
+ <programlisting><![CDATA[from Cat where name='Fritz']]></programlisting>
+
+ <para>
+ 如果指派了别名,需要使用完整的属性名:
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.name='Fritz']]></programlisting>
+
+ <para>
+ 返回名为(属性name等于)'Fritz'的<literal>Cat</literal>类的实例。
+ </para>
+
+ <programlisting><![CDATA[select foo
+from Foo foo, Bar bar
+where foo.startDate = bar.date]]></programlisting>
+
+ <para>
+ 将返回所有满足下面条件的<literal>Foo</literal>类的实例:
+ 存在如下的<literal>bar</literal>的一个实例,其<literal>date</literal>属性等于
+ <literal>Foo</literal>的<literal>startDate</literal>属性。
+ 复合路径表达式使得<literal>where</literal>子句非常的强大,考虑如下情况:
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.mate.name is not null]]></programlisting>
+
+ <para>
+ 该查询将被翻译成为一个含有表连接(内连接)的SQL查询。如果你打算写像这样的查询语句
+ </para>
+
+ <programlisting><![CDATA[from Foo foo
+where foo.bar.baz.customer.address.city is not null]]></programlisting>
+
+ <para>
+ 在SQL中,你为达此目的将需要进行一个四表连接的查询。
+ </para>
+
+ <para>
+ <literal>=</literal>运算符不仅可以被用来比较属性的值,也可以用来比较实例:
+ </para>
+
+ <programlisting><![CDATA[from Cat cat, Cat rival where cat.mate = rival.mate]]></programlisting>
+
+ <programlisting><![CDATA[select cat, mate
+from Cat cat, Cat mate
+where cat.mate = mate]]></programlisting>
+
+ <para>
+ 特殊属性(小写)<literal>id</literal>可以用来表示一个对象的唯一的标识符。(你也可以使用该对象的属性名。)
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.id = 123
+
+from Cat as cat where cat.mate.id = 69]]></programlisting>
+
+ <para>
+ 第二个查询是有效的。此时不需要进行表连接!
+ </para>
+
+ <para>
+ 同样也可以使用复合标识符。比如<literal>Person</literal>类有一个复合标识符,它由<literal>country</literal>属性
+ 与<literal>medicareNumber</literal>属性组成。
+ </para>
+
+ <programlisting><![CDATA[from bank.Person person
+where person.id.country = 'AU'
+ and person.id.medicareNumber = 123456]]></programlisting>
+
+ <programlisting><![CDATA[from bank.Account account
+where account.owner.id.country = 'AU'
+ and account.owner.id.medicareNumber = 123456]]></programlisting>
+
+ <para>
+ 第二个查询也不需要进行表连接。
+ </para>
+
+ <para>
+ 同样的,特殊属性<literal>class</literal>在进行多态持久化的情况下被用来存取一个实例的鉴别值(discriminator value)。
+ 一个嵌入到where子句中的Java类的名字将被转换为该类的鉴别值。
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.class = DomesticCat]]></programlisting>
+
+ <para>
+ 你也可以声明一个属性的类型是组件或者复合用户类型(以及由组件构成的组件等等)。永远不要尝试使用以组件类型来结尾的路径表达式(path-expression)
+ (与此相反,你应当使用组件的一个属性来结尾)。
+ 举例来说,如果<literal>store.owner</literal>含有一个包含了组件的实体<literal>address</literal>
+ </para>
+
+ <programlisting><![CDATA[store.owner.address.city // 正确
+store.owner.address // 错误!]]></programlisting>
+
+ <para>
+ 一个“任意”类型有两个特殊的属性<literal>id</literal>和<literal>class</literal>,
+ 来允许我们按照下面的方式表达一个连接(<literal>AuditLog.item</literal>
+ 是一个属性,该属性被映射为<literal><any></literal>)。
+ </para>
+
+ <programlisting><![CDATA[from AuditLog log, Payment payment
+where log.item.class = 'Payment' and log.item.id = payment.id]]></programlisting>
+
+ <para>
+ 注意,在上面的查询与句中,<literal>log.item.class</literal> 和 <literal>payment.class</literal>
+ 将涉及到完全不同的数据库中的列。
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-expressions">
+ <title>表达式</title>
+
+ <para>
+ 在<literal>where</literal>子句中允许使用的表达式包括
+ 大多数你可以在SQL使用的表达式种类:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 数学运算符<literal>+, -, *, /</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 二进制比较运算符<literal>=, >=, <=, <>, !=, like</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 逻辑运算符<literal>and, or, not</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>in</literal>,
+ <literal>not in</literal>,
+ <literal>between</literal>,
+ <literal>is null</literal>,
+ <literal>is not null</literal>,
+ <literal>is empty</literal>,
+ <literal>is not empty</literal>,
+ <literal>member of</literal> and
+ <literal>not member of</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ "简单的" case, <literal>case ... when ... then ... else ... end</literal>,和
+ "搜索" case, <literal>case when ... then ... else ... end</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 字符串连接符<literal>...||...</literal> or <literal>concat(...,...)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>current_date()</literal>, <literal>current_time()</literal>,
+ <literal>current_timestamp()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>second(...)</literal>, <literal>minute(...)</literal>,
+ <literal>hour(...)</literal>, <literal>day(...)</literal>,
+ <literal>month(...)</literal>, <literal>year(...)</literal>,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ EJB-QL 3.0定义的任何函数或操作:<literal>substring(), trim(),
+ lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>coalesce()</literal> 和 <literal>nullif()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>str()</literal> 把数字或者时间值转换为可读的字符串
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>cast(... as ...)</literal>, 其第二个参数是某Hibernate类型的名字,以及<literal>extract(... from ...)</literal>,只要ANSI
+ <literal>cast()</literal> 和 <literal>extract()</literal> 被底层数据库支持
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ HQL <literal>index()</literal> 函数,作用于join的有序集合的别名。
+
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ HQL函数,把集合作为参数:<literal>size(), minelement(), maxelement(), minindex(), maxindex()</literal>,还有特别的<literal>elements()</literal> 和<literal>indices</literal>函数,可以与数量词加以限定:<literal>some, all, exists, any, in</literal>。
+
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 任何数据库支持的SQL标量函数,比如<literal>sign()</literal>,
+ <literal>trunc()</literal>, <literal>rtrim()</literal>, <literal>sin()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ JDBC风格的参数传入 <literal>?</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 命名参数<literal>:name</literal>, <literal>:start_date</literal>, <literal>:x1</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ SQL 直接常量 <literal>'foo'</literal>, <literal>69</literal>, <literal>6.66E+2</literal>, <literal>'1970-01-01 10:00:01.0'</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Java <literal>public static final</literal> 类型的常量 <literal>eg.Color.TABBY</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 关键字<literal>in</literal>与<literal>between</literal>可按如下方法使用:
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name between 'A' and 'B']]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )]]></programlisting>
+
+ <para>
+ 而且否定的格式也可以如下书写:
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name not between 'A' and 'B']]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )]]></programlisting>
+
+ <para>
+ 同样, 子句<literal>is null</literal>与<literal>is not null</literal>可以被用来测试空值(null).
+ </para>
+
+ <para>
+ 在Hibernate配置文件中声明HQL“查询替代(query substitutions)”之后,
+ 布尔表达式(Booleans)可以在其他表达式中轻松的使用:
+ </para>
+
+ <programlisting><![CDATA[<property name="hibernate.query.substitutions">true 1, false 0</property>]]></programlisting>
+
+ <para>
+ 系统将该HQL转换为SQL语句时,该设置表明将用字符 <literal>1</literal> 和
+<literal>0</literal> 来
+ 取代关键字<literal>true</literal> 和 <literal>false</literal>:
+
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.alive = true]]></programlisting>
+
+ <para>
+ 你可以用特殊属性<literal>size</literal>, 或是特殊函数<literal>size()</literal>测试一个集合的大小。
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.kittens.size > 0]]></programlisting>
+
+ <programlisting><![CDATA[from Cat cat where size(cat.kittens) > 0]]></programlisting>
+
+ <para>
+ 对于索引了(有序)的集合,你可以使用<literal>minindex</literal> 与 <literal>maxindex</literal>函数来引用到最小与最大的索引序数。
+ 同理,你可以使用<literal>minelement</literal> 与 <literal>maxelement</literal>函数来
+引用到一个基本数据类型的集合中最小与最大的元素。
+
+ </para>
+
+ <programlisting><![CDATA[from Calendar cal where maxelement(cal.holidays) > current_date]]></programlisting>
+
+ <programlisting><![CDATA[from Order order where maxindex(order.items) > 100]]></programlisting>
+
+ <programlisting><![CDATA[from Order order where minelement(order.items) > 10000]]></programlisting>
+
+ <para>
+在传递一个集合的索引集或者是元素集(<literal>elements</literal>与<literal>indices</literal> 函数)
+ 或者传递一个子查询的结果的时候,可以使用SQL函数<literal>any, some, all, exists, in</literal>
+
+ </para>
+
+ <programlisting><![CDATA[select mother from Cat as mother, Cat as kit
+where kit in elements(foo.kittens)]]></programlisting>
+
+ <programlisting><![CDATA[select p from NameList list, Person p
+where p.name = some elements(list.names)]]></programlisting>
+
+ <programlisting><![CDATA[from Cat cat where exists elements(cat.kittens)]]></programlisting>
+
+ <programlisting><![CDATA[from Player p where 3 > all elements(p.scores)]]></programlisting>
+
+ <programlisting><![CDATA[from Show show where 'fizard' in indices(show.acts)]]></programlisting>
+
+ <para>
+ 注意,在Hibernate3种,这些结构变量- <literal>size</literal>, <literal>elements</literal>,
+ <literal>indices</literal>, <literal>minindex</literal>, <literal>maxindex</literal>,
+ <literal>minelement</literal>, <literal>maxelement</literal> - 只能在where子句中使用。
+ </para>
+
+ <para>
+ 一个被索引过的(有序的)集合的元素(arrays, lists, maps)可以在其他索引中被引用(只能在where子句中):
+ </para>
+
+ <programlisting><![CDATA[from Order order where order.items[0].id = 1234]]></programlisting>
+
+ <programlisting><![CDATA[select person from Person person, Calendar calendar
+where calendar.holidays['national day'] = person.birthDay
+ and person.nationality.calendar = calendar]]></programlisting>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11]]></programlisting>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ maxindex(order.items) ] = item and order.id = 11]]></programlisting>
+
+ <para>
+ 在<literal>[]</literal>中的表达式甚至可以是一个算数表达式。
+ </para>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ size(order.items) - 1 ] = item]]></programlisting>
+
+ <para>
+ 对于一个一对多的关联(one-to-many association)或是值的集合中的元素,
+ HQL也提供内建的<literal>index()</literal>函数,
+ </para>
+
+ <programlisting><![CDATA[select item, index(item) from Order order
+ join order.items item
+where index(item) < 5]]></programlisting>
+
+ <para>
+ 如果底层数据库支持标量的SQL函数,它们也可以被使用
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where upper(cat.name) like 'FRI%']]></programlisting>
+
+ <para>
+ 如果你还不能对所有的这些深信不疑,想想下面的查询。如果使用SQL,语句长度会增长多少,可读性会下降多少:
+ </para>
+
+ <programlisting><![CDATA[select cust
+from Product prod,
+ Store store
+ inner join store.customers cust
+where prod.name = 'widget'
+ and store.location.name in ( 'Melbourne', 'Sydney' )
+ and prod = all elements(cust.currentOrder.lineItems)]]></programlisting>
+
+ <para>
+ <emphasis>提示:</emphasis> 会像如下的语句
+ </para>
+
+ <programlisting><![CDATA[SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order
+FROM customers cust,
+ stores store,
+ locations loc,
+ store_customers sc,
+ product prod
+WHERE prod.name = 'widget'
+ AND store.loc_id = loc.id
+ AND loc.name IN ( 'Melbourne', 'Sydney' )
+ AND sc.store_id = store.id
+ AND sc.cust_id = cust.id
+ AND prod.id = ALL(
+ SELECT item.prod_id
+ FROM line_items item, orders o
+ WHERE item.order_id = o.id
+ AND cust.current_order = o.id
+ )]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-ordering">
+ <title>order by子句</title>
+
+ <para>
+ 查询返回的列表(list)可以按照一个返回的类或组件(components)中的任何属性(property)进行排序:
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat
+order by cat.name asc, cat.weight desc, cat.birthdate]]></programlisting>
+
+ <para>
+ 可选的<literal>asc</literal>或<literal>desc</literal>关键字指明了按照升序或降序进行排序.
+ </para>
+ </sect1>
+
+ <sect1 id="queryhql-grouping" revision="1">
+ <title>group by子句</title>
+
+ <para>
+ 一个返回聚集值(aggregate values)的查询可以按照一个返回的类或组件(components)中的任何属性(property)进行分组:
+ </para>
+
+ <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat)
+from Cat cat
+group by cat.color]]></programlisting>
+
+ <programlisting><![CDATA[select foo.id, avg(name), max(name)
+from Foo foo join foo.names name
+group by foo.id]]></programlisting>
+
+ <para>
+ <literal>having</literal>子句在这里也允许使用.
+ </para>
+
+ <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat)
+from Cat cat
+group by cat.color
+having cat.color in (eg.Color.TABBY, eg.Color.BLACK)]]></programlisting>
+
+ <para>
+ 如果底层的数据库支持的话(例如不能在MySQL中使用),SQL的一般函数与聚集函数也可以出现
+ 在<literal>having</literal>与<literal>order by</literal> 子句中。
+ </para>
+
+ <programlisting><![CDATA[select cat
+from Cat cat
+ join cat.kittens kitten
+group by cat.id, cat.name, cat.other, cat.properties
+having avg(kitten.weight) > 100
+order by count(kitten) asc, sum(kitten.weight) desc]]></programlisting>
+
+ <para>
+ 注意<literal>group by</literal>子句与
+ <literal>order by</literal>子句中都不能包含算术表达式(arithmetic expressions).
+
+ 也要注意Hibernate目前不会扩展group的实体,因此你不能写<literal>group by cat</literal>,除非<literal>cat</literal>的所有属性都不是聚集的(non-aggregated)。你必须明确的列出所有的非聚集属性。
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="queryhql-subqueries" revision="2">
+ <title>子查询</title>
+
+ <para>
+ 对于支持子查询的数据库,Hibernate支持在查询中使用子查询。一个子查询必须被圆括号包围起来(经常是SQL聚集函数的圆括号)。
+ 甚至相互关联的子查询(引用到外部查询中的别名的子查询)也是允许的。
+ </para>
+
+ <programlisting><![CDATA[from Cat as fatcat
+where fatcat.weight > (
+ select avg(cat.weight) from DomesticCat cat
+)]]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat as cat
+where cat.name = some (
+ select name.nickName from Name as name
+)]]></programlisting>
+
+ <programlisting><![CDATA[from Cat as cat
+where not exists (
+ from Cat as mate where mate.mate = cat
+)]]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat as cat
+where cat.name not in (
+ select name.nickName from Name as name
+)]]></programlisting>
+
+ <programlisting><![CDATA[select cat.id, (select max(kit.weight) from cat.kitten kit)
+from Cat as cat]]></programlisting>
+
+ <para>
+ 注意,HQL自查询只可以在select或者where子句中出现。
+ </para>
+
+ <para>
+ 在select列表中包含一个表达式以上的子查询,你可以使用一个元组构造符(tuple constructors):
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+where not ( cat.name, cat.color ) in (
+ select cat.name, cat.color from DomesticCat cat
+)]]></programlisting>
+
+ <para>
+ 注意在某些数据库中(不包括Oracle与HSQL),你也可以在其他语境中使用元组构造符,
+ 比如查询用户类型的组件与组合:
+ </para>
+
+ <programlisting><![CDATA[from Person where name = ('Gavin', 'A', 'King')]]></programlisting>
+
+ <para>
+ 该查询等价于更复杂的:
+ </para>
+
+ <programlisting><![CDATA[from Person where name.first = 'Gavin' and name.initial = 'A' and name.last = 'King')]]></programlisting>
+
+ <para>
+ 有两个很好的理由使你不应当作这样的事情:首先,它不完全适用于各个数据库平台;其次,查询现在依赖于映射文件中属性的顺序。
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-examples">
+ <title>HQL示例</title>
+
+ <para>
+ Hibernate查询可以非常的强大与复杂。实际上,Hibernate的一个主要卖点就是查询语句的威力。这里有一些例子,它们与我在最近的
+ 一个项目中使用的查询非常相似。注意你能用到的大多数查询比这些要简单的多!
+ </para>
+
+ <para>
+ 下面的查询对于某个特定的客户的所有未支付的账单,在给定给最小总价值的情况下,返回订单的id,条目的数量和总价值,
+ 返回值按照总价值的结果进行排序。为了决定价格,查询使用了当前目录。作为转换结果的SQL查询,使用了<literal>ORDER</literal>,
+ <literal>ORDER_LINE</literal>, <literal>PRODUCT</literal>, <literal>CATALOG</literal> 和<literal>PRICE</literal>
+ 库表。
+ </para>
+
+ <programlisting><![CDATA[select order.id, sum(price.amount), count(item)
+from Order as order
+ join order.lineItems as item
+ join item.product as product,
+ Catalog as catalog
+ join catalog.prices as price
+where order.paid = false
+ and order.customer = :customer
+ and price.product = product
+ and catalog.effectiveDate < sysdate
+ and catalog.effectiveDate >= all (
+ select cat.effectiveDate
+ from Catalog as cat
+ where cat.effectiveDate < sysdate
+ )
+group by order
+having sum(price.amount) > :minAmount
+order by sum(price.amount) desc]]></programlisting>
+
+ <para>
+ 这简直是一个怪物!实际上,在现实生活中,我并不热衷于子查询,所以我的查询语句看起来更像这个:
+ </para>
+
+ <programlisting><![CDATA[select order.id, sum(price.amount), count(item)
+from Order as order
+ join order.lineItems as item
+ join item.product as product,
+ Catalog as catalog
+ join catalog.prices as price
+where order.paid = false
+ and order.customer = :customer
+ and price.product = product
+ and catalog = :currentCatalog
+group by order
+having sum(price.amount) > :minAmount
+order by sum(price.amount) desc]]></programlisting>
+
+ <para>
+ 下面一个查询计算每一种状态下的支付的数目,除去所有处于<literal>AWAITING_APPROVAL</literal>状态的支付,因为在该状态下
+ 当前的用户作出了状态的最新改变。该查询被转换成含有两个内连接以及一个相关联的子选择的SQL查询,该查询使用了表
+ <literal>PAYMENT</literal>, <literal>PAYMENT_STATUS</literal> 以及
+ <literal>PAYMENT_STATUS_CHANGE</literal>。
+ </para>
+
+ <programlisting><![CDATA[select count(payment), status.name
+from Payment as payment
+ join payment.currentStatus as status
+ join payment.statusChanges as statusChange
+where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
+ or (
+ statusChange.timeStamp = (
+ select max(change.timeStamp)
+ from PaymentStatusChange change
+ where change.payment = payment
+ )
+ and statusChange.user <> :currentUser
+ )
+group by status.name, status.sortOrder
+order by status.sortOrder]]></programlisting>
+
+ <para>
+ 如果我把<literal>statusChanges</literal>实例集映射为一个列表(list)而不是一个集合(set),
+ 书写查询语句将更加简单.
+ </para>
+
+ <programlisting><![CDATA[select count(payment), status.name
+from Payment as payment
+ join payment.currentStatus as status
+where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
+ or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :currentUser
+group by status.name, status.sortOrder
+order by status.sortOrder]]></programlisting>
+
+ <para>
+ 下面一个查询使用了MS SQL Server的 <literal>isNull()</literal>函数用以返回当前用户所属组织的组织帐号及组织未支付的账。
+ 它被转换成一个对表<literal>ACCOUNT</literal>, <literal>PAYMENT</literal>, <literal>PAYMENT_STATUS</literal>,
+ <literal>ACCOUNT_TYPE</literal>, <literal>ORGANIZATION</literal> 以及 <literal>ORG_USER</literal>进行的三个内连接,
+ 一个外连接和一个子选择的SQL查询。
+ </para>
+
+ <programlisting><![CDATA[select account, payment
+from Account as account
+ left outer join account.payments as payment
+where :currentUser in elements(account.holder.users)
+ and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
+order by account.type.sortOrder, account.accountNumber, payment.dueDate]]></programlisting>
+
+ <para>
+ 对于一些数据库,我们需要弃用(相关的)子选择。
+ </para>
+
+ <programlisting><![CDATA[select account, payment
+from Account as account
+ join account.holder.users as user
+ left outer join account.payments as payment
+where :currentUser = user
+ and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
+order by account.type.sortOrder, account.accountNumber, payment.dueDate]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-bulk" revision="2">
+ <title>批量的UPDATE和DELETE</title>
+
+ <para>
+ HQL现在支持 <literal>update</literal>, <literal>delete</literal> 和
+ <literal>insert ... select ...</literal>语句. 查阅
+ <xref linkend="batch-direct"/> 以获得更多信息。
+ </para>
+ </sect1>
+
+ <sect1 id="queryhql-tipstricks">
+ <title>小技巧 & 小窍门</title>
+
+ <para>
+ 你可以统计查询结果的数目而不必实际的返回他们:
+ </para>
+
+ <programlisting><![CDATA[( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue()]]></programlisting>
+
+ <para>
+ 若想根据一个集合的大小来进行排序,可以使用如下的语句:
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User as usr
+ left join usr.messages as msg
+group by usr.id, usr.name
+order by count(msg)]]></programlisting>
+
+ <para>
+ 如果你的数据库支持子选择,你可以在你的查询的where子句中为选择的大小(selection size)指定一个条件:
+ </para>
+
+ <programlisting><![CDATA[from User usr where size(usr.messages) >= 1]]></programlisting>
+
+ <para>
+ 如果你的数据库不支持子选择语句,使用下面的查询:
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User usr.name
+ join usr.messages msg
+group by usr.id, usr.name
+having count(msg) >= 1]]></programlisting>
+
+ <para>
+ 因为内连接(inner join)的原因,这个解决方案不能返回含有零个信息的<literal>User</literal>
+ 类的实例, 所以这种情况下使用下面的格式将是有帮助的:
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User as usr
+ left join usr.messages as msg
+group by usr.id, usr.name
+having count(msg) = 0]]></programlisting>
+
+ <para>
+ JavaBean的属性可以被绑定到一个命名查询(named query)的参数上:
+ </para>
+
+ <programlisting><![CDATA[Query q = s.createQuery("from foo Foo as foo where foo.name=:name and foo.size=:size");
+q.setProperties(fooBean); // fooBean包含方法getName()与getSize()
+List foos = q.list();]]></programlisting>
+
+ <para>
+ 通过将接口<literal>Query</literal>与一个过滤器(filter)一起使用,集合(Collections)是可以分页的:
+ </para>
+
+ <programlisting><![CDATA[Query q = s.createFilter( collection, "" ); // 一个简单的过滤器
+q.setMaxResults(PAGE_SIZE);
+q.setFirstResult(PAGE_SIZE * pageNumber);
+List page = q.list();]]></programlisting>
+
+ <para>
+ 通过使用查询过滤器(query filter)可以将集合(Collection)的原素分组或排序:
+ </para>
+
+ <programlisting><![CDATA[Collection orderedCollection = s.filter( collection, "order by this.amount" );
+Collection counts = s.filter( collection, "select this.type, count(this) group by this.type" );]]></programlisting>
+
+ <para>
+ 不用通过初始化,你就可以知道一个集合(Collection)的大小:
+ </para>
+
+ <programlisting><![CDATA[( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue();]]></programlisting>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/query_sql.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/query_sql.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/query_sql.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/query_sql.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,715 @@
+<chapter id="querysql" revision="2">
+ <title>Native SQL查询</title>
+ <para>
+ 你也可以使用你的数据库的Native SQL语言来查询数据。这对你在要使用数据库的某些特性的时候(比如说在查询提示或者Oracle中的
+ <literal>CONNECT</literal>关键字),这是非常有用的。这就能够扫清你把原来直接使用SQL/JDBC 的程序迁移到基于
+ Hibernate应用的道路上的障碍。
+ </para>
+
+ <para>
+ Hibernate3允许你使用手写的sql来完成所有的create,update,delete,和load操作(包括存储过程)
+ </para>
+
+ <sect1 id="querysql-creating" revision="4">
+ <title>使用<literal>SQLQuery</literal></title>
+
+ <para>对原生SQL查询执行的控制是通过<literal>SQLQuery</literal>接口进行的,通过执行<literal>Session.createSQLQuery()</literal>获取这个接口。下面来描述如何使用这个API进行查询。</para>
+
+ <sect2>
+ <title>标量查询(Scalar queries)</title>
+
+ <para>
+ 最基本的SQL查询就是获得一个标量(数值)的列表。 </para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS").list();
+sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").list();
+]]></programlisting>
+
+ <para>
+ 它们都将返回一个Object数组(Object[])组成的List,数组每个元素都是CATS表的一个字段值。Hibernate会使用ResultSetMetadata来判定返回的标量值的实际顺序和类型。
+ </para>
+
+ <para>
+ 如果要避免过多的使用<literal>ResultSetMetadata</literal>,或者只是为了更加明确的指名返回值,可以使用<literal>addScalar()</literal>。
+ </para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS")
+ .addScalar("ID", Hibernate.LONG)
+ .addScalar("NAME", Hibernate.STRING)
+ .addScalar("BIRTHDATE", Hibernate.DATE)
+]]></programlisting>
+
+
+ <para>这个查询指定了:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL查询字符串</para>
+ </listitem>
+
+ <listitem>
+ <para>要返回的字段和类型</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 它仍然会返回Object数组,但是此时不再使用<literal>ResultSetMetdata</literal>,而是明确的将ID,NAME和BIRTHDATE按照Long,String和Short类型从resultset中取出。同时,也指明了就算query是使用<literal>*</literal>来查询的,可能获得超过列出的这三个字段,也仅仅会返回这三个字段。
+ </para>
+
+ <para>
+ 对全部或者部分的标量值不设置类型信息也是可以的。
+ </para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS")
+ .addScalar("ID", Hibernate.LONG)
+ .addScalar("NAME")
+ .addScalar("BIRTHDATE")
+]]></programlisting>
+
+ <para>
+ 基本上这和前面一个查询相同,只是此时使用<literal>ResultSetMetaData</literal>来决定NAME和BIRTHDATE的类型,而ID的类型是明确指出的。
+ </para>
+
+ <para>
+ 关于从ResultSetMetaData返回的java.sql.Types是如何映射到Hibernate类型,是由方言(Dialect)控制的。假若某个指定的类型没有被映射,或者不是你所预期的类型,你可以通过Dialet的<literal>registerHibernateType</literal>调用自行定义。
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>实体查询(Entity queries)</title>
+
+ <para>
+ 上面的查询都是返回标量值的,也就是从resultset中返回的“裸”数据。下面展示如何通过<literal>addEntity()</literal>让原生查询返回实体对象。
+ </para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS").addEntity(Cat.class);
+sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").addEntity(Cat.class);
+]]></programlisting>
+
+ <para>这个查询指定:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL查询字符串</para>
+ </listitem>
+
+ <listitem>
+ <para>要返回的实体</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 假设Cat被映射为拥有ID,NAME和BIRTHDATE三个字段的类,以上的两个查询都返回一个List,每个元素都是一个Cat实体。
+ </para>
+
+ <para>
+ 假若实体在映射时有一个<literal>many-to-one</literal>的关联指向另外一个实体,在查询时必须也返回那个实体,否则会导致发生一个"column not found"的数据库错误。这些附加的字段可以使用*标注来自动返回,但我们希望还是明确指明,看下面这个具有指向<literal>Dog</literal>的<literal>many-to-one</literal>的例子:
+ </para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE, DOG_ID FROM CATS").addEntity(Cat.class);
+]]></programlisting>
+
+ <para>
+ 这样cat.getDog()就能正常运作。
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>处理关联和集合类(Handling associations and collections)</title>
+
+ <para>
+ 通过提前抓取将<literal>Dog</literal>连接获得,而避免初始化proxy带来的额外开销也是可能的。这是通过<literal>addJoin()</literal>方法进行的,这个方法可以让你将关联或集合连接进来。
+ </para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT c.ID, NAME, BIRTHDATE, DOG_ID, D_ID, D_NAME FROM CATS c, DOGS d WHERE c.DOG_ID = d.D_ID")
+ .addEntity("cat", Cat.class)
+ .addJoin("cat.dog");
+]]></programlisting>
+
+ <para>
+ 上面这个例子中,返回的<literal>Cat</literal>对象,其<literal>dog</literal>属性被完全初始化了,不再需要数据库的额外操作。注意,我们加了一个别名("cat"),以便指明join的目标属性路径。通过同样的提前连接也可以作用于集合类,例如,假若<literal>Cat</literal>有一个指向<literal>Dog</literal>的一对多关联。
+ </para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE, D_ID, D_NAME, CAT_ID FROM CATS c, DOGS d WHERE c.ID = d.CAT_ID")
+ .addEntity("cat", Cat.class)
+ .addJoin("cat.dogs");
+]]></programlisting>
+
+ <p>
+ 到此为止,我们碰到了天花板:若不对SQL查询进行增强,这些已经是在Hibernate中使用原生SQL查询所能做到的最大可能了。下面的问题即将出现:返回多个同样类型的实体怎么办?或者默认的别名/字段不够又怎么办?
+
+ </p>
+ </sect2>
+
+ <sect2>
+ <title>返回多个实体(Returning multiple entities)</title>
+
+ <para>
+ 到目前为止,结果集字段名被假定为和映射文件中指定的的字段名是一致的。假若SQL查询连接了多个表,同一个字段名可能在多个表中出现多次,这就会造成问题。
+ </para>
+
+ <para>
+ 下面的查询中需要使用字段别名注射(这个例子本身会失败):
+ </para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT c.*, m.* FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
+ .addEntity("cat", Cat.class)
+ .addEntity("mother", Cat.class)
+]]></programlisting>
+
+ <para>
+ 这个查询的本意是希望每行返回两个Cat实例,一个是cat,另一个是它的妈妈。但是因为它们的字段名被映射为相同的,而且在某些数据库中,返回的字段别名是“c.ID”,"c.NAME"这样的形式,而它们和在映射文件中的名字("ID"和"NAME")不匹配,这就会造成失败。
+
+ </para>
+
+ <para>
+ 下面的形式可以解决字段名重复:
+ </para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT {cat.*}, {mother.*} FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
+ .addEntity("cat", Cat.class)
+ .addEntity("mother", Cat.class)
+]]></programlisting>
+
+ <para>这个查询指明:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ SQL查询语句,其中包含占位附来让Hibernate注射字段别名</para>
+ </listitem>
+
+ <listitem>
+ <para>
+ 查询返回的实体
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 上面使用的{cat.*}和{mother.*}标记是作为“所有属性”的简写形式出现的。当然你也可以明确地罗列出字段名,但在这个例子里面我们让Hibernate来为每个属性注射SQL字段别名。字段别名的占位符是属性名加上表别名的前缀。在下面的例子中,我们从另外一个表(cat_log)中通过映射元数据中的指定获取Cat和它的妈妈。注意,要是我们愿意,我们甚至可以在where子句中使用属性别名。
+
+ </para>
+
+ <programlisting><![CDATA[String sql = "SELECT ID as {c.id}, NAME as {c.name}, " +
+ "BIRTHDATE as {c.birthDate}, MOTHER_ID as {c.mother}, {mother.*} " +
+ "FROM CAT_LOG c, CAT_LOG m WHERE {c.mother} = c.ID";
+
+List loggedCats = sess.createSQLQuery(sql)
+ .addEntity("cat", Cat.class)
+ .addEntity("mother", Cat.class).list()
+]]></programlisting>
+
+ <sect3 id="querysql-aliasreferences" revision="2">
+ <title>别名和属性引用(Alias and property references)</title>
+
+ <para>
+ 大多数情况下,都需要上面的属性注射,但在使用更加复杂的映射,比如复合属性、通过标识符构造继承树,以及集合类等等情况下,也有一些特别的别名,来允许Hibernate注射合适的别名。
+ </para>
+
+ <para>
+ 下表列出了使用别名注射参数的不同可能性。注意:下面结果中的别名只是示例,实用时每个别名需要唯一并且不同的名字。
+ </para>
+
+ <table frame="topbot" id="aliasinjection-summary">
+ <title>别名注射(alias injection names)</title>
+
+ <tgroup cols="3">
+ <colspec colwidth="1*" />
+
+ <colspec colwidth="1*" />
+
+ <colspec colwidth="2.5*" />
+
+ <thead>
+ <row>
+ <entry>描述</entry>
+
+ <entry>语法</entry>
+
+ <entry>示例</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>简单属性</entry>
+ <entry><literal>{[aliasname].[propertyname]</literal></entry>
+ <entry><literal>A_NAME as {item.name}</literal></entry>
+ </row>
+ <row>
+ <entry>复合属性</entry>
+ <entry><literal>{[aliasname].[componentname].[propertyname]}</literal></entry>
+ <entry><literal>CURRENCY as {item.amount.currency}, VALUE as {item.amount.value}</literal></entry>
+ </row>
+ <row>
+ <entry>实体辨别器(Discriminator of an entity)</entry>
+ <entry><literal>{[aliasname].class}</literal></entry>
+ <entry><literal>DISC as {item.class}</literal></entry>
+ </row>
+ <row>
+ <entry>实体的所有属性</entry>
+ <entry><literal>{[aliasname].*}</literal></entry>
+ <entry><literal>{item.*}</literal></entry>
+ </row>
+ <row>
+ <entry>集合键(collection key)</entry>
+ <entry><literal>{[aliasname].key}</literal></entry>
+ <entry><literal>ORGID as {coll.key}</literal></entry>
+ </row>
+ <row>
+ <entry>集合id</entry>
+ <entry><literal>{[aliasname].id}</literal></entry>
+ <entry><literal>EMPID as {coll.id}</literal></entry>
+ </row>
+ <row>
+ <entry>集合元素</entry>
+ <entry><literal>{[aliasname].element}</literal></entry>
+ <entry><literal>XID as {coll.element}</literal></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>集合元素的属性</entry>
+ <entry><literal>{[aliasname].element.[propertyname]}</literal></entry>
+ <entry><literal>NAME as {coll.element.name}</literal></entry>
+ </row>
+ <row>
+ <entry>集合元素的所有属性</entry>
+ <entry><literal>{[aliasname].element.*}</literal></entry>
+ <entry><literal>{coll.element.*}</literal></entry>
+ </row>
+ <row>
+ <entry>集合的所有属性</entry>
+ <entry><literal>{[aliasname].*}</literal></entry>
+ <entry><literal>{coll.*}</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>返回非受管实体(Returning non-managed entities)</title>
+
+ <para>
+ 可以对原生sql 查询使用ResultTransformer。这会返回不受Hibernate管理的实体。
+
+ </para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT NAME, BIRTHDATE FROM CATS")
+ .setResultTransformer(Transformers.aliasToBean(CatDTO.class))]]></programlisting>
+
+ <para>这个查询指定:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL查询字符串</para>
+ </listitem>
+
+ <listitem>
+ <para>结果转换器(result transformer)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 上面的查询将会返回<literal>CatDTO</literal>的列表,它将被实例化并且将NAME和BIRTHDAY的值注射入对应的属性或者字段。
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>处理继承(Handling inheritance)</title>
+
+ <para>
+ 原生SQL查询假若其查询结果实体是继承树中的一部分,它必须包含基类和所有子类的所有属性。
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>参数(Parameters)</title>
+
+ <para>
+ 原生查询支持位置参数和命名参数:
+ </para>
+
+ <programlisting><![CDATA[Query query = sess.createSQLQuery("SELECT * FROM CATS WHERE NAME like ?").addEntity(Cat.class);
+List pusList = query.setString(0, "Pus%").list();
+
+query = sess.createSQLQuery("SELECT * FROM CATS WHERE NAME like :name").addEntity(Cat.class);
+List pusList = query.setString("name", "Pus%").list(); ]]></programlisting>
+ </sect2>
+
+
+
+ </sect1>
+
+
+ <sect1 id="querysql-namedqueries" revision="3">
+ <title>命名SQL查询</title>
+
+ <para>
+ 可以在映射文档中定义查询的名字,然后就可以象调用一个命名的HQL查询一样直接调用命名SQL查询.在这种情况下,我们<emphasis>不</emphasis>
+ 需要调用<literal>addEntity()</literal>方法.
+ </para>
+
+ <programlisting><![CDATA[<sql-query name="persons">
+ <return alias="person" class="eg.Person"/>
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex}
+ FROM PERSON person
+ WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+ <programlisting><![CDATA[List people = sess.getNamedQuery("persons")
+ .setString("namePattern", namePattern)
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ <para><literal><return-join></literal>和
+ <literal><load-collection></literal> 元素是用来连接关联以及将查询定义为预先初始化各个集合的。</para>
+
+ <programlisting><![CDATA[<sql-query name="personsWith">
+ <return alias="person" class="eg.Person"/>
+ <return-join alias="address" property="person.mailingAddress"/>
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex},
+ address.STREET AS {address.street},
+ address.CITY AS {address.city},
+ address.STATE AS {address.state},
+ address.ZIP AS {address.zip}
+ FROM PERSON person
+ JOIN ADDRESS address
+ ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
+ WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+
+ <para>
+ 一个命名查询可能会返回一个标量值.你必须使用<literal><return-scalar></literal>元素来指定字段的别名和
+ Hibernate类型
+ </para>
+
+ <programlisting><![CDATA[<sql-query name="mySqlQuery">
+ <return-scalar column="name" type="string"/>
+ <return-scalar column="age" type="long"/>
+ SELECT p.NAME AS name,
+ p.AGE AS age,
+ FROM PERSON p WHERE p.NAME LIKE 'Hiber%'
+</sql-query>]]></programlisting>
+
+ <para>
+ 你可以把结果集映射的信息放在外部的<literal><resultset></literal>元素中,这样就可以在多个命名查询间,或者通过<literal>setResultSetMapping()</literal>API来访问。(此处原文即存疑。原文为:You can externalize the resultset mapping informations in a
+ <literal><resultset></literal> element to either reuse them accross
+ several named queries or through the
+ <literal>setResultSetMapping()</literal> API.)
+ </para>
+
+ <programlisting><![CDATA[<resultset name="personAddress">
+ <return alias="person" class="eg.Person"/>
+ <return-join alias="address" property="person.mailingAddress"/>
+</resultset>
+
+<sql-query name="personsWith" resultset-ref="personAddress">
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex},
+ address.STREET AS {address.street},
+ address.CITY AS {address.city},
+ address.STATE AS {address.state},
+ address.ZIP AS {address.zip}
+ FROM PERSON person
+ JOIN ADDRESS address
+ ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
+ WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+ <para>
+ 另外,你可以在java代码中直接使用hbm文件中的结果集定义信息。
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createSQLQuery(
+ "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id"
+ )
+ .setResultSetMapping("catAndKitten")
+ .list();]]></programlisting>
+
+ <sect2 id="propertyresults">
+ <title>使用return-property来明确地指定字段/别名</title>
+
+ <para>
+ 使用<literal><return-property></literal>你可以明确的告诉Hibernate使用哪些字段别名,这取代了使用<literal>{}</literal>-语法
+ 来让Hibernate注入它自己的别名.
+ </para>
+
+ <programlisting><![CDATA[<sql-query name="mySqlQuery">
+ <return alias="person" class="eg.Person">
+ <return-property name="name" column="myName"/>
+ <return-property name="age" column="myAge"/>
+ <return-property name="sex" column="mySex"/>
+ </return>
+ SELECT person.NAME AS myName,
+ person.AGE AS myAge,
+ person.SEX AS mySex,
+ FROM PERSON person WHERE person.NAME LIKE :name
+</sql-query>
+]]></programlisting>
+ <literal><return-property></literal>也可用于多个字段,它解决了使用<literal>{}</literal>-语法不能细粒度控制多个字段的限制
+ <programlisting><![CDATA[<sql-query name="organizationCurrentEmployments">
+ <return alias="emp" class="Employment">
+ <return-property name="salary">
+ <return-column name="VALUE"/>
+ <return-column name="CURRENCY"/>
+ </return-property>
+ <return-property name="endDate" column="myEndDate"/>
+ </return>
+ SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer},
+ STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},
+ REGIONCODE as {emp.regionCode}, EID AS {emp.id}, VALUE, CURRENCY
+ FROM EMPLOYMENT
+ WHERE EMPLOYER = :id AND ENDDATE IS NULL
+ ORDER BY STARTDATE ASC
+</sql-query>]]></programlisting>
+
+ <para>
+ 注意在这个例子中,我们使用了<literal><return-property></literal>结合<literal>{}</literal>的注入语法.
+ 允许用户来选择如何引用字段以及属性.
+ </para>
+
+ <para>
+ 如果你映射一个识别器(discriminator),你必须使用<literal><return-discriminator></literal> 来指定识别器字段
+ </para>
+ </sect2>
+
+ <sect2 id="sp_query" revision="1">
+ <title>使用存储过程来查询</title>
+
+ <para>
+ Hibernate 3引入了对存储过程查询(stored procedure)和函数(function)的支持.以下的说明中,这二者一般都适用。
+
+ 存储过程/函数必须返回一个结果集,作为Hibernate能够使用的第一个外部参数.
+
+ 下面是一个Oracle9和更高版本的存储过程例子.</para>
+
+ <programlisting><![CDATA[CREATE OR REPLACE FUNCTION selectAllEmployments
+ RETURN SYS_REFCURSOR
+AS
+ st_cursor SYS_REFCURSOR;
+BEGIN
+ OPEN st_cursor FOR
+ SELECT EMPLOYEE, EMPLOYER,
+ STARTDATE, ENDDATE,
+ REGIONCODE, EID, VALUE, CURRENCY
+ FROM EMPLOYMENT;
+ RETURN st_cursor;
+ END;]]></programlisting>
+ <para>
+ 在Hibernate里要要使用这个查询,你需要通过命名查询来映射它.
+ </para>
+
+ <programlisting><![CDATA[<sql-query name="selectAllEmployees_SP" callable="true">
+ <return alias="emp" class="Employment">
+ <return-property name="employee" column="EMPLOYEE"/>
+ <return-property name="employer" column="EMPLOYER"/>
+ <return-property name="startDate" column="STARTDATE"/>
+ <return-property name="endDate" column="ENDDATE"/>
+ <return-property name="regionCode" column="REGIONCODE"/>
+ <return-property name="id" column="EID"/>
+ <return-property name="salary">
+ <return-column name="VALUE"/>
+ <return-column name="CURRENCY"/>
+ </return-property>
+ </return>
+ { ? = call selectAllEmployments() }
+</sql-query>]]></programlisting>
+
+ <para>
+ 注意存储过程当前仅仅返回标量和实体.现在不支持<literal><return-join></literal>和<literal><load-collection></literal>
+
+ </para>
+
+ <sect3 id="querysql-limits-storedprocedures" revision="1">
+ <title>使用存储过程的规则和限制</title>
+
+ <para>
+ 为了在Hibernate中使用存储过程,你必须遵循一些规则.不遵循这些规则的存储过程将不可用.如果你仍然想要使用他们,
+ 你必须通过<literal>session.connection()</literal>来执行他们.这些规则针对于不同的数据库.因为数据库
+ 提供商有各种不同的存储过程语法和语义.
+ </para>
+
+ <para>
+ 对存储过程进行的查询无法使用<literal>setFirstResult()/setMaxResults()</literal>进行分页。
+ </para>
+
+
+ <para>建议采用的调用方式是标准SQL92: <literal>{ ? = call
+ functionName(<parameters>) }</literal> 或者 <literal>{ ? = call
+ procedureName(<parameters>}</literal>.原生调用语法不被支持。</para>
+
+ <para>
+ 对于Oracle有如下规则:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>函数必须返回一个结果集。存储过程的第一个参数必须是<literal>OUT</literal>,它返回一个结果集。这是通过Oracle 9或10的<literal>SYS_REFCURSOR</literal>类型来完成的。在Oracle中你需要定义一个<literal>REF CURSOR</literal>类型,参见Oracle的手册。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 对于Sybase或者MS SQL server有如下规则:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 存储过程必须返回一个结果集。.注意这些servers可能返回多个结果集以及更新的数目.Hibernate将取出第一条结果集作为它的返回值,
+ 其他将被丢弃。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 如果你能够在存储过程里设定<literal>SET NOCOUNT ON</literal>,这可能会效率更高,但这不是必需的。
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="querysql-cud">
+ <title>定制SQL用来create,update和delete</title>
+
+ <para>
+ Hibernate3能够使用定制的SQL语句来执行create,update和delete操作。在Hibernate中,持久化的类和集合已经
+ 包含了一套配置期产生的语句(insertsql, deletesql, updatesql等等),这些映射标记 <literal><sql-insert></literal>,
+ <literal><sql-delete></literal>, and <literal><sql-update></literal>重载了
+ 这些语句。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ? )</sql-insert>
+ <sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete>
+</class>]]></programlisting>
+
+ <para>
+ 这些SQL直接在你的数据库里执行,所以你可以自由的使用你喜欢的任意语法。但如果你使用数据库特定的语法,
+ 这当然会降低你映射的可移植性。
+ </para>
+
+ <para>
+ 如果设定<literal>callable</literal>,则能够支持存储过程了。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <sql-insert callable="true">{call createPerson (?, ?)}</sql-insert>
+ <sql-delete callable="true">{? = call deletePerson (?)}</sql-delete>
+ <sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update>
+</class>]]></programlisting>
+
+ <para>
+ 参数的位置顺序是非常重要的,他们必须和Hibernate所期待的顺序相同。
+ </para>
+
+ <para>
+ 你能够通过设定日志调试级别为<literal>org.hiberante.persister.entity</literal>,来查看Hibernate所期待的顺序。在这个级别下,
+ Hibernate将会打印出create,update和delete实体的静态SQL。(如果想看到预计的顺序。记得不要将定制SQL包含在映射文件里,
+ 因为他们会重载Hibernate生成的静态SQL。)
+ </para>
+
+ <para>
+ 在大多数情况下(最好这么做),存储过程需要返回插入/更新/删除的行数,因为Hibernate对语句的成功执行有些运行时的检查。
+ Hibernate常会把进行CUD操作的语句的第一个参数注册为一个数值型输出参数。
+ </para>
+
+ <programlisting><![CDATA[CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname IN VARCHAR2)
+ RETURN NUMBER IS
+BEGIN
+
+ update PERSON
+ set
+ NAME = uname,
+ where
+ ID = uid;
+
+ return SQL%ROWCOUNT;
+
+END updatePerson;]]></programlisting>
+
+
+ </sect1>
+
+ <sect1 id="querysql-load">
+ <title>定制装载SQL</title>
+
+ <para>
+ 你可能需要声明你自己的SQL(或HQL)来装载实体
+ </para>
+
+ <programlisting><![CDATA[<sql-query name="person">
+ <return alias="pers" class="Person" lock-mode="upgrade"/>
+ SELECT NAME AS {pers.name}, ID AS {pers.id}
+ FROM PERSON
+ WHERE ID=?
+ FOR UPDATE
+</sql-query>]]></programlisting>
+
+ <para>
+ 这只是一个前面讨论过的命名查询声明,你可以在类映射里引用这个命名查询。
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <loader query-ref="person"/>
+</class>]]></programlisting>
+
+ <para>
+ 这也可以用于存储过程
+ </para>
+
+ <para>你甚至可以定一个用于集合装载的查询:</para>
+
+ <programlisting><![CDATA[<set name="employments" inverse="true">
+ <key/>
+ <one-to-many class="Employment"/>
+ <loader query-ref="employments"/>
+</set>]]></programlisting>
+
+ <programlisting><![CDATA[<sql-query name="employments">
+ <load-collection alias="emp" role="Person.employments"/>
+ SELECT {emp.*}
+ FROM EMPLOYMENT emp
+ WHERE EMPLOYER = :id
+ ORDER BY STARTDATE ASC, EMPLOYEE ASC
+</sql-query>]]></programlisting>
+
+ <para>你甚至还可以定义一个实体装载器,它通过连接抓取装载一个集合:</para>
+
+ <programlisting><![CDATA[<sql-query name="person">
+ <return alias="pers" class="Person"/>
+ <return-join alias="emp" property="pers.employments"/>
+ SELECT NAME AS {pers.*}, {emp.*}
+ FROM PERSON pers
+ LEFT OUTER JOIN EMPLOYMENT emp
+ ON pers.ID = emp.PERSON_ID
+ WHERE ID=?
+</sql-query>]]></programlisting>
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/quickstart.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/quickstart.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/quickstart.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/quickstart.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,461 @@
+<chapter id="quickstart">
+ <title>在Tomcat中快速上手</title>
+
+ <sect1 id="quickstart-intro" revision="2">
+ <title>开始Hibernate之旅</title>
+
+ <para>
+ 这份教程描述如何在Apache Tomcat servlet容器中为web应用程序配置Hibernate 3.0(我们使用Tomcat 4.1版本,与5.0版本差别很小)。Hibernate在大多数主流J2EE应用服务器
+ 的运行环境中都可以工作良好,甚至也可以在独立Java应用程序中使用。在本教程中使用的示例数据库系统是PostgreSQL 7.4,只需要修改Hibernate SQL语言配置与连接属性,就可以
+ 很容易的支持其他数据库了。
+ </para>
+
+ <para>
+ 第一步,我们必须拷贝所有需要的库文件到Tomcat安装目录中。在这篇教程中,我们使用一个独立的web Context配置(<literal>webapps/quickstart</literal>)。我们确认全局库文件(<literal>TOMCAT/common/lib</literal>)和本web应用程序上下文的路径(对于jar来说是<literal>webapps/quickstart/WEB-INF/lib</literal>,对于class文件来说是<literal>webapps/quickstart/WEB-INF/classes</literal>)能够被类装载器检索到。我们把这两个类装载器级别分别称做全局类路径(global classpath)和上下文类路径(context classpath)。
+ </para>
+
+ <para>
+ 现在,把这些库文件copy到两个类路径去:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ 把数据库需要的JDBC驱动文件拷贝到全局类路径,这是tomcat捆绑的DBCP连接池所需要的。Hibernate使用JDBC连接数据库方式执行SQL语句,所以你要么提供外部连接池中的连接给Hibernate,或者配置Hibernate自带的连接池(C3PO,Proxool)。对于本教程来说,把<literal>pg74jdbc3.jar</literal>库文件(支持PostgreSQL 7.4和JDK 1.4)到全局类装载路径下即可。如果你希望使用其他的数据库,拷贝其相应的JDBC 驱动文件)。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 永远不要拷贝任何其他东西到Tomcat的全局类路径下,否则你可能在使用其他一些工具上遇到麻烦,比如log4j, commons-logging等等。
+ 一定要让每个web应用程序使用自己的上下文类路径,就是说把你自己需要的类库拷贝到<literal>WEB-INF/lib</literal>下去,把配置文件configuration/property等配置文件拷贝到<literal>WEB-INF/classes</literal>下面去。这两个目录都是当前程序缺省的上下文类路径。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Hibernate本身打包成一个JAR类库。将<literal>hibernate3.jar</literal>文件拷贝到程序的上下文类路径下,和你应用程序的其他库文件放一起。在运行时,Hibernate还需要一些第三方类库,它们在Hibernate发行包的<literal>lib/</literal>目录下。参见<xref linkend="3rdpartylibs"/>。把所需要的第三方库文件也拷贝到上下文类路径下。
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <table frame="topbot" id="3rdpartylibs">
+ <title>
+ Hibernate 第三方类库
+ </title>
+ <tgroup cols="2" rowsep="1" colsep="1">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry align="center">
+ 类库
+ </entry>
+ <entry align="center">
+ 描述
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ antlr (必需)
+ </entry>
+ <entry>
+ Hibernate使用ANTLR来产生查询分析器,这个类库在运行环境下时也是必需的。
+ </entry>
+ </row>
+ <row>
+ <entry>
+ dom4j (必需)
+ </entry>
+ <entry>
+ Hibernate使用dom4j解析XML配置文件和XML映射元文件。
+ </entry>
+ </row>
+ <row>
+ <entry>
+ CGLIB ,asm(必需)
+ </entry>
+ <entry>
+ Hibernate在运行时使用这个代码生成库增强类(与Java反射机制联合使用)。
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Commons Collections, Commons Logging (必需)
+ </entry>
+ <entry>
+ Hibernat使用Apache Jakarta Commons项目提供的多个工具类库。
+ </entry>
+ </row>
+ <row>
+ <entry>
+ EHCache (必需)
+ </entry>
+ <entry>
+ Hibernate可以使用不同cache缓存工具作为二级缓存。EHCache是缺省的cache缓存工具。
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Log4j (可选)
+ </entry>
+ <entry>
+ Hibernate使用Commons Logging API,它也可以依次使用Log4j作为底层实施log的机制。如果上下文类目录中存在Log4j库,则Commons Logging使用Log4j和并它在上下文类路径中寻找的<literal>log4j.properties</literal>文件。你可以使用在Hibernate发行包中包含中的那个示例Log4j的配置文件。这样,把log4j.jar和它的配置文件(位于<literal>src/</literal>目录中)拷贝到你的上下文类路径下,就可以在后台看到底程序如何运行的。
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 其他文件是不是必需的?
+ </entry>
+ <entry>
+ 请察看Hibernate发行包中的 lib/README.txt文件,这是一个Hibernate发行包中附带的第三方类库的列表,他们总是保持最新的。你可以在那里找到所有必需或者可选的类库(注意:其中的"buildtime required"指的是编译Hibernate时所需要而非编译你自己的程序所必需的类库)。
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 接下来我们来配置在Tomcat和Hibernate中共用的数据库连接池。也就是说Tomcat会提供经过池处理的JDBC连接(用它内置的DBCP连接池),Hibernate通过JNDI方式来请求获得JDBC连接。作为替代方案,你也可以让Hibernate自行管理连接池。Tomcat把连接池绑定到JNDI,我们要在Tomcat的主配置文件(<literal>TOMCAT/conf/server.xml</literal>)中加一个资源声明:
+ </para>
+
+ <programlisting><![CDATA[<Context path="/quickstart" docBase="quickstart">
+ <Resource name="jdbc/quickstart" scope="Shareable" type="javax.sql.DataSource"/>
+ <ResourceParams name="jdbc/quickstart">
+ <parameter>
+ <name>factory</name>
+ <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+ </parameter>
+
+ <!-- DBCP database connection settings -->
+ <parameter>
+ <name>url</name>
+ <value>jdbc:postgresql://localhost/quickstart</value>
+ </parameter>
+ <parameter>
+ <name>driverClassName</name><value>org.postgresql.Driver</value>
+ </parameter>
+ <parameter>
+ <name>username</name>
+ <value>quickstart</value>
+ </parameter>
+ <parameter>
+ <name>password</name>
+ <value>secret</value>
+ </parameter>
+
+ <!-- DBCP connection pooling options -->
+ <parameter>
+ <name>maxWait</name>
+ <value>3000</value>
+ </parameter>
+ <parameter>
+ <name>maxIdle</name>
+ <value>100</value>
+ </parameter>
+ <parameter>
+ <name>maxActive</name>
+ <value>10</value>
+ </parameter>
+ </ResourceParams>
+</Context>]]></programlisting>
+
+ <para>
+ 我们在这个例子中要配置的上下文叫做<literal>quickstart</literal>,它位于<literal>TOMCAT/webapp/quickstart</literal>目录下。如果要访问这个应用程序,在你的浏览器中输入<literal>http://localhost:8080/quickstart</literal>就可以了(当然,在后面加上在你的<literal>web.xml</literal>文件中配置好你的servlet)。你现在可以创建一个只含有空<literal>process()</literal>的简单servlet了。
+ </para>
+
+ <para>
+ Tomcat现在通过JNDI的方式:<literal>java:comp/env/jdbc/quickstart</literal>来提供连接。如果你在配置连接池遇到问题,请查阅Tomcat文档。如果你遇到了JDBC驱动所报的exception出错信息,请在没有Hibernate的环境下,先测试JDBC连接池本身是否配置正确。Tomcat和JDBC的配置教程可以在Web上查到。
+ </para>
+
+ <para>
+ 下一步就是配置Hibernate。首先Hibernate必须知道它如何获得JDBC连接,在这里我们使用基于XML格式的Hibernate配置文件。当然使用properties文件的进行配置,但缺少一些XML语法的特性。这个XML配置文件必须放在上下文类路径(<literal>WEB-INF/classes</literal>)下面,命名为<literal>hibernate.cfg.xml</literal>:
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration
+ PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <session-factory>
+
+ <property name="connection.datasource">java:comp/env/jdbc/quickstart</property>
+ <property name="show_sql">false</property>
+ <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
+
+ <!-- Mapping files -->
+ <mapping resource="Cat.hbm.xml"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ 在这里我们关闭了SQL命令的log,同时告诉Hibernate使用哪种SQL数据库用语(Dialet),以及如何得到JDBC连接(通过Tomcat声明绑定的JNDI地址)。Dialet是必需配置的,因为不同的数据库都和"SQL标准"有一些出入。不用担心,Hibernate会替你处理这些差异,Hibernate支持所有主流的商业和开放源代码数据库。
+ </para>
+
+ <para>
+ <literal>SessionFactory</literal>是Hibernate的一个概念,表示对应一个数据存储源。通过创建多个XML配置文件并在你的程序中创建多个<literal>Configuration</literal>和<literal>SessionFactory</literal>对象,就可以支持多个数据库了。
+ </para>
+
+ <para>
+ 在<literal>hibernate.cfg.xml</literal>中的最后一个元素声明了<literal>Cat.hbm.xml</literal>,这是一个Hibernate XML映射文件,对应于持久化类<literal>Cat</literal>。这个文件包含了把<literal>Cat</literal> POJO类映射到数据库表(或多个数据库表)的元数据。我们稍后就回来看这个文件。下一步让我们先编写这个POJO类,然后在声明它的映射元数据。
+ </para>
+
+ </sect1>
+
+ <sect1 id="quickstart-persistentclass" revision="1">
+ <title>第一个持久化类</title>
+
+ <para>
+ Hibernate使用简单的Java对象(Plain Old Java Objects ,就是POJOs,有时候也称作Plain Ordinary Java Objects)这种编程模型来进行持久化。一个POJO很像JavaBean,通过getter和setter方法访问其属性,对外则隐藏了内部实现的细节(假若需要的话,Hibernate也可以直接访问其属性字段)。
+ </para>
+
+ <programlisting><![CDATA[package org.hibernate.examples.quickstart;
+
+public class Cat {
+
+ private String id;
+ private String name;
+ private char sex;
+ private float weight;
+
+ public Cat() {
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ private void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public char getSex() {
+ return sex;
+ }
+
+ public void setSex(char sex) {
+ this.sex = sex;
+ }
+
+ public float getWeight() {
+ return weight;
+ }
+
+ public void setWeight(float weight) {
+ this.weight = weight;
+ }
+
+}]]></programlisting>
+
+ <para>
+ Hibernate对属性使用的类型不加任何限制。所有的Java JDK类型和原始类型(比如<literal>String</literal>,<literal>char</literal>和<literal>Date</literal>)都可以被映射,也包括Java 集合(Java collections framework)中的类。你可以把它们映射成为值,值集合,或者与其他实体类相关联。<literal>id</literal>是一个特殊的属性,代表了这个类的数据库标识符(主键),对于类似于<literal>Cat</literal>这样的实体类我们强烈建议使用。Hibernate也可以使用内部标识符,但这样我们会失去一些程序架构方面的灵活性。
+ </para>
+
+ <para>
+ 持久化类不需要实现什么特别的接口,也不需要从一个特别的持久化根类继承下来。Hibernate也不需要使用任何编译期处理,比如字节码增强操作,它独立的使用Java反射机制和运行时类增强(通过CGLIB)。所以不依赖于Hibernate,我们就可以把POJO的类映射成为数据库表。
+ </para>
+
+ </sect1>
+
+ <sect1 id="quickstart-mapping" revision="1">
+ <title>映射cat</title>
+
+ <para>
+ <literal>Cat.hbm.xml</literal>映射文件包含了对象/关系映射(O/R Mapping)所需的元数据。元数据包含持久化类的声明和属性到数据库的映射(指向字段和其他实体的外键关联)。
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping
+ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping>
+
+ <class name="org.hibernate.examples.quickstart.Cat" table="CAT">
+
+ <!-- A 32 hex character is our surrogate key. It's automatically
+ generated by Hibernate with the UUID pattern. -->
+ <id name="id" type="string" unsaved-value="null" >
+ <column name="CAT_ID" sql-type="char(32)" not-null="true"/>
+ <generator class="uuid.hex"/>
+ </id>
+
+ <!-- A cat has to have a name, but it shouldn' be too long. -->
+ <property name="name">
+ <column name="NAME" length="16" not-null="true"/>
+ </property>
+
+ <property name="sex"/>
+
+ <property name="weight"/>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 每个持久化类都应该有一个标识属性(实际上,这个类只代表实体,而不是独立的值类型类,后者会被映射称为实体对象中的一个组件)。这个属性用来区分持久化对象:如果<literal>catA.getId().equals(catB.getId())</literal>结果是true的话,这两个Cat就是相同的。这个概念称为<emphasis>数据库标识</emphasis>。Hiernate附带了几种不同的标识符生成器,用于不同的场合(包括数据库本地的顺序(sequence)生成器、hi/lo高低位标识模式、和程序自己定义的标识符)。我们在这里使用UUID生成器(只在测试时建议使用,如果使用数据库自己生成的整数类型的键值更好),并指定<literal>CAT</literal>表中的<literal>CAT_ID</literal>字段(作为表的主键)存放生成的标识值。
+ </para>
+
+ <para>
+ <literal>Cat</literal>的其他属性都映射到同一个表的字段。对<literal>name</literal>属性来说,我们把它显式地声明映射到一个数据库字段。如果数据库schema是通过由映射声明使用Hibernate的<emphasis>SchemaExport</emphasis>工具自动生成的(作为SQL DDL指令)的话,这就特别有用。所有其它的属性都用Hibernate的默认值映射,大多数情况你都会这样做。数据库中的<literal>CAT</literal>表看起来是这样的:
+ </para>
+
+ <programlisting><![CDATA[ Column | Type | Modifiers
+--------+-----------------------+-----------
+ cat_id | character(32) | not null
+ name | character varying(16) | not null
+ sex | character(1) |
+ weight | real |
+Indexes: cat_pkey primary key btree (cat_id)]]></programlisting>
+
+ <para>
+ 你现在可以在你的数据库中手工创建这个表了,如果你需要使用<literal>hbm2ddl</literal>工具把这个步骤自动化,请参阅<xref linkend="toolsetguide"/>。这个工具能够创建完整的SQL DDL,包括表定义,自定义的字段类型约束,惟一约束和索引。
+ </para>
+
+ </sect1>
+
+ <sect1 id="quickstart-playingwithcats" revision="2">
+ <title>与Cat同乐</title>
+
+ <para>
+ 我们现在可以开始Hibernate的<literal>Session</literal>了。它是一个<emphasis>持久化管理器</emphasis>,我们通过它来从数据库中存取<literal>Cat</literal>。首先,我们要从<literal>SessionFactory</literal>中获取一个<literal>Session</literal>(Hibernate的工作单元)。
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sessionFactory =
+ new Configuration().configure().buildSessionFactory();]]></programlisting>
+
+ <para>
+ 通过对<literal>configure()</literal>的调用来装载<literal>hibernate.cfg.xml</literal>配置文件,并初始化这个<literal>Configuration</literal>实例。
+ 在创建 <literal>SessionFactory</literal><emphasis>之前</emphasis>(它是不可变的),你可以访问<literal>Configuration</literal>来设置其他属性(甚至修改映射的元数据)。我们应该在哪儿创建<literal>SessionFactory</literal>,在我们的程序中又如何访问它呢?
+ <literal>SessionFactory</literal>通常只是被初始化一次,比如说通过一个<emphasis>load-on-startup</emphasis> servlet的来初始化。这意味着你不应该在serlvet中把它作为一个实例变量来持有,而应该放在其他地方。进一步的说,我们需要使用<emphasis>单例(Singleton)</emphasis>模式,我们才能更容易的在程序中访问<literal>SessionFactory</literal>。下面的方法就同时解决了两个问题:对<literal>SessionFactory</literal>的初始配置与便捷使用。
+ </para>
+
+ <para>
+ 我们实现一个<literal>HibernateUtil</literal>辅助类:
+ </para>
+
+
+ <programlisting><![CDATA[import org.hibernate.*;
+import org.hibernate.cfg.*;
+
+public class HibernateUtil {
+
+ private static Logger log = LoggerFactory.getLogger(HibernateUtil.class);
+
+ private static final SessionFactory sessionFactory;
+
+ static {
+ try {
+ // Create the SessionFactory
+ sessionFactory = new Configuration().configure().buildSessionFactory();
+ } catch (Throwable ex) {
+ // Make sure you log the exception, as it might be swallowed
+ log.error("Initial SessionFactory creation failed.", ex);
+ throw new ExceptionInInitializerError(ex);
+ }
+ }
+
+ public static final ThreadLocal session = new ThreadLocal();
+
+ public static Session currentSession() {
+ Session s = (Session) session.get();
+ // Open a new Session, if this Thread has none yet
+ if (s == null) {
+ s = sessionFactory.openSession();
+ session.set(s);
+ }
+ return s;
+ }
+
+ public static void closeSession() {
+ Session s = (Session) session.get();
+ if (s != null)
+ s.close();
+ session.set(null);
+ }
+}]]></programlisting>
+
+ <para>
+ 这个类不但在它的静态初始器中使用了<literal>SessionFactory</literal>,还使用了一个<literal>ThreadLocal</literal>变量来保存<literal>Session</literal>做为当前工作线程。在你使用这个辅助类之前,请确保你理解了thread-local变量这个Java概念。你可以在<literal>CaveatEmptor</literal>(http://caveatemptor.hibernate.org/)上找到一个更加复杂和强大的 <literal>HibernateUtil</literal>。
+ </para>
+
+ <para>
+ <literal>SessionFactory</literal>是安全线程,可以由很多线程并发访问并获取到<literal>Sessions</literal>。单个<literal>Session</literal>不是安全线程对象,它只代表与数据库之间的一次操作。<literal>Session</literal>通过<literal>SessionFactory</literal>获得并在所有的工作完成后关闭。在你servlet的<literal>process()</literal>中可以象是这么写的(省略了异常情况处理):
+ </para>
+
+ <programlisting><![CDATA[Session session = HibernateUtil.currentSession();
+
+Transaction tx= session.beginTransaction();
+
+Cat princess = new Cat();
+princess.setName("Princess");
+princess.setSex('F');
+princess.setWeight(7.4f);
+
+session.save(princess);
+tx.commit();
+
+HibernateUtil.closeSession();]]></programlisting>
+
+ <para>
+ 在一个<literal>Session</literal>中,每个数据库操作都是在一个事务(transaction)中进行的,这样就可以隔离开不同的操作(甚至包括只读操作)。我们使用Hibernate的<literal>Transaction</literal> API来从底层的事务策略中(本例中是JDBC事务)脱身出来。这样,我们就不需要更改任何源代码,就可以把我们的程序部署到一个由容器管理事务的环境中去(使用JTA)。
+
+ </para>
+
+ <para>
+ 这样你就可以随心所欲的多次调用<literal>HibernateUtil.currentSession();</literal>,你每次都会得到同一个当前线程的<literal>Session</literal>。不管是在你的servlet代码中,或者在servlet filter中还是在HTTP结果返回之前,你都必须确保这个<literal>Session</literal>在你的数据库访问工作完成后关闭。这样做还有一个好处就是可以容易的使用延迟装载(lazy initialization):<literal>Session</literal>在渲染view层的时候仍然打开着的,所以你在遍历当前对象图的时候可以装载所需的对象。
+ </para>
+
+ <para>
+ Hibernate有不同的方法用来从数据库中取回对象。最灵活的方式就是使用Hibernate查询语言(HQL),这是一种容易学习的语言,是对SQL的面向对象的强大扩展。
+ </para>
+
+ <programlisting><![CDATA[Transaction tx= session.beginTransaction();
+
+Query query = session.createQuery("select c from Cat as c where c.sex = :sex");
+query.setCharacter("sex", 'F');
+for (Iterator it = query.iterate(); it.hasNext();) {
+ Cat cat = (Cat) it.next();
+ out.println("Female Cat: " + cat.getName() );
+}
+
+tx.commit();]]></programlisting>
+
+ <para>
+ Hibernate也提供一种面向对象的<emphasis>按条件查询</emphasis>API,可以执行简洁安全类型的查询。当然,Hibernate在所有与数据库的交互中都使用<literal>PrepatedStatement</literal>和参数绑定。你也可以使用Hibernate的直接SQL查询特性,或者在特殊情况下从<literal>Session</literal>获取一个原始的JDBC连接。
+ </para>
+
+ </sect1>
+
+ <sect1 id="quickstart-summary" revision="1">
+ <title>结语</title>
+
+ <para>
+ 在这个短小的教程中,我们对Hibernate浅尝即止。请注意我们没有在例子中包含任何servlet相关代码。你必须自行编写servlet,并插入适合你的Hibernate代码。
+ </para>
+
+ <para>
+ 请记住Hibernate作为一个数据库访问层,是与你的程序紧密相关的。通常情况下,所有其他层次都依赖持久机制。请确信你理解了这种设计的内涵。
+ </para>
+
+ <para>
+ 若希望学习更复杂的例子,请参阅http://caveatemptor.hibernate.org/ 。在 http://www.hibernate.org/Documentation 也可以得到其他教程的链接。
+
+ </para>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/session_api.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/session_api.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/session_api.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/session_api.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,1117 @@
+<chapter id="objectstate">
+
+ <title>与对象共事</title>
+
+ <para>
+ Hibernate是完整的对象/关系映射解决方案,它提供了对象<emphasis>状态管理(state management)</emphasis>的功能,使开发者不再需要理会底层数据库系统的细节。
+ 也就是说,相对于常见的JDBC/SQL持久层方案中需要<literal>管理SQL语句</literal>,Hibernate采用了更自然的面向对象的视角来持久化Java应用中的数据。
+ </para>
+
+
+ <para>
+ 换句话说,使用Hibernate的开发者应该总是关注对象的<emphasis>状态(state)</emphasis>,不必考虑SQL语句的执行。
+ 这部分细节已经由Hibernate掌管妥当,只有开发者在进行系统性能调优的时候才需要进行了解。
+ </para>
+
+ <sect1 id="objectstate-overview">
+
+ <title>Hibernate对象状态(object states)</title>
+
+
+ <para>
+ Hibernate定义并支持下列对象状态(state):
+ </para>
+
+ <itemizedlist>
+ <listitem>
+
+ <para>
+ <emphasis>瞬时(Transient)</emphasis> - 由<literal>new</literal>操作符创建,且尚未与Hibernate <literal>Session</literal>
+ 关联的对象被认定为瞬时(Transient)的。瞬时(Transient)对象不会被持久化到数据库中,也不会被赋予持久化标识(identifier)。
+ 如果瞬时(Transient)对象在程序中没有被引用,它会被垃圾回收器(garbage collector)销毁。
+ 使用Hibernate <literal>Session</literal>可以将其变为持久(Persistent)状态。(Hibernate会自动执行必要的SQL语句)
+ </para>
+
+ </listitem>
+ <listitem>
+
+ <para>
+ <emphasis>持久(Persistent)</emphasis> - 持久(Persistent)的实例在数据库中有对应的记录,并拥有一个持久化标识(identifier)。
+ 持久(Persistent)的实例可能是刚被保存的,或刚被加载的,无论哪一种,按定义,它存在于相关联的<literal>Session</literal>作用范围内。
+ Hibernate会检测到处于持久(Persistent)状态的对象的任何改动,在当前操作单元(unit of work)执行完毕时将对象数据(state)与数据库同步(synchronize)。
+ 开发者不需要手动执行<literal>UPDATE</literal>。将对象从持久(Persistent)状态变成瞬时(Transient)状态同样也不需要手动执行<literal>DELETE</literal>语句。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>脱管(Detached)</emphasis> - 与持久(Persistent)对象关联的<literal>Session</literal>被关闭后,对象就变为脱管(Detached)的。
+ 对脱管(Detached)对象的引用依然有效,对象可继续被修改。脱管(Detached)对象如果重新关联到某个新的<literal>Session</literal>上,
+ 会再次转变为持久(Persistent)的(在Detached其间的改动将被持久化到数据库)。
+ 这个功能使得一种编程模型,即中间会给用户思考时间(user think-time)的长时间运行的操作单元(unit of work)的编程模型成为可能。
+ 我们称之为<emphasis>应用程序事务</emphasis>,即从用户观点看是一个操作单元(unit of work)。
+ </para>
+
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 接下来我们来细致的讨论下状态(states)及状态间的转换(state transitions)(以及触发状态转换的Hibernate方法)。
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-makingpersistent" revision="1">
+ <title>使对象持久化</title>
+
+ <para>
+ Hibernate认为持久化类(persistent class)新实例化的对象是<emphasis>瞬时(Transient)</emphasis>的。
+ 我们可通过将瞬时(Transient)对象与session关联而把它变为<emphasis>持久(Persistent)</emphasis>的。
+ </para>
+
+ <programlisting><![CDATA[DomesticCat fritz = new DomesticCat();
+fritz.setColor(Color.GINGER);
+fritz.setSex('M');
+fritz.setName("Fritz");
+Long generatedId = (Long) sess.save(fritz);]]></programlisting>
+
+ <para>
+ 如果<literal>Cat</literal>的持久化标识(identifier)是<literal>generated</literal>类型的,
+ 那么该标识(identifier)会自动在<literal>save()</literal>被调用时产生并分配给<literal>cat</literal>。
+ 如果<literal>Cat</literal>的持久化标识(identifier)是<literal>assigned</literal>类型的,或是一个复合主键(composite key),
+ 那么该标识(identifier)应当在调用<literal>save()</literal>之前手动赋予给<literal>cat</literal>。
+ 你也可以按照EJB3 early draft中定义的语义,使用<literal>persist()</literal>替代<literal>save()</literal>。
+ </para>
+
+
+ <para>
+ 此外,你可以用一个重载版本的<literal>save()</literal>方法。
+ </para>
+
+<programlisting><![CDATA[DomesticCat pk = new DomesticCat();
+pk.setColor(Color.TABBY);
+pk.setSex('F');
+pk.setName("PK");
+pk.setKittens( new HashSet() );
+pk.addKitten(fritz);
+sess.save( pk, new Long(1234) );]]></programlisting>
+
+
+ <para>
+ 如果你持久化的对象有关联的对象(associated objects)(例如上例中的<literal>kittens</literal>集合)
+ 那么对这些对象(译注:pk和kittens)进行持久化的顺序是任意的(也就是说可以先对kittens进行持久化也可以先对pk进行持久化),
+ 除非你在外键列上有<literal>NOT NULL</literal>约束。
+ Hibernate不会违反外键约束,但是如果你用错误的顺序持久化对象(译注:在pk持久化之前持久化kitten),那么可能会违反<literal>NOT NULL</literal>约束。
+ </para>
+
+ <para>
+ 通常你不会为这些细节烦心,因为你很可能会使用Hibernate的
+ <emphasis>传播性持久化(transitive persistence)</emphasis>功能自动保存相关联那些对象。
+ 这样连违反<literal>NOT NULL</literal>约束的情况都不会出现了 - Hibernate会管好所有的事情。
+ 传播性持久化(transitive persistence)将在本章稍后讨论。
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-loading">
+ <title>装载对象</title>
+ <para>
+ 如果你知道某个实例的持久化标识(identifier),你就可以使用<literal>Session</literal>的<literal>load()</literal>方法
+ 来获取它。 <literal>load()</literal>的另一个参数是指定类的.class对象。
+ 本方法会创建指定类的持久化实例,并从数据库加载其数据(state)。
+ </para>
+
+ <programlisting><![CDATA[Cat fritz = (Cat) sess.load(Cat.class, generatedId);]]></programlisting>
+
+<programlisting><![CDATA[// you need to wrap primitive identifiers
+long id = 1234;
+DomesticCat pk = (DomesticCat) sess.load( DomesticCat.class, new Long(id) );]]></programlisting>
+
+ <para>
+ 此外, 你可以把数据(state)加载到指定的对象实例上(覆盖掉该实例原来的数据)。
+ </para>
+
+<programlisting><![CDATA[Cat cat = new DomesticCat();
+// load pk's state into cat
+sess.load( cat, new Long(pkId) );
+Set kittens = cat.getKittens();]]></programlisting>
+
+
+ <para>
+ 请注意如果没有匹配的数据库记录,<literal>load()</literal>方法可能抛出无法恢复的异常(unrecoverable exception)。
+ 如果类的映射使用了代理(proxy),<literal>load()</literal>方法会返回一个未初始化的代理,直到你调用该代理的某方法时才会去访问数据库。
+ 若你希望在某对象中创建一个指向另一个对象的关联,又不想在从数据库中装载该对象时同时装载相关联的那个对象,那么这种操作方式就用得上的了。
+ 如果为相应类映射关系设置了<literal>batch-size</literal>,
+ 那么使用这种操作方式允许多个对象被一批装载(因为返回的是代理,无需从数据库中抓取所有对象的数据)。
+ </para>
+
+
+ <para>
+ 如果你不确定是否有匹配的行存在,应该使用<literal>get()</literal>方法,它会立刻访问数据库,如果没有对应的记录,会返回null。
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) sess.get(Cat.class, id);
+if (cat==null) {
+ cat = new Cat();
+ sess.save(cat, id);
+}
+return cat;]]></programlisting>
+
+ <para>
+ 你甚至可以选用某个<literal>LockMode</literal>,用SQL的<literal>SELECT ... FOR UPDATE</literal>装载对象。
+ 请查阅API文档以获取更多信息。
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) sess.get(Cat.class, id, LockMode.UPGRADE);]]></programlisting>
+
+
+ <para>
+ 注意,任何关联的对象或者包含的集合都<emphasis>不会</emphasis>被以<literal>FOR UPDATE</literal>方式返回,
+ 除非你指定了<literal>lock</literal>或者<literal>all</literal>作为关联(association)的级联风格(cascade style)。
+ </para>
+
+
+ <para>
+ 任何时候都可以使用<literal>refresh()</literal>方法强迫装载对象和它的集合。如果你使用数据库触发器功能来处理对象的某些属性,这个方法就很有用了。
+ </para>
+
+ <programlisting><![CDATA[sess.save(cat);
+sess.flush(); //force the SQL INSERT
+sess.refresh(cat); //re-read the state (after the trigger executes)]]></programlisting>
+
+
+ <para>
+ 此处通常会出现一个重要问题: Hibernate会从数据库中装载多少东西?会执行多少条相应的SQL<literal>SELECT</literal>语句?
+ 这取决于<emphasis>抓取策略(fetching strategy)</emphasis>,会在<xref linkend="performance-fetching"/>中解释。
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-querying" revision="1">
+ <title>查询</title>
+ <para>
+ 如果不知道所要寻找的对象的持久化标识,那么你需要使用查询。Hibernate支持强大且易于使用的面向对象查询语言(HQL)。
+ 如果希望通过编程的方式创建查询,Hibernate提供了完善的按条件(Query By Criteria, QBC)以及按样例(Query By Example, QBE)进行查询的功能。
+ 你也可以用原生SQL(native SQL)描述查询,Hibernate额外提供了将结果集(result set)转化为对象的支持。
+ </para>
+
+ <sect2 id="objectstate-querying-executing" revision="1">
+ <title>执行查询</title>
+
+ <para>
+ HQL和原生SQL(native SQL)查询要通过为<literal>org.hibernate.Query</literal>的实例来表达。
+ 这个接口提供了参数绑定、结果集处理以及运行实际查询的方法。
+ 你总是可以通过当前<literal>Session</literal>获取一个<literal>Query</literal>对象:
+ </para>
+
+ <programlisting><![CDATA[List cats = session.createQuery(
+ "from Cat as cat where cat.birthdate < ?")
+ .setDate(0, date)
+ .list();
+
+List mothers = session.createQuery(
+ "select mother from Cat as cat join cat.mother as mother where cat.name = ?")
+ .setString(0, name)
+ .list();
+
+List kittens = session.createQuery(
+ "from Cat as cat where cat.mother = ?")
+ .setEntity(0, pk)
+ .list();
+
+Cat mother = (Cat) session.createQuery(
+ "select cat.mother from Cat as cat where cat = ?")
+ .setEntity(0, izi)
+ .uniqueResult();]]
+
+Query mothersWithKittens = (Cat) session.createQuery(
+ "select mother from Cat as mother left join fetch mother.kittens");
+Set uniqueMothers = new HashSet(mothersWithKittens.list());]]></programlisting>
+
+
+ <para>
+ 一个查询通常在调用<literal>list()</literal>时被执行,执行结果会完全装载进内存中的一个集合(collection)。
+ 查询返回的对象处于持久(persistent)状态。如果你知道的查询只会返回一个对象,可使用<literal>list()</literal>的快捷方式<literal>uniqueResult()</literal>。
+ 注意,使用集合预先抓取的查询往往会返回多次根对象(他们的集合类都被初始化了)。你可以通过一个集合来过滤这些重复对象。
+ </para>
+
+ <sect3 id="objectstate-querying-executing-iterate">
+
+ <title>迭代式获取结果(Iterating results)</title>
+
+ <para>
+ 某些情况下,你可以使用<literal>iterate()</literal>方法得到更好的性能。
+ 这通常是你预期返回的结果在session,或二级缓存(second-level cache)中已经存在时的情况。
+ 如若不然,<literal>iterate()</literal>会比<literal>list()</literal>慢,而且可能简单查询也需要进行多次数据库访问:
+ <literal>iterate()</literal>会首先使用<emphasis>1</emphasis>条语句得到所有对象的持久化标识(identifiers),再根据持久化标识执行<emphasis>n</emphasis>条附加的select语句实例化实际的对象。
+ </para>
+
+ <programlisting><![CDATA[// fetch ids
+Iterator iter = sess.createQuery("from eg.Qux q order by q.likeliness").iterate();
+while ( iter.hasNext() ) {
+ Qux qux = (Qux) iter.next(); // fetch the object
+ // something we couldnt express in the query
+ if ( qux.calculateComplicatedAlgorithm() ) {
+ // delete the current instance
+ iter.remove();
+ // dont need to process the rest
+ break;
+ }
+}]]></programlisting>
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-tuples">
+ <title>返回元组(tuples)的查询</title>
+
+ <para>
+ (译注:元组(tuples)指一条结果行包含多个对象)
+ Hibernate查询有时返回元组(tuples),每个元组(tuples)以数组的形式返回:
+ </para>
+
+ <programlisting><![CDATA[Iterator kittensAndMothers = sess.createQuery(
+ "select kitten, mother from Cat kitten join kitten.mother mother")
+ .list()
+ .iterator();
+
+while ( kittensAndMothers.hasNext() ) {
+ Object[] tuple = (Object[]) kittensAndMothers.next();
+ Cat kitten = (Cat) tuple[0];
+ Cat mother = (Cat) tuple[1];
+ ....
+}]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-scalar" revision="1">
+ <title>标量(Scalar)结果</title>
+
+ <para>
+ 查询可在<literal>select</literal>从句中指定类的属性,甚至可以调用SQL统计(aggregate)函数。
+ 属性或统计结果被认定为"标量(Scalar)"的结果(而不是持久(persistent state)的实体)。
+ </para>
+
+ <programlisting><![CDATA[Iterator results = sess.createQuery(
+ "select cat.color, min(cat.birthdate), count(cat) from Cat cat " +
+ "group by cat.color")
+ .list()
+ .iterator();
+
+while ( results.hasNext() ) {
+ Object[] row = (Object[]) results.next();
+ Color type = (Color) row[0];
+ Date oldest = (Date) row[1];
+ Integer count = (Integer) row[2];
+ .....
+}]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-parameters">
+ <title>绑定参数</title>
+
+ <para>
+ 接口<literal>Query</literal>提供了对命名参数(named parameters)、JDBC风格的<literal>问号(?)</literal>参数进行绑定的方法。
+ <emphasis>不同于JDBC,Hibernate对参数从0开始计数。</emphasis>
+ 命名参数(named parameters)在查询字符串中是形如<literal>:name</literal>的标识符。
+ 命名参数(named parameters)的优点是:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 命名参数(named parameters)与其在查询串中出现的顺序无关
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 它们可在同一查询串中多次出现
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 它们本身是自我说明的
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting><![CDATA[//named parameter (preferred)
+Query q = sess.createQuery("from DomesticCat cat where cat.name = :name");
+q.setString("name", "Fritz");
+Iterator cats = q.iterate();]]></programlisting>
+
+ <programlisting><![CDATA[//positional parameter
+Query q = sess.createQuery("from DomesticCat cat where cat.name = ?");
+q.setString(0, "Izi");
+Iterator cats = q.iterate();]]></programlisting>
+
+ <programlisting><![CDATA[//named parameter list
+List names = new ArrayList();
+names.add("Izi");
+names.add("Fritz");
+Query q = sess.createQuery("from DomesticCat cat where cat.name in (:namesList)");
+q.setParameterList("namesList", names);
+List cats = q.list();]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-pagination">
+ <title>分页</title>
+
+ <para>
+ 如果你需要指定结果集的范围(希望返回的最大行数/或开始的行数),应该使用<literal>Query</literal>接口提供的方法:
+ </para>
+
+ <programlisting><![CDATA[Query q = sess.createQuery("from DomesticCat cat");
+q.setFirstResult(20);
+q.setMaxResults(10);
+List cats = q.list();]]></programlisting>
+
+ <para>
+ Hibernate 知道如何将这个有限定条件的查询转换成你的数据库的原生SQL(native SQL)。
+ </para>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-scrolling">
+ <title>可滚动遍历(Scrollable iteration)</title>
+
+
+ <para>
+ 如果你的JDBC驱动支持可滚动的<literal>ResuleSet</literal>,<literal>Query</literal>接口可以使用<literal>ScrollableResults</literal>,允许你在查询结果中灵活游走。
+ </para>
+
+ <programlisting><![CDATA[Query q = sess.createQuery("select cat.name, cat from DomesticCat cat " +
+ "order by cat.name");
+ScrollableResults cats = q.scroll();
+if ( cats.first() ) {
+
+ // find the first name on each page of an alphabetical list of cats by name
+ firstNamesOfPages = new ArrayList();
+ do {
+ String name = cats.getString(0);
+ firstNamesOfPages.add(name);
+ }
+ while ( cats.scroll(PAGE_SIZE) );
+
+ // Now get the first page of cats
+ pageOfCats = new ArrayList();
+ cats.beforeFirst();
+ int i=0;
+ while( ( PAGE_SIZE > i++ ) && cats.next() ) pageOfCats.add( cats.get(1) );
+
+}
+cats.close()]]></programlisting>
+
+ <para>
+ 请注意,使用此功能需要保持数据库连接(以及游标(cursor))处于一直打开状态。
+ 如果你需要断开连接使用分页功能,请使用<literal>setMaxResult()</literal>/<literal>setFirstResult()</literal>
+ </para>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-named" revision="1">
+ <title>外置命名查询(Externalizing named queries)</title>
+
+ <para>
+ 你可以在映射文件中定义命名查询(named queries)。
+ (如果你的查询串中包含可能被解释为XML标记(markup)的字符,别忘了用<literal>CDATA</literal>包裹起来。)
+ </para>
+
+ <programlisting><![CDATA[<query name="ByNameAndMaximumWeight"><![CDATA[
+ from eg.DomesticCat as cat
+ where cat.name = ?
+ and cat.weight > ?
+] ]></query>]]></programlisting>
+
+
+ <para>
+ 参数绑定及执行以编程方式(programatically)完成:
+ </para>
+
+ <programlisting><![CDATA[Query q = sess.getNamedQuery("ByNameAndMaximumWeight");
+q.setString(0, name);
+q.setInt(1, minWeight);
+List cats = q.list();]]></programlisting>
+
+
+ <para>
+ 请注意实际的程序代码与所用的查询语言无关,你也可在元数据中定义原生SQL(native SQL)查询,
+ 或将原有的其他的查询语句放在配置文件中,这样就可以让Hibernate统一管理,达到迁移的目的。
+ </para>
+
+ <para>
+
+ 也请注意在<literal><hibernate-mapping></literal>元素中声明的查询必须有一个全局唯一的名字,而在<literal><class></literal>元素中声明的查询自动具有全局名,是通过类的全名加以限定的。比如<literal>eg.Cat.ByNameAndMaximumWeight</literal>。
+ </para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="objectstate-filtering" revision="1">
+ <title>过滤集合</title>
+
+
+ <para>
+ 集合<emphasis>过滤器(filter)</emphasis>是一种用于一个持久化集合或者数组的特殊的查询。查询字符串中可以使用<literal>"this"</literal>来引用集合中的当前元素。
+ </para>
+
+ <programlisting><![CDATA[Collection blackKittens = session.createFilter(
+ pk.getKittens(),
+ "where this.color = ?")
+ .setParameter( Color.BLACK, Hibernate.custom(ColorUserType.class) )
+ .list()
+);]]></programlisting>
+
+
+ <para>
+ 返回的集合可以被认为是一个包(bag, 无顺序可重复的集合(collection)),它是所给集合的副本。
+ 原来的集合不会被改动(这与“过滤器(filter)”的隐含的含义不符,不过与我们期待的行为一致)。
+ </para>
+
+ <para>
+ 请注意过滤器(filter)并不需要<literal>from</literal>子句(当然需要的话它们也可以加上)。过滤器(filter)不限定于只能返回集合元素本身。
+ </para>
+
+ <programlisting><![CDATA[Collection blackKittenMates = session.createFilter(
+ pk.getKittens(),
+ "select this.mate where this.color = eg.Color.BLACK.intValue")
+ .list();]]></programlisting>
+
+ <para>
+ 即使无条件的过滤器(filter)也是有意义的。例如,用于加载一个大集合的子集:
+ </para>
+
+ <programlisting><![CDATA[Collection tenKittens = session.createFilter(
+ mother.getKittens(), "")
+ .setFirstResult(0).setMaxResults(10)
+ .list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="objecstate-querying-criteria" revision="1">
+ <title>条件查询(Criteria queries)</title>
+
+ <para>
+ HQL极为强大,但是有些人希望能够动态的使用一种面向对象API创建查询,而非在他们的Java代码中嵌入字符串。对于那部分人来说,Hibernate提供了直观的<literal>Criteria</literal>查询API。
+ </para>
+
+ <programlisting><![CDATA[Criteria crit = session.createCriteria(Cat.class);
+crit.add( Restrictions.eq( "color", eg.Color.BLACK ) );
+crit.setMaxResults(10);
+List cats = crit.list();]]></programlisting>
+
+
+ <para>
+ <literal>Criteria</literal>以及相关的<literal>样例(Example)</literal>API将会再<xref linkend="querycriteria"/>中详细讨论。
+ </para>
+
+ </sect2>
+
+ <sect2 id="objectstate-querying-nativesql" revision="2">
+ <title>使用原生SQL的查询</title>
+
+
+ <para>
+ 你可以使用<literal>createSQLQuery()</literal>方法,用SQL来描述查询,并由Hibernate将结果集转换成对象。
+ 请注意,你可以在任何时候调用<literal>session.connection()</literal>来获得并使用JDBC <literal>Connection</literal>对象。
+ 如果你选择使用Hibernate的API, 你必须把SQL别名用大括号包围起来:
+ </para>
+
+ <programlisting><![CDATA[List cats = session.createSQLQuery("SELECT {cat.*} FROM CAT {cat} WHERE ROWNUM<10")
+ .addEntity("cat", Cat.class)
+.list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = session.createSQLQuery(
+ "SELECT {cat}.ID AS {cat.id}, {cat}.SEX AS {cat.sex}, " +
+ "{cat}.MATE AS {cat.mate}, {cat}.SUBCLASS AS {cat.class}, ... " +
+ "FROM CAT {cat} WHERE ROWNUM<10")
+ .addEntity("cat", Cat.class)
+.list()]]></programlisting>
+
+ <para>
+ 和Hibernate查询一样,SQL查询也可以包含命名参数和占位参数。
+ 可以在<xref linkend="querysql"/>找到更多关于Hibernate中原生SQL(native SQL)的信息。
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="objectstate-modifying" revision="1">
+ <title>修改持久对象</title>
+
+ <para>
+ <emphasis>事务中的持久实例</emphasis>(就是通过<literal>session</literal>装载、保存、创建或者查询出的对象)
+ 被应用程序操作所造成的任何修改都会在<literal>Session</literal>被<emphasis>刷出(flushed)</emphasis>的时候被持久化(本章后面会详细讨论)。
+ 这里不需要调用某个特定的方法(比如<literal>update()</literal>,设计它的目的是不同的)将你的修改持久化。
+ 所以最直接的更新一个对象的方法就是在<literal>Session</literal>处于打开状态时<literal>load()</literal>它,然后直接修改即可:
+ </para>
+
+ <programlisting><![CDATA[DomesticCat cat = (DomesticCat) sess.load( Cat.class, new Long(69) );
+cat.setName("PK");
+sess.flush(); // changes to cat are automatically detected and persisted]]></programlisting>
+
+ <para>
+ 有时这种程序模型效率低下,因为它在同一Session里需要一条SQL <literal>SELECT</literal>语句(用于加载对象)
+ 以及一条SQL <literal>UPDATE</literal>语句(持久化更新的状态)。
+ 为此Hibernate提供了另一种途径,使用脱管(detached)实例。
+ </para>
+
+
+ <para>
+ <emphasis>请注意Hibernate本身不提供直接执行<literal>UPDATE</literal>或<literal>DELETE</literal>语句的API。
+ Hibernate提供的是<emphasis>状态管理(state management)</emphasis>服务,你不必考虑要使用的<emphasis>语句(statements)</emphasis>。
+ JDBC是出色的执行SQL语句的API,任何时候调用<literal>session.connection()</literal>你都可以得到一个JDBC <literal>Connection</literal>对象。
+ 此外,在联机事务处理(OLTP)程序中,大量操作(mass operations)与对象/关系映射的观点是相冲突的。
+ Hibernate的将来版本可能会提供专门的进行大量操作(mass operation)的功能。
+ 参考<xref linkend="batch"/>,寻找一些可用的批量(batch)操作技巧。</emphasis>
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-detached" revision="2">
+ <title>修改脱管(Detached)对象</title>
+
+ <para>
+ 很多程序需要在某个事务中获取对象,然后将对象发送到界面层去操作,最后在一个新的事务保存所做的修改。
+ 在高并发访问的环境中使用这种方式,通常使用附带版本信息的数据来保证这些“长“工作单元之间的隔离。
+ </para>
+
+ <para>
+ Hibernate通过提供<literal>Session.update()</literal>或<literal>Session.merge()</literal>
+ 重新关联脱管实例的办法来支持这种模型。
+ </para>
+
+
+ <programlisting><![CDATA[// in the first session
+Cat cat = (Cat) firstSession.load(Cat.class, catId);
+Cat potentialMate = new Cat();
+firstSession.save(potentialMate);
+
+// in a higher layer of the application
+cat.setMate(potentialMate);
+
+// later, in a new session
+secondSession.update(cat); // update cat
+secondSession.update(mate); // update mate]]></programlisting>
+
+ <para>
+ 如果具有<literal>catId</literal>持久化标识的<literal>Cat</literal>之前已经被<literal>另一Session(secondSession)</literal>装载了,
+ 应用程序进行重关联操作(reattach)的时候会抛出一个异常。
+ </para>
+
+
+ <para>
+ 如果你确定当前session没有包含与之具有相同持久化标识的持久实例,使用<literal>update()</literal>。
+ 如果想随时合并你的的改动而不考虑session的状态,使用<literal>merge()</literal>。
+ 换句话说,在一个新session中通常第一个调用的是<literal>update()</literal>方法,以便保证重新关联脱管(detached)对象的操作首先被执行。
+ </para>
+
+
+ <para>
+ 如果希望相关联的脱管对象(通过引用“可到达”的脱管对象)的数据也要更新到数据库时(并且也<emphasis>仅仅</emphasis>在这种情况),
+ 可以对该相关联的脱管对象单独调用<literal>update()</literal>
+ 当然这些可以自动完成,即通过使用<emphasis>传播性持久化(transitive persistence)</emphasis>,请看<xref linkend="objectstate-transitive"/>。
+ </para>
+
+
+ <para>
+ <literal>lock()</literal>方法也允许程序重新关联某个对象到一个新session上。不过,该脱管(detached)的对象必须是没有修改过的!
+ </para>
+
+ <programlisting><![CDATA[//just reassociate:
+sess.lock(fritz, LockMode.NONE);
+//do a version check, then reassociate:
+sess.lock(izi, LockMode.READ);
+//do a version check, using SELECT ... FOR UPDATE, then reassociate:
+sess.lock(pk, LockMode.UPGRADE);]]></programlisting>
+
+
+ <para>
+ 请注意,<literal>lock()</literal>可以搭配多种<literal>LockMode</literal>,
+ 更多信息请阅读API文档以及关于事务处理(transaction handling)的章节。重新关联不是<literal>lock()</literal>的唯一用途。
+ </para>
+
+
+ <para>
+ 其他用于长时间工作单元的模型会在<xref linkend="transactions-optimistic"/>中讨论。
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-saveorupdate">
+ <title>自动状态检测</title>
+
+
+ <para>
+ Hibernate的用户曾要求一个既可自动分配新持久化标识(identifier)保存瞬时(transient)对象,又可更新/重新关联脱管(detached)实例的通用方法。
+ <literal>saveOrUpdate()</literal>方法实现了这个功能。
+ </para>
+
+ <programlisting><![CDATA[// in the first session
+Cat cat = (Cat) firstSession.load(Cat.class, catID);
+
+// in a higher tier of the application
+Cat mate = new Cat();
+cat.setMate(mate);
+
+// later, in a new session
+secondSession.saveOrUpdate(cat); // update existing state (cat has a non-null id)
+secondSession.saveOrUpdate(mate); // save the new instance (mate has a null id)]]></programlisting>
+
+
+ <para>
+ <literal>saveOrUpdate()</literal>用途和语义可能会使新用户感到迷惑。
+ 首先,只要你没有尝试在某个session中使用来自另一session的实例,你就应该不需要使用<literal>update()</literal>,
+ <literal>saveOrUpdate()</literal>,或<literal>merge()</literal>。有些程序从来不用这些方法。
+ </para>
+
+
+ <para>
+ 通常下面的场景会使用<literal>update()</literal>或<literal>saveOrUpdate()</literal>:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 程序在第一个session中加载对象
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 该对象被传递到表现层
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 对象发生了一些改动
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 该对象被返回到业务逻辑层
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 程序调用第二个session的<literal>update()</literal>方法持久这些改动
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>saveOrUpdate()</literal>做下面的事:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 如果对象已经在本session中持久化了,不做任何事
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 如果另一个与本session关联的对象拥有相同的持久化标识(identifier),抛出一个异常
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 如果对象没有持久化标识(identifier)属性,对其调用<literal>save()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 如果对象的持久标识(identifier)表明其是一个新实例化的对象,对其调用<literal>save()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 如果对象是附带版本信息的(通过<literal><version></literal>或<literal><timestamp></literal>)
+ 并且版本属性的值表明其是一个新实例化的对象,<literal>save()</literal>它。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 否则<literal>update()</literal> 这个对象
+ </para>
+ </listitem>
+ </itemizedlist>
+
+
+ <para>
+ <literal>merge()</literal>可非常不同:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象的状态覆盖旧有的持久实例
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 如果session没有相应的持久实例,则尝试从数据库中加载,或创建新的持久化实例
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 最后返回该持久实例
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 用户给出的这个对象没有被关联到session上,它依旧是脱管的
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 id="objectstate-deleting" revision="1">
+ <title>删除持久对象</title>
+
+ <para>
+ 使用<literal>Session.delete()</literal>会把对象的状态从数据库中移除。
+ 当然,你的应用程序可能仍然持有一个指向已删除对象的引用。所以,最好这样理解:<literal>delete()</literal>的用途是把一个持久实例变成瞬时(transient)实例。
+ </para>
+
+ <programlisting><![CDATA[sess.delete(cat);]]></programlisting>
+
+
+ <para>
+ 你可以用你喜欢的任何顺序删除对象,不用担心外键约束冲突。当然,如果你搞错了顺序,还是有可能引发在外键字段定义的<literal>NOT NULL</literal>约束冲突。
+ 例如你删除了父对象,但是忘记删除孩子们。
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-replicating" revision="1">
+ <title>在两个不同数据库间复制对象</title>
+
+
+ <para>
+ 偶尔会用到不重新生成持久化标识(identifier),将持久实例以及其关联的实例持久到不同的数据库中的操作。
+ </para>
+
+ <programlisting><![CDATA[//retrieve a cat from one database
+Session session1 = factory1.openSession();
+Transaction tx1 = session1.beginTransaction();
+Cat cat = session1.get(Cat.class, catId);
+tx1.commit();
+session1.close();
+
+//reconcile with a second database
+Session session2 = factory2.openSession();
+Transaction tx2 = session2.beginTransaction();
+session2.replicate(cat, ReplicationMode.LATEST_VERSION);
+tx2.commit();
+session2.close();]]></programlisting>
+
+
+ <para>
+ <literal>ReplicationMode</literal>决定在和数据库中已存在记录由冲突时,<literal>replicate()</literal>如何处理。
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>ReplicationMode.IGNORE</literal> - 忽略它
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.OVERWRITE</literal> - 覆盖相同的行
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.EXCEPTION</literal> - 抛出异常
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.LATEST_VERSION</literal> - 如果当前的版本较新,则覆盖,否则忽略
+ </para>
+ </listitem>
+ </itemizedlist>
+
+
+ <para>
+ 这个功能的用途包括使录入的数据在不同数据库中一致,产品升级时升级系统配置信息,回滚non-ACID事务中的修改等等。
+ (译注,non-ACID,非ACID;ACID,Atomic,Consistent,Isolated and Durable的缩写)
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-flushing">
+ <title>Session刷出(flush)</title>
+
+
+ <para>
+ 每间隔一段时间,<literal>Session</literal>会执行一些必需的SQL语句来把内存中的对象的状态同步到JDBC连接中。这个过程被称为<emphasis>刷出(flush)</emphasis>,默认会在下面的时间点执行:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 在某些查询执行之前
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 在调用<literal>org.hibernate.Transaction.commit()</literal>的时候
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 在调用<literal>Session.flush()</literal>的时候
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 涉及的SQL语句会按照下面的顺序发出执行:
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ 所有对实体进行插入的语句,其顺序按照对象执行<literal>Session.save()</literal>的时间顺序
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 所有对实体进行更新的语句
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 所有进行集合删除的语句
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 所有对集合元素进行删除,更新或者插入的语句
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 所有进行集合插入的语句
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 所有对实体进行删除的语句,其顺序按照对象执行<literal>Session.delete()</literal>的时间顺序
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ (有一个例外是,如果对象使用<literal>native</literal>方式来生成ID(持久化标识)的话,它们一执行save就会被插入。)
+ </para>
+
+ <para>
+ 除非你明确地发出了<literal>flush()</literal>指令,关于Session<emphasis>何时</emphasis>会执行这些JDBC调用是完全无法保证的,只能保证它们执行的前后顺序。
+ 当然,Hibernate保证,<literal>Query.list(..)</literal>绝对不会返回已经失效的数据,也不会返回错误数据。
+ </para>
+
+
+ <para>
+ 也可以改变默认的设置,来让刷出(flush)操作发生的不那么频繁。
+ <literal>FlushMode</literal>类定义了三种不同的方式。
+ 仅在提交时刷出(仅当Hibernate的<literal>Transaction</literal> API被使用时有效),
+ 按照刚才说的方式刷出,
+ 以及除非明确使用<literal>flush()</literal>否则从不刷出。
+ 最后一种模式对于那些需要长时间保持<literal>Session</literal>为打开或者断线状态的长时间运行的工作单元很有用。
+ (参见 <xref linkend="transactions-optimistic-longsession"/>).
+ </para>
+
+ <programlisting><![CDATA[sess = sf.openSession();
+Transaction tx = sess.beginTransaction();
+sess.setFlushMode(FlushMode.COMMIT); // allow queries to return stale state
+
+Cat izi = (Cat) sess.load(Cat.class, id);
+izi.setName(iznizi);
+
+// might return stale data
+sess.find("from Cat as cat left outer join cat.kittens kitten");
+
+// change to izi is not flushed!
+...
+tx.commit(); // flush occurs
+sess.close();]]></programlisting>
+
+
+ <para>
+ 刷出(flush)期间,可能会抛出异常。(例如一个DML操作违反了约束)
+ 异常处理涉及到对Hibernate事务性行为的理解,因此我们将在<xref linkend="transactions"/>中讨论。
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-transitive" revision="1">
+ <title>传播性持久化(transitive persistence)</title>
+
+ <para>
+ 对每一个对象都要执行保存,删除或重关联操作让人感觉有点麻烦,尤其是在处理许多彼此关联的对象的时候。
+ 一个常见的例子是父子关系。考虑下面的例子:
+ </para>
+
+
+ <para>
+ 如果一个父子关系中的子对象是值类型(value typed)(例如,地址或字符串的集合)的,他们的生命周期会依赖于父对象,可以享受方便的级联操作(Cascading),不需要额外的动作。
+ 父对象被保存时,这些值类型(value typed)子对象也将被保存;父对象被删除时,子对象也将被删除。
+ 这对将一个子对象从集合中移除是同样有效:Hibernate会检测到,并且因为值类型(value typed)的对象不可能被其他对象引用,所以Hibernate会在数据库中删除这个子对象。
+ </para>
+
+
+ <para>
+ 现在考虑同样的场景,不过父子对象都是实体(entities)类型,而非值类型(value typed)(例如,类别与个体,或母猫和小猫)。
+ 实体有自己的生命期,允许共享对其的引用(因此从集合中移除一个实体,不意味着它可以被删除),
+ 并且实体到其他关联实体之间默认没有级联操作的设置。
+ Hibernate默认不实现所谓的<emphasis>可到达即持久化(persistence by reachability)</emphasis>的策略。
+ </para>
+
+ <para>
+ 每个Hibernate session的基本操作 - 包括 <literal>persist(), merge(),
+ saveOrUpdate(), delete(), lock(), refresh(), evict(), replicate()</literal> - 都有对应的级联风格(cascade style)。
+ 这些级联风格(cascade style)风格分别命名为 <literal>create,
+ merge, save-update, delete, lock, refresh, evict, replicate</literal>。
+ 如果你希望一个操作被顺着关联关系级联传播,你必须在映射文件中指出这一点。例如:
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="person" cascade="persist"/>]]></programlisting>
+
+
+ <para>
+ 级联风格(cascade style)是可组合的:
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="person" cascade="persist,delete,lock"/>]]></programlisting>
+
+
+ <para>
+ 你可以使用<literal>cascade="all"</literal>来指定<emphasis>全部</emphasis>操作都顺着关联关系级联(cascaded)。
+ 默认值是<literal>cascade="none"</literal>,即任何操作都不会被级联(cascaded)。
+ </para>
+
+ <para>
+ 注意有一个特殊的级联风格(cascade style) <literal>delete-orphan</literal>,只应用于one-to-many关联,表明<literal>delete()</literal>操作
+ 应该被应用于所有从关联中删除的对象。
+ </para>
+
+
+
+ <para>
+ 建议:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 通常在<literal><many-to-one></literal>或<literal><many-to-many></literal>关系中应用级联(cascade)没什么意义。
+ 级联(cascade)通常在 <literal><one-to-one></literal>和<literal><one-to-many></literal>关系中比较有用。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 如果子对象的寿命限定在父亲对象的寿命之内,可通过指定<literal>cascade="all,delete-orphan"</literal>将其变为<emphasis>自动生命周期管理的对象(life cycle object)</emphasis>。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 其他情况,你可根本不需要级联(cascade)。但是如果你认为你会经常在某个事务中同时用到父对象与子对象,并且你希望少打点儿字,可以考虑使用<literal>cascade="persist,merge,save-update"</literal>。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 可以使用<literal>cascade="all"</literal>将一个关联关系(无论是对值对象的关联,或者对一个集合的关联)标记为<emphasis>父/子</emphasis>关系的关联。
+ 这样对父对象进行save/update/delete操作就会导致子对象也进行save/update/delete操作。
+ </para>
+
+ <para>
+ 此外,一个持久的父对象对子对象的浅引用(mere reference)会导致子对象被同步save/update。
+ 不过,这个隐喻(metaphor)的说法并不完整。除非关联是<literal><one-to-many></literal>关联并且被标记为<literal>cascade="delete-orphan"</literal>,
+ 否则父对象失去对某个子对象的引用<emphasis>不会</emphasis>导致该子对象被自动删除。
+ 父子关系的级联(cascading)操作准确语义如下:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 如果父对象被<literal>persist()</literal>,那么所有子对象也会被<literal>persist()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 如果父对象被<literal>merge()</literal>,那么所有子对象也会被<literal>merge()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 如果父对象被<literal>save()</literal>,<literal>update()</literal>或
+ <literal>saveOrUpdate()</literal>,那么所有子对象则会被<literal>saveOrUpdate()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 如果某个持久的父对象引用了瞬时(transient)或者脱管(detached)的子对象,那么子对象将会被<literal>saveOrUpdate()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 如果父对象被删除,那么所有子对象也会被<literal>delete()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 除非被标记为<literal>cascade="delete-orphan"</literal>(删除“孤儿”模式,此时不被任何一个父对象引用的子对象会被删除),
+ 否则子对象失掉父对象对其的引用时,<emphasis>什么事也不会发生</emphasis>。
+ 如果有特殊需要,应用程序可通过显式调用delete()删除子对象。
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ 最后,注意操作的级联可能是在<emphasis>调用期(call time)</emphasis>或者<emphasis>写入期(flush time)</emphasis>作用到对象图上的。所有的操作,如果允许,都在操作被执行的时候级联到可触及的关联实体上。然而,<literal>save-upate</literal>和<literal>delete-orphan</literal>是在<literal>Session</literal> flush的时候才作用到所有可触及的被关联对象上的。
+ </para>
+
+
+ </sect1>
+
+ <sect1 id="objectstate-metadata">
+ <title>使用元数据</title>
+
+ <para>
+ Hibernate中有一个非常丰富的元级别(meta-level)的模型,含有所有的实体和值类型数据的元数据。
+ 有时这个模型对应用程序本身也会非常有用。
+ 比如说,应用程序可能在实现一种“智能”的深度拷贝算法时,
+ 通过使用Hibernate的元数据来了解哪些对象应该被拷贝(比如,可变的值类型数据),
+ 那些不应该(不可变的值类型数据,也许还有某些被关联的实体)。
+ </para>
+
+
+ <para>
+ Hibernate提供了<literal>ClassMetadata</literal>接口,<literal>CollectionMetadata</literal>接口和<literal>Type</literal>层次体系来访问元数据。
+ 可以通过<literal>SessionFactory</literal>获取元数据接口的实例。
+ </para>
+
+ <programlisting><![CDATA[Cat fritz = ......;
+ClassMetadata catMeta = sessionfactory.getClassMetadata(Cat.class);
+
+Object[] propertyValues = catMeta.getPropertyValues(fritz);
+String[] propertyNames = catMeta.getPropertyNames();
+Type[] propertyTypes = catMeta.getPropertyTypes();
+
+// get a Map of all properties which are not collections or associations
+Map namedValues = new HashMap();
+for ( int i=0; i<propertyNames.length; i++ ) {
+ if ( !propertyTypes[i].isEntityType() && !propertyTypes[i].isCollectionType() ) {
+ namedValues.put( propertyNames[i], propertyValues[i] );
+ }
+}]]></programlisting>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/toolset_guide.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/toolset_guide.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/toolset_guide.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/toolset_guide.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,564 @@
+<chapter id="toolsetguide" revision="2">
+ <title>工具箱指南</title>
+
+ <para>
+ 可以通过一系列Eclipse插件、命令行工具和Ant任务来进行与Hibernate关联的转换。
+
+ </para>
+
+ <para>
+ 除了Ant任务外,当前的<emphasis>Hibernate Tools</emphasis>也包含了Eclipse IDE的插件,用于与现存数据库的逆向工程。
+ </para>
+
+ <itemizedlist>
+ <listitem><para>
+
+ <emphasis>Mapping Editor:</emphasis> Hibernate XML映射文件的编辑器,支持自动完成和语法高亮。它也支持对类名和属性/字段名的语义自动完成,比通常的XML编辑器方便得多。
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Console:</emphasis> Console是Eclipse的一个新视图。除了对你的console配置的树状概览,你还可以获得对你持久化类及其关联的交互式视图。Console允许你对数据库执行HQL查询,并直接在Eclipse中浏览结果。
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Development Wizards:</emphasis> 在Hibernate Eclipse tools中还提供了几个向导;你可以用向导快速生成Hibernate 配置文件(cfg.xml),你甚至还可以同现存的数据库schema中反向工程出POJO源代码与Hibernate 映射文件。反向工程支持可定制的模版。
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Ant Tasks:</emphasis>
+ </para></listitem>
+
+ </itemizedlist>
+
+ <para>
+ 要得到更多信息,请查阅 <emphasis>Hibernate Tools</emphasis> 包及其文档。
+ </para>
+
+ <para>
+ 同时,Hibernate主发行包还附带了一个集成的工具(它甚至可以在Hibernate“内部”快速运行)<emphasis>SchemaExport</emphasis> ,也就是 <literal>hbm2ddl</literal>。
+
+ </para>
+
+ <sect1 id="toolsetguide-s1" revision="2">
+ <title>Schema自动生成(Automatic schema generation)</title>
+
+ <para>
+ 可以从你的映射文件使用一个Hibernate工具生成DDL。 生成的schema包含有对实体和集合类表的完整性引用约束(主键和外键)。涉及到的标示符生成器所需的表和sequence也会同时生成。
+ </para>
+
+ <para>
+ 在使用这个工具的时候,你<emphasis>必须</emphasis> 通过<literal>hibernate.dialet</literal>属性指定一个SQL<literal>方言(Dialet)</literal>,因为DDL是与供应商高度相关的。
+ </para>
+
+ <para>
+ 首先,要定制你的映射文件,来改善生成的schema。
+ </para>
+
+ <sect2 id="toolsetguide-s1-2" revision="3">
+ <title>对schema定制化(Customizing the schema)</title>
+
+ <para>
+ 很多Hibernate映射元素定义了可选的<literal>length</literal>、<literal>precision</literal> 或者 <literal>scale</literal>属性。你可以通过这个属性设置字段的长度、精度、小数点位数。
+ </para>
+
+ <programlisting><![CDATA[<property name="zip" length="5"/>]]></programlisting>
+ <programlisting><![CDATA[<property name="balance" precision="12" scale="2"/>]]></programlisting>
+
+ <para>
+ 有些tag还接受<literal>not-null</literal>属性(用来在表字段上生成<literal>NOT NULL</literal>约束)和<literal>unique</literal>属性(用来在表字段上生成<literal>UNIQUE</literal>约束)。
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="bar" column="barId" not-null="true"/>]]></programlisting>
+ <programlisting><![CDATA[<element column="serialNumber" type="long" not-null="true" unique="true"/>]]></programlisting>
+
+ <para>
+ <literal>unique-key</literal>属性可以对成组的字段指定一个唯一键约束(unique key constraint)。目前,<literal>unique-key</literal>属性指定的值在生成DDL时<emphasis>并不会</emphasis>被当作这个约束的名字,它们只是在用来在映射文件内部用作区分的。
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="org" column="orgId" unique-key="OrgEmployeeId"/>
+<property name="employeeId" unique-key="OrgEmployee"/>]]></programlisting>
+
+ <para>
+ <literal>index</literal>属性会用对应的字段(一个或多个)生成一个index,它指出了这个index的名字。如果多个字段对应的index名字相同,就会生成包含这些字段的index。
+ </para>
+
+ <programlisting><![CDATA[<property name="lastName" index="CustName"/>
+<property name="firstName" index="CustName"/>]]></programlisting>
+
+ <para>
+ <literal>foreign-key</literal>属性可以用来覆盖任何生成的外键约束的名字。
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="bar" column="barId" foreign-key="FKFooBar"/>]]></programlisting>
+
+ <para>
+ 很多映射元素还接受<literal><column></literal>子元素。这在定义跨越多字段的类型时特别有用。
+ </para>
+
+ <programlisting><![CDATA[<property name="name" type="my.customtypes.Name"/>
+ <column name="last" not-null="true" index="bar_idx" length="30"/>
+ <column name="first" not-null="true" index="bar_idx" length="20"/>
+ <column name="initial"/>
+</property>]]></programlisting>
+
+ <para>
+ <literal>default</literal>属性为字段指定一个默认值 (在保存被映射的类的新实例之前,你应该将同样的值赋于对应的属性)。
+ </para>
+
+ <programlisting><![CDATA[<property name="credits" type="integer" insert="false">
+ <column name="credits" default="10"/>
+</property>]]></programlisting>
+
+ <programlisting><![CDATA[<version name="version" type="integer" insert="false">
+ <column name="version" default="0"/>
+</property>]]></programlisting>
+
+ <para>
+ <literal>sql-type</literal>属性允许用户覆盖默认的Hibernate类型到SQL数据类型的映射。
+ </para>
+
+ <programlisting><![CDATA[<property name="balance" type="float">
+ <column name="balance" sql-type="decimal(13,3)"/>
+</property>]]></programlisting>
+
+ <para>
+ <literal>check</literal>属性允许用户指定一个约束检查。
+ </para>
+
+ <programlisting><![CDATA[<property name="foo" type="integer">
+ <column name="foo" check="foo > 10"/>
+</property>]]></programlisting>
+
+ <programlisting><![CDATA[<class name="Foo" table="foos" check="bar < 100.0">
+ ...
+ <property name="bar" type="float"/>
+</class>]]></programlisting>
+
+
+ <table frame="topbot" id="schemattributes-summary" revision="1">
+ <title>Summary</title>
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>属性(Attribute)</entry>
+ <entry>值(Values)</entry>
+ <entry>解释(Interpretation)</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>length</literal></entry>
+ <entry>数字</entry>
+ <entry>字段长度</entry>
+
+ </row>
+ <row>
+ <entry><literal>precision</literal></entry>
+ <entry>数字</entry>
+ <entry>精度(decimal precision)</entry>
+ </row>
+ <row>
+ <entry><literal>scale</literal></entry>
+ <entry>数字</entry>
+ <entry>小数点位数(decimal scale)</entry>
+ </row>
+ <row>
+ <entry><literal>not-null</literal></entry>
+ <entry><literal>true|false</literal></entry>
+ <entry>指明字段是否应该是非空的</entry>
+ </row>
+ <row>
+ <entry><literal>unique</literal></entry>
+ <entry><literal>true|false</literal></entry>
+ <entry>指明是否该字段具有惟一约束</entry>
+ </row>
+ <row>
+ <entry><literal>index</literal></entry>
+ <entry><literal>index_name</literal></entry>
+ <entry>指明一个(多字段)的索引(index)的名字</entry>
+ </row>
+ <row>
+ <entry><literal>unique-key</literal></entry>
+ <entry><literal>unique_key_name</literal></entry>
+ <entry>指明多字段惟一约束的名字(参见上面的说明)</entry>
+ </row>
+ <row>
+ <entry><literal>foreign-key</literal></entry>
+ <entry><literal>foreign_key_name</literal></entry>
+ <entry>
+ specifies the name of the foreign key constraint generated
+ for an association, for a <literal><one-to-one></literal>,
+ <literal><many-to-one></literal>, <literal><key></literal>,
+ or <literal><many-to-many></literal> mapping element. Note that
+ <literal>inverse="true"</literal> sides will not be considered
+ by <literal>SchemaExport</literal>.
+ 指明一个外键的名字,它是为关联生成的,或者<literal><one-to-one></literal>,<literal><many-to-one></literal>, <literal><key></literal>, 或者<literal><many-to-many></literal>映射元素。注意<literal>inverse="true"</literal>在<literal>SchemaExport</literal>时会被忽略。
+
+ </entry>
+ </row>
+ <row>
+ <entry><literal>sql-type</literal></entry>
+ <entry><literal>SQL 字段类型</literal></entry>
+ <entry>
+ 覆盖默认的字段类型(只能用于<literal><column></literal>属性)
+ </entry>
+ </row>
+ <row>
+ <entry><literal>default</literal></entry>
+ <entry>SQL表达式</entry>
+ <entry>
+ 为字段指定默认值
+ </entry>
+ </row>
+ <row>
+ <entry><literal>check</literal></entry>
+ <entry>SQL 表达式</entry>
+ <entry>
+ 对字段或表加入SQL约束检查
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <literal><comment></literal>元素可以让你在生成的schema中加入注释。
+ </para>
+
+ <programlisting><![CDATA[<class name="Customer" table="CurCust">
+ <comment>Current customers only</comment>
+ ...
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[<property name="balance">
+ <column name="bal">
+ <comment>Balance in USD</comment>
+ </column>
+</property>]]></programlisting>
+
+ <para>
+ 结果是在生成的DDL中包含<literal>comment on table</literal> 或者
+ <literal>comment on column</literal>语句(假若支持的话)。
+ </para>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-3" revision="2">
+ <title>运行该工具</title>
+
+ <para>
+ <literal>SchemaExport</literal>工具把DDL脚本写到标准输出,同时/或者执行DDL语句。
+ </para>
+
+ <para>
+ <literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaExport</literal> <emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title><literal>SchemaExport</literal>命令行选项</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>选项</entry>
+ <entry>说明</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>--quiet</literal></entry>
+ <entry>不要把脚本输出到stdout</entry>
+ </row>
+ <row>
+ <entry><literal>--drop</literal></entry>
+ <entry>只进行drop tables的步骤</entry>
+ </row>
+ <row>
+ <entry><literal>--create</literal></entry>
+ <entry>只创建表</entry>
+ </row>
+ <row>
+ <entry><literal>--text</literal></entry>
+ <entry>不执行在数据库中运行的步骤</entry>
+ </row>
+ <row>
+ <entry><literal>--output=my_schema.ddl</literal></entry>
+ <entry>把输出的ddl脚本输出到一个文件</entry>
+ </row>
+ <row>
+ <entry><literal>--naming=eg.MyNamingStrategy</literal></entry>
+ <entry>选择一个命名策略(<literal>NamingStrategy</literal>)</entry>
+ </row>
+ <row>
+ <entry><literal>--config=hibernate.cfg.xml</literal></entry>
+ <entry>从XML文件读入Hibernate配置</entry>
+ </row>
+ <row>
+ <entry><literal>--properties=hibernate.properties</literal></entry>
+ <entry>从文件读入数据库属性</entry>
+ </row>
+ <row>
+ <entry><literal>--format</literal></entry>
+ <entry>把脚本中的SQL语句对齐和美化</entry>
+ </row>
+ <row>
+ <entry><literal>--delimiter=;</literal></entry>
+ <entry>为脚本设置行结束符</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 你甚至可以在你的应用程序中嵌入<literal>SchemaExport</literal>工具:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaExport(cfg).create(false, true);]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-4">
+ <title>属性(Properties)</title>
+
+ <para>
+ 可以通过如下方式指定数据库属性:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>通过<literal>-D</literal><emphasis><property></emphasis>系统参数</para>
+ </listitem>
+ <listitem>
+ <para>在<literal>hibernate.properties</literal>文件中</para>
+ </listitem>
+ <listitem>
+ <para>位于一个其它名字的properties文件中,然后用 <literal>--properties</literal>参数指定</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 所需的参数包括:
+ </para>
+
+ <table frame="topbot">
+ <title>SchemaExport 连接属性</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>属性名</entry>
+ <entry>说明</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>hibernate.connection.driver_class</literal></entry>
+ <entry>jdbc driver class</entry>
+ </row>
+ <row>
+ <entry><literal>hibernate.connection.url</literal></entry>
+ <entry>jdbc url</entry>
+ </row>
+ <row>
+ <entry><literal>hibernate.connection.username</literal></entry>
+ <entry>database user</entry>
+ </row>
+ <row>
+ <entry><literal>hibernate.connection.password</literal></entry>
+ <entry>user password</entry>
+ </row>
+ <row>
+ <entry><literal>hibernate.dialect</literal></entry>
+ <entry>方言(dialect)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-5">
+ <title>使用Ant(Using Ant)</title>
+
+ <para>
+ 你可以在你的Ant build脚本中调用<literal>SchemaExport</literal>:
+ </para>
+
+ <programlisting><![CDATA[<target name="schemaexport">
+ <taskdef name="schemaexport"
+ classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
+ classpathref="class.path"/>
+
+ <schemaexport
+ properties="hibernate.properties"
+ quiet="no"
+ text="no"
+ drop="no"
+ delimiter=";"
+ output="schema-export.sql">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemaexport>
+</target>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-6" revision="2">
+ <title>对schema的增量更新(Incremental schema updates)</title>
+
+ <para>
+ <literal>SchemaUpdate</literal>工具对已存在的schema采用"增量"方式进行更新。注意<literal>SchemaUpdate</literal>严重依赖于JDBC metadata API,所以它并非对所有JDBC驱动都有效。
+ </para>
+
+ <para>
+ <literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaUpdate</literal> <emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title><literal>SchemaUpdate</literal>命令行选项</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>选项</entry>
+ <entry>说明</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>--quiet</literal></entry>
+ <entry>不要把脚本输出到stdout</entry>
+ </row>
+ <row>
+ <entry><literal>--text</literal></entry>
+ <entry>不把脚本输出到数据库</entry>
+ </row>
+ <row>
+ <entry><literal>--naming=eg.MyNamingStrategy</literal></entry>
+ <entry>选择一个命名策略 (<literal>NamingStrategy</literal>)</entry>
+ </row>
+ <row>
+ <entry><literal>--properties=hibernate.properties</literal></entry>
+ <entry>从指定文件读入数据库属性</entry>
+ </row>
+ <row>
+ <entry><literal>--config=hibernate.cfg.xml</literal></entry>
+ <entry>指定一个 <literal>.cfg.xml</literal>文件</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 你可以在你的应用程序中嵌入<literal>SchemaUpdate</literal>工具:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaUpdate(cfg).execute(false);]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-7">
+ <title>用Ant来增量更新schema(Using Ant for incremental schema updates)</title>
+
+ <para>
+ 你可以在Ant脚本中调用<literal>SchemaUpdate</literal>:
+ </para>
+
+ <programlisting><![CDATA[<target name="schemaupdate">
+ <taskdef name="schemaupdate"
+ classname="org.hibernate.tool.hbm2ddl.SchemaUpdateTask"
+ classpathref="class.path"/>
+
+ <schemaupdate
+ properties="hibernate.properties"
+ quiet="no">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemaupdate>
+</target>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-8" revision="1">
+ <title>Schema 校验</title>
+
+ <para>
+ <literal>SchemaValidator</literal>工具会比较数据库现状是否与映射文档“匹配”。注意,<literal>SchemaValidator</literal> 严重依赖于JDBC的metadata API,因此不是对所有的JDBC驱动都适用。这一工具在测试的时候特别有用。
+ </para>
+
+ <para>
+ <literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaValidator</literal> <emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title><literal>SchemaValidator</literal>命令行参数</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>选项</entry>
+ <entry>描述</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>--naming=eg.MyNamingStrategy</literal></entry>
+ <entry>选择一个命名策略 (<literal>NamingStrategy</literal>)</entry>
+ </row>
+ <row>
+ <entry><literal>--properties=hibernate.properties</literal></entry>
+ <entry>从文件中读取数据库属性</entry>
+ </row>
+ <row>
+ <entry><literal>--config=hibernate.cfg.xml</literal></entry>
+ <entry>指定一个<literal>.cfg.xml</literal>文件</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 你可以在你的应用程序中嵌入<literal>SchemaValidator</literal>:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaValidator(cfg).validate();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-9">
+ <title>使用Ant进行schema校验</title>
+
+ <para>
+ 你可以在Ant脚本中调用<literal>SchemaValidator</literal>:
+ </para>
+
+ <programlisting><![CDATA[<target name="schemavalidate">
+ <taskdef name="schemavalidator"
+ classname="org.hibernate.tool.hbm2ddl.SchemaValidatorTask"
+ classpathref="class.path"/>
+
+ <schemavalidator
+ properties="hibernate.properties">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemavalidator>
+</target>]]></programlisting>
+
+ </sect2>
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/transactions.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/transactions.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/transactions.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/transactions.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,870 @@
+<chapter id="transactions" revision="2">
+ <title>事务和并发</title>
+ <para>
+ Hibernate的事务和并发控制很容易掌握。Hibernate直接使用JDBC连接和JTA资源,不添加任何附加锁定
+ 行为。我们强烈推荐你花点时间了解JDBC编程,ANSI SQL查询语言和你使用
+ 的数据库系统的事务隔离规范。
+ </para>
+
+ <para>
+ Hibernate不锁定内存中的对象。你的应用程序会按照你的数据库事务的隔离级别规定的那样运作。幸亏有了<literal>Session</literal>,使得Hibernate通过标识符查找,和实体查询(不是返回标量值的报表查询)提供了可重复的读取(Repeatable reads)功能,<literal>Session</literal>同时也是事务范围内的缓存(cache)。
+ </para>
+
+ <para>
+ 除了对自动乐观并发控制提供版本管理,针对行级悲观锁定,Hibernate也提供了辅助的(较小的)API,它使用了
+ <literal>SELECT FOR UPDATE</literal>的SQL语法。本章后面会讨论乐观并发控制和这个API。
+ </para>
+ <para>
+ 我们从<literal>Configuration</literal>层、<literal>SessionFactory</literal>层, 和
+ <literal>Session</literal>层开始讨论Hibernate的并行控制、数据库事务和应用
+ 程序的长事务。
+ </para>
+ <sect1 id="transactions-basics" revision="1">
+ <title>Session和事务范围(transaction scope)</title>
+ <para>
+ <literal>SessionFactory</literal>对象的创建代价很昂贵,它是线程安全的对象,它为所有的应用程序线程所共享。它只创建一次,通常是在应用程序启动的时候,由一个<literal>Configuraion</literal>的实例来创建。
+ </para>
+ <para>
+ <literal>Session</literal>对象的创建代价比较小,是非线程安全的,对于单个请求,单个会话、单个的
+ 工作单元而言,它只被使用一次,然后就丢弃。只有在需要的时候,一个<literal>Session</literal>对象
+ 才会获取一个JDBC的<literal>Connection</literal>(或一个<literal>Datasource</literal>)
+ 对象,因此假若不使用的时候它不消费任何资源。
+ </para>
+ <para>
+ 此外我们还要考虑数据库事务。数据库事务应该尽可能的短,降低数据库中的锁争用。
+ 数据库长事务会阻止你的应用程序扩展到高的并发负载。因此,假若在用户思考期间让数据库事务开着,直到整个工作单元完成才关闭这个事务,这绝不是一个好的设计。
+ </para>
+ <para>
+ 一个操作单元(Unit of work)的范围是多大?单个的Hibernate <literal>Session</literal>能跨越多个
+ 数据库事务吗?还是一个<literal>Session</literal>的作用范围对应一个数据库事务的范围?应该何时打开
+ <literal>Session</literal>,何时关闭<literal>Session</literal>?,你又如何划分数据库事务的边界呢?
+ </para>
+ <sect2 id="transactions-basics-uow" revision="1">
+ <title>操作单元(Unit of work)</title>
+ <para>
+ 首先,别用<emphasis>session-per-operation</emphasis>这种反模式了,也就是说,在单个线程中,
+ 不要因为一次简单的数据库调用,就打开和关闭一次<literal>Session</literal>!数据库事务也是如此。
+ 应用程序中的数据库调用是按照计划好的次序,分组为原子的操作单元。(注意,这也意味着,应用程
+ 序中,在单个的SQL语句发送之后,自动事务提交(auto-commit)模式失效了。这种模式专门为SQL控制台操作设计的。
+ Hibernate禁止立即自动事务提交模式,或者期望应用服务器禁止立即自动事务提交模式。)数据库事务绝不是可有可无的,任何与数据库之间的通讯都必须在某个事务中进行,不管你是在读还是在写数据。对读数据而言,应该避免auto-commit行为,因为很多小的事务比一个清晰定义的工作单元性能差。后者也更容易维护和扩展。
+ </para>
+ <para>
+ 在多用户的client/server应用程序中,最常用的模式是 <emphasis>每个请求一个会话(session-per-request)</emphasis>。
+ 在这种模式下,来自客户端的请求被发送到服务器端(即Hibernate持久化层运行的地方),一
+ 个新的Hibernate <literal>Session</literal>被打开,并且执行这个操作单元中所有的数据库操作。
+ 一旦操作完成(同时对客户端的响应也准备就绪),session被同步,然后关闭。你也可以使用单
+ 个数据库事务来处理客户端请求,在你打开<literal>Session</literal>之后启动事务,在你关闭
+ <literal>Session</literal>之前提交事务。会话和请求之间的关系是一对一的关系,这种模式对
+ 于大多数应用程序来说是很棒的。
+ </para>
+ <para>
+ 实现才是真正的挑战。Hibernate内置了对"当前session(current session)" 的管理,用于简化此模式。你要做的一切就是在服务器端要处理请求的时候,开启事务,在响应发送给客户之前结束事务。你可以用任何方式来完成这一操作,通常的方案有<literal>ServletFilter</literal>,在service方法中进行pointcut的AOP拦截器,或者proxy/interception容器。EJB容器是实现横切诸如EJB session bean上的事务分界,用CMT对事务进行声明等方面的标准手段。假若你决定使用编程式的事务分界,请参考本章后面讲到的Hibernate <literal>Transaction</literal> API,这对易用性和代码可移植性都有好处。
+ </para>
+
+ <para>
+ 在任何时间,任何地方,你的应用代码可以通过简单的调用<literal>sessionFactory.getCurrentSession()</literal>来访问"当前session",用于处理请求。你总是会得到当前数据库事务范围内的<literal>Session</literal>。在使用本地资源或JTA环境时,必须配置它,请参见<xref linkend="architecture-current-session"/>。
+ </para>
+
+ <para>
+ 有时,将<literal>Session</literal>和数据库事务的边界延伸到"展示层被渲染后"会带来便利。有些serlvet应用程序在对请求进行处理后,有个单独的渲染期,这种延伸对这种程序特别有用。假若你实现你自己的拦截器,把事务边界延伸到展示层渲染结束后非常容易。然而,假若你依赖有容器管理事务的EJB,这就不太容易了,因为事务会在EJB方法返回后结束,而那是在任何展示层渲染开始之前。请访问Hibernate网站和论坛,你可以找到<emphasis>Open Session in View</emphasis>这一模式的提示和示例。
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-basics-apptx" revision="1">
+ <title>长对话</title>
+ <para>
+ session-per-request模式不仅仅是一个可以用来设计操作单元的有用概念。很多业务处理都需
+ 要一系列完整的与用户之间的交互,而这些用户是指对数据库有交叉访问的用户。在基于web的应用和企业
+ 应用中,跨用户交互的数据库事务是无法接受的。考虑下面的例子:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ 在界面的第一屏,打开对话框,用户所看到的数据是被一个特定的 <literal>Session</literal> 和数据
+ 库事务载入(load)的。用户可以随意修改对话框中的数据对象。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 5分钟后,用户点击“保存”,期望所做出的修改被持久化;同时他也期望自己是唯一修改这个信息的人,不会出现
+ 修改冲突。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 从用户的角度来看,我们把这个操作单元称为长时间运行的<emphasis>对话</emphasis>(conversation),或者(or <emphasis>应用事务</emphasis>,application transaction)。
+ 在你的应用程序中,可以有很多种方法来实现它。
+ </para>
+ <para>
+ 头一个幼稚的做法是,在用户思考的过程中,保持<literal>Session</literal>和数据库事务是打开的,
+ 保持数据库锁定,以阻止并发修改,从而保证数据库事务隔离级别和原子操作。这种方式当然是一个反模式,
+ 因为锁争用会导致应用程序无法扩展并发用户的数目。
+ </para>
+ <para>
+ 很明显,我们必须使用多个数据库事务来实现这个对话。在这个例子中,维护业务处理的
+ 事务隔离变成了应用程序层的部分责任。一个对话通常跨越多个数据库事务。如果仅仅只有一
+ 个数据库事务(最后的那个事务)保存更新过的数据,而所有其他事务只是单纯的读取数据(例如在一
+ 个跨越多个请求/响应周期的向导风格的对话框中),那么应用程序事务将保证其原子性。这种方式比听
+ 起来还要容易实现,特别是当你使用了Hibernate的下述特性的时候:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>自动版本化</emphasis> - Hibernate能够自动进行乐观并发控制 ,如果在用户思考
+ 的过程中发生并发修改,Hibernate能够自动检测到。一般我们只在对话结束时才检查。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>脱管对象</emphasis>(Detached Objects)- 如果你决定采用前面已经讨论过的
+ <emphasis>session-per-request</emphasis>模式,所有载入的实例在用户思考的过程
+ 中都处于与Session脱离的状态。Hibernate允许你把与Session脱离的对象重新关联到Session
+ 上,并且对修改进行持久化,这种模式被称为
+ <emphasis>session-per-request-with-detached-objects</emphasis>。自动版本化被用来隔离并发修改。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Extended (or Long) Session</emphasis> - Hibernate 的<literal>Session</literal>
+ 可以在数据库事务提交之后和底层的JDBC连接断开,当一个新的客户端请求到来的时候,它又重新连接上底层的
+ JDBC连接。这种模式被称之为<emphasis>session-per-conversation</emphasis>,这种情况可
+ 能会造成不必要的Session和JDBC连接的重新关联。自动版本化被用来隔离并发修改, <literal>Session</literal>通常不允许自动flush,而是明确flush。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <emphasis>session-per-request-with-detached-objects</emphasis> 和
+ <emphasis>session-per-conversation</emphasis> 各有优缺点,我们在本章后面乐观并发
+ 控制那部分再进行讨论。
+ </para>
+ </sect2>
+
+ <sect2 id="transactions-basics-identity">
+ <title>关注对象标识(Considering object identity)</title>
+ <para>
+ 应用程序可能在两个不同的<literal>Session</literal>中并发访问同一持久化状态,但是,
+ 一个持久化类的实例无法在两个 <literal>Session</literal>中共享。因此有两种不同的标识语义:
+ </para>
+ <para>
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>数据库标识</term>
+ <listitem>
+ <para>
+ <literal>foo.getId().equals( bar.getId() )</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>JVM 标识</term>
+ <listitem>
+ <para>
+ <literal>foo==bar</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ 对于那些关联到 <emphasis>特定</emphasis><literal>Session</literal>
+ (也就是在单个<literal>Session</literal>的范围内)上的对象来说,这
+ 两种标识的语义是等价的,与数据库标识对应的JVM标识是由Hibernate来保
+ 证的。不过,当应用程序在两个不同的session中并发访问具有同一持久化标
+ 识的业务对象实例的时候,这个业务对象的两个实例事实上是不相同的(从
+ JVM识别来看)。这种冲突可以通过在同步和提交的时候使用自动版本化和乐
+ 观锁定方法来解决。
+ </para>
+ <para>
+ 这种方式把关于并发的头疼问题留给了Hibernate和数据库;由于在单个线程内,操作单元中的对象识别不
+ 需要代价昂贵的锁定或其他意义上的同步,因此它同时可以提供最好的可伸缩性。只要在单个线程只持有一个
+ <literal>Session</literal>,应用程序就不需要同步任何业务对象。在<literal>Session</literal>
+ 的范围内,应用程序可以放心的使用<literal>==</literal>进行对象比较。
+ </para>
+ <para>
+ 不过,应用程序在<literal>Session</literal>的外面使用<literal>==</literal>进行对象比较可能会
+ 导致无法预期的结果。在一些无法预料的场合,例如,如果你把两个脱管对象实例放进同一个
+ <literal>Set</literal>的时候,就可能发生。这两个对象实例可能有同一个数据库标识(也就是说,
+ 他们代表了表的同一行数据),从JVM标识的定义上来说,对脱管的对象而言,Hibernate无法保证他们
+ 的的JVM标识一致。开发人员必须覆盖持久化类的<literal>equals()</literal>方法和
+ <literal>hashCode()</literal> 方法,从而实现自定义的对象相等语义。警告:不要使用数据库标识
+ 来实现对象相等,应该使用业务键值,由唯一的,通常不变的属性组成。当一个瞬时对象被持久化的时
+ 候,它的数据库标识会发生改变。如果一个瞬时对象(通常也包括脱管对象实例)被放入一
+ 个<literal>Set</literal>,改变它的hashcode会导致与这个<literal>Set</literal>的关系中断。虽
+ 然业务键值的属性不象数据库主键那样稳定不变,但是你只需要保证在同一个<literal>Set</literal>
+ 中的对象属性的稳定性就足够了。请到Hibernate网站去寻求这个问题更多的详细的讨论。请注意,这不是一
+ 个有关Hibernate的问题,而仅仅是一个关于Java对象标识和判等行为如何实现的问题。
+ </para>
+ </para>
+ </sect2>
+
+ <sect2 id="transactions-basics-issues">
+ <title>常见问题</title>
+ <para>
+ 决不要使用反模式<emphasis>session-per-user-session</emphasis>或者<emphasis>
+ session-per-application</emphasis>(当然,这个规定几乎没有例外)。请注意,
+ 下述一些问题可能也会出现在我们推荐的模式中,在你作出某个设计决定之前,请务必理解该模式的应用前提。
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>Session</literal> 对象是非线程安全的。如果一个<literal>Session</literal>
+ 实例允许共享的话,那些支持并发运行的东东,例如HTTP request,session beans,或者是
+ Swing workers,将会导致出现资源争用(race condition)。如果在<literal>HttpSession</literal>中有
+ Hibernate 的<literal>Session</literal>的话(稍后讨论),你应该考虑同步访问你的Http session。
+ 否则,只要用户足够快的点击浏览器的“刷新”,就会导致两个并发运行线程使用同一个
+ <literal>Session</literal>。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 一个由Hibernate抛出的异常意味着你必须立即回滚数据库事务,并立即关闭<literal>Session</literal>
+ (稍后会展开讨论)。如果你的<literal>Session</literal>绑定到一个应用程序上,你必
+ 须停止该应用程序。回滚数据库事务并不会把你的业务对象退回到事务启动时候的状态。这
+ 意味着数据库状态和业务对象状态不同步。通常情况下,这不是什么问题,因为异常是不可
+ 恢复的,你必须在回滚之后重新开始执行。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session</literal> 缓存了处于持久化状态的每个对象(Hibernate会监视和检查脏数据)。
+ 这意味着,如果你让<literal>Session</literal>打开很长一段时间,或是仅仅载入了过多的数据,
+ <literal>Session</literal>占用的内存会一直增长,直到抛出OutOfMemoryException异常。这个
+ 问题的一个解决方法是调用<literal>clear()</literal> 和<literal>evict()</literal>来管理
+ <literal>Session</literal>的缓存,但是如果你需要大批量数据操作的话,最好考虑
+ 使用存储过程。在<xref linkend="batch"/>中有一些解决方案。在用户会话期间一直保持
+ <literal>Session</literal>打开也意味着出现脏数据的可能性很高。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="transactions-demarcation">
+ <title>数据库事务声明</title>
+ <para>
+ 数据库(或者系统)事务的声明总是必须的。在数据库事务之外,就无法和数据库通讯(这可能会让那些习惯于
+ 自动提交事务模式的开发人员感到迷惑)。永远使用清晰的事务声明,即使只读操作也是如此。进行
+ 显式的事务声明并不总是需要的,这取决于你的事务隔离级别和数据库的能力,但不管怎么说,声明事务总归有益无害。当然,一个单独的数据库事务总是比很多琐碎的事务性能更好,即时对读数据而言也是一样。
+ </para>
+ <para>
+ 一个Hibernate应用程序可以运行在非托管环境中(也就是独立运行的应用程序,简单Web应用程序,
+ 或者Swing图形桌面应用程序),也可以运行在托管的J2EE环境中。在一个非托管环境中,Hibernate
+ 通常自己负责管理数据库连接池。应用程序开发人员必须手工设置事务声明,换句话说,就是手工启
+ 动,提交,或者回滚数据库事务。一个托管的环境通常提供了容器管理事务(CMT),例如事务装配通过可声
+ 明的方式定义在EJB session beans的部署描述符中。可编程式事务声明不再需要,即使是
+ <literal>Session</literal> 的同步也可以自动完成。
+ </para>
+ <para>
+ 让持久层具备可移植性是人们的理想,这种移植发生在非托管的本地资源环境,与依赖JTA但是使用BMT而非CMT的系统之间。在两种情况下你都可以使用编程式的事务管理。Hibernate提供了一套称为<literal>Transaction</literal>的封装API,
+ 用来把你的部署环境中的本地事务管理系统转换到Hibernate事务上。这个API是可选的,但是我们强烈
+ 推荐你使用,除非你用CMT session bean。
+ </para>
+ <para>
+ 通常情况下,结束 <literal>Session</literal> 包含了四个不同的阶段:
+ </para>
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 同步session(flush,刷出到磁盘)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 提交事务
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 关闭session
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 处理异常
+ </para>
+ </listitem>
+ </itemizedlist>
+
+
+ <para>
+ session的同步(flush,刷出)前面已经讨论过了,我们现在进一步考察在托管和非托管环境下的事务声明和异常处理。
+ </para>
+
+ <sect2 id="transactions-demarcation-nonmanaged" revision="2">
+ <title>非托管环境</title>
+ <para>
+ 如果Hibernat持久层运行在一个非托管环境中,数据库连接通常由Hibernate的简单(即非DataSource)连接池机制
+ 来处理。session/transaction处理方式如下所示:
+ </para>
+ <programlisting><![CDATA[//Non-managed environment idiom
+Session sess = factory.openSession();
+Transaction tx = null;
+try {
+ tx = sess.beginTransaction();
+
+ // do some work
+ ...
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ if (tx != null) tx.rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+ <para>
+ 你不需要显式<literal>flush()</literal> <literal>Session</literal> -
+ 对<literal>commit()</literal>的调用会自动触发session的同步(取决于session的<xref linkend="objectstate-flushing">FlushMode</xref>)。调用 <literal>close()</literal> 标志session的结束。<literal>close()</literal>方法重要的暗示是,<literal>session</literal>释放了JDBC连接。这段Java代码在非托管环境下和JTA环境下都可以运行。
+ </para>
+
+ <para>
+ 更加灵活的方案是Hibernate内置的"current session"上下文管理,前文已经讲过:
+ </para>
+
+ <programlisting><![CDATA[// Non-managed environment idiom with getCurrentSession()
+try {
+ factory.getCurrentSession().beginTransaction();
+
+ // do some work
+ ...
+
+ factory.getCurrentSession().getTransaction().commit();
+}
+catch (RuntimeException e) {
+ factory.getCurrentSession().getTransaction().rollback();
+ throw e; // or display error message
+}]]></programlisting>
+
+ <para>
+ 你很可能从未在一个通常的应用程序的业务代码中见过这样的代码片断:致命的(系统)异常应该总是
+ 在应用程序“顶层”被捕获。换句话说,执行Hibernate调用的代码(在持久层)和处理
+ <literal>RuntimeException</literal>异常的代码(通常只能清理和退出应用程序)应该在不同
+ 的应用程序逻辑层。Hibernate的当前上下文管理可以极大地简化这一设计,你所有的一切就是<literal>SessionFactory</literal>。 异常处理将在本章稍后进行讨论。
+ </para>
+
+ <para>
+ 请注意,你应该选择 <literal>org.hibernate.transaction.JDBCTransactionFactory</literal>
+ (这是默认选项),对第二个例子来说,<literal>hibernate.current_session_context_class</literal>应该是<literal>"thread"</literal>
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-jta" revision="3">
+ <title>使用JTA</title>
+ <para>
+ 如果你的持久层运行在一个应用服务器中(例如,在EJB session beans的后面),Hibernate获取
+ 的每个数据源连接将自动成为全局JTA事务的一部分。
+ 你可以安装一个独立的JTA实现,使用它而不使用EJB。Hibernate提供了两种策略进行JTA集成。
+ </para>
+
+ <para>
+ 如果你使用bean管理事务(BMT),可以通过使用Hibernate的 <literal>Transaction</literal> API来告诉
+ 应用服务器启动和结束BMT事务。因此,事务管理代码和在非托管环境下是一样的。
+ </para>
+
+ <programlisting><![CDATA[// BMT idiom
+Session sess = factory.openSession();
+Transaction tx = null;
+try {
+ tx = sess.beginTransaction();
+
+ // do some work
+ ...
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ if (tx != null) tx.rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>
+ 如果你希望使用与事务绑定的<literal>Session</literal>,也就是使用<literal>getCurrentSession()</literal>来简化上下文管理,你将不得不直接使用JTA <literal>UserTransaction</literal>API。
+ </para>
+
+ <programlisting><![CDATA[// BMT idiom with getCurrentSession()
+try {
+ UserTransaction tx = (UserTransaction)new InitialContext()
+ .lookup("java:comp/UserTransaction");
+
+ tx.begin();
+
+ // Do some work on Session bound to transaction
+ factory.getCurrentSession().load(...);
+ factory.getCurrentSession().persist(...);
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ tx.rollback();
+ throw e; // or display error message
+}]]></programlisting>
+
+
+ <para>
+ 在CMT方式下,事务声明是在session bean的部署描述符中,而不需要编程。
+ 因此,代码被简化为:
+ </para>
+
+ <programlisting><![CDATA[// CMT idiom
+Session sess = factory.getCurrentSession();
+
+// do some work
+...
+
+]]></programlisting>
+
+ <para>
+ 在CMT/EJB中甚至会自动rollback,因为假若有未捕获的<literal>RuntimeException</literal>从session bean方法中抛出,这就会通知容器把全局事务回滚。<emphasis>这就意味着,在BMT或者CMT中,你根本就不需要使用Hibernate <literal>Transaction</literal> API ,你自动得到了绑定到事务的“当前”Session。
+ </emphasis>
+ </para>
+
+ <para>
+ 注意,当你配置Hibernate的transaction factory的时候,在直接使用JTA的时候(BMT),你应该选择<literal>org.hibernate.transaction.JTATransactionFactory</literal>,在CMT session bean中选择<literal>org.hibernate.transaction.CMTTransactionFactory</literal>。记得也要设置<literal>hibernate.transaction.manager_lookup_class</literal>。还有,确认你的<literal>hibernate.current_session_context_class</literal>未设置(为了向下兼容),或者设置为<literal>"jta"</literal>。
+ </para>
+
+ <para>
+ <literal>getCurrentSession()</literal>在JTA环境中有一个弊端。对<literal>after_statement</literal>连接释放方式有一个警告,这是被默认使用的。因为JTA规范的一个很愚蠢的限制,Hibernate不可能自动清理任何未关闭的<literal>ScrollableResults</literal> 或者<literal>Iterator</literal>,它们是由<literal>scroll()</literal>或<literal>iterate()</literal>产生的。你<emphasis>must</emphasis>通过在<literal>finally</literal>块中,显式调用<literal>ScrollableResults.close()</literal>或者<literal>Hibernate.close(Iterator)</literal>方法来释放底层数据库游标。(当然,大部分程序完全可以很容易的避免在JTA或CMT代码中出现<literal>scroll()</literal>或<literal>iterate()</literal>。)
+ </para>
+
+
+ </sect2>
+
+
+
+ <sect2 id="transactions-demarcation-exceptions">
+ <title>异常处理</title>
+ <para>
+ 如果 <literal>Session</literal> 抛出异常 (包括任何<literal>SQLException</literal>),
+ 你应该立即回滚数据库事务,调用 <literal>Session.close()</literal> ,丢弃该
+ <literal>Session</literal>实例。<literal>Session</literal>的某些方法可能会导致session
+ 处于不一致的状态。所有由Hibernate抛出的异常都视为不可以恢复的。确保在
+ <literal>finally</literal> 代码块中调用<literal>close()</literal>方法,以关闭掉
+ <literal>Session</literal>。
+ </para>
+ <para>
+ <literal>HibernateException</literal>是一个非检查期异常(这不同于Hibernate老的版本),
+ 它封装了Hibernate持久层可能出现的大多数错误。我们的观点是,不应该强迫应用程序开发人员
+ 在底层捕获无法恢复的异常。在大多数软件系统中,非检查期异常和致命异常都是在相应方法调用
+ 的堆栈的顶层被处理的(也就是说,在软件上面的逻辑层),并且提供一个错误信息给应用软件的用户
+ (或者采取其他某些相应的操作)。请注意,Hibernate也有可能抛出其他并不属于
+ <literal>HibernateException</literal>的非检查期异常。这些异常同样也是无法恢复的,应该
+ 采取某些相应的操作去处理。
+ </para>
+ <para>
+ 在和数据库进行交互时,Hibernate把捕获的<literal>SQLException</literal>封装为Hibernate的
+ <literal>JDBCException</literal>。事实上,Hibernate尝试把异常转换为更有实际含义
+ 的<literal>JDBCException</literal>异常的子类。底层的<literal>SQLException</literal>可以
+ 通过<literal>JDBCException.getCause()</literal>来得到。Hibernate通过使用关联到
+ <literal>SessionFactory</literal>上的<literal>SQLExceptionConverter</literal>来
+ 把<literal>SQLException</literal>转换为一个对应的<literal>JDBCException</literal>
+ 异常的子类。默认情况下,<literal>SQLExceptionConverter</literal>可以通过配置dialect
+ 选项指定;此外,也可以使用用户自定义的实现类(参考javadocs
+ <literal>SQLExceptionConverterFactory</literal>类来了解详情)。标准的
+ <literal>JDBCException</literal>子类型是:
+ </para>
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>JDBCConnectionException</literal> - 指明底层的JDBC通讯出现错误
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>SQLGrammarException</literal> - 指明发送的SQL语句的语法或者格式错误
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ConstraintViolationException</literal> - 指明某种类型的约束违例错误
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockAcquisitionException</literal> - 指明了在执行请求操作时,获取
+ 所需的锁级别时出现的错误。
+
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>GenericJDBCException</literal> - 不属于任何其他种类的原生异常
+ </para>
+ </listitem>
+ </itemizedlist>
+
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-timeout">
+ <title>事务超时</title>
+
+ <para>
+ EJB这样的托管环境有一项极为重要的特性,而它从未在非托管环境中提供过,那就是事务超时。在出现错误的事务行为的时候,超时可以确保不会无限挂起资源、对用户没有交代。在托管(JTA)环境之外,Hibernate无法完全提供这一功能。但是,Hiberante至少可以控制数据访问,确保数据库级别的死锁,和返回巨大结果集的查询被限定在一个规定的时间内。在托管环境中,Hibernate会把事务超时转交给JTA。这一功能通过Hibernate <literal>Transaction</literal>对象进行抽象。
+ </para>
+
+ <programlisting><![CDATA[
+Session sess = factory.openSession();
+try {
+ //set transaction timeout to 3 seconds
+ sess.getTransaction().setTimeout(3);
+ sess.getTransaction().begin();
+
+ // do some work
+ ...
+
+ sess.getTransaction().commit()
+}
+catch (RuntimeException e) {
+ sess.getTransaction().rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>
+ 注意<literal>setTimeout()</literal>不应该在CMT bean中调用,此时事务超时值应该是被声明式定义的。
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="transactions-optimistic">
+ <title>乐观并发控制(Optimistic concurrency control)</title>
+ <para>
+ 唯一能够同时保持高并发和高可伸缩性的方法就是使用带版本化的乐观并发控制。版本检查使用版本号、
+ 或者时间戳来检测更新冲突(并且防止更新丢失)。Hibernate为使用乐观并发控制的代码提供了三种可
+ 能的方法,应用程序在编写这些代码时,可以采用它们。我们已经在前面应用程序对话那部分展示了
+ 乐观并发控制的应用场景,此外,在单个数据库事务范围内,版本检查也提供了防止更新丢失的好处。
+ </para>
+
+ <sect2 id="transactions-optimistic-manual">
+ <title>应用程序级别的版本检查(Application version checking)</title>
+ <para>
+ 未能充分利用Hibernate功能的实现代码中,每次和数据库交互都需要一个新的
+ <literal>Session</literal>,而且开发人员必须在显示数据之前从数据库中重
+ 新载入所有的持久化对象实例。这种方式迫使应用程序自己实现版本检查来确保
+ 对话事务的隔离,从数据访问的角度来说是最低效的。这种使用方式和
+ entity EJB最相似。
+ </para>
+
+ <programlisting><![CDATA[// foo is an instance loaded by a previous Session
+session = factory.openSession();
+Transaction t = session.beginTransaction();
+
+int oldVersion = foo.getVersion();
+session.load( foo, foo.getKey() ); // load the current state
+if ( oldVersion != foo.getVersion() ) throw new StaleObjectStateException();
+foo.setProperty("bar");
+
+t.commit();
+session.close();]]></programlisting>
+
+ <para>
+ <literal>version</literal> 属性使用 <literal><version></literal>来映射,如果对象
+ 是脏数据,在同步的时候,Hibernate会自动增加版本号。
+ </para>
+
+ <para>
+ 当然,如果你的应用是在一个低数据并发环境下,并不需要版本检查的话,你照样可以使用
+ 这种方式,只不过跳过版本检查就是了。在这种情况下,<emphasis>最晚提交生效</emphasis>
+ (<emphasis>last commit wins</emphasis>)就是你的长对话的默认处理策略。
+ 请记住这种策略可能会让应用软件的用户感到困惑,因为他们有可能会碰上更新丢失掉却没
+ 有出错信息,或者需要合并更改冲突的情况。
+ </para>
+
+ <para>
+ 很明显,手工进行版本检查只适合于某些软件规模非常小的应用场景,对于大多数软件应用场景
+ 来说并不现实。通常情况下,不仅是单个对象实例需要进行版本检查,整个被修改过的关
+ 联对象图也都需要进行版本检查。作为标准设计范例,Hibernate使用扩展周期的
+ <literal>Session</literal>的方式,或者脱管对象实例的方式来提供自动版本检查。
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-longsession">
+ <title>扩展周期的session和自动版本化</title>
+ <para>
+ 单个 <literal>Session</literal>实例和它所关联的所有持久化对象实例都被用于整个
+ 对话,这被称为<emphasis>session-per-conversation</emphasis>。Hibernate在同步的时候进行对象实例的版本检查,如果检测到并发修
+ 改则抛出异常。由开发人员来决定是否需要捕获和处理这个异常(通常的抉择是给用户
+ 提供一个合并更改,或者在无脏数据情况下重新进行业务对话的机会)。
+ </para>
+ <para>
+ 在等待用户交互的时候, <literal>Session</literal> 断开底层的JDBC连接。这种方式
+ 以数据库访问的角度来说是最高效的方式。应用程序不需要关心版本检查或脱管对象实例
+ 的重新关联,在每个数据库事务中,应用程序也不需要载入读取对象实例。
+ </para>
+
+ <programlisting><![CDATA[// foo is an instance loaded earlier by the old session
+Transaction t = session.beginTransaction(); // Obtain a new JDBC connection, start transaction
+
+foo.setProperty("bar");
+
+session.flush(); // Only for last transaction in conversation
+t.commit(); // Also return JDBC connection
+session.close(); // Only for last transaction in conversation]]></programlisting>
+
+ <para>
+ <literal>foo</literal>对象知道它是在哪个<literal>Session</literal>中被装入的。在一个旧session中开启一个新的数据库事务,会导致session获取一个新的连接,并恢复session的功能。将数据库事务提交,使得session从JDBC连接断开,并将此连接交还给连接池。在重新连接之后,要强制对你没有更新的数据进行一次版本检查,你可以对所有可能被其他事务修改过的对象,使用参数<literal>LockMode.READ</literal>来调用<literal>Session.lock()</literal>。你不用lock任何你<emphasis>正在</emphasis>更新的数据。一般你会在扩展的<literal>Session</literal>上设置<literal>FlushMode.MANUAL</literal>,因此只有最后一个数据库事务循环才会真正的吧整个对话中发生的修改发送到数据库。因此,只有这最后一次数据库事务才会包含<literal>flush()</literal>操作,然后在整个对话结束后,还要<litera!
l>close()</literal>这个session。
+ </para>
+
+ <para>
+ 如果在用户思考的过程中,<literal>Session</literal>因为太大了而不能保存,那么这种模式是有
+ 问题的。举例来说,一个<literal>HttpSession</literal>应该尽可能的小。由于
+ <literal>Session</literal>是一级缓存,并且保持了所有被载入过的对象,因此
+ 我们只应该在那些少量的request/response情况下使用这种策略。你应该只把一个<literal>Session</literal>用于单个对话,因为它很快就会出现脏数据。
+ </para>
+
+ <para>
+ (注意,早期的Hibernate版本需要明确的对<literal>Session</literal>进行disconnec和reconnect。这些方法现在已经过时了,打开事务和关闭事务会起到同样的效果。)
+ </para>
+
+
+ <para>
+ 此外,也请注意,你应该让与数据库连接断开的<literal>Session</literal>对持久层保持
+ 关闭状态。换句话说,在三层环境中,使用有状态的EJB session bean来持有<literal>Session</literal>,
+ 而不要把它传递到web层(甚至把它序列化到一个单独的层),保存在<literal>HttpSession</literal>中。
+ </para>
+
+ <para>
+ 扩展session模式,或者被称为<emphasis>每次对话一个session(session-per-conversation)</emphasis>, 在与自动管理当前session上下文联用的时候会更困难。你需要提供你自己的<literal>CurrentSessionContext</literal>实现。请参阅Hibernate Wiki以获得示例。
+ </para>
+
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-detached">
+ <title>脱管对象(deatched object)和自动版本化</title>
+
+ <para>
+ 这种方式下,与持久化存储的每次交互都发生在一个新的<literal>Session</literal>中。
+ 然而,同一持久化对象实例可以在多次与数据库的交互中重用。应用程序操纵脱管对象实例
+ 的状态,这个脱管对象实例最初是在另一个<literal>Session</literal> 中载入的,然后
+ 调用 <literal>Session.update()</literal>,<literal>Session.saveOrUpdate()</literal>, 或者
+ <literal>Session.merge()</literal> 来重新关联该对象实例。
+ </para>
+
+ <programlisting><![CDATA[// foo is an instance loaded by a previous Session
+foo.setProperty("bar");
+session = factory.openSession();
+Transaction t = session.beginTransaction();
+session.saveOrUpdate(foo); // Use merge() if "foo" might have been loaded already
+t.commit();
+session.close();]]></programlisting>
+
+ <para>
+ Hibernate会再一次在同步的时候检查对象实例的版本,如果发生更新冲突,就抛出异常。
+ </para>
+
+ <para>
+ 如果你确信对象没有被修改过,你也可以调用<literal>lock()</literal> 来设置
+ <literal>LockMode.READ</literal>(绕过所有的缓存,执行版本检查),从而取
+ 代 <literal>update()</literal>操作。
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-customizing">
+ <title>定制自动版本化行为</title>
+ <para>
+ 对于特定的属性和集合,通过为它们设置映射属性<literal>optimistic-lock</literal>的值
+ 为<literal>false</literal>,来禁止Hibernate的版本自动增加。这样的话,如果该属性
+ 脏数据,Hibernate将不再增加版本号。
+ </para>
+
+ <para>
+ 遗留系统的数据库Schema通常是静态的,不可修改的。或者,其他应用程序也可能访问同一数据
+ 库,根本无法得知如何处理版本号,甚至时间戳。在以上的所有场景中,实现版本化不能依靠
+ 数据库表的某个特定列。在<literal><class></literal>的映射中设置
+ <literal>optimistic-lock="all"</literal>可以在没有版本或者时间戳属性映射的情况下实现
+ 版本检查,此时Hibernate将比较一行记录的每个字段的状态。请注意,只有当Hibernate能够比
+ 较新旧状态的情况下,这种方式才能生效,也就是说,
+ 你必须使用单个长生命周期<literal>Session</literal>模式,而不能使用
+ session-per-request-with-detached-objects模式。
+ </para>
+
+ <para>
+ 有些情况下,只要更改不发生交错,并发修改也是允许的。当你在<literal><class></literal>
+ 的映射中设置<literal>optimistic-lock="dirty"</literal>,Hibernate在同步的时候将只比较有脏
+ 数据的字段。
+ </para>
+
+ <para>
+ 在以上所有场景中,不管是专门设置一个版本/时间戳列,还是进行全部字段/脏数据字段比较,
+ Hibernate都会针对每个实体对象发送一条<literal>UPDATE</literal>(带有相应的
+ <literal>WHERE</literal>语句 )的SQL语句来执行版本检查和数据更新。如果你对关联实体
+ 设置级联关系使用传播性持久化(transitive persistence),那么Hibernate可能会执行不必
+ 要的update语句。这通常不是个问题,但是数据库里面对<emphasis>on update</emphasis>点火
+ 的触发器可能在脱管对象没有任何更改的情况下被触发。因此,你可以在
+ <literal><class></literal>的映射中,通过设置<literal>select-before-update="true"</literal>
+ 来定制这一行为,强制Hibernate <literal>SELECT</literal>这个对象实例,从而保证,
+ 在更新记录之前,对象的确是被修改过。
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="transactions-locking">
+ <title>悲观锁定(Pessimistic Locking)</title>
+ <para>
+ 用户其实并不需要花很多精力去担心锁定策略的问题。通常情况下,只要为JDBC连接指定一下隔
+ 离级别,然后让数据库去搞定一切就够了。然而,高级用户有时候希望进行一个排它的悲观锁定,
+ 或者在一个新的事务启动的时候,重新进行锁定。
+ </para>
+
+ <para>
+ Hibernate总是使用数据库的锁定机制,从不在内存中锁定对象!
+ </para>
+
+ <para>
+ 类<literal>LockMode</literal> 定义了Hibernate所需的不同的锁定级别。一个锁定
+ 可以通过以下的机制来设置:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 当Hibernate更新或者插入一行记录的时候,锁定级别自动设置为<literal>LockMode.WRITE</literal>。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 当用户显式的使用数据库支持的SQL格式<literal>SELECT ... FOR UPDATE</literal>
+ 发送SQL的时候,锁定级别设置为<literal>LockMode.UPGRADE</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 当用户显式的使用Oracle数据库的SQL语句<literal>SELECT ... FOR UPDATE NOWAIT</literal>
+ 的时候,锁定级别设置<literal>LockMode.UPGRADE_NOWAIT</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 当Hibernate在“可重复读”或者是“序列化”数据库隔离级别下读取数据的时候,锁定模式
+ 自动设置为<literal>LockMode.READ</literal>。这种模式也可以通过用户显式指定进行设置。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.NONE</literal> 代表无需锁定。在<literal>Transaction</literal>结束时,
+ 所有的对象都切换到该模式上来。与session相关联的对象通过调用<literal>update()</literal>
+ 或者<literal>saveOrUpdate()</literal>脱离该模式。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ "显式的用户指定"可以通过以下几种方式之一来表示:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 调用 <literal>Session.load()</literal>的时候指定<literal>锁定模式(LockMode)</literal>。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 调用<literal>Session.lock()</literal>。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 调用<literal>Query.setLockMode()</literal>。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 如果在<literal>UPGRADE</literal>或者<literal>UPGRADE_NOWAIT</literal>锁定模式下调
+ 用<literal>Session.load()</literal>,并且要读取的对象尚未被session载入过,那么对象
+ 通过<literal>SELECT ... FOR UPDATE</literal>这样的SQL语句被载入。如果为一个对象调用
+ <literal>load()</literal>方法时,该对象已经在另一个较少限制的锁定模式下被载入了,那
+ 么Hibernate就对该对象调用<literal>lock()</literal> 方法。
+ </para>
+
+ <para>
+ 如果指定的锁定模式是<literal>READ</literal>, <literal>UPGRADE</literal> 或
+ <literal>UPGRADE_NOWAIT</literal>,那么<literal>Session.lock()</literal>就
+ 执行版本号检查。(在<literal>UPGRADE</literal> 或者<literal>UPGRADE_NOWAIT</literal>
+ 锁定模式下,执行<literal>SELECT ... FOR UPDATE</literal>这样的SQL语句。)
+ </para>
+
+ <para>
+ 如果数据库不支持用户设置的锁定模式,Hibernate将使用适当的替代模式(而不是扔出异常)。
+ 这一点可以确保应用程序的可移植性。
+ </para>
+ </sect1>
+ <sect1 id="transactions-connection-release">
+ <title>连接释放模式(Connection Release Modes)</title>
+
+ <para>
+ Hibernate关于JDBC连接管理的旧(2.x)行为是,<literal>Session</literal>在第一次需要的时候获取一个连接,在session关闭之前一直会持有这个连接。Hibernate引入了连接释放的概念,来告诉session如何处理它的JDBC连接。注意,下面的讨论只适用于采用配置<literal>ConnectionProvider</literal>来提供连接的情况,用户自己提供的连接与这里的讨论无关。通过<literal>org.hibernate.ConnectionReleaseMode</literal>的不同枚举值来使用不用的释放模式:
+
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>ON_CLOSE</literal> - 基本上就是上面提到的老式行为。Hibernate session在第一次需要进行JDBC操作的时候获取连接,然后持有它,直到session关闭。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>AFTER_TRANSACTION</literal> - 在<literal>org.hibernate.Transaction</literal>结束后释放连接。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>AFTER_STATEMENT</literal> (也被称做积极释放) - 在每一条语句被执行后就释放连接。但假若语句留下了与session相关的资源,那就不会被释放。目前唯一的这种情形就是使用<literal>org.hibernate.ScrollableResults</literal>。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>hibernate.connection.release_mode</literal>配置参数用来指定使用哪一种释放模式。可能的值有:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>auto</literal>(默认) - 这一选择把释放模式委派给<literal>org.hibernate.transaction.TransactionFactory.getDefaultReleaseMode()</literal>方法。对JTATransactionFactory来说,它会返回ConnectionReleaseMode.AFTER_STATEMENT;对JDBCTransactionFactory来说,则是ConnectionReleaseMode.AFTER_TRANSACTION。很少需要修改这一默认行为,因为假若设置不当,就会带来bug,或者给用户代码带来误导。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>on_close</literal> - 使用 ConnectionReleaseMode.ON_CLOSE. 这种方式是为了向下兼容的,但是已经完全不被鼓励使用了。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>after_transaction</literal> - 使用ConnectionReleaseMode.AFTER_TRANSACTION。这一设置不应该在JTA环境下使用。也要注意,使用ConnectionReleaseMode.AFTER_TRANSACTION的时候,假若session 处于auto-commit状态,连接会像AFTER_STATEMENT那样被释放。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>after_statement</literal> - 使用ConnectionReleaseMode.AFTER_STATEMENT。除此之外,会查询配置的<literal>ConnectionProvider</literal>,是否它支持这一设置((<literal>supportsAggressiveRelease()</literal>))。假若不支持,释放模式会被设置为ConnectionReleaseMode.AFTER_TRANSACTION。只有在你每次调用<literal>ConnectionProvider.getConnection()</literal>获取底层JDBC连接的时候,都可以确信获得同一个连接的时候,这一设置才是安全的;或者在auto-commit环境中,你可以不管是否每次都获得同一个连接的时候,这才是安全的。
+
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/tutorial.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/tutorial.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/tutorial.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/tutorial.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,1233 @@
+<chapter id="tutorial">
+ <title>
+ Hibernate入门
+ </title>
+ <sect1 id="tutorial-intro" revision="1">
+ <title>
+ 前言
+ </title>
+
+ <para>
+ 本章是面向Hibernate初学者的一个入门教程。我们从一个使用驻留内存式(in-memory)数据库的简单命令行应用程序开始, 用易于理解的方式逐步开发。
+
+ </para>
+
+ <para>
+ 本章面向Hibernate初学者,但需要Java和SQL知识。它是在Michael Goegl所写的指南的基础上完成的。在这里,我们称第三方库文件是指JDK 1.4和5.0。若使用JDK1.3,你可能需要其它的库文件。
+ </para>
+
+ <para>
+ 本章的源代码已包含在发布包中,位于<literal>doc/reference/tutorial/</literal>目录下。
+ </para>
+
+ </sect1>
+
+ <sect1 id="tutorial-firstapp" revision="2">
+ <title>
+ 第一部分 - 第一个Hibernate应用程序
+ </title>
+ <para>
+ 首先我们将创建一个简单的基于控制台的(console-based)Hibernate应用程序。由于我们使用Java数据库(HSQL DB),所以不必安装任何数据库服务器。
+ </para>
+
+ <para>
+ 假设我们希望有一个小应用程序可以保存我们希望参加的活动(events)和这些活动主办方的相关信息。
+ (译者注:在本教程的后面部分,我们将直接使用event而不是它的中文翻译“活动”,以免混淆。)
+ </para>
+
+ <para>
+ 我们所做的第一件事就是创建我们的开发目录,并且把所有需要用到的Java库文件放进去。解压缩从Hibernate网站下载的Hibernate发布包,并把<literal>/lib</literal>目录下所有需要的库文件拷到我们新建开发目录下的<literal>/lib</literal>目录下。看起来就像这样:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ antlr.jar
+ cglib.jar
+ asm.jar
+ asm-attrs.jars
+ commons-collections.jar
+ commons-logging.jar
+ ehcache.jar
+ hibernate3.jar
+ jta.jar
+ dom4j.jar
+ log4j.jar ]]></programlisting>
+
+ <para>
+ <emphasis>到编写本文时为止</emphasis>,这些是Hibernate运行所需要的最小库文件集合(注意我们也拷贝了 Hibernate3.jar,这个是最主要的文件)。你正使用的Hibernate版本可能需要比这更多或少一些的库文件。请参见发布包中的<literal>lib/</literal>目录下的<literal>README.txt</literal>,以获取更多关于所需和可选的第三方库文件信息(事实上,Log4j并不是必须的库文件,但被许多开发者所喜欢)。
+
+ </para>
+
+ <para>
+ 接下来我们创建一个类,用来代表那些我们希望储存在数据库里的event。
+ </para>
+
+ <sect2 id="tutorial-firstapp-firstclass" revision="1">
+ <title>
+ 第一个class
+ </title>
+
+ <para>
+ 我们的第一个持久化类是一个带有一些属性(property)的简单JavaBean类:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+import java.util.Date;
+
+public class Event {
+ private Long id;
+
+ private String title;
+ private Date date;
+
+ public Event() {}
+
+ public Long getId() {
+ return id;
+ }
+
+ private void setId(Long id) {
+ this.id = id;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}]]></programlisting>
+
+ <para>
+ 你可以看到这个类对属性的存取方法(getter and setter method)使用了标准JavaBean命名约定,同时把类属性(field)的访问级别设成私有的(private)。这是推荐的设计,但并不是必须的。Hibernate也可以直接访问这些field,而使用访问方法(accessor method)的好处是提供了重构时的健壮性(robustness)。为了通过反射机制(Reflection)来实例化这个类的对象,我们需要提供一个无参的构造器(no-argument constructor)。
+ </para>
+
+ <para>
+ 对一特定的event, <literal>id</literal> 属性持有唯一的标识符(identifier)的值。如果我们希望使用Hibernate提供的所有特性,那么所有的持久化实体(persistent entity)类(这里也包括一些次要依赖类)都需要一个这样的标识符属性。而事实上,大多数应用程序(特别是web应用程序)都需要通过标识符来区别对象,所以你应该考虑使用标识符属性而不是把它当作一种限制。然而,我们通常不会操作对象的标识(identity),因此它的setter方法的访问级别应该声明private。这样当对象被保存的时候,只有Hibernate可以为它分配标识符值。你可看到Hibernate可以直接访问public,private和protected的访问方法和field。所以选择哪种方式完全取决于你,你可以使你的选择与你的应用程序设计相吻合。
+ </para>
+
+ <para>
+ 所有的持久化类(persistent classes)都要求有无参的构造器,因为Hibernate必须使用Java反射机制来为你创建对象。构造器(constructor)的访问级别可以是private,然而当生成运行时代理(runtime proxy)的时候则要求使用至少是package 级别的访问控制,这样在没有字节码指令(bytecode instrumentation)的情况下,从持久化类里获取数据会更有效率。
+ </para>
+
+ <para>
+ 把这个Java源代码文件放到开发目录下的<literal>src</literal>目录里,注意包位置要正确。 现在这个目录看起来应该像这样:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java]]></programlisting>
+
+ <para>
+ 下一步,我们把这个持久化类的信息告诉Hibernate。
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-mapping" revision="1">
+ <title>
+ 映射文件
+ </title>
+
+ <para>
+ Hibernate需要知道怎样去加载(load)和存储(store)持久化类的对象。这正是Hibernate映射文件发挥作用的地方。映射文件告诉Hibernate它,应该访问数据库(database)里面的哪个表(table)及应该使用表里面的哪些字段(column)。
+
+ </para>
+
+ <para>
+ 一个映射文件的基本结构看起来像这样:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping>
+[...]
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 注意Hibernate的DTD是非常复杂的。你的编辑器或者IDE里使用它来自动完成那些用来映射的XML元素(element)和属性(attribute)。你也可以在文本编辑器里打开DTD-这是最简单的方式来概览所有的元素和attribute,并查看它们的缺省值以及注释。注意Hibernate不会从web加载DTD文件,但它会首先在应用程序的classpath中查找。DTD文件已包括在<literal>hibernate3.jar</literal>里,同时也在Hibernate发布包的<literal>src/</literal>目录下。
+ </para>
+
+ <para>
+ 为缩短代码长度,在以后的例子里我们会省略DTD的声明。当然,在实际的应用程序中,DTD声明是必须的。
+ </para>
+
+ <para>
+ 在<literal>hibernate-mapping</literal>标签(tag)之间, 含有一个<literal>class</literal>元素。所有的持久化实体类(再次声明,或许接下来会有依赖类,就是那些次要的实体)都需要一个这样的映射,来把类对象映射到SQL数据库里的表。
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 到目前为止,我们告诉了Hibernate怎样把<literal>Events</literal>类的对象持久化到数据库的<literal>EVENTS</literal>表里,以及怎样从<literal>EVENTS</literal>表加载到<literal>Events</literal>类的对象。每个实例对应着数据库表中的一行。现在我们将继续讨论有关唯一标识符属性到数据库表的映射。另外,由于我们不关心怎样处理这个标识符,我们就配置由Hibernate的标识符生成策略来产生代理主键字段。
+
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+ <id name="id" column="EVENT_ID">
+ <generator class="native"/>
+ </id>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>id</literal>元素是标识符属性的声明,<literal>name="id"</literal> 声明了Java属性的名字 - Hibernate会使用<literal>getId()</literal>和<literal>setId()</literal>来访问它。 <literal>column</literal>属性则告诉Hibernate, 我们使用<literal>EVENTS</literal>表的哪个字段作为主键。嵌套的<literal>generator</literal>元素指定了标识符生成策略,在这里我们指定<literal>native</literal>,它根据已配置的数据库(方言)自动选择最佳的标识符生成策略。Hibernate支持由数据库生成,全局唯一性(globally unique)和应用程序指定(或者你自己为任何已有策略所写的扩展)这些策略来生成标识符。
+ </para>
+
+ <para>
+ 最后我们在映射文件里面包含需要持久化属性的声明。默认情况下,类里面的属性都被视为非持久化的:
+ </para>
+
+ <programlisting><![CDATA[
+<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+ <id name="id" column="EVENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="date" type="timestamp" column="EVENT_DATE"/>
+ <property name="title"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 和<literal>id</literal>元素一样,<literal>property</literal>元素的<literal>name</literal>属性告诉Hibernate使用哪个getter和setter方法。在此例中,Hibernate会寻找<literal>getDate()/setDate()</literal>, 以及<literal>getTitle()/setTitle()</literal>。
+ </para>
+
+ <para>
+ 为什么<literal>date</literal>属性的映射含有<literal>column</literal> attribute,而<literal>title</literal>却没有?当没有设定<literal>column</literal> attribute 的时候,Hibernate缺省地使用JavaBean的属性名作为字段名。对于<literal>title</literal>,这样工作得很好。然而,<literal>date</literal>在多数的数据库里,是一个保留关键字,所以我们最好把它映射成一个不同的名字。
+
+ </para>
+
+ <para>
+ 另一有趣的事情是<literal>title</literal>属性缺少一个<literal>type</literal> attribute。我们在映射文件里声明并使用的类型,却不是我们期望的那样,是Java数据类型,同时也不是SQL数据库的数据类型。这些类型就是所谓的Hibernate 映射类型<emphasis>(mapping types)</emphasis>,它们能把Java数据类型转换到SQL数据类型,反之亦然。再次重申,如果在映射文件中没有设置<literal>type</literal>属性的话,Hibernate会自己试着去确定正确的转换类型和它的映射类型。在某些情况下这个自动检测机制(在Java 类上使用反射机制)不会产生你所期待或需要的缺省值。<literal>date</literal>属性就是个很好的例子,Hibernate无法知道这个属性(<literal>java.util.Date</literal>类型的)应该被映射成:SQL <literal>date</literal>,或<literal>timestamp</literal>,还是<literal>time</literal> 字段。在此例中�!
�把这个属性映射成<literal>timestamp</literal> 转换器,这样我们预留了日期和时间的全部信息。
+ </para>
+
+ <para>
+ 应该把这个映射文件保存为<literal>Event.hbm.xml</literal>,且就在<literal>Event</literal>Java类的源文件目录下。映射文件可随意地命名,但<literal>hbm.xml</literal>的后缀已成为Hibernate开发者社区的约定。现在目录结构看起来应该像这样:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java
+ Event.hbm.xml]]></programlisting>
+
+ <para>
+ 我们继续进行Hibernate的主要配置。
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-configuration" revision="2">
+ <title>
+ Hibernate配置
+ </title>
+
+ <para>
+ 现在我们已经有了一个持久化类和它的映射文件,该是配置Hibernate的时候了。在此之前,我们需要一个数据库。 HSQL DB是种基于Java 的SQL数据库管理系统(DBMS),可以从HSQL DB的网站上下载。实际上,你只需下载的包中的<literal>hsqldb.jar</literal>文件,并把这个文件放在开发文件夹的<literal>lib/</literal>目录下即可。
+
+ </para>
+
+ <para>
+ 在开发的根目录下创建一个<literal>data</literal>目录 - 这是HSQL DB存储数据文件的地方。此时在data目录中运行<literal>java -classpath ../lib/hsqldb.jar org.hsqldb.Server</literal>就可启动数据库。你可以在log中看到它的启动,及绑定到TCP/IP套结字,这正是我们的应用程序稍后会连接的地方。如果你希望在本例中运行一个全新的数据库,就在窗口中按下<literal>CTRL + C</literal>来关闭HSQL数据库,并删除<literal>data/</literal>目录下的所有文件,再重新启动HSQL数据库。
+ </para>
+
+ <para>
+ Hibernate是你的应用程序里连接数据库的那层,所以它需要连接用的信息。连接(connection)是通过一个也由我们配置的JDBC连接池(connection pool)来完成的。Hibernate的发布包里包含了许多开源的(open source)连接池,但在我们例子中使用Hibernate内置的连接池。注意,如果你希望使用一个产品级(production-quality)的第三方连接池软件,你必须拷贝所需的库文件到你的classpath下,并使用不同的连接池设置。
+ </para>
+
+ <para>
+ 为了保存Hibernate的配置,我们可以使用一个简单的<literal>hibernate.properties</literal>文件,或者一个稍微复杂的<literal>hibernate.cfg.xml</literal>,甚至可以完全使用程序来配置Hibernate。多数用户更喜欢使用XML配置文件:
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <session-factory>
+
+ <!-- Database connection settings -->
+ <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
+ <property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
+ <property name="connection.username">sa</property>
+ <property name="connection.password"></property>
+
+ <!-- JDBC connection pool (use the built-in) -->
+ <property name="connection.pool_size">1</property>
+
+ <!-- SQL dialect -->
+ <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
+
+ <!-- Enable Hibernate's automatic session context management -->
+ <property name="current_session_context_class">thread</property>
+
+ <!-- Disable the second-level cache -->
+ <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
+
+ <!-- Echo all executed SQL to stdout -->
+ <property name="show_sql">true</property>
+
+ <!-- Drop and re-create the database schema on startup -->
+ <property name="hbm2ddl.auto">create</property>
+
+ <mapping resource="events/Event.hbm.xml"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ 注意这个XML配置使用了一个不同的DTD。在这里,我们配置了Hibernate的<literal>SessionFactory</literal>-一个关联于特定数据库全局的工厂(factory)。如果你要使用多个数据库,就要用多个的<literal><session-factory></literal>,通常把它们放在多个配置文件中(为了更容易启动)。
+ </para>
+
+ <para>
+ 最开始的4个<literal>property</literal>元素包含必要的JDBC连接信息。方言(dialect)的<literal>property</literal>元素指明Hibernate 生成的特定SQL变量。你很快会看到,Hibernate对持久化上下文的自动session管理就会派上用场。 打开<literal>hbm2ddl.auto</literal>选项将自动生成数据库模式(schema)- 直接加入数据库中。当然这个选项也可以被关闭(通过去除这个配置选项)或者通过Ant任务<literal>SchemaExport</literal>的帮助来把数据库schema重定向到文件中。最后,在配置中为持久化类加入映射文件。
+ </para>
+
+ <para>
+ 把这个文件拷贝到源代码目录下面,这样它就位于classpath的根目录的最后。Hibernate在启动时会自动在classpath的根目录查找名为<literal>hibernate.cfg.xml</literal>的配置文件。
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-ant" revision="1">
+ <title>
+ 用Ant构建
+ </title>
+
+ <para>
+ 现在我们用Ant来构建应用程序。你必须先安装Ant-可以从<ulink url="http://ant.apache.org/bindownload.cgi">Ant 下载页面</ulink>得到它。怎样安装Ant就不在这里介绍了,请参考<ulink url="http://ant.apache.org/manual/index.html">Ant 用户手册</ulink>。当你安装完了Ant,就可以开始创建<literal>build.xml</literal>文件,把它直接放在开发目录下面。
+ </para>
+ <para>
+ 一个简单的build文件看起来像这样:
+ </para>
+
+ <programlisting><![CDATA[<project name="hibernate-tutorial" default="compile">
+
+ <property name="sourcedir" value="${basedir}/src"/>
+ <property name="targetdir" value="${basedir}/bin"/>
+ <property name="librarydir" value="${basedir}/lib"/>
+
+ <path id="libraries">
+ <fileset dir="${librarydir}">
+ <include name="*.jar"/>
+ </fileset>
+ </path>
+
+ <target name="clean">
+ <delete dir="${targetdir}"/>
+ <mkdir dir="${targetdir}"/>
+ </target>
+
+ <target name="compile" depends="clean, copy-resources">
+ <javac srcdir="${sourcedir}"
+ destdir="${targetdir}"
+ classpathref="libraries"/>
+ </target>
+
+ <target name="copy-resources">
+ <copy todir="${targetdir}">
+ <fileset dir="${sourcedir}">
+ <exclude name="**/*.java"/>
+ </fileset>
+ </copy>
+ </target>
+
+</project>]]></programlisting>
+
+ <para>
+ 这将告诉Ant把所有在lib目录下以<literal>.jar</literal>结尾的文件拷贝到classpath中以供编译之用。它也把所有的非Java源代码文件,例如配置和Hibernate映射文件,拷贝到目标目录。如果你现在运行Ant,会得到以下输出:
+ </para>
+
+ <programlisting><![CDATA[C:\hibernateTutorial\>ant
+Buildfile: build.xml
+
+copy-resources:
+ [copy] Copying 2 files to C:\hibernateTutorial\bin
+
+compile:
+ [javac] Compiling 1 source file to C:\hibernateTutorial\bin
+
+BUILD SUCCESSFUL
+Total time: 1 second ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-helpers" revision="3">
+ <title>
+ 启动和辅助类
+ </title>
+
+
+ <para>
+ 是时候来加载和储存一些<literal>Event</literal>对象了,但首先我们得编写一些基础的代码以完成设置。我们必须启动Hibernate,此过程包括创建一个全局的<literal>SessoinFactory</literal>,并把它储存在应用程序代码容易访问的地方。<literal>SessionFactory</literal>可以创建并打开新的<literal>Session</literal>。一个<literal>Session</literal>代表一个单线程的单元操作,<literal>SessionFactory</literal>则是个线程安全的全局对象,只需要被实例化一次。
+ </para>
+
+ <para>
+ 我们将创建一个<literal>HibernateUtil</literal>辅助类(helper class)来负责启动Hibernate和更方便地操作<literal>SessionFactory</literal>。让我们来看一下它的实现:
+ </para>
+
+ <programlisting><![CDATA[package util;
+
+import org.hibernate.*;
+import org.hibernate.cfg.*;
+
+public class HibernateUtil {
+
+ private static final SessionFactory sessionFactory;
+
+ static {
+ try {
+ // Create the SessionFactory from hibernate.cfg.xml
+ sessionFactory = new Configuration().configure().buildSessionFactory();
+ } catch (Throwable ex) {
+ // Make sure you log the exception, as it might be swallowed
+ System.err.println("Initial SessionFactory creation failed." + ex);
+ throw new ExceptionInInitializerError(ex);
+ }
+ }
+
+ public static SessionFactory getSessionFactory() {
+ return sessionFactory;
+ }
+
+}]]></programlisting>
+
+
+ <para>
+ 这个类不但在它的静态初始化过程(仅当加载这个类的时候被JVM执行一次)中产生全局的<literal>SessionFactory</literal>,而且隐藏了它使用了静态singleton的事实。它也可能在应用程序服务器中的JNDI查找<literal>SessionFactory</literal>。
+ </para>
+
+ <para>
+ 如果你在配置文件中给<literal>SessionFactory</literal>一个名字,在<literal>SessionFactory</literal>创建后,Hibernate会试着把它绑定到JNDI。要完全避免这样的代码,你也可以使用JMX部署,让具有JMX能力的容器来实例化<literal>HibernateService</literal>并把它绑定到JNDI。这些高级可选项在后面的章节中会讨论到。
+ </para>
+
+ <para>
+ 把<literal>HibernateUtil.java</literal>放在开发目录的源代码路径下,与放<literal>events</literal>的包并列:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java
+ Event.hbm.xml
+ +util
+ HibernateUtil.java
+ hibernate.cfg.xml
++data
+build.xml]]></programlisting>
+
+
+ <para>
+ 再次编译这个应用程序应该不会有问题。最后我们需要配置一个日志(logging)系统 - Hibernate使用通用日志接口,允许你在Log4j和JDK 1.4 日志之间进行选择。多数开发者更喜欢Log4j:从Hibernate的发布包中(它在<literal>etc/</literal>目录下)拷贝<literal>log4j.properties</literal>到你的<literal>src</literal>目录,与<literal>hibernate.cfg.xml</literal>.放在一起。看一下配置示例,如果你希望看到更加详细的输出信息,你可以修改配置。默认情况下,只有Hibernate的启动信息才会显示在标准输出上。
+ </para>
+
+ <para>
+ 示例的基本框架完成了 - 现在我们可以用Hibernate来做些真正的工作。
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-workingpersistence" revision="5">
+ <title>
+ 加载并存储对象
+ </title>
+
+ <para>
+ 我们终于可以使用Hibernate来加载和存储对象了,编写一个带有<literal>main()</literal>方法的<literal>EventManager</literal>类:
+
+ </para>
+
+ <programlisting><![CDATA[package events;
+import org.hibernate.Session;
+
+import java.util.Date;
+
+import util.HibernateUtil;
+
+public class EventManager {
+
+ public static void main(String[] args) {
+ EventManager mgr = new EventManager();
+
+ if (args[0].equals("store")) {
+ mgr.createAndStoreEvent("My Event", new Date());
+ }
+
+ HibernateUtil.getSessionFactory().close();
+ }
+
+ private void createAndStoreEvent(String title, Date theDate) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+ session.beginTransaction();
+
+ Event theEvent = new Event();
+ theEvent.setTitle(title);
+ theEvent.setDate(theDate);
+
+ session.save(theEvent);
+
+ session.getTransaction().commit();
+ }
+
+}]]></programlisting>
+
+
+ <para>
+ 我们创建了个新的<literal>Event</literal>对象并把它传递给Hibernate。现在Hibernate负责与SQL打交道,并把<literal>INSERT</literal>命令传给数据库。在运行之前,让我们看一下处理<literal>Session</literal>和<literal>Transaction</literal>的代码。
+
+ </para>
+ <para>
+ 一个<literal>Session</literal>就是个单一的工作单元。我们暂时让事情简单一些,并假设Hibernate<literal>Session</literal>和数据库事务是一一对应的。为了让我们的代码从底层的事务系统中脱离出来(此例中是JDBC,但也可能是JTA),我们使用Hibernate <literal>Session</literal>中的<literal>Transaction</literal> API。
+ </para>
+
+ <para>
+ <literal>sessionFactory.getCurrentSession()</literal>是干什么的呢?首先,只要你持有<literal>SessionFactory</literal>(幸亏我们有<literal>HibernateUtil</literal>,可以随时获得),大可在任何时候、任何地点调用这个方法。<literal>getCurrentSession()</literal>方法总会返回“当前的”工作单元。记得我们在<literal>hibernate.cfg.xml</literal>中把这一配置选项调整为"thread"了吗?因此,因此,当前工作单元被绑定到当前执行我们应用程序的Java线程。但是,这并非是完全准确的,你还得考虑工作单元的生命周期范围 (scope),它何时开始,又何时结束.
+ </para>
+
+ <para>
+ <literal>Session</literal>在第一次被使用的时候,即第一次调用<literal>getCurrentSession()</literal>的时候,其生命周期就开始。然后它被Hibernate绑定到当前线程。当事务结束的时候,不管是提交还是回滚,Hibernate会自动把<literal>Session</literal>从当前线程剥离,并且关闭它。假若你再次调用<literal>getCurrentSession()</literal>,你会得到一个新的<literal>Session</literal>,并且开始一个新的工作单元。这种<emphasis>线程绑定(thread-bound)</emphasis>的编程模型(model)是使用Hibernate的最广泛的方式,因为它支持对你的代码灵活分层(事务划分可以和你的数据访问代码分离开来,在本教程的后面部分就会这么做)。
+
+ </para>
+
+ <para>
+
+ 和工作单元的生命周期这个话题相关,Hibernate <literal>Session</literal>是否被应该用来执行多次数据库操作?上面的例子对每一次操作使用了一个<literal>Session</literal>,这完全是巧合,这个例子不是很复杂,无法展示其他方式。Hibernate <literal>Session</literal>的生命周期可以很灵活,但是你绝不要把你的应用程序设计成为<emphasis>每一次</emphasis>数据库操作都用一个新的Hibernate <literal>Session</literal>。因此就算下面的例子(它们都很简单)中你可以看到这种用法,记住<emphasis>每次操作一个session</emphasis>是一个反模式。在本教程的后面会展示一个真正的(web)程序。
+ </para>
+
+
+
+ <para>
+ 关于事务处理及事务边界界定的详细信息,请参看<xref linkend="transactions"/>。在上面的例子中,我们也忽略了所有的错误与回滚的处理。
+ </para>
+
+ <para>
+ 为第一次运行我们的程序,我们得在Ant的build文件中增加一个可以调用得到的target。
+ </para>
+
+ <programlisting><![CDATA[<target name="run" depends="compile">
+ <java fork="true" classname="events.EventManager" classpathref="libraries">
+ <classpath path="${targetdir}"/>
+ <arg value="${action}"/>
+ </java>
+</target>]]></programlisting>
+
+ <para>
+ <literal>action</literal>参数(argument)的值是通过命令行调用这个target的时候设置的:
+ </para>
+
+ <programlisting><![CDATA[C:\hibernateTutorial\>ant run -Daction=store]]></programlisting>
+
+ <para>
+ 你应该会看到,编译以后,Hibernate根据你的配置启动,并产生一大堆的输出日志。在日志最后你会看到下面这行:
+ </para>
+
+ <programlisting><![CDATA[[java] Hibernate: insert into EVENTS (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)]]></programlisting>
+
+ <para>
+ 这是Hibernate执行的<literal>INSERT</literal>命令,问号代表JDBC的绑定参数。如果想要看到绑定参数的值或者减少日志的长度,就要调整你在<literal>log4j.properties</literal>文件里的设置。
+ </para>
+
+ <para>
+ 我们想要列出所有已经被存储的events,就要增加一个条件分支选项到main方法中去。
+ </para>
+
+ <programlisting><![CDATA[if (args[0].equals("store")) {
+ mgr.createAndStoreEvent("My Event", new Date());
+}
+else if (args[0].equals("list")) {
+ List events = mgr.listEvents();
+ for (int i = 0; i < events.size(); i++) {
+ Event theEvent = (Event) events.get(i);
+ System.out.println("Event: " + theEvent.getTitle() +
+ " Time: " + theEvent.getDate());
+ }
+}]]></programlisting>
+
+ <para>
+ 我们也增加一个新的<literal>listEvents()</literal>方法:
+ </para>
+
+ <programlisting><![CDATA[private List listEvents() {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+ session.beginTransaction();
+
+ List result = session.createQuery("from Event").list();
+
+ session.getTransaction().commit();
+
+ return result;
+}]]></programlisting>
+
+ <para>
+ 我们在这里是用一个HQL(Hibernate Query Language-Hibernate查询语言)查询语句来从数据库中加载所有存在的<literal>Event</literal>对象。Hibernate会生成适当的SQL,把它发送到数据库,并操作从查询得到数据的<literal>Event</literal>对象。当然,你可以使用HQL来创建更加复杂的查询。
+ </para>
+
+ <para>
+ 现在,根据以下步骤来执行并测试以上各项:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ 运行<literal>ant run -Daction=store</literal>来保存一些内容到数据库。当然,先得用hbm2ddl来生成数据库schema。
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 现在把<literal>hibernate.cfg.xml</literal>文件中hbm2ddl属性注释掉,这样我们就取消了在启动时用hbm2ddl来生成数据库schema。通常只有在不断重复进行单元测试的时候才需要打开它,但再次运行hbm2ddl会把你保存的一切都删掉(<emphasis>drop</emphasis>)——<literal>create</literal>配置的真实含义是:“在创建SessionFactory的时候,从schema 中drop 掉所有的表,再重新创建它们”。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+
+ <para>
+ 如果你现在使用命令行参数<literal>-Daction=list</literal>运行Ant,你会看到那些至今为止我们所储存的events。当然,你也可以多调用几次<literal>store</literal>以保存更多的envents。
+ </para>
+
+ <para>
+ 注意,很多Hibernate新手在这一步会失败,我们不时看到关于<emphasis>Table not found</emphasis>错误信息的提问。但是,只要你根据上面描述的步骤来执行,就不会有这个问题,因为hbm2ddl会在第一次运行的时候创建数据库schema,后继的应用程序重起后还能继续使用这个schema。假若你修改了映射,或者修改了数据库schema,你必须把hbm2ddl重新打开一次。
+ </para>
+
+ </sect2>
+
+ </sect1>
+ <sect1 id="tutorial-associations">
+ <title>
+ 第二部分 - 关联映射
+ </title>
+
+ <para>
+ 我们已经映射了一个持久化实体类到表上。让我们在这个基础上增加一些类之间的关联。首先我们往应用程序里增加人(people)的概念,并存储他们所参与的一个Event列表。(译者注:与Event一样,我们在后面将直接使用person来表示“人”而不是它的中文翻译)
+ </para>
+
+ <sect2 id="tutorial-associations-mappinguser" revision="1">
+ <title>
+ 映射Person类
+ </title>
+
+ <para>
+ 最初简单的<literal>Person</literal>类:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+public class Person {
+
+ private Long id;
+ private int age;
+ private String firstname;
+ private String lastname;
+
+ public Person() {}
+
+ // Accessor methods for all properties, private setter for 'id'
+
+}]]></programlisting>
+
+ <para>
+ 创建一个名为<literal>Person.hbm.xml</literal>的新映射文件(别忘了最上面的DTD引用):
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="native"/>
+ </id>
+ <property name="age"/>
+ <property name="firstname"/>
+ <property name="lastname"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 最后,把新的映射加入到Hibernate的配置中:
+ </para>
+
+ <programlisting><![CDATA[<mapping resource="events/Event.hbm.xml"/>
+<mapping resource="events/Person.hbm.xml"/>]]></programlisting>
+
+ <para>
+ 现在我们在这两个实体之间创建一个关联。显然,persons可以参与一系列events,而events也有不同的参加者(persons)。我们需要处理的设计问题是关联方向(directionality),阶数(multiplicity)和集合(collection)的行为。
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-unidirset" revision="3">
+ <title>
+ 单向Set-based的关联
+ </title>
+
+ <para>
+ 我们将向<literal>Person</literal>类增加一连串的events。那样,通过调用<literal>aPerson.getEvents()</literal>,就可以轻松地导航到特定person所参与的events,而不用去执行一个显式的查询。我们使用Java的集合类(collection):<literal>Set</literal>,因为set 不包含重复的元素及与我们无关的排序。
+ </para>
+
+ <para>
+ 我们需要用set 实现一个单向多值关联。让我们在Java类里为这个关联编码,接着映射它:
+ </para>
+
+ <programlisting><![CDATA[public class Person {
+
+ private Set events = new HashSet();
+
+ public Set getEvents() {
+ return events;
+ }
+
+ public void setEvents(Set events) {
+ this.events = events;
+ }
+}]]></programlisting>
+
+ <para>
+ 在映射这个关联之前,先考虑一下此关联的另外一端。很显然,我们可以保持这个关联是单向的。或者,我们可以在<literal>Event</literal>里创建另外一个集合,如果希望能够双向地导航,如:<literal>anEvent.getParticipants()</literal>。从功能的角度来说,这并不是必须的。因为你总可以显式地执行一个查询,以获得某个特定event的所有参与者。这是个在设计时需要做出的选择,完全由你来决定,但此讨论中关于关联的阶数是清楚的:即两端都是“多”值的,我们把它叫做<emphasis>多对多(many-to-many)</emphasis>关联。因而,我们使用Hibernate的多对多映射:
+ </para>
+
+ <programlisting><![CDATA[<class name="events.Person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="native"/>
+ </id>
+ <property name="age"/>
+ <property name="firstname"/>
+ <property name="lastname"/>
+
+ <set name="events" table="PERSON_EVENT">
+ <key column="PERSON_ID"/>
+ <many-to-many column="EVENT_ID" class="events.Event"/>
+ </set>
+
+</class>]]></programlisting>
+
+ <para>
+ Hibernate支持各种各样的集合映射,<literal><set></literal>使用的最为普遍。对于多对多关联(或叫<emphasis>n:m</emphasis>实体关系), 需要一个关联表(association table)。<literal>表</literal>里面的每一行代表从person到event的一个关联。表名是由<literal>set</literal>元素的<literal>table</literal>属性配置的。关联里面的标识符字段名,对于person的一端,是由<literal><key></literal>元素定义,而event一端的字段名是由<literal><many-to-many></literal>元素的<literal>column</literal>属性定义。你也必须告诉Hibernate集合中对象的类(也就是位于这个集合所代表的关联另外一端的类)。
+ </para>
+
+ <para>
+ 因而这个映射的数据库schema是:
+ </para>
+
+ <programlisting><![CDATA[
+ _____________ __________________
+ | | | | _____________
+ | EVENTS | | PERSON_EVENT | | |
+ |_____________| |__________________| | PERSON |
+ | | | | |_____________|
+ | *EVENT_ID | <--> | *EVENT_ID | | |
+ | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID |
+ | TITLE | |__________________| | AGE |
+ |_____________| | FIRSTNAME |
+ | LASTNAME |
+ |_____________|
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-working" revision="2">
+ <title>
+ 使关联工作
+ </title>
+
+ <para>
+ 我们把一些people和events 一起放到<literal>EventManager</literal>的新方法中:
+ </para>
+
+ <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session.load(Person.class, personId);
+ Event anEvent = (Event) session.load(Event.class, eventId);
+
+ aPerson.getEvents().add(anEvent);
+
+ session.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ 在加载一<literal>Person</literal>和<literal>Event</literal>后,使用普通的集合方法就可容易地修改我们定义的集合。如你所见,没有显式的<literal>update()</literal>或<literal>save()</literal>,Hibernate会自动检测到集合已经被修改并需要更新回数据库。这叫做自动脏检查(<emphasis>automatic dirty checking</emphasis>),你也可以尝试修改任何对象的name或者date属性,只要他们处于<emphasis>持久化</emphasis>状态,也就是被绑定到某个Hibernate 的<literal>Session</literal>上(如:他们刚刚在一个单元操作被加载或者保存),Hibernate监视任何改变并在后台隐式写的方式执行SQL。同步内存状态和数据库的过程,通常只在单元操作结束的时候发生,称此过程为清理缓存<emphasis>(flushing)</emphasis>。在我们的代码中,工作单元由数据库事务的提交(或者回滚)来结束——这是由<literal>Curren!
tSessionContext</literal>类的<literal>thread</literal>配置选项定义的。
+ </para>
+
+ <para>
+ 当然,你也可以在不同的单元操作里面加载person和event。或在<literal>Session</literal>以外修改不是处在持久化(persistent)状态下的对象(如果该对象以前曾经被持久化,那么我们称这个状态为<emphasis>脱管(detached)</emphasis>)。你甚至可以在一个集合被脱管时修改它:
+ </para>
+
+ <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session
+ .createQuery("select p from Person p left join fetch p.events where p.id = :pid")
+ .setParameter("pid", personId)
+ .uniqueResult(); // Eager fetch the collection so we can use it detached
+
+ Event anEvent = (Event) session.load(Event.class, eventId);
+
+ session.getTransaction().commit();
+
+ // End of first unit of work
+
+ aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached
+
+ // Begin second unit of work
+
+ Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
+ session2.beginTransaction();
+
+ session2.update(aPerson); // Reattachment of aPerson
+
+ session2.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ 对<literal>update</literal>的调用使一个脱管对象重新持久化,你可以说它被绑定到一个新的单元操作上,所以在脱管状态下对它所做的任何修改都会被保存到数据库里。这也包括你对这个实体对象的集合所作的任何改动(增加/删除)。
+ </para>
+
+ <para>
+ 这对我们当前的情形不是很有用,但它是非常重要的概念,你可以把它融入到你自己的应用程序设计中。在<literal>EventManager</literal>的main方法中添加一个新的动作,并从命令行运行它来完成我们所做的练习。如果你需要person及event的标识符 — 那就用<literal>save()</literal>方法返回它(你可能需要修改前面的一些方法来返回那个标识符):
+ </para>
+
+ <programlisting><![CDATA[else if (args[0].equals("addpersontoevent")) {
+ Long eventId = mgr.createAndStoreEvent("My Event", new Date());
+ Long personId = mgr.createAndStorePerson("Foo", "Bar");
+ mgr.addPersonToEvent(personId, eventId);
+ System.out.println("Added person " + personId + " to event " + eventId);
+}]]></programlisting>
+
+ <para>
+ 上面是个关于两个同等重要的实体类间关联的例子。像前面所提到的那样,在特定的模型中也存在其它的类和类型,这些类和类型通常是“次要的”。你已看到过其中的一些,像<literal>int</literal>或<literal>String</literal>。我们称这些类为<emphasis>值类型(value type)</emphasis>,它们的实例<emphasis>依赖(depend)</emphasis>在某个特定的实体上。这些类型的实例没有它们自己的标识(identity),也不能在实体间被共享(比如,两个person不能引用同一个<literal>firstname</literal>对象,即使他们有相同的first name)。当然,值类型并不仅仅在JDK中存在(事实上,在一个Hibernate应用程序中,所有的JDK类都被视为值类型),而且你也可以编写你自己的依赖类,例如<literal>Address</literal>,<literal>MonetaryAmount</literal>。
+ </para>
+
+ <para>
+ 你也可以设计一个值类型的集合,这在概念上与引用其它实体的集合有很大的不同,但是在Java里面看起来几乎是一样的。
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-valuecollections">
+ <title>
+ 值类型的集合
+ </title>
+
+ <para>
+ 我们把一个值类型对象的集合加入<literal>Person</literal>实体中。我们希望保存email地址,所以使用<literal>String</literal>类型,而且这次的集合类型又是<literal>Set</literal>:
+ </para>
+ <programlisting><![CDATA[private Set emailAddresses = new HashSet();
+
+public Set getEmailAddresses() {
+ return emailAddresses;
+}
+
+public void setEmailAddresses(Set emailAddresses) {
+ this.emailAddresses = emailAddresses;
+}]]></programlisting>
+
+ <para>
+ 这个<literal>Set</literal>的映射
+ </para>
+
+ <programlisting><![CDATA[<set name="emailAddresses" table="PERSON_EMAIL_ADDR">
+ <key column="PERSON_ID"/>
+ <element type="string" column="EMAIL_ADDR"/>
+</set>]]></programlisting>
+
+ <para>
+ 比较这次和此前映射的差别,主要在于<literal>element</literal>部分,这次并没有包含对其它实体引用的集合,而是元素类型为<literal>String</literal>的集合(在映射中使用小写的名字”string“是向你表明它是一个Hibernate的映射类型或者类型转换器)。和之前一样,<literal>set</literal>元素的<literal>table</literal>属性决定了用于集合的表名。<literal>key</literal>元素定义了在集合表中外键的字段名。<literal>element</literal>元素的<literal>column</literal>属性定义用于实际保存<literal>String</literal>值的字段名。
+ </para>
+
+ <para>
+ 看一下修改后的数据库schema。
+ </para>
+
+ <programlisting><![CDATA[
+ _____________ __________________
+ | | | | _____________
+ | EVENTS | | PERSON_EVENT | | | ___________________
+ |_____________| |__________________| | PERSON | | |
+ | | | | |_____________| | PERSON_EMAIL_ADDR |
+ | *EVENT_ID | <--> | *EVENT_ID | | | |___________________|
+ | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID | <--> | *PERSON_ID |
+ | TITLE | |__________________| | AGE | | *EMAIL_ADDR |
+ |_____________| | FIRSTNAME | |___________________|
+ | LASTNAME |
+ |_____________|
+ ]]></programlisting>
+
+ <para>
+ 你可以看到集合表的主键实际上是个复合主键,同时使用了2个字段。这也暗示了对于同一个person不能有重复的email地址,这正是Java里面使用Set时候所需要的语义(Set里元素不能重复)。
+ </para>
+
+ <para>
+ 你现在可以试着把元素加入到这个集合,就像我们在之前关联person和event的那样。其实现的Java代码是相同的:
+ </para>
+ <programlisting><![CDATA[private void addEmailToPerson(Long personId, String emailAddress) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session.load(Person.class, personId);
+
+ // The getEmailAddresses() might trigger a lazy load of the collection
+ aPerson.getEmailAddresses().add(emailAddress);
+
+ session.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ 这次我们没有使用<emphasis>fetch</emphasis>查询来初始化集合。因此,调用其getter方法会触发另一附加的select来初始化集合,这样我们才能把元素添加进去。检查SQL log,试着通过预先抓取来优化它。
+ </para>
+
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-bidirectional" revision="1">
+ <title>
+ 双向关联
+ </title>
+
+ <para>
+ 接下来我们将映射双向关联(bi-directional association)- 在Java里让person和event可以从关联的任何一端访问另一端。当然,数据库schema没有改变,我们仍然需要多对多的阶数。一个关系型数据库要比网络编程语言 更加灵活,所以它并不需要任何像导航方向(navigation direction)的东西 - 数据可以用任何可能的方式进行查看和获取。
+ </para>
+
+ <para>
+ 首先,把一个参与者(person)的集合加入<literal>Event</literal>类中:
+ </para>
+
+ <programlisting><![CDATA[private Set participants = new HashSet();
+
+public Set getParticipants() {
+ return participants;
+}
+
+public void setParticipants(Set participants) {
+ this.participants = participants;
+}]]></programlisting>
+
+ <para>
+ 在<literal>Event.hbm.xml</literal>里面也映射这个关联。
+ </para>
+
+ <programlisting><![CDATA[<set name="participants" table="PERSON_EVENT" inverse="true">
+ <key column="EVENT_ID"/>
+ <many-to-many column="PERSON_ID" class="events.Person"/>
+</set>]]></programlisting>
+ <para>
+ 如你所见,两个映射文件里都有普通的<literal>set</literal>映射。注意在两个映射文件中,互换了<literal>key</literal>和<literal>many-to-many</literal>的字段名。这里最重要的是<literal>Event</literal>映射文件里增加了<literal>set</literal>元素的<literal>inverse="true"</literal>属性。
+ </para>
+
+ <para>
+ 这意味着在需要的时候,Hibernate能在关联的另一端 - <literal>Person</literal>类得到两个实体间关联的信息。这将会极大地帮助你理解双向关联是如何在两个实体间被创建的。
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-usingbidir">
+ <title>
+ 使双向连起来
+ </title>
+
+ <para>
+ 首先请记住,Hibernate并不影响通常的Java语义。 在单向关联的例子中,我们是怎样在<literal>Person</literal>和<literal>Event</literal>之间创建联系的?我们把<literal>Event</literal>实例添加到<literal>Person</literal>实例内的event引用集合里。因此很显然,如果我们要让这个关联可以双向地工作,我们需要在另外一端做同样的事情 - 把<literal>Person</literal>实例加入<literal>Event</literal>类内的Person引用集合。这“在关联的两端设置联系”是完全必要的而且你都得这么做。
+ </para>
+
+ <para>
+ 许多开发人员防御式地编程,创建管理关联的方法来保证正确的设置了关联的两端,比如在<literal>Person</literal>里:
+ </para>
+
+ <programlisting><![CDATA[protected Set getEvents() {
+ return events;
+}
+
+protected void setEvents(Set events) {
+ this.events = events;
+}
+
+public void addToEvent(Event event) {
+ this.getEvents().add(event);
+ event.getParticipants().add(this);
+}
+
+public void removeFromEvent(Event event) {
+ this.getEvents().remove(event);
+ event.getParticipants().remove(this);
+}]]></programlisting>
+
+ <para>
+ 注意现在对于集合的get和set方法的访问级别是protected - 这允许在位于同一个包(package)中的类以及继承自这个类的子类可以访问这些方法,但禁止其他任何人的直接访问,避免了集合内容的混乱。你应尽可能地在另一端也把集合的访问级别设成protected。
+ </para>
+
+ <para>
+ <literal>inverse</literal>映射属性究竟表示什么呢?对于你和Java来说,一个双向关联仅仅是在两端简单地正确设置引用。然而,Hibernate并没有足够的信息去正确地执行<literal>INSERT</literal>和<literal>UPDATE</literal>语句(以避免违反数据库约束),所以它需要一些帮助来正确的处理双向关联。把关联的一端设置为<literal>inverse</literal>将告诉Hibernate忽略关联的这一端,把这端看成是另外一端的一个<emphasis>镜象(mirror)</emphasis>。这就是所需的全部信息,Hibernate利用这些信息来处理把一个有向导航模型转移到数据库schema时的所有问题。你只需要记住这个直观的规则:所有的双向关联需要有一端被设置为<literal>inverse</literal>。在一对多关联中它必须是代表多(many)的那端。而在多对多(many-to-many)关联中,你可以任意选取一端,因为两端之间并没有差别。
+ </para>
+ </sect2>
+ <para>
+ 让我们把进入一个小型的web应用程序。
+ </para>
+
+ </sect1>
+
+ <sect1 id="tutorial-webapp">
+ <title>第三部分 - EventManager web应用程序</title>
+
+ <para>
+ Hibernate web应用程序使用<literal>Session</literal> 和<literal>Transaction</literal>的方式几乎和独立应用程序是一样的。但是,有一些常见的模式(pattern)非常有用。现在我们编写一个<literal>EventManagerServlet</literal>。这个servlet可以列出数据库中保存的所有的events,还提供一个HTML表单来增加新的events。
+ </para>
+
+ <sect2 id="tutorial-webapp-servlet" revision="2">
+ <title>编写基本的servlet</title>
+
+ <para>
+ 在你的源代码目录的<literal>events</literal>包中创建一个新的类:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+// Imports
+
+public class EventManagerServlet extends HttpServlet {
+
+ // Servlet code
+}]]></programlisting>
+
+ <para>
+ 我们后面会用到<literal>dateFormatter</literal> 的工具, 它把<literal>Date</literal>对象转换为字符串。只要一个formatter作为servlet的成员就可以了。
+ </para>
+
+ <para>
+ 这个servlet只处理 HTTP <literal>GET</literal> 请求,因此,我们要实现的是<literal>doGet()</literal>方法:
+ </para>
+
+ <programlisting><![CDATA[protected void doGet(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+
+ SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");
+
+ try {
+ // Begin unit of work
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().beginTransaction();
+
+ // Process request and render page...
+
+ // End unit of work
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().getTransaction().commit();
+
+ } catch (Exception ex) {
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().getTransaction().rollback();
+ throw new ServletException(ex);
+ }
+
+}]]></programlisting>
+ <para>
+我们称这里应用的模式为每次请求一个session<emphasis>(session-per-request)</emphasis>。当有请求到达这个servlet的时候,通过对<literal>SessionFactory</literal>的第一次调用,打开一个新的Hibernate <literal>Session</literal>。然后启动一个数据库事务—所有的数据访问都是在事务中进行,不管是读还是写(我们在应用程序中不使用auto-commit模式)。
+ </para>
+
+ <para>
+
+ <emphasis>不要</emphasis>为每次数据库操作都使用一个新的Hibernate <literal>Session</literal>。将Hibernate <literal>Session</literal>的范围设置为整个请求。要用<literal>getCurrentSession()</literal>,这样它自动会绑定到当前Java线程。
+ </para>
+
+ <para>
+ 下一步,对请求的可能动作进行处理,渲染出反馈的HTML。我们很快就会涉及到那部分。
+ </para>
+
+ <para>
+ 最后,当处理与渲染都结束的时候,这个工作单元就结束了。假若在处理或渲染的时候有任何错误发生,会抛出一个异常,回滚数据库事务。这样,<literal>session-per-request</literal>模式就完成了。为了避免在每个servlet中都编写事务边界界定的代码,可以考虑写一个servlet 过滤器(filter)来更好地解决。关于这一模式的更多信息,请参阅Hibernate网站和Wiki,这一模式叫做<emphasis>Open Session in View</emphasis>—只要你考虑用JSP来渲染你的视图(view),而不是在servlet中,你就会很快用到它。
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-webapp-processing" revision="1">
+ <title>处理与渲染</title>
+
+ <para>
+ 我们来实现处理请求以及渲染页面的工作。
+ </para>
+
+<programlisting><![CDATA[// Write HTML header
+PrintWriter out = response.getWriter();
+out.println("<html><head><title>Event Manager</title></head><body>");
+
+// Handle actions
+if ( "store".equals(request.getParameter("action")) ) {
+
+ String eventTitle = request.getParameter("eventTitle");
+ String eventDate = request.getParameter("eventDate");
+
+ if ( "".equals(eventTitle) || "".equals(eventDate) ) {
+ out.println("<b><i>Please enter event title and date.</i></b>");
+ } else {
+ createAndStoreEvent(eventTitle, dateFormatter.parse(eventDate));
+ out.println("<b><i>Added event.</i></b>");
+ }
+}
+
+// Print page
+printEventForm(out);
+listEvents(out, dateFormatter);
+
+// Write HTML footer
+out.println("</body></html>");
+out.flush();
+out.close();]]></programlisting>
+ <para>
+ <literal>listEvents()</literal>方法使用绑定到当前线程的Hibernate <literal>Session</literal>来执行查询:
+ </para>
+
+ <programlisting><![CDATA[private void listEvents(PrintWriter out, SimpleDateFormat dateFormatter) {
+
+ List result = HibernateUtil.getSessionFactory()
+ .getCurrentSession().createCriteria(Event.class).list();
+ if (result.size() > 0) {
+ out.println("<h2>Events in database:</h2>");
+ out.println("<table border='1'>");
+ out.println("<tr>");
+ out.println("<th>Event title</th>");
+ out.println("<th>Event date</th>");
+ out.println("</tr>");
+ for (Iterator it = result.iterator(); it.hasNext();) {
+ Event event = (Event) it.next();
+ out.println("<tr>");
+ out.println("<td>" + event.getTitle() + "</td>");
+ out.println("<td>" + dateFormatter.format(event.getDate()) + "</td>");
+ out.println("</tr>");
+ }
+ out.println("</table>");
+ }
+}]]></programlisting>
+
+ <para>
+ 最后,<literal>store</literal>动作会被导向到<literal>createAndStoreEvent()</literal>方法,它也使用当前线程的<literal>Session</literal>:
+ </para>
+
+ <programlisting><![CDATA[protected void createAndStoreEvent(String title, Date theDate) {
+ Event theEvent = new Event();
+ theEvent.setTitle(title);
+ theEvent.setDate(theDate);
+
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().save(theEvent);
+}]]></programlisting>
+
+ <para>
+ 大功告成,这个servlet写完了。Hibernate会在单一的<literal>Session</literal> 和<literal>Transaction</literal>中处理到达的servlet请求。如同在前面的独立应用程序中那样,Hibernate可以自动的把这些对象绑定到当前运行的线程中。这给了你用任何你喜欢的方式来对代码分层及访问<literal>SessionFactory</literal>的自由。通常,你会用更加完备的设计,把数据访问代码转移到数据访问对象中(DAO模式)。请参见Hibernate Wiki,那里有更多的例子。
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-webapp-deploy">
+ <title>部署与测试</title>
+
+ <para>
+ 要发布这个程序,你得把它打成web发布包:WAR文件。把下面的脚本加入到你的<literal>build.xml</literal>中:
+ </para>
+
+<programlisting><![CDATA[<target name="war" depends="compile">
+ <war destfile="hibernate-tutorial.war" webxml="web.xml">
+ <lib dir="${librarydir}">
+ <exclude name="jsdk*.jar"/>
+ </lib>
+
+ <classes dir="${targetdir}"/>
+ </war>
+</target>]]></programlisting>
+
+ <para>
+ 这段代码在你的开发目录中创建一个<literal>hibernate-tutorial.war</literal>的文件。它把所有的类库和<literal>web.xml</literal>描述文件都打包进去,web.xml 文件应该位于你的开发根目录中:
+ </para>
+
+<programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4"
+ xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+ <servlet>
+ <servlet-name>Event Manager</servlet-name>
+ <servlet-class>events.EventManagerServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Event Manager</servlet-name>
+ <url-pattern>/eventmanager</url-pattern>
+ </servlet-mapping>
+</web-app>]]></programlisting>
+
+ <para>
+ 请注意在你编译和部署web应用程之前,需要一个附加的类库:<literal>jsdk.jar</literal>。这是Java Servlet开发包,假若你还没有,可以从Sun网站上下载,把它copy到你的lib目录。但是,它仅仅是在编译时需要,不会被打入WAR包。
+ </para>
+
+ <para>
+ 在你的开发目录中,调用<literal>ant war</literal>来构建、打包,然后把<literal>hibernate-tutorial.war</literal>文件拷贝到你的tomcat的<literal>webapps</literal>目录下。假若你还没安装Tomcat,就去下载一个,按照指南来安装。对此应用的发布,你不需要修改任何Tomcat的配置。
+ </para>
+
+ <para>
+ 在部署完,启动Tomcat之后,通过<literal>http://localhost:8080/hibernate-tutorial/eventmanager</literal>进行访问你的应用,在第一次servlet 请求发生时,请在Tomcat log中确认你看到Hibernate被初始化了(<literal>HibernateUtil</literal>的静态初始化器被调用),假若有任何异常抛出,也可以看到详细的输出。
+ </para>
+
+ </sect2>
+
+ </sect1>
+ <sect1 id="tutorial-summary">
+ <title>
+ 总结
+ </title>
+
+ <para>
+ 本章覆盖了如何编写一个简单独立的Hibernate命令行应用程序及小型的Hibernate web应用程序的基本要素。
+ </para>
+
+ <para>
+ 如果你已经对Hibernate感到自信,通过开发指南目录,继续浏览你感兴趣的内容-那些会被问到的问题大多是事务处理 (<xref linkend="transactions"/>),抓取(fetch)的效率 (<xref linkend="performance"/>),或者API的使用 (<xref linkend="objectstate"/>)和查询的特性(<xref linkend="objectstate-querying"/>)。
+ </para>
+
+ <para>
+ 别忘了去Hibernate的网站查看更多(有针对性的)示例。
+ </para>
+
+ </sect1>
+</chapter>
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/content/xml.xml (from rev 14080, core/trunk/documentation/manual/zh-CN/src/main/docbook/modules/xml.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/content/xml.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/content/xml.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,285 @@
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<chapter id="xml">
+ <title>XML映射</title>
+ <para><emphasis>
+ 注意这是Hibernate 3.0的一个实验性的特性。这一特性仍在积极开发中。
+ </emphasis></para>
+
+ <sect1 id="xml-intro" revision="1">
+ <title>用XML数据进行工作</title>
+
+ <para>
+ Hibernate使得你可以用XML数据来进行工作,恰如你用持久化的POJO进行工作那样。解析过的XML树
+ 可以被认为是代替POJO的另外一种在对象层面上表示关系型数据的途径.
+ </para>
+
+ <para>
+ Hibernate支持采用dom4j作为操作XML树的API。你可以写一些查询从数据库中检索出
+ dom4j树,随后你对这颗树做的任何修改都将自动同步回数据库。你甚至可以用dom4j解析
+ 一篇XML文档,然后使用Hibernate的任一基本操作将它写入数据库:
+ <literal>persist(), saveOrUpdate(), merge(), delete(), replicate()</literal>
+ (合并操作merge()目前还不支持)。
+ </para>
+
+ <para>
+ 这一特性可以应用在很多场合,包括数据导入导出,通过JMS或SOAP具体化实体数据以及
+ 基于XSLT的报表。
+ </para>
+
+ <para>
+ 一个单一的映射就可以将类的属性和XML文档的节点同时映射到数据库。如果不需要映射类,
+ 它也可以用来只映射XML文档。
+ </para>
+
+ <sect2 id="xml-intro-mapping">
+ <title>指定同时映射XML和类</title>
+
+ <para>
+ 这是一个同时映射POJO和XML的例子:
+ </para>
+
+ <programlisting><![CDATA[<class name="Account"
+ table="ACCOUNTS"
+ node="account">
+
+ <id name="accountId"
+ column="ACCOUNT_ID"
+ node="@id"/>
+
+ <many-to-one name="customer"
+ column="CUSTOMER_ID"
+ node="customer/@id"
+ embed-xml="false"/>
+
+ <property name="balance"
+ column="BALANCE"
+ node="balance"/>
+
+ ...
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="xml-onlyxml">
+ <title>只定义XML映射</title>
+
+ <para>
+ 这是一个不映射POJO的例子:
+ </para>
+
+ <programlisting><![CDATA[<class entity-name="Account"
+ table="ACCOUNTS"
+ node="account">
+
+ <id name="id"
+ column="ACCOUNT_ID"
+ node="@id"
+ type="string"/>
+
+ <many-to-one name="customerId"
+ column="CUSTOMER_ID"
+ node="customer/@id"
+ embed-xml="false"
+ entity-name="Customer"/>
+
+ <property name="balance"
+ column="BALANCE"
+ node="balance"
+ type="big_decimal"/>
+
+ ...
+
+</class>]]></programlisting>
+
+ <para>
+ 这个映射使得你既可以把数据作为一棵dom4j树那样访问,又可以作为由属性键值对(java <literal>Map</literal>s)
+ 组成的图那样访问。属性名字纯粹是逻辑上的结构,你可以在HQL查询中引用它。
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="xml-mapping" revision="1">
+ <title>XML映射元数据</title>
+
+ <para>
+ 许多Hibernate映射元素具有<literal>node</literal>属性。这使你可以指定用来保存
+ 属性或实体数据的XML属性或元素。<literal>node</literal>属性必须是下列格式之一:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>"element-name"</literal> - 映射为指定的XML元素</para>
+ </listitem>
+ <listitem>
+ <para><literal>"@attribute-name"</literal> - 映射为指定的XML属性</para>
+ </listitem>
+ <listitem>
+ <para><literal>"."</literal> - 映射为父元素</para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>"element-name/@attribute-name"</literal> -
+ 映射为指定元素的指定属性
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 对于集合和单值的关联,有一个额外的<literal>embed-xml</literal>属性可用。
+ 这个属性的缺省值是真(<literal>embed-xml="true"</literal>)。如果<literal>embed-xml="true"</literal>,
+ 则对应于被关联实体或值类型的集合的XML树将直接嵌入拥有这些关联的实体的XML树中。
+ 否则,如果<literal>embed-xml="false"</literal>,那么对于单值的关联,仅被引用的实体的标识符出现在
+ XML树中(被引用实体本身不出现),而集合则根本不出现。
+ </para>
+
+ <para>
+ 你应该小心,不要让太多关联的embed-xml属性为真(<literal>embed-xml="true"</literal>),因为XML不能很好地处理
+ 循环引用!
+ </para>
+
+ <programlisting><![CDATA[<class name="Customer"
+ table="CUSTOMER"
+ node="customer">
+
+ <id name="id"
+ column="CUST_ID"
+ node="@id"/>
+
+ <map name="accounts"
+ node="."
+ embed-xml="true">
+ <key column="CUSTOMER_ID"
+ not-null="true"/>
+ <map-key column="SHORT_DESC"
+ node="@short-desc"
+ type="string"/>
+ <one-to-many entity-name="Account"
+ embed-xml="false"
+ node="account"/>
+ </map>
+
+ <component name="name"
+ node="name">
+ <property name="firstName"
+ node="first-name"/>
+ <property name="initial"
+ node="initial"/>
+ <property name="lastName"
+ node="last-name"/>
+ </component>
+
+ ...
+
+</class>]]></programlisting>
+
+ <para>
+ 在这个例子中,我们决定嵌入帐目号码(account id)的集合,但不嵌入实际的帐目数据。下面的HQL查询:
+ </para>
+
+ <programlisting><![CDATA[from Customer c left join fetch c.accounts where c.lastName like :lastName]]></programlisting>
+
+ <para>
+ 返回的数据集将是这样:
+ </para>
+
+ <programlisting><![CDATA[<customer id="123456789">
+ <account id="987632567" short-desc="Savings"/>
+ <account id="985612323" short-desc="Credit Card"/>
+ <name>
+ <first-name>Gavin</first-name>
+ <initial>A</initial>
+ <last-name>King</last-name>
+ </name>
+ ...
+</customer>]]></programlisting>
+
+ <para>
+ 如果你把一对多映射<literal><one-to-many></literal>的embed-xml属性置为真(<literal>embed-xml="true"</literal>),
+ 则数据看上去就像这样:
+ </para>
+
+ <programlisting><![CDATA[<customer id="123456789">
+ <account id="987632567" short-desc="Savings">
+ <customer id="123456789"/>
+ <balance>100.29</balance>
+ </account>
+ <account id="985612323" short-desc="Credit Card">
+ <customer id="123456789"/>
+ <balance>-2370.34</balance>
+ </account>
+ <name>
+ <first-name>Gavin</first-name>
+ <initial>A</initial>
+ <last-name>King</last-name>
+ </name>
+ ...
+</customer>]]></programlisting>
+
+ </sect1>
+
+
+ <sect1 id="xml-manipulation" revision="1">
+ <title>操作XML数据</title>
+
+ <para>
+ 让我们来读入和更新应用程序中的XML文档。通过获取一个dom4j会话可以做到这一点:
+ </para>
+
+ <programlisting><![CDATA[Document doc = ....;
+
+Session session = factory.openSession();
+Session dom4jSession = session.getSession(EntityMode.DOM4J);
+Transaction tx = session.beginTransaction();
+
+List results = dom4jSession
+ .createQuery("from Customer c left join fetch c.accounts where c.lastName like :lastName")
+ .list();
+for ( int i=0; i<results.size(); i++ ) {
+ //add the customer data to the XML document
+ Element customer = (Element) results.get(i);
+ doc.getRootElement().add(customer);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <programlisting><![CDATA[Session session = factory.openSession();
+Session dom4jSession = session.getSession(EntityMode.DOM4J);
+Transaction tx = session.beginTransaction();
+
+Element cust = (Element) dom4jSession.get("Customer", customerId);
+for ( int i=0; i<results.size(); i++ ) {
+ Element customer = (Element) results.get(i);
+ //change the customer name in the XML and database
+ Element name = customer.element("name");
+ name.element("first-name").setText(firstName);
+ name.element("initial").setText(initial);
+ name.element("last-name").setText(lastName);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ 将这一特色与Hibernate的<literal>replicate()</literal>操作结合起来对于实现的基于XML的数据导入/导出将非常有用.
+ </para>
+
+ </sect1>
+
+</chapter>
Deleted: core/trunk/documentation/manual/zh-CN/src/main/docbook/glossary.txt
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/glossary.txt 2007-10-09 19:32:35 UTC (rev 14080)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/glossary.txt 2007-10-09 20:10:34 UTC (rev 14081)
@@ -1,27 +0,0 @@
-O/R Mapping 对象/关系数据库映射
-identifier property: 标识属性
-discriminator: 辨别标志(不使用"鉴别器")
-
-join-subclass,union-subclass,join: 不翻译
-
-fine-grained 细粒度
-domain model 领域模型
-business object 业务对象(v2的时候翻译为"商业对象",被无数人痛骂....)
-annotations 注解(这个词还比较新,也见到有翻译为"特殊注释"/"标注"的)
-
-Aggregate functions 统计函数 (聚集函数?聚合函数? 还是翻译为统计函数才能让人看懂)
-Criteria Queries 条件查询(标准查询?这里Criteria是"判据"的含义,而非"标准",意译为条件查询更加明白)
-
-session flush session清洗
-lazy fetching 延迟加载(懒加载,翻译很直白,但是却不易理解)
-
-对象状态:
- persistent class 持久化类
- persistent object 持久对象 (体现这是与某个持久化设备联系的,掉电之后不消失)
- transient object 瞬时对象 (其含义是仅在内存中存在的,掉电之后消失,翻译为瞬时对象比较好)
- detached object 脱管对象(与session脱离的对象)
-
-outer-join fetching 外连接抓取 (fetch一般翻译为"获取",v2翻译的时候,为了突出其主动获取的特点,翻译为"抓取")
-
-class hierarchy 类分层结构 http://www.umlchina.com/xprogrammer/glossary1.htm
-inheritance hierarchy 继承层次 http://www-128.ibm.com/developerworks/cn/java/j-aopwork4/?ca=dwcn-newslet...
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/AuthorWork.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/AuthorWork.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/AuthorWork.zargo (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/AuthorWork.zargo)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/CustomerOrderProduct.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/CustomerOrderProduct.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/CustomerOrderProduct.zargo (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/CustomerOrderProduct.zargo)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/EmployerEmployee.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/EmployerEmployee.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/EmployerEmployee.zargo (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/EmployerEmployee.zargo)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/full_cream.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/full_cream.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/full_cream.svg (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/full_cream.svg)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/images/full_cream.svg (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/images/full_cream.svg 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,429 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="354.331"
+ height="336.614"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,5.25349)"
+ style="font-size:12;"
+ id="g659">
+ <rect
+ width="212.257"
+ height="57.2441"
+ x="17.9576"
+ y="100.132"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ transform="matrix(0.743454,0,0,0.482981,6.46949,52.2178)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <rect
+ width="325.86"
+ height="63.6537"
+ x="17.4083"
+ y="15.194"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="325.86"
+ height="63.6537"
+ x="13.6713"
+ y="12.4966"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ <g
+ transform="matrix(1.14345,0,0,0.729078,-1.67818,105.325)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <text
+ x="170.824753"
+ y="58.402939"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="170.824997"
+ y="58.402901"
+ id="tspan360">
+Application</tspan>
+ </text>
+ <text
+ x="178.076340"
+ y="364.281433"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="178.076004"
+ y="364.281006"
+ id="tspan421">
+Database</tspan>
+ </text>
+ <text
+ x="68.605331"
+ y="138.524582"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="68.605301"
+ y="138.524994"
+ id="tspan384">
+SessionFactory</tspan>
+ </text>
+ <rect
+ width="67.0014"
+ height="101.35"
+ x="196.927"
+ y="89.2389"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect387" />
+ <rect
+ width="67.0014"
+ height="101.35"
+ x="194.633"
+ y="86.4389"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect388" />
+ <text
+ x="249.108841"
+ y="173.885559"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text389">
+ <tspan
+ x="249.108994"
+ y="173.886002"
+ id="tspan392">
+Session</tspan>
+ </text>
+ <rect
+ width="73.0355"
+ height="101.35"
+ x="270.995"
+ y="90.0018"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect395" />
+ <rect
+ width="73.0355"
+ height="101.35"
+ x="267.869"
+ y="87.2018"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect396" />
+ <text
+ x="328.593658"
+ y="174.715622"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text397">
+ <tspan
+ x="328.593994"
+ y="174.716003"
+ id="tspan563">
+Transaction</tspan>
+ </text>
+ <g
+ transform="matrix(0.29544,0,0,0.397877,9.70533,103.96)"
+ style="font-size:12;"
+ id="g565">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect566" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect567" />
+ </g>
+ <text
+ x="25.592752"
+ y="204.497803"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:10;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text568">
+ <tspan
+ x="25.592800"
+ y="204.498001"
+ id="tspan662">
+TransactionFactory</tspan>
+ </text>
+ <g
+ transform="matrix(0.298082,0,0,0.397877,99.6898,103.96)"
+ style="font-size:12;"
+ id="g573">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect574" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect575" />
+ </g>
+ <text
+ x="134.030670"
+ y="205.532791"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:10;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text576">
+ <tspan
+ x="134.031006"
+ y="205.533005"
+ id="tspan664">
+ConnectionProvider</tspan>
+ </text>
+ <g
+ transform="matrix(1.14345,0,0,0.729078,-1.67818,38.9539)"
+ style="font-size:12;"
+ id="g587">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect588" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect589" />
+ </g>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="25.6196"
+ y="206.028"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect594" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="24.4229"
+ y="204.135"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect595" />
+ <text
+ x="85.575645"
+ y="282.300354"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text596">
+ <tspan
+ x="85.575600"
+ y="282.299988"
+ id="tspan607">
+JNDI</tspan>
+ </text>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="236.937"
+ y="206.791"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect610" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="235.741"
+ y="204.898"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect611" />
+ <text
+ x="342.093201"
+ y="283.226410"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text612">
+ <tspan
+ x="342.092987"
+ y="283.226013"
+ id="tspan621">
+JTA</tspan>
+ </text>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="130.134"
+ y="206.791"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect616" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="128.937"
+ y="204.898"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect617" />
+ <text
+ x="212.445343"
+ y="283.226410"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text618">
+ <tspan
+ x="212.445007"
+ y="283.226013"
+ id="tspan623">
+JDBC</tspan>
+ </text>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,6.19341)"
+ style="font-size:12;"
+ id="g637">
+ <g
+ transform="matrix(0.499515,0,0,0.415467,-0.237339,5.61339)"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="33.749969"
+ y="50.589706"
+ style="font-size:11;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="33.750000"
+ y="50.589699"
+ id="tspan635">
+Transient Objects</tspan>
+ </text>
+ </g>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,5.25349)"
+ style="font-size:12;"
+ id="g644">
+ <g
+ transform="matrix(0.297486,0,0,0.516482,230.251,36.9178)"
+ id="g364">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect365" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect366" />
+ </g>
+ <text
+ x="277.123230"
+ y="85.155571"
+ style="font-size:11;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text367">
+ <tspan
+ x="277.122986"
+ y="85.155602"
+ id="tspan631">
+Persistent</tspan>
+ <tspan
+ x="277.122986"
+ y="96.155602"
+ id="tspan633">
+Objects</tspan>
+ </text>
+ </g>
+</svg>
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/hibernate_logo_a.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/hibernate_logo_a.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/lite.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/lite.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/lite.svg (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/lite.svg)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/images/lite.svg (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/images/lite.svg 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,334 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="318.898"
+ height="248.031"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <rect
+ width="291.837"
+ height="57.0074"
+ x="17.3169"
+ y="18.646"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="291.837"
+ height="57.0074"
+ x="13.9703"
+ y="16.2302"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ <g
+ transform="matrix(0.326107,0,0,0.765831,9.59261,8.98517)"
+ style="font-size:12;"
+ id="g161">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <g
+ transform="matrix(1.02406,0,0,0.652953,0.223384,39.9254)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <g
+ transform="matrix(0.449834,0,0,0.338463,-3.15909,9.73319)"
+ style="font-size:12;"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="302.277679"
+ y="65.943230"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="302.277954"
+ y="65.943184"
+ id="tspan360">
+Application</tspan>
+ </text>
+ <text
+ x="36.235924"
+ y="63.796055"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:14;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="36.235950"
+ y="63.796051"
+ id="tspan427">
+Transient Objects</tspan>
+ </text>
+ <text
+ x="180.416245"
+ y="290.543701"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="180.415939"
+ y="290.543549"
+ id="tspan421">
+Database</tspan>
+ </text>
+ <text
+ x="25.037701"
+ y="179.154755"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="25.037655"
+ y="179.154648"
+ id="tspan384">
+SessionFactory</tspan>
+ </text>
+ <g
+ transform="matrix(0.252763,0,0,0.765831,109.104,8.98517)"
+ style="font-size:12;"
+ id="g386">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect387" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect388" />
+ </g>
+ <g
+ transform="matrix(0.297394,0,0,0.572692,101.502,21.6359)"
+ style="font-size:12;"
+ id="g364">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect365" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect366" />
+ </g>
+ <text
+ x="202.746506"
+ y="102.992203"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:14;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text367">
+ <tspan
+ x="202.746948"
+ y="102.992249"
+ id="tspan423">
+Persistent</tspan>
+ <tspan
+ x="202.746948"
+ y="116.992355"
+ id="tspan425">
+Objects</tspan>
+ </text>
+ <text
+ x="174.458496"
+ y="180.080795"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text389">
+ <tspan
+ x="174.458618"
+ y="180.080338"
+ id="tspan392">
+Session</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,188.675,8.98517)"
+ style="font-size:12;"
+ id="g394">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect395" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect396" />
+ </g>
+ <text
+ x="260.413269"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text397">
+ <tspan
+ x="260.412964"
+ y="179.154343"
+ id="tspan400">
+JDBC</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,229.156,8.98517)"
+ style="font-size:12;"
+ id="g405">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect406" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect407" />
+ </g>
+ <text
+ x="320.606903"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text408">
+ <tspan
+ x="320.606964"
+ y="179.154343"
+ id="tspan417">
+JNDI</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,269.281,8.98517)"
+ style="font-size:12;"
+ id="g411">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect412" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect413" />
+ </g>
+ <text
+ x="377.096313"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text414">
+ <tspan
+ x="377.096008"
+ y="179.154999"
+ id="tspan145">
+JTA</tspan>
+ </text>
+</svg>
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/overview.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/overview.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/images/overview.svg (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/overview.svg)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/images/overview.svg (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/images/overview.svg 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,250 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="248.031"
+ height="248.031"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,-3.02123)"
+ style="font-size:12;"
+ id="g158">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="17.3527"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="15.3883"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,3.04452)"
+ style="font-size:12;"
+ id="g161">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,8.0993)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.543505,2.59104,21.1103)"
+ style="font-size:12;"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="105.392174"
+ y="56.568123"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="105.392273"
+ y="56.568146"
+ id="tspan186">
+Application</tspan>
+ </text>
+ <text
+ x="81.820183"
+ y="103.149330"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:20;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="81.820213"
+ y="103.149727"
+ id="tspan206">
+Persistent Objects</tspan>
+ </text>
+ <text
+ x="111.548180"
+ y="278.927887"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="111.547874"
+ y="278.927551"
+ id="tspan200">
+Database</tspan>
+ </text>
+ <text
+ x="94.436180"
+ y="153.805740"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="94.436180"
+ y="153.805740"
+ id="tspan221">
+HIBERNATE</tspan>
+ </text>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,2.59083,1.02261)"
+ style="font-size:12;"
+ id="g254">
+ <g
+ transform="translate(4.58374,2.61928)"
+ id="g176">
+ <g
+ transform="matrix(0.571429,0,0,0.67347,-10.6174,117.093)"
+ id="g170">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect171" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect172" />
+ </g>
+ <g
+ transform="matrix(0.571429,0,0,0.67347,138.682,117.093)"
+ id="g173">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect174" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect175" />
+ </g>
+ </g>
+ <text
+ x="47.259438"
+ y="182.367538"
+ style="font-weight:bold;stroke-width:1pt;font-family:Courier;"
+ id="text191">
+ <tspan
+ x="47.259399"
+ y="182.367996"
+ id="tspan212">
+hibernate.</tspan>
+ <tspan
+ x="47.259399"
+ y="194.367996"
+ id="tspan214">
+properties</tspan>
+ </text>
+ <text
+ x="198.523010"
+ y="188.260941"
+ style="font-weight:normal;stroke-width:1pt;font-family:helvetica;"
+ id="text194">
+ <tspan
+ id="tspan195">
+XML Mapping</tspan>
+ </text>
+ </g>
+</svg>
Copied: core/trunk/documentation/manual/zh-CN/src/main/docbook/legal_notice.xml (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/legal_notice.xml)
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/legal_notice.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/legal_notice.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,52 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!DOCTYPE legalnotice PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<legalnotice id="Legal_Notice">
+ <title>Legal Notice</title>
+ <para>
+ <address>
+ <street>1801 Varsity Drive</street>
+ <city>Raleigh</city>, <state>NC</state><postcode>27606-2072</postcode><country>USA</country>
+ <phone>Phone: +1 919 754 3700</phone>
+ <phone>Phone: 888 733 4281</phone>
+ <fax>Fax: +1 919 754 3701</fax>
+ <pob>PO Box 13588</pob><city>Research Triangle Park</city>, <state>NC</state><postcode>27709</postcode><country>USA</country>
+ </address>
+ </para>
+ <para>
+ Copyright <trademark class="copyright"></trademark> 2007 by Red Hat, Inc. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, V1.0 or later (the latest version is presently available at <ulink url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).
+ </para>
+ <para>
+ Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder.
+ </para>
+ <para>
+ Distribution of the work or derivative of the work in any standard (paper) book form for commercial purposes is prohibited unless prior permission is obtained from the copyright holder.
+ </para>
+ <para>
+ Red Hat and the Red Hat "Shadow Man" logo are registered trademarks of Red Hat, Inc. in the United States and other countries.
+ </para>
+ <para>
+ All other trademarks referenced herein are the property of their respective owners.
+ </para>
+ <para>
+ The GPG fingerprint of the security(a)redhat.com key is:
+ </para>
+ <para>
+ CA 20 86 86 2B D6 9D FC 65 F6 EC C4 21 91 80 CD DB 42 A6 0E
+ </para>
+</legalnotice>
\ No newline at end of file
Deleted: core/trunk/documentation/manual/zh-CN/src/main/docbook/master.xml
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/master.xml 2007-10-09 19:32:35 UTC (rev 14080)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/master.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -1,474 +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 tutorial SYSTEM "modules/tutorial.xml">
-<!ENTITY architecture SYSTEM "modules/architecture.xml">
-<!ENTITY configuration SYSTEM "modules/configuration.xml">
-<!ENTITY persistent-classes SYSTEM "modules/persistent_classes.xml">
-<!ENTITY basic-mapping SYSTEM "modules/basic_mapping.xml">
-<!ENTITY collection-mapping SYSTEM "modules/collection_mapping.xml">
-<!ENTITY association-mapping SYSTEM "modules/association_mapping.xml">
-<!ENTITY component-mapping SYSTEM "modules/component_mapping.xml">
-<!ENTITY inheritance-mapping SYSTEM "modules/inheritance_mapping.xml">
-<!ENTITY session-api SYSTEM "modules/session_api.xml">
-<!ENTITY transactions SYSTEM "modules/transactions.xml">
-<!ENTITY events SYSTEM "modules/events.xml">
-<!ENTITY batch SYSTEM "modules/batch.xml">
-<!ENTITY query-hql SYSTEM "modules/query_hql.xml">
-<!ENTITY query-criteria SYSTEM "modules/query_criteria.xml">
-<!ENTITY query-sql SYSTEM "modules/query_sql.xml">
-<!ENTITY filters SYSTEM "modules/filters.xml">
-<!ENTITY xml SYSTEM "modules/xml.xml">
-<!ENTITY performance SYSTEM "modules/performance.xml">
-<!ENTITY toolset-guide SYSTEM "modules/toolset_guide.xml">
-<!ENTITY example-parentchild SYSTEM "modules/example_parentchild.xml">
-<!ENTITY example-weblog SYSTEM "modules/example_weblog.xml">
-<!ENTITY example-mappings SYSTEM "modules/example_mappings.xml">
-<!ENTITY best-practices SYSTEM "modules/best_practices.xml">
-]>
-
-
-<book lang="zh-cn">
-
- <bookinfo>
- <title>HIBERNATE - 符合Java习惯的关系数据库持久化</title>
-
- <subtitle>Hibernate参考文档</subtitle>
- <releaseinfo>3.2</releaseinfo>
- </bookinfo>
-
- <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(a)yahoo.com>
- </para>
-
- <para>
- 在今日的企业环境中,把面向对象的软件和关系数据库一起使用可能是相当麻烦、浪费时间的。Hibernate是一个面向Java环境的对象/关系数据库映射工具。对象/关系数据库映射(object/relational mapping (ORM))这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去。
- </para>
-
- <para>
- Hibernate不仅仅管理Java类到数据库表的映射(包括Java数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用SQL和JDBC处理数据的时间。
- </para>
-
- <para>
- Hibernate的目标是对于开发者通常的数据持久化相关的编程任务,解放其中的95%。对于以数据为中心的程序来说,它们往往只在数据库中使用存储过程来实现商业逻辑,Hibernate可能不是最好的解决方案;对于那些在基于Java的中间层应用中,它们实现面向对象的业务模型和商业逻辑的应用,Hibernate是最有用的。不管怎样,Hibernate一定可以帮助你消除或者包装那些针对特定厂商的SQL代码,并且帮你把结果集从表格式的表示形式转换到一系列的对象去。
- </para>
-
- <para>
- 如果你对Hibernate和对象/关系数据库映射还是个新手,或者甚至对Java也不熟悉,请按照下面的步骤来学习。
- </para>
-
- <orderedlist>
- <listitem>
- <para>
- 阅读<xref linkend="tutorial"/>,这是一篇包含详细的逐步指导的指南。本指南的源代码包含在发行包中,你可以在<literal>doc/reference/tutorial/</literal>目录下找到。 </para>
- </listitem>
- <listitem>
- <para>
- 阅读<xref linkend="architecture"/>来理解Hibernate可以使用的环境。
- </para>
- </listitem>
- <listitem>
- <para>
- 查看Hibernate发行包中的<literal>eg/</literal>目录,里面有一个简单的独立运行的程序。把你的JDBC驱动拷贝到<literal>lib/</literal>目录下,修改一下<literal>src/hibernate.properties</literal>,指定其中你的数据库的信息。进入命令行,切换到你的发行包的目录,输入<literal>ant eg</literal>(使用了Ant),或者在Windows操作系统中使用<literal>build eg</literal>。
- </para>
- </listitem>
- <listitem>
- <para>
- 把这份参考文档作为你学习的主要信息来源。
- </para>
- </listitem>
- <listitem>
- <para>
- 在Hibernate 的网站上可以找到经常提问的问题与解答(FAQ)。
- </para>
- </listitem>
- <listitem>
- <para>
- 在Hibernate网站上还有第三方的演示、示例和教程的链接。
- </para>
- </listitem>
- <listitem>
- <para>
- Hibernate网站的“社区(Community Area)”是讨论关于设计模式以及很多整合方案(Tomcat, JBoss AS, Struts, EJB,等等)的好地方。
- </para>
- </listitem>
- </orderedlist>
-
- <para>
- 如果你有问题,请使用Hibernate网站上链接的用户论坛。我们也提供一个JIRA问题追踪系统,来搜集bug报告和新功能请求。如果你对开发Hibernate有兴趣,请加入开发者的邮件列表。(Hibernate网站上的用户论坛有一个中文版面,JavaEye也有Hibernate中文版面,您可以在那里交流问题与经验。)
- </para>
-
- <para>
- 商业开发、产品支持和Hibernate培训可以通过JBoss Inc.获得。(请查阅:http://www.hibernate.org/SupportTraining/)。
- Hibernate是一个专业的开放源代码项目(Professional Open Source project),也是JBoss Enterprise Middleware System(JEMS),JBoss企业级中间件系统的一个核心组件。
- </para>
-
- <sect1 id="preface-translate-comments-zh-cn">
- <title>翻译说明</title>
-
- <para>
- 本文档的翻译是在网络上协作进行的,也会不断根据Hibernate的升级进行更新。提供此文档的目的是为了减缓学习Hibernate的坡度,而非代替原文档。我们建议所有有能力的读者都直接阅读英文原文。若您对翻译有异议,或发现翻译错误,敬请不吝赐教,报告到如下email地址:cao at redsaga.com
- </para>
-
- <para>
- Hibernate版本3的翻译由满江红翻译团队(RedSaga Translate Team)集体进行,这也是一次大规模网络翻译的试验。在不到20天的时间内,我们完成了两百多页文档的翻译,这一成果是通过十几位网友集体努力完成的。通过这次翻译,我们也有了一套完整的流程,从初译、技术审核一直到文字审核、发布。我们的翻译团队还会继续完善我们的翻译流程,并翻译其他优秀的Java开源资料,敬请期待。
- </para>
-
- <table frame="topbot" id="redsaga-translate-team">
- <title>
- Hibernate v3翻译团队
- </title>
- <tgroup cols="5" rowsep="1" colsep="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">
- v3翻译
- </entry>
- <entry align="center">
- v3审校
- </entry>
- <entry align="center">
- v3.1审校
- </entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>--</entry>
- <entry>Quickstart with Tomcat</entry>
- <entry>在Tomcat中快速上手(3.1版本中取消)</entry>
- <entry>曹晓钢</entry>
- <entry>zoujm</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#1</entry>
- <entry>Turtotial</entry>
- <entry>Hibernate入门</entry>
- <entry>Zheng Shuai</entry>
- <entry>-</entry>
- <entry>Sean Chan</entry>
- </row>
- <row>
- <entry>#2</entry>
- <entry>Architecture</entry>
- <entry>体系结构</entry>
- <entry>Hilton(BJUG)</entry>
- <entry>厌倦发呆</entry>
- <entry>Sean Chan</entry>
- </row>
- <row>
- <entry>#3</entry>
- <entry>Configuration</entry>
- <entry>配置</entry>
- <entry>Goncha</entry>
- <entry>mochow</entry>
- <entry>zcgly</entry>
- </row>
- <row>
- <entry>#4</entry>
- <entry>Persistent Classes</entry>
- <entry>持久化类</entry>
- <entry>曹晓钢</entry>
- <entry>mochow</entry>
- <entry>DigitalSonic</entry>
- </row>
- <row>
- <entry>#5</entry>
- <entry>Basic O/R Mapping</entry>
- <entry>对象/关系数据库映射基础(上)</entry>
- <entry>moxie</entry>
- <entry>Kingfish</entry>
- <entry>张成钢</entry>
- </row>
- <row>
- <entry></entry>
- <entry></entry>
- <entry>对象/关系数据库映射基础(下)</entry>
- <entry>inter_dudu</entry>
- <entry>刘国雄(vincent)</entry>
- <entry>张成钢</entry>
- </row>
- <row>
- <entry>#6</entry>
- <entry>Collection Mapping</entry>
- <entry>集合类映射</entry>
- <entry>曹晓钢</entry>
- <entry>robbin</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#7</entry>
- <entry>Association Mappings</entry>
- <entry>关联关系映射</entry>
- <entry>Robbin</entry>
- <entry>devils.advocate</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#8</entry>
- <entry>Component Mapping</entry>
- <entry>组件映射</entry>
- <entry>曹晓钢</entry>
- <entry>Robbin</entry>
- <entry>Song guo qiang</entry>
- </row>
- <row>
- <entry>#9</entry>
- <entry>Inheritance Mappings</entry>
- <entry>继承映射</entry>
- <entry>morning(BJUG)</entry>
- <entry>mochow</entry>
- <entry>Liang cheng</entry>
- </row>
- <row>
- <entry>#10</entry>
- <entry>Working with objects</entry>
- <entry>与对象共事</entry>
- <entry>程广楠</entry>
- <entry>厌倦发呆</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#11</entry>
- <entry>Transactions And Concurrency</entry>
- <entry>事务和并发</entry>
- <entry>Robbin</entry>
- <entry>mochow</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#12</entry>
- <entry>Interceptors and events</entry>
- <entry>继承映射</entry>
- <entry>七彩狼(BJUG)</entry>
- <entry>厌倦发呆</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#13</entry>
- <entry>Batch processing</entry>
- <entry>批量处理</entry>
- <entry>Kingfish(BJUG)</entry>
- <entry>厌倦发呆</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#14</entry>
- <entry>HQL: The Hibernate Query Language</entry>
- <entry>HQL: Hibernate查询语言</entry>
- <entry>郑浩(BJUG)</entry>
- <entry>Zheng Shuai</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#15</entry>
- <entry>Criteria Queries</entry>
- <entry>条件查询</entry>
- <entry>nemo(BJUG)</entry>
- <entry>Zheng Shuai</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#16</entry>
- <entry>Native SQL</entry>
- <entry>Native SQL查询</entry>
- <entry>似水流年</entry>
- <entry>zoujm</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#17</entry>
- <entry>Filters</entry>
- <entry>过滤数据</entry>
- <entry>冰云(BJUG)</entry>
- <entry>Goncha</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#18</entry>
- <entry>XML Mapping</entry>
- <entry>XML映射</entry>
- <entry>edward(BJUG)</entry>
- <entry>Goncha</entry>
- <entry>huxb</entry>
- </row>
- <row>
- <entry>#19</entry>
- <entry>Improving performance</entry>
- <entry>性能提升</entry>
- <entry>Wangjinfeng</entry>
- <entry>Robbin</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#20</entry>
- <entry>Toolset Guide</entry>
- <entry>工具箱指南</entry>
- <entry>曹晓钢</entry>
- <entry>Robbin</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#21</entry>
- <entry>Example: Parent/Child</entry>
- <entry>示例:父子关系</entry>
- <entry>曹晓钢</entry>
- <entry>devils.advocate</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#22</entry>
- <entry>Example: Weblog Application</entry>
- <entry>示例:Weblog 应用程序</entry>
- <entry>曹晓钢</entry>
- <entry>devils.advocate</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#23</entry>
- <entry>Example: Various Mappings</entry>
- <entry>示例:多种映射</entry>
- <entry>shidu(BJUG)</entry>
- <entry>冰云</entry>
- <entry>--</entry>
- </row>
- <row>
- <entry>#24</entry>
- <entry>Best Practices</entry>
- <entry>最佳实践</entry>
- <entry>曹晓钢</entry>
- <entry>冰云</entry>
- <entry>--</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>
- v3.2版本在2006年11月份由曹晓钢更新。
- </para>
-
- <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>北京Java用户组, http://www.bjug.org</term>
- <listitem>
- <para>
- Beiing Java User Group,民间技术交流组织,成立于2004年6月。以交流与共享为宗旨,每两周举行一次技术聚会活动。BJUG的目标是,通过小部分人的努力,形成一个技术社群,创建良好的交流氛围,并将新的技术和思想推广到整个IT界,让我们共同进步。
-
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Java视线, http://www.javaeye.com</term>
- <listitem>
- <para>
- Java视线在是Hibernate中文论坛(http://www.hibernate.org.cn,Hibernate中文论坛是中国最早的Hibernate专业用户论坛,为Hibernate在中国的推广做出了巨大的贡献)基础上发展起来的Java深度技术网站,目标是成为一个高品质的,有思想深度的、原创精神的Java技术交流网站,为软件从业人员提供一个自由的交流技术,交流思想和交流信息的平台。
-
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>致谢</term>
- <listitem>
- <para>还有一些朋友给我们发来了勘误,在此致谢:Kurapica,李毅,李海林。
- </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>
-
- &tutorial;
-
- &architecture;
-
- &configuration;
-
- &persistent-classes;
-
- &basic-mapping;
- &collection-mapping;
- &association-mapping;
- &component-mapping;
- &inheritance-mapping;
-
- &session-api;
- &transactions;
- &events;
- &batch;
-
- &query-hql;
- &query-criteria;
- &query-sql;
- &filters;
- &xml;
-
- &performance;
-
- &toolset-guide;
-
- &example-parentchild;
- &example-weblog;
- &example-mappings;
-
- &best-practices;
-
-</book>
-
Added: core/trunk/documentation/manual/zh-CN/src/main/docbook/translators.xml
===================================================================
--- core/trunk/documentation/manual/zh-CN/src/main/docbook/translators.xml (rev 0)
+++ core/trunk/documentation/manual/zh-CN/src/main/docbook/translators.xml 2007-10-09 20:10:34 UTC (rev 14081)
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding="UTF-8"?>
+
+<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<authorgroup id="translators">
+
+ <othercredit class="translator">
+ <firstname>Cao</firstname>
+ <surname>Xiaogang</surname>
+ <affiliation>
+ <orgname>RedSaga</orgname>
+ </affiliation>
+ <contrib>Translation Lead</contrib>
+ <email>caoxg(a)yahoo.com</email>
+ </othercredit>
+
+</authorgroup>
18 years, 6 months
Hibernate SVN: r14080 - in core/trunk/documentation/manual/pt-BR/src/main: docbook and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2007-10-09 15:32:35 -0400 (Tue, 09 Oct 2007)
New Revision: 14080
Added:
core/trunk/documentation/manual/pt-BR/src/main/docbook/Hibernate_Reference.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/architecture.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/association_mapping.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/basic_mapping.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/batch.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/best_practices.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/collection_mapping.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/component_mapping.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/configuration.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/events.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_mappings.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_parentchild.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_weblog.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/filters.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/inheritance_mapping.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/performance.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/persistent_classes.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/preface.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_criteria.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_hql.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_sql.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/session_api.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/toolset_guide.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/transactions.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tutorial.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tutorial1.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/content/xml.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/AuthorWork.png
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/AuthorWork.zargo
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/CustomerOrderProduct.png
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/CustomerOrderProduct.zargo
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/EmployerEmployee.png
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/EmployerEmployee.zargo
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/full_cream.png
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/full_cream.svg
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/hibernate_logo_a.png
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/lite.png
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/lite.svg
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/overview.png
core/trunk/documentation/manual/pt-BR/src/main/docbook/images/overview.svg
core/trunk/documentation/manual/pt-BR/src/main/docbook/legal_notice.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/legal_notice2.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/translators.xml
Removed:
core/trunk/documentation/manual/pt-BR/src/main/docbook/master.xml
core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/
core/trunk/documentation/manual/pt-BR/src/main/resources/
Log:
new docbook layout (prep for translations migration to PO)
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/Hibernate_Reference.xml (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/Hibernate_Reference.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/Hibernate_Reference.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/Hibernate_Reference.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,73 @@
+<?xml version='1.0' encoding="iso-8859-1"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+ <!ENTITY versionNumber "3.3.0.alpha1">
+ <!ENTITY copyrightYear "2004">
+ <!ENTITY copyrightHolder "Red Hat Middleware, LLC.">
+]>
+
+<book>
+
+ <bookinfo>
+ <title>HIBERNATE - Relational Persistence for Idiomatic Java</title>
+ <subtitle>Documenta��o da Refer�ncia do Hibernate</subtitle>
+ <releaseinfo>&versionNumber;</releaseinfo>
+ <productnumber>&versionNumber;</productnumber>
+ <issuenum>1</issuenum>
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/hibernate_logo_a.png" align="center" />
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="images/hibernate_logo_a.png" depth="3cm" />
+ </imageobject>
+ </mediaobject>
+ <copyright>
+ <year>©rightYear;</year>
+ <holder>©rightHolder;</holder>
+ </copyright>
+ <xi:include href="translators.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="legal_notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="legal_notice2.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </bookinfo>
+
+ <toc/>
+
+ <xi:include href="content/preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/tutorial.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/configuration.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/persistent_classes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/basic_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/collection_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/association_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/component_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/inheritance_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/session_api.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/transactions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/events.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/batch.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/query_hql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/query_criteria.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/query_sql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/filters.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/xml.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/performance.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/toolset_guide.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/example_parentchild.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/example_weblog.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/example_mappings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/best_practices.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+</book>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/architecture.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/architecture.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/architecture.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/architecture.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,374 @@
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<chapter id="architecture">
+
+ <title>Arquitetura</title>
+
+ <sect1 id="architecture-overview" revision="1">
+ <title>Visão Geral</title>
+
+ <para>
+ Uma visão bem ampla da arquitetura do Hibernate:
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/overview.svg" format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/overview.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ Esse diagrama mostra o Hibernate usando o banco de dados e a configuração
+ de dados para prover persistência de serviços (e persistência de objetos)
+ para o aplicativo.
+ </para>
+
+ <para>
+ Nós gostaríamos de mostrar uma visão mais detalhada da arquitetura em execução.
+ Infelizmente, o Hibernate é muito flexível e suporta várias aproximações.
+ Nós iremos mostrar os dois extremos. Na arquitetura mais simples o aplicativo
+ fornece suas próprias conexões JDBC e gerencia suas transações. Esta abordagem
+ usa o mínimo de subconjuntos das APIs do Hibernate:
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/lite.svg" format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/lite.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ A arquitetura "completa" abstrai a aplicação de ter de lidar diretamente
+ com JDBC/JTA e APIs e deixa o Hibernate tomar conta dos detalhes.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/full_cream.svg" format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/full_cream.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ Algumas definições dos objetos do diagrama:
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>SessionFactory (<literal>org.hibernate.SessionFactory</literal>)</term>
+ <listitem>
+ <para>
+ Um cache threadsafe (imutáveis) composto de identidades compiladas para um
+ único banco de dados. Uma fabrica para <literal>Session</literal> e um cliente
+ de <literal>ConnectionProvider</literal>. Pode conter um cachê opcional de
+ dados (segundo nível) reutilizáveis entre transações, no nível de processo- ou cluster.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Session (<literal>org.hibernate.Session</literal>)</term>
+ <listitem>
+ <para>
+ Objeto single-threaded, de vida curta, representando uma conversação entre
+ o aplicativo e o armazenamento persistente. Cria uma camada sobre uma conexão JDBC.
+ É uma fabrica de <literal>Transaction</literal>. Possui um cachê obrigatório
+ (primeiro nível) de objetos persistentes, usado para navegação no gráficos
+ de objetos e pesquisa de objetos pelo identificador.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Objetos persistentes e coleções</term>
+ <listitem>
+ <para>
+ Objetos, de vida curta, single threaded contendo estado persistente e função
+ de negócios. Esses podem ser JavaBeans/POJOs, onde única coisa especial sobre
+ eles é que são associados a (exatamente uma) <literal>Session</literal>.
+ Quando a <literal>Session</literal> é fechada, eles são separados e liberados
+ para serem usados dentro de qualquer camada da aplicacao (Ex. diretamente como
+ data transfer objects de e para a camada de apresentação)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Objetos e coleções desatachados e transientes</term>
+ <listitem>
+ <para>
+ Instâncias de classes persistentes que ainda não estão associadas a uma
+ <literal>Session</literal>. Eles podem ter sido instanciados pela aplicação
+ e não persistido (ainda) ou eles foram instanciados por uma <literal>Session</literal>
+ que foi encerrada.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Transaction (<literal>org.hibernate.Transaction</literal>)</term>
+ <listitem>
+ <para>
+ (Opcional) Objeto de vida curta, single threaded, usado pela aplicação para
+ especificar unidades atômicas de trabalho. Abstrai o aplicativo de lidar
+ diretamente com transações JDBC, JTA ou CORBA. Uma <literal>Session</literal> pode,
+ em alguns casos, iniciar várias <literal>Transaction</literal>s. Entretanto,
+ a demarcação da transação, mesmo utilizando API ou Transaction subjacentes,
+ nunca é opcional!
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ConnectionProvider (<literal>org.hibernate.connection.ConnectionProvider</literal>)</term>
+ <listitem>
+ <para>
+ (Opcional) Uma fábrica de (e combinações de) conexões JDBC. Abstrai a aplicação
+ de lidar diretamente com <literal>Datasource</literal> ou <literal>DriverManager</literal>.
+ Não exposto para a aplicação, mas pode ser implementado ou estendido pelo programador.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>TransactionFactory (<literal>org.hibernate.TransactionFactory</literal>)</term>
+ <listitem>
+ <para>
+ (Opcional) Uma fábrica para instâncias de <literal>Transaction</literal>. Não exposta
+ a aplicação, mas pode ser extendida/implementada pelo programador.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis>Extension Interfaces</emphasis></term>
+ <listitem>
+ <para>
+ O Hibernate oferece várias opções de interfaces estendidas que você pode implementar
+ para customizar sua camada persistente. Veja a documentação da API para maiores detalhes.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Dada uma arquitetura simples, o aplicativo passa pelas APIs
+ <literal>Transaction</literal>/<literal>TransactionFactory</literal> e/ou
+ <literal>ConnectionProvider</literal> para se comunicar diretamente com a transação JTA ou JDBC.
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-states" revision="1">
+ <title>Estados de instância</title>
+ <para>
+ Uma instância de classes persistentes pode estar em um dos três diferentes estados,
+ que são definidos respeitando um <emphasis>contexto persistente</emphasis>.
+ O objeto <literal>Session</literal> do Hibernate é o contexto persistente:
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>transiente</term>
+ <listitem>
+ <para>
+ A instância não é, e nunca foi associada com nenhum
+ contexto persistente. Não possui uma identidade persistente
+ (valor de chave primária).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>persistente</term>
+ <listitem>
+ <para>
+ A instância está atualmente associada a um contexto persistente.
+ Possui uma identidade persistente (valor de chave primária) e,
+ talvez, correspondente a um registro no banco de dados. Para um
+ contexto persistente em particular, o Hibernate
+ <emphasis>guarantees</emphasis> que a identidade persistente
+ é equivalente a identidade Java (na localização em memória do
+ objeto).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>desatachado</term>
+ <listitem>
+ <para>
+ A instância foi associada com um contexto persistente,
+ porém este contexto foi fechado, ou a instância
+ foi serializada por outro processo. Possui uma identidade
+ persistente, e, talvez, correspondenta a um registro no
+ banco de dados. Para instâncias desatachadas, o Hibernate
+ não garante o relacionamento entre identidade persistente
+ e identidade Java.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 id="architecture-jmx" revision="1">
+ <title>Integração JMX</title>
+
+ <para>
+ JMX é padrão J2EE para manipulação de componentes Java. O Hibernate pode ser manipulado
+ por um serviço JMX padrão. Nós fornecemos uma implementação do MBean na distribuição,
+ <literal>org.hibernate.jmx.HibernateService</literal>.
+ </para>
+
+ <para>
+ Para um exemplo de como instalar o Hibernate como um serviço JMX em um servidor de
+ aplicativo JBoss, por favor, consulte o manual do usuário do JBoss. No JBoss As, você
+ poderá ver os benefícios de de se fazer o deploy usando JMX:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Session Management:</emphasis> O ciclo de vida de uma <literal>Session</literal> do
+ Hibernate pode ser automaticamente conectada a um escopo de transação JTA. Isso significa
+ que você não precisará mais abrir e fechar manualmente uma <literal>Session</literal>, isso
+ se torna trabalho para um interceptor EJB do JBoss . Você também não precisa se preocupar,
+ nunca mais, com demarcação de transação em seu código (a não ser que você prefira escrever
+ uma camada persistente portável, para isso, use a API opcional do Hibernate
+ <literal>Transaction</literal>). Você deve chamar <literal>HibernateContext</literal>
+ para acessar uma <literal>Session</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>HAR deployment:</emphasis>: Normalmente você faz o deploy de um serviço JMX do
+ Hibernate usando um serviço descritor de deploy do JBoss (em um EAR e/ou arquivo SAR),
+ que suporta todas as configurações usuais de uma <literal>SessionFactory</literal> do
+ Hibernate. Entretanto, você ainda precisa nomear todos os seus arquivos de mapeamento
+ no descritor de deploração. Se você decidir usar o deploy opcional HAR, o JBoss irá
+ automaticamente detectar todos os seus arquivos de mapeamento no seu arquivo HAR.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Consulte o manual do usuário do JBoss AS, para obter maiores informações sobre essas opções.
+ </para>
+
+ <para>
+ Another feature available as a JMX service are runtime Hibernate statistics. See
+ <xref linkend="configuration-optional-statistics"/>.
+ Outra opção disponível como um serviço JMX são as estatísticas de execução do Hibernate.
+ Veja a <xref linkend="configuration-optional-statistics"/>.
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-jca" revision="1">
+ <title>Suporte JCA</title>
+ <para>
+ Hibernate may also be configured as a JCA connector. Please see the website for more
+ details. Please note that Hibernate JCA support is still considered experimental.
+ O Hibernate pode também ser configurado como um conector JCA. Por favor, visite o
+ website para maiores detalhes. Entretanto, note que o suporte JCA do Hibernate
+ ainda é considerado experimental.
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-current-session" revision="2">
+ <title>Sessões contextuais</title>
+ <para>
+ Muitas aplicações que usam o Hibernate necessita de algum tipo de sessão "contextual",
+ onde uma sessão dada é na verdade um escopo de um contexto. Entretanto, através de aplicações
+ a definição sobre um contexto é geralmente diferente; e contextos diferentes definem escopos
+ diferentes. Aplicações usando versões anteriores ao Hibernate 3.0 tendem a utilizar tanto
+ sessões contextuais baseadas em <literal>ThreadLocal</literal>, classes utilitárias como
+ <literal>HibernateUtil</literal>, ou utilizar frameworks de terceiros(como Spring ou Pico)
+ que provê sessões contextuais baseadas em proxy.
+
+ </para>
+ <para>
+ A partir da versão 3.0.1, o Hibernate adicionou o método <literal>SessionFactory.getCurrentSession()</literal>.
+ Inicialmente, este assume o uso de transações <literal>JTA</literal>, onde a transação
+ <literal>JTA</literal> define tanto o escopo quanto o contexto de uma sessão atual.
+ O time do Hibernate mantém este recurso, desenvolvendo as diversas implementações do
+ <literal>JTA TransactionManager</literal>, a maioria (se não todos) aplicativos deveria
+ utilizar o gerenciador de transações <literal>JTA</literal> sendo ou não instalados dentro
+ de um container <literal>J2EE</literal>. Baseado neste recurso, você deveria sempre utilizar sessões
+ contextuais baseadas em <literal>JTA</literal>.
+ </para>
+ <para>
+ Entretanto, na versão 3.1, o processo por trás do método <literal>SessionFactory.getCurrentSession()</literal>
+ é agora plugavel. Com isso, uma nova interface (<literal>org.hibernate.context.CurrentSessionContext</literal>)
+ e um novo parâmetro de configuração (<literal>hibernate.current_session_context_class</literal>)
+ foram adicionados para possibilitar a compatibilidade do contexto e do escopo na definição de sessões correntes.
+ </para>
+ <para>
+ De uma olhada em Javadocs sobre a interface <literal>org.hibernate.context.CurrentSessionContext</literal>
+ para uma discussão detalhada. Ela define um método único, <literal>currentSession()</literal>,
+ com o qual a implementação é responsável por rastrear a sessão contextual corrente.
+ Por fora do "encapsulamento", o Hibernate possui duas implementações dessa interface.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>org.hibernate.context.JTASessionContext</literal> - As sessões correntes
+ são rastreadas e recebem um escopo por uma transação <literal>JTA</literal>.
+ O processamento aqui é exatamente igual ao antigo processo JTA. Consulte em
+ Javadocs para maiores detalhes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>org.hibernate.context.ThreadLocalSessionContext</literal> - As sessões
+ correntes são rastreadas por uma thread de execução. Novamente, consulte em
+ Javadocs para maiores detalhes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>org.hibernate.context.ManagedSessionContext</literal> - current
+ sessions are tracked by thread of execution. However, you are responsible to
+ bind and unbind a <literal>Session</literal> instance with static methods
+ on this class, it does never open, flush, or close a <literal>Session</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ As duas primeiras implementações usam o modelo de programação "uma sessão – uma transação
+ do banco de dados", também conhecida e usado como <emphasis>sessão por requisição</emphasis>.
+ O começo e o fim de uma sessão Hibernate é definida pela duração da transação do banco de dados.
+ Se você usa demarcação programática de transação (por exemplo. em J2SE puro ou com JTA
+ /UserTransaction/BMT), você é recomendado a usar a API Hibernate <literal>Transaction</literal>
+ para esconder a base do sistema de transação do seu código. Se você executa em um container EJB
+ que suporta CMT, os limites das transações são definidas declarativamente e você não necessita
+ de qualquer transação ou operação de demarcação de sessão no seu código. Consulte o <xref linkend="transactions"/>
+ para mais informações exemplos de código.
+ </para>
+
+ <para>
+ O parâmetro de configuração <literal>hibernate.current_session_context_class</literal>
+ define que a implementação <literal>org.hibernate.context.CurrentSessionContext</literal>
+ deve ser usada. Note que para compatibilidade anterior, se este parâmetro de configuração
+ não é determinado mas um <literal>org.hibernate.transaction.TransactionManagerLookup</literal>
+ é configurado, Hibernate usará o <literal>org.hibernate.context.JTASessionContext</literal>.
+ Tipicamente, o valor deste parâmetro nomearia apenas a classe de implementação para usar;
+ para as duas implementações out-of-the-box, entretanto, há três pequenos nomes correspondentes,
+ "jta", "thread", and "managed".
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/association_mapping.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/association_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/association_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/association_mapping.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,635 @@
+<chapter id="associations">
+
+ <title>Mapeamento de Associações</title>
+
+ <sect1 id="assoc-intro" revision="1">
+ <title>Introdução</title>
+
+ <para>
+ Mapeamentos de associações são freqüentemente a coisa mais difícil de se
+ acertar. Nesta seção nós passaremos pêlos casos canônicos um pôr um,
+ começando com mapeamentos unidirecionais e considerando os casos
+ bidirecionais. Nos vamos usar <literal>Person</literal> e
+ <literal>Address</literal> em todos os exemplos.
+ </para>
+
+ <para>
+ Nós classificaremos as associações pelo seu mapeamento ou a falta do
+ mesmo, sua intervenção na tabela associativa, e pela sua multiplicidade.
+ </para>
+
+ <para>
+ O uso de chaves estrangeiras não obrigatórias não é considerada uma boa
+ prática na modelagem de dados tradicional, assim todos nossos exemplos
+ usam chaves estrangeiras obrigatórias. Esta não é uma exigência do
+ Hibernate, e todas as mapeamentos funcionarão se você remover as
+ constraints de obrigatoriedade.
+ </para>
+
+ </sect1>
+
+ <sect1 id="assoc-unidirectional" revision="1">
+ <title>Associações Unidirecionais</title>
+
+ <sect2 id="assoc-unidirectional-m21">
+ <title>muitos para um</title>
+
+ <para>
+ Uma <emphasis>associação unidirecional muitos-para-um</emphasis> é o
+ tipo mais comum de associação unidirecional.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-121">
+ <title>um para um</title>
+
+ <para>
+ Uma <emphasis>associação unidirecional um-para-um em uma chave estrangeira
+ </emphasis> é quase idêntica. A única diferença é a constraint unique
+ na coluna.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ unique="true"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ Uma <emphasis>associação unidirecional um-para-um na chave primaria</emphasis>
+ geralmente usa um gerador de id special. ( Note que nós invertemos a
+ direção da associação nesse exemplo).
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+</class>
+
+<class name="Address">
+ <id name="id" column="personId">
+ <generator class="foreign">
+ <param name="property">person</param>
+ </generator>
+ </id>
+ <one-to-one name="person" constrained="true"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( personId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-12m">
+ <title>um para muitos</title>
+
+ <para>
+ Uma <emphasis>associação unidirecional um-para-muitos em uma chave
+ estrangeira</emphasis> é um caso muito incomum, e realmente não é recomendada.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses">
+ <key column="personId"
+ not-null="true"/>
+ <one-to-many class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( addressId bigint not null primary key, personId bigint not null )
+ ]]></programlisting>
+
+ <para>
+ Nós achamos que é melhor usar uma tabela associativa para este tipo de
+ associação.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-unidirectional-join" revision="1">
+ <title>Associações Unidirecionais com tabelas associativas</title>
+
+ <sect2 id="assoc-unidirectional-join-12m">
+ <title>um para muitos</title>
+
+ <para>
+ Uma <emphasis>associação um-para-muitos unidirecional usando uma tabela
+ associativa</emphasis> e o mais comum. Note que se especificarmos
+ <literal>unique="true"</literal>, estaremos modificando a cardinalidade
+ de muitos-para-muitos para um-para-muitos.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ unique="true"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId not null, addressId bigint not null primary key )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-m21">
+ <title>muitos para um</title>
+
+ <para>
+ Uma <emphasis>associação unidirecional muitos-para-um em uma tabela
+ associativa</emphasis> é bastante comum quando a associação for opcional.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId" unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-121">
+ <title>um para um</title>
+
+ <para>
+ Uma <emphasis>associação unidirecional um-para-um em uma tabela
+ associativa</emphasis> é extremamente incomum, mas possível.
+
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId"
+ unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-m2m">
+ <title>muitos para muitos</title>
+
+ <para>
+ Finalmente, nós temos a <emphasis>associação unidirecional muitos-para-
+ muitos</emphasis>.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-bidirectional" revision="1">
+ <title>Associações Bidirecionais</title>
+
+ <sect2 id="assoc-bidirectional-m21" revision="2">
+ <title>um para muitos / muitos para um</title>
+
+ <para>
+ Uma <emphasis>associação bidirecional muitos-para-um</emphasis> é o
+ tipo mais comum de associação. (Esse é o relacionamento padrão
+ pai / filho. )
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <set name="people" inverse="true">
+ <key column="addressId"/>
+ <one-to-many class="Person"/>
+ </set>
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ Se você usar uma <literal>List</literal> ( ou outra coleção indexada ), você
+ precisa especificar a coluna <literal>chave</literal> estrangeira como not null,
+ e deixar o Hibernate administrar a associação do lado da coleção para que
+ seja mantido o índice de cada elemento da coleção (fazendo com que o outro
+ lado seja virtualmente inverso setando <literal>update="false"</literal>
+ e <literal>insert="false"</literal>):
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id"/>
+ ...
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ insert="false"
+ update="false"/>
+</class>
+
+<class name="Address">
+ <id name="id"/>
+ ...
+ <list name="people">
+ <key column="addressId" not-null="true"/>
+ <list-index column="peopleIdx"/>
+ <one-to-many class="Person"/>
+ </list>
+</class>]]></programlisting>
+
+ <para>
+ É importante que você defina <literal>not-null="true"</literal> no elemento
+ <literal><key></literal> no mapeamento na coleção se a coluna de chave
+ estrangeira for <literal>NOT NULL</literal>. Não declare como
+ <literal>not-null="true"</literal> apenas um elemento aninhado
+ <literal><column></literal>, mas sim o elemento
+ <literal><key></literal>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-121">
+ <title>um para um</title>
+
+ <para>
+ Uma <emphasis>associação bidirecional um para um em uma chave estrangeira</emphasis>
+ é bastante comum.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ unique="true"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <one-to-one name="person"
+ property-ref="address"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ Uma <emphasis>associação bidirecional um para um em uma chave primária</emphasis>
+ usa um gerador de id especial.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <one-to-one name="address"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="personId">
+ <generator class="foreign">
+ <param name="property">person</param>
+ </generator>
+ </id>
+ <one-to-one name="person"
+ constrained="true"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( personId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-bidirectional-join" revision="1">
+ <title>Associações Bidirecionais com tabelas associativas</title>
+
+ <sect2 id="assoc-bidirectional-join-12m">
+ <title>um para muitos / muitos para um</title>
+
+ <para>
+ Uma <emphasis>associação bidirecional um para muitos em uma tabela
+ associativa</emphasis>. Veja que <literal>inverse="true"</literal> pode ser
+ colocado em qualquer ponta associação, na coleção, ou no join.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses"
+ table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ unique="true"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ inverse="true"
+ optional="true">
+ <key column="addressId"/>
+ <many-to-one name="person"
+ column="personId"
+ not-null="true"/>
+ </join>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null primary key )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-join-121">
+ <title>one to one</title>
+
+ <para>
+ Uma <emphasis>associação bidirecional um-para-um em uma tabela de
+ associação</emphasis> é algo bastante incomum, mas possivel.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId"
+ unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true"
+ inverse="true">
+ <key column="addressId"
+ unique="true"/>
+ <many-to-one name="person"
+ column="personId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-join-m2m" revision="1">
+ <title>muitos para muitos</title>
+
+ <para>
+ Finally, we have a <emphasis>bidirectional many-to-many association</emphasis>.
+ Finalmente, nós temos uma associação bidirecional de muitos para muitos.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <set name="people" inverse="true" table="PersonAddress">
+ <key column="addressId"/>
+ <many-to-many column="personId"
+ class="Person"/>
+ </set>
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-complex">
+ <title>Mapeamento de associações mais complexas</title>
+
+ <para>
+ More complex association joins are <emphasis>extremely</emphasis> rare.
+ Hibernate makes it possible to handle more complex situations using
+ SQL fragments embedded in the mapping document. For example, if a table
+ with historical account information data defines
+ <literal>accountNumber</literal>, <literal>effectiveEndDate</literal>
+ and <literal>effectiveStartDate</literal>columns, mapped as follows:
+Joins de associações mais complexas são extremamente raros. O Hibernate torna possível tratar mapeamentos mais complexos usando fragmentos de SQL embutidos no documento de mapeamento. Por exemplo, se uma tabela com informações de dados históricos de uma conta define a coluna accountNumber, effectiveEndDate e effectiveStartDate, mapeadas assim como segue:
+ </para>
+
+ <programlisting><![CDATA[<properties name="currentAccountKey">
+ <property name="accountNumber" type="string" not-null="true"/>
+ <property name="currentAccount" type="boolean">
+ <formula>case when effectiveEndDate is null then 1 else 0 end</formula>
+ </property>
+</properties>
+<property name="effectiveEndDate" type="date"/>
+<property name="effectiveStateDate" type="date" not-null="true"/>]]></programlisting>
+
+ <para>
+ Then we can map an association to the <emphasis>current</emphasis> instance
+ (the one with null <literal>effectiveEndDate</literal>) using:
+Então nós podemos mapear uma associação para a instância corrente (aquela com a effectiveEndDate igual a null) usando:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="currentAccountInfo"
+ property-ref="currentAccountKey"
+ class="AccountInfo">
+ <column name="accountNumber"/>
+ <formula>'1'</formula>
+</many-to-one>]]></programlisting>
+
+ <para>
+ In a more complex example, imagine that the association between
+ <literal>Employee</literal> and <literal>Organization</literal> is maintained
+ in an <literal>Employment</literal> table full of historical employment data.
+ Then an association to the employee's <emphasis>most recent</emphasis> employer
+ (the one with the most recent <literal>startDate</literal>) might be mapped this way:
+Em um exemplo mais complexo, imagine que a associação entre Employee e Organization é mantida em uma tabela Employment cheia de dados históricos do trabalho. Então a associação do funcionário mais recentemente empregado (aquele com a mais recente startDate) deve ser mapeado desta maneira:
+ </para>
+
+ <programlisting><![CDATA[<join>
+ <key column="employeeId"/>
+ <subselect>
+ select employeeId, orgId
+ from Employments
+ group by orgId
+ having startDate = max(startDate)
+ </subselect>
+ <many-to-one name="mostRecentEmployer"
+ class="Organization"
+ column="orgId"/>
+</join>]]></programlisting>
+
+ <para>
+ You can get quite creative with this functionality, but it is usually more practical
+ to handle these kinds of cases using HQL or a criteria query.
+Você pode ser criativo com esta funcionalidade, mas geralmente é mais prático tratar estes tipos de casos, usando uma pesquisa HQL ou uma pesquisa por criteria.
+ </para>
+
+ </sect1>
+
+
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/basic_mapping.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/basic_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/basic_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/basic_mapping.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,3491 @@
+<chapter id="mapping">
+ <title>Mapeamento O/R Bassico</title>
+
+ <sect1 id="mapping-declaration" revision="1">
+ <title>Declaração de mapeamento</title>
+
+ <para>
+ Object/relational mappings are usually defined in an XML document. The mapping
+ document is designed to be readable and hand-editable. The mapping language is
+ Java-centric, meaning that mappings are constructed around persistent class
+ declarations, not table declarations.
+ </para>
+
+ <para>
+ Note that, even though many Hibernate users choose to write the XML by hand,
+ a number of tools exist to generate the mapping document, including XDoclet,
+ Middlegen and AndroMDA.
+ </para>
+
+ <para>
+ Lets kick off with an example mapping:
+ </para>
+
+ <programlisting id="mapping-declaration-ex1" revision="1"><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class name="Cat"
+ table="cats"
+ discriminator-value="C">
+
+ <id name="id">
+ <generator class="native"/>
+ </id>
+
+ <discriminator column="subclass"
+ type="character"/>
+
+ <property name="weight"/>
+
+ <property name="birthdate"
+ type="date"
+ not-null="true"
+ update="false"/>
+
+ <property name="color"
+ type="eg.types.ColorUserType"
+ not-null="true"
+ update="false"/>
+
+ <property name="sex"
+ not-null="true"
+ update="false"/>
+
+ <property name="litterId"
+ column="litterId"
+ update="false"/>
+
+ <many-to-one name="mother"
+ column="mother_id"
+ update="false"/>
+
+ <set name="kittens"
+ inverse="true"
+ order-by="litter_id">
+ <key column="mother_id"/>
+ <one-to-many class="Cat"/>
+ </set>
+
+ <subclass name="DomesticCat"
+ discriminator-value="D">
+
+ <property name="name"
+ type="string"/>
+
+ </subclass>
+
+ </class>
+
+ <class name="Dog">
+ <!-- mapping for Dog could go here -->
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Discutir agora o conteúdo deste documento de mapeamento. Iremos apenas descrever
+ os elementos do documento e atributos que são utilizados pelo Hibernate em tempo
+ de execução. O documento de mapeamento também contém alguns atributos adicionais
+ e opcionais além de elementos que afetam os esquemas de banco de dados exportados
+ pela ferramenta de exportação de esquemas. (Por exemplo, o atributo
+ <literal>not-null</literal>).
+ </para>
+
+
+
+ <sect2 id="mapping-declaration-doctype" revision="3">
+ <title>Doctype</title>
+
+ <para>
+ Todos os mapeamentos de XML devem declarar o doctype exibido. O DTD atual pode
+ ser encontrado na URL abaixo, no diretório <literal>hibernate-x.x.x/src/org/
+ hibernate </literal> ou no <literal>hibernate3.jar</literal>. O Hibernate sempre
+ irá procurar pelo DTD inicialmente no seu classpath. Se você tentar localizar
+ o DTD usando uma conexão de internet, compare a declaração do seu DTD com o
+ conteúdo do seu classpath
+ </para>
+
+ <sect3 id="mapping-declaration-entity-resolution">
+ <title>EntityResolver</title>
+ <para>
+ As mentioned previously, Hibernate will first attempt to resolve DTDs in its classpath. The
+ manner in which it does this is by registering a custom <literal>org.xml.sax.EntityResolver</literal>
+ implementation with the SAXReader it uses to read in the xml files. This custom
+ <literal>EntityResolver</literal> recognizes two different systemId namespaces.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ a <literal>hibernate namespace</literal> is recognized whenever the
+ resolver encounteres a systemId starting with
+ <literal>http://hibernate.sourceforge.net/</literal>; the resolver
+ attempts to resolve these entities via the classlaoder which loaded
+ the Hibernate classes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ a <literal>user namespace</literal> is recognized whenever the
+ resolver encounteres a systemId using a <literal>classpath://</literal>
+ URL protocol; the resolver will attempt to resolve these entities
+ via (1) the current thread context classloader and (2) the
+ classloader which loaded the Hibernate classes.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ An example of utilizing user namespacing:
+ </para>
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" [
+ <!ENTITY types SYSTEM "classpath://your/domain/types.xml">
+]>
+
+<hibernate-mapping package="your.domain">
+ <class name="MyEntity">
+ <id name="id" type="my-custom-id-type">
+ ...
+ </id>
+ <class>
+ &types;
+</hibernate-mapping>]]></programlisting>
+ <para>
+ Where <literal>types.xml</literal> is a resource in the <literal>your.domain</literal>
+ package and contains a custom <xref linkend="mapping-types-custom">typedef</xref>.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="mapping-declaration-mapping" revision="3">
+ <title>hibernate-mapping</title>
+
+ <para>
+ Este elemento tem diversos atributos opcionais. Os atributos
+ <literal>schema</literal> e <literal>catalog</literal> especificam que tabelas
+ referenciadas neste mapeamento pertencem ao esquema e/ou ao catalogo nomeado.
+ Se especificados, os nomes das tabelas irão ser qualificados no schema ou catalog dado.
+ Se não, os nomes das tabelas não serão qualificados. O atributo <literal>default-cascade
+ </literal> especifica qual estilo de cascata será assumido pelas propriedades e
+ coleções que não especificarm um atributo <literal>cascade</literal>. O atributo
+ <literal>auto-import</literal> nos deixa utilizar nomes de classes não qualificados
+ na linguagem de consulta, por default.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="hm1" coords="2 55"/>
+ <area id="hm2" coords="3 55"/>
+ <area id="hm3" coords="4 55"/>
+ <area id="hm4" coords="5 55"/>
+ <area id="hm5" coords="6 55"/>
+ <area id="hm6" coords="7 55"/>
+ <area id="hm7" coords="8 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<hibernate-mapping
+ schema="schemaName"
+ catalog="catalogName"
+ default-cascade="cascade_style"
+ default-access="field|property|ClassName"
+ default-lazy="true|false"
+ auto-import="true|false"
+ package="package.name"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="hm1">
+ <para>
+ <literal>schema</literal> (opcional): O nome do esquema do banco de dados.
+ </para>
+ </callout>
+ <callout arearefs="hm2">
+ <para>
+ <literal>catalog</literal> (opcional): O nome do catálogo do banco de dados.
+ </para>
+ </callout>
+ <callout arearefs="hm3">
+ <para>
+ <literal>default-cascade</literal> (opcional – default é <literal>nenhum
+ </literal>): Um estilo cascata default.
+ </para>
+ </callout>
+ <callout arearefs="hm4">
+ <para>
+ <literal>default-access</literal> (opcional – default é <literal>property</literal>):
+ A estratégia que o Hibernate deve utilizar para acessar todas as propridades. Pode
+ ser uma implementação própria de <literal>PropertyAccessor</literal>.
+ </para>
+ </callout>
+ <callout arearefs="hm5">
+ <para>
+ <literal>default-lazy</literal> (opcional - default é <literal>true</literal>):
+ O valor default para atributos <literal>lazy</literal> da classe e dos
+ mapeamentos de coleções.
+ </para>
+ </callout>
+ <callout arearefs="hm6">
+ <para>
+ <literal>auto-import</literal> ((opcional - default é <literal>true</literal>):
+ Especifica se nós podemos usar nomes de classess não qualificados
+ (das classes deste mapeamento) na linguagem de consulta.
+ </para>
+ </callout>
+ <callout arearefs="hm7">
+ <para>
+ <literal>package</literal> (opcional): Especifica um prefixo da package para
+ assumir para nomes de classes não qualificadas no documento de mapeamento.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Se voce tem duas classes persistentes com o mesmo nome (não qualificadas), você deve
+ setar <literal>auto-import="false"</literal>. O Hibernate irá gerar uma exceção se
+ você tentar setar duas classes para o mesmo nome "importado".
+ </para>
+
+ <para>
+ Observe que o elemento <literal>hibernate-mapping</literal> permite a você
+ aninhar diversos mapeamentos de <literal><class></literal> persistentes,
+ como mostrado abaixo. Entretanto, é uma boa prática (e esperado por algumas
+ ferramentas)o mapeamento de apenas uma classe persistente simples (ou uma
+ hierarquia de classes simples) em um arquivo de mapeamento e nomea-la após
+ a superclasse persistente, por exemplo: <literal>Cat.hbm.xml</literal>,
+ <literal>Dog.hbm.xml</literal>, ou se estiver usando herança,
+ <literal>Animal.hbm.xml</literal>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-class" revision="3">
+ <title>class</title>
+
+ <para>
+ Você pode declarar uma classe persistente utilizando o elemento
+ <literal>class</literal>:
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="class1" coords="2 55"/>
+ <area id="class2" coords="3 55" />
+ <area id="class3" coords="4 55"/>
+ <area id="class4" coords="5 55" />
+ <area id="class5" coords="6 55"/>
+ <area id="class6" coords="7 55" />
+ <area id="class7" coords="8 55"/>
+ <area id="class8" coords="9 55" />
+ <area id="class9" coords="10 55" />
+ <area id="class10" coords="11 55"/>
+ <area id="class11" coords="12 55"/>
+ <area id="class12" coords="13 55"/>
+ <area id="class13" coords="14 55"/>
+ <area id="class14" coords="15 55"/>
+ <area id="class15" coords="16 55"/>
+ <area id="class16" coords="17 55"/>
+ <area id="class17" coords="18 55"/>
+ <area id="class18" coords="19 55"/>
+ <area id="class19" coords="20 55"/>
+ <area id="class20" coords="21 55"/>
+ <area id="class21" coords="22 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<class
+ name="ClassName"
+ table="tableName"
+ discriminator-value="discriminator_value"
+ mutable="true|false"
+ schema="owner"
+ catalog="catalog"
+ proxy="ProxyInterface"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ select-before-update="true|false"
+ polymorphism="implicit|explicit"
+ where="arbitrary sql where condition"
+ persister="PersisterClass"
+ batch-size="N"
+ optimistic-lock="none|version|dirty|all"
+ lazy="true|false"
+ entity-name="EntityName"
+ check="arbitrary sql check condition"
+ rowid="rowid"
+ subselect="SQL expression"
+ abstract="true|false"
+ node="element-name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="class1">
+ <para>
+ <literal>name</literal> (opcional): O nome da classe Java inteiramente qualificado
+ da classe persistente (ou interface); Se o atributo é ausente, assume-se que o
+ mapeamento é para intidades não-POJO.
+ </para>
+ </callout>
+ <callout arearefs="class2">
+ <para>
+ <literal>table</literal> (opcional – default para nomes de classes não
+ qualificadas) O nome da sua tabela do banco de dados.
+ </para>
+ </callout>
+ <callout arearefs="class3">
+ <para>
+ <literal>discriminator-value</literal> (opcional – default para o nome da classe):
+ Um valor que distingue subclasses individuais, usadas para o comportamento polimorfico.
+ Valores aceitos incluem <literal>null</literal> e <literal>not null</literal>
+ </para>
+ </callout>
+ <callout arearefs="class4">
+ <para>
+ <literal>mutable</literal> (opcional - valor default <literal>true</literal>):
+ Especifica que instancias da classe são (ou não) mutáveis
+ </para>
+ </callout>
+ <callout arearefs="class5">
+ <para>
+ <literal>schema</literal> (opcional): Sobrepõe o nome do esquema especificado
+ pelo elemento root <literal><hibernate-mapping></literal>.
+ </para>
+ </callout>
+ <callout arearefs="class6">
+ <para>
+ <literal>catalog</literal> (opcional): Sobrepõe o nome do catálogo especificado
+ pelo elemento root <literal><hibernate-mapping></literal>.
+ </para>
+ </callout>
+ <callout arearefs="class7">
+ <para>
+ <literal>proxy</literal> (opcional): Especifica um interface para ser
+ utilizada pelos proxies de inicialização tardia. Você pode especificar o
+ nome da própria classe.
+ </para>
+ </callout>
+ <callout arearefs="class8">
+ <para>
+ <literal>dynamic-update</literal> (opcional, valor default <literal>false</literal>):
+ Especifica que o SQL de <literal>UPDATE</literal> deve ser gerado em tempo de
+ execução e conter apenas aquelas colunas cujos valores foram alterados.
+ </para>
+ </callout>
+ <callout arearefs="class9">
+ <para>
+ <literal>dynamic-insert</literal> (opcional, valor default <literal>false</literal>):
+ Especifica que o SQL de <literal>INSERT</literal> deve ser gerado em tempo de
+ execução e conter apenas aquelas colunas cujos valores não estão nulos.
+ </para>
+ </callout>
+ <callout arearefs="class10">
+ <para>
+ <literal>select-before-update</literal> (opcional, valor default <literal>false</literal>):
+ Especifica que o Hibernate <emphasis>never</emphasis> deve executar um SQL de
+ <literal>UPDATE</literal> a não ser que com certeza um objeto está atualmente modificado.
+ Em certos casos (atualmente, apenas quando um objeto transiente foi associado com uma nova
+ sessão utilizando <literal>update()</literal>), isto significa que o Hibernate ira executar
+ uma instrução SQL de <literal>SELECT</literal> adicional para determinar se um
+ <literal>UPDATE</literal> é necessário nesse momento.
+ </para>
+ </callout>
+ <callout arearefs="class11">
+ <para>
+ <literal>polymorphism</literal> (opcional, default para <literal>implicit</literal>):
+ Determina se deve ser utilizado a query polimorfica implicita ou explicitamente.
+ </para>
+ </callout>
+ <callout arearefs="class12">
+ <para>
+ <literal>where</literal> (opicional) especifica um comando SQL <literal>WHERE</literal>
+ arbitrário para ser usado quando da recuperação de objetos desta classe.
+ </para>
+ </callout>
+ <callout arearefs="class13">
+ <para>
+ <literal>persister</literal> (opcional): Espeicifca uma <literal>ClassPersister</literal>
+ customizada.
+ </para>
+ </callout>
+ <callout arearefs="class14">
+ <para>
+ <literal>batch-size</literal> (opcional, valor default <literal>1</literal>) especifica um
+ "tamanho de lote" para a recuperação de instancias desta classe pelo identificador.
+ </para>
+ </callout>
+ <callout arearefs="class15">
+ <para>
+ <literal>optimistic-lock</literal> (octional, valor default <literal>version</literal>):
+ Determina a estratégia de bloqueio.
+ </para>
+ </callout>
+ <callout arearefs="class16">
+ <para>
+ <literal>lazy</literal> (opcional): A recuperação tardia pode ser completamente
+ desabilitada, setando <literal>lazy="false"</literal>.
+ </para>
+ </callout>
+ <callout arearefs="class17">
+ <para>
+ <literal>entity-name</literal> (opcional, default para o nome da classe): O
+ Hibernate3 permite uma classe ser mapeada multiplas vezes, (potencialmente,para
+ diferentes tabelas), e permite mapeamentos de entidades que são representadas
+ por Maps ou XML no nível Java. Nestes casos, você deve especificar um nome
+ arbitrário explicitamente para a entidade. Veja <xref linkend="persistent-classes-dynamicmodels"/>
+ e <xref linkend="xml"/> para maiores informações.
+ </para>
+ </callout>
+ <callout arearefs="class18">
+ <para>
+ <literal>check</literal> (opcional): Uma expressão SQL utilizada para gerar uma
+ constraint de <emphasis>verificação</emphasis> de múltiplas linhas para a geração
+ automática do esquema.
+ </para>
+ </callout>
+ <callout arearefs="class19">
+ <para>
+ <literal>rowid</literal> (opcional): O Hibernate poder usar as assim chamadas
+ ROWIDs em bancos de dados que a suportam. Por exemplo, no Oracle, o Hibernate
+ pode utilizar a coluna extra rowid para atualizações mais rápidas se você
+ configurar esta opção para <literal>rowid</literal>. Um ROWID é uma implementação
+ que representa de maneira detalhada a localização física de uma determinada
+ tupla armazenado.
+ </para>
+ </callout>
+ <callout arearefs="class20">
+ <para>
+ <literal>subselect</literal> (optional): Maps an immutable and read-only entity
+ to a database subselect. Useful if you want to have a view instead of a base table,
+ but don't. See below for more information.
+ <literal>subselect</literal> (opcional): Mapeia uma entidade imutavel e somente
+ de leitura para um subconjunto do banco de dados. Útil se você quiser ter uma
+ view em vez de uma tabela. Veja abaixo para mais informações.
+ </para>
+ </callout>
+ <callout arearefs="class21">
+ <para>
+ <literal>abstract</literal> (opcional): Utilizada para marcar superclasses
+ abstratas em hierarquias <literal><union-subclass></literal>.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ É perfeitamente aceitável para uma classe persitente nomeada ser uma interface. Você deverá
+ então declarar as classes implementadas desta interface utilizando o elemento
+ <literal><subclass></literal>. Você pode persistir qualquer classe de aninhada
+ <emphasis>estatica</emphasis>. Você deverá especificar o nome da classe usando a forma
+ padrão, por exemplo: <literal>eg.Foo$Bar</literal>.
+ </para>
+
+ <para>
+ Classes imutáveis, <literal>mutable="false"</literal>, não podem ser modificadas ou excluídas
+ pela aplicação. Isso permite ao Hibernate fazer alguns aperfeiçoamentos de performance.
+ </para>
+
+ <para>
+ O atributo opcional <literal>proxy</literal> habilita a inicialização tardia das
+ instâncias persistentes da classe. O Hibernate irá retornar CGLIB proxies como implementado
+ na interface nomeada. O objeto persistente atual será carregado quando um método do proxy
+ for invocado. Veja "Inicializando coleções e proxies" abaixo.
+ </para>
+
+ <para>Polimorfismo <emphasis>implícito</emphasis> significa que instâncias de uma classe
+ serão retornada por uma query que dá nome a qualquer superclasse ou interface implementada,
+ ou a classe e as instancias de qualquer subclasse da classe será retornada por umq query
+ que nomeia a classe por si. Polimorfismo <emphasis>explícito</emphasis> significa que
+ instancias da classe serão retornadas apenas por queries que explicitamente nomeiam a
+ classe e que queries que nomeiam as classes irão retornar apenas instancias de subclasses
+ mapeadas dentro da declaração <literal><class></literal> como uma
+ <literal><subclass></literal> ou <literal><joined-subclass></literal>.
+ Para a maioria dos casos, o valor default <literal>polymorphism="implicit"</literal>,
+ é apropriado. Polimorfismo explicito é útil quando duas classes distintas estão mapeadas
+ para a mesma tabela (isso permite um classe "peso leve" que contem um subconjunto
+ de colunas da tabela).
+ </para>
+
+ <para>
+ O atributo <literal>persister</literal> deixa você customizar a estratégia de persistência
+ utilizada para a classe. Você pode, por exemplo, especificar sua prórpia subclasse do
+ <literal>org.hibernate.persister.EntityPersister</literal> ou você pode criar
+ uma implementação completamente nova da interface
+ <literal>org.hibernate.persister.ClassPersister</literal> que implementa a persistência
+ através de, por exemplo, chamadas a stored procedeures, serialização de arquivos flat ou
+ LDAP. Veja <literal>org.hibernate.test.CustomPersister</literal> para um exemplo
+ simples (de "persistencia" para uma <literal>Hashtable</literal>).
+ </para>
+
+ <para>
+ Observe que as configurações <literal>dynamic-update</literal> e
+ <literal>dynamic-insert</literal> não sao herdadas pelas subclasses e assim podem tambem
+ ser especificadas em elementos <literal><subclass></literal> or
+ <literal><joined-subclass></literal>. Estas configurações podem incrementar a
+ performance em alguns casos, mas pode realmente diminuir a performance em outras.
+ Use-as de forma bastante criteriosa.
+ </para>
+
+ <para>
+ O uso de <literal>select-before-update</literal> geralmente irá diminuir a performance. Ela é
+ muito útil para prevenir que uma trigger de atualização no banco de dados seja ativada
+ desnecessariamente, se você reconectar um nó de uma instancia desconectada em uma
+ <literal>Session</literal>.
+ </para>
+
+ <para>
+ Se você ativar <literal>dynamic-update</literal>, você terá de escolher
+ a estratégia de bloqueio otimista:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>version</literal> verifica a versão e a hora das colunas
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>all</literal> cverifica todas as colunas
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>dirty</literal> verifica as colunas modificadas, permitindo
+ alguns updates concorrentes
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>none</literal> não utiliza o bloqueio otimista
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Nós <emphasis>recomendamos</emphasis> com muita enfase que você utilize a
+ versão e a hora das colunas para o bloqueio otimista com o Hibernate.
+ Esta é a melhor estratégia com respeito a performance e é a única estratégia
+ que trata corretamente as modificações efetuadas em instancias desconectadas
+ (por exemplo, quando <literal>Session.merge()</literal> é utilizado).
+
+ </para>
+
+ <para>
+ Não ha diferença entre uma view e uma tabela para o mapeamento do Hibernate, e como
+ esperado isto é transparente no nível do banco de dados (observe que alguns bancos de
+ dados não suportam views apropriadamente, especialmente com updates). Algumas vezes,
+ você quer utilizar uma view, ma snão pode cria-la no banco de dados (por exemplo,
+ com um esquema legado). Neste caso, você pode mapear uma entidade imutável e de
+ somente leitura, para uma dada expressão SQL, que representa um subselect:
+ </para>
+
+ <programlisting><![CDATA[<class name="Summary">
+ <subselect>
+ select item.name, max(bid.amount), count(*)
+ from item
+ join bid on bid.item_id = item.id
+ group by item.name
+ </subselect>
+ <synchronize table="item"/>
+ <synchronize table="bid"/>
+ <id name="name"/>
+ ...
+</class>]]></programlisting>
+
+ <para>
+ Declare as tabelas para sincronizar com esta entidade, garantindo que o auto-flush
+ ocorra corretamente, e que as queries para esta entidade derivada não retornem dados
+ desatualizados. O <literal><subselect></literal> está disponível tanto como um
+ atributo como um elemento mapeado nested.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-id" revision="4">
+ <title>id</title>
+
+ <para>
+ Classes mapeadas <emphasis>precisam</emphasis> declarar a coluna de chave primaria da
+ tabela do banco de dados. Muitas classes irão tambem ter uma propriedade ao estilo
+ Java-Beans declarando o identificador unico de uma instancia. O elemento
+ <literal><id></literal> define o mapeamento desta propriedade para a chave primária.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="id1" coords="2 70"/>
+ <area id="id2" coords="3 70" />
+ <area id="id3" coords="4 70"/>
+ <area id="id4" coords="5 70" />
+ <area id="id5" coords="6 70" />
+ </areaspec>
+ <programlisting><![CDATA[<id
+ name="propertyName"
+ type="typename"
+ column="column_name"
+ unsaved-value="null|any|none|undefined|id_value"
+ access="field|property|ClassName">
+ node="element-name|@attribute-name|element/@attribute|."
+
+ <generator class="generatorClass"/>
+</id>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="id1">
+ <para>
+ <literal>name</literal> (opcional): O nome do identificador.
+ </para>
+ </callout>
+ <callout arearefs="id2">
+ <para>
+ <literal>type</literal> (opcional): Um nome que indica o tipo no Hibernate.
+ </para>
+ </callout>
+ <callout arearefs="id3">
+ <para>
+ <literal>column</literal> (opcional – default para o a propridade name): O
+ nome coluna chave primaria.
+ </para>
+ </callout>
+ <callout arearefs="id4">
+ <para>
+ <literal>unsaved-value</literal> (opcional - default para um valor "sensível"):
+ Uma propriedade de identificação que indica que a instancia foi novamente
+ instanciada (unsaved), diferenciando de instancias desconectadas que foram
+ salvas ou carregadas em uma sessão anterior.
+ </para>
+ </callout>
+ <callout arearefs="id5">
+ <para>
+ <literal>access</literal> (opcional - valor default <literal>property</literal>): A
+ estratégia que o Hiberante deve utilizar para acessar o valor da propriedade
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Se o atributo <literal>name</literal> não for declarado, assume-se que a classe não tem
+ a propriedade de identificação.
+ </para>
+
+ <para>
+ O atributo <literal>unsaved-value</literal> não é mais necessário no Hibernate 3.
+ </para>
+
+ <para>
+ Há declaração alternativa <literal><composite-id></literal> permite o acesso a
+ dados legados com chaves compostas. Nós desencorajamos fortemente o seu uso por
+ qualquer pessoa.
+ </para>
+
+ <sect3 id="mapping-declaration-id-generator" revision="2">
+ <title>Generator</title>
+
+ <para>
+ O elemento filho opcional <literal><generator></literal> nomeia uma classe Java
+ usada para gerar identificadores unicos para instancias de uma classe persistente.
+ Se algum parâmetro é requerido para configurar ou inicializar a instancia geradora,
+ eles são passados utilizando o elemento <literal><param></literal>.
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+ <generator class="org.hibernate.id.TableHiLoGenerator">
+ <param name="table">uid_table</param>
+ <param name="column">next_hi_value_column</param>
+ </generator>
+</id>]]></programlisting>
+
+ <para>
+ Todos os generators implementam a interface <literal>org.hibernate.id.IdentifierGenerator</literal>.
+ Esta é uma interface bem simples; algumas aplicações podem prover sua própria implementação
+ esepecializada. Entretanto, o Hibernate disponibiliza um conjunto de implementações internamente.
+ Há nomes de atalhos para estes generators próprios:
+ <variablelist>
+ <varlistentry>
+ <term><literal>increment</literal></term>
+ <listitem>
+ <para>
+ gera identificadores dos tipos <literal>long</literal>, <literal>short</literal> ou
+ <literal>int</literal> que são unicos apenas quando nenhum outro processo está
+ inserindo dados na mesma tabela. <emphasis>Não utilize em ambientes
+ de cluster.</emphasis>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>identity</literal></term>
+ <listitem>
+ <para>
+ suporta colunas de identidade em DB2, MySQL, MS SQL Server, Sybase e
+ HypersonicSQL. O identificador retornado é do tipo <literal>long</literal>,
+ <literal>short</literal> ou <literal>int</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>sequence</literal></term>
+ <listitem>
+ <para>
+ utiliza uma sequence em DB2, PostgreSQL, Oracle, SAP DB, McKoi ou um
+ generator no Interbase. O identificador de retorno é do tipo <literal>
+ long</literal>, <literal>short</literal> ou <literal>int</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>hilo</literal></term>
+ <listitem>
+ <para id="mapping-declaration-id-hilodescription" revision="1">
+ utiliza um algoritmo hi/lo para gerar de forma eficiente identificadores do tipo
+ <literal>long</literal>, <literal>short</literal> ou <literal>int</literal>,
+ a partir de uma tabela e coluna fornecida (por default
+ <literal>hibernate_unique_key</literal> e <literal>next_hi</literal>)
+ como fonte para os valores hi. O algoritmo hi/lo gera identificadores que são
+ únicos apenas para um banco de dados particular.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>seqhilo</literal></term>
+ <listitem>
+ <para>
+ utiliza um algoritmo hi/lo para gerar de forma eficinete identificadores do tipo
+ <literal>long</literal>, <literal>short</literal> ou <literal>int</literal>,
+ a partir de uma sequence de banco de dados fornecida.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>uuid</literal></term>
+ <listitem>
+ <para>
+ utiliza um algortimo UUID de 128-bits para gerar identificadores do
+ tipo string, unicos em uma rede(o endereço IP é utilizado). O UUID é
+ codificado como um string de digitos hexadecimais de tamanho 32.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>guid</literal></term>
+ <listitem>
+ <para>
+ utiliza um string GUID gerado pelo banco de dados no MS SQL Server
+ e MySQL.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>native</literal></term>
+ <listitem>
+ <para>
+ seleciona entre <literal>identity</literal>, <literal>sequence</literal>
+ ou <literal>hilo</literal> dependendo das capacidades do banco de dados
+ utilizado.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>assigned</literal></term>
+ <listitem>
+ <para>
+ deixa a aplicação definir um identificador para o objeto antes que o
+ <literal>save()</literal> seja chamado. Esta é a estratégia default
+ se nenhum elemento <literal><generator></literal> é especificado.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>select</literal></term>
+ <listitem>
+ <para>
+ retorna a chave primaria recuperada por uma trigger do banco de
+ dados, selecionado uma linha pela chave única e recuperando o valor
+ da chave primária.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>foreign</literal></term>
+ <listitem>
+ <para>
+ utiliza o identificador de um outro objeto associado. Normalmente utilizado
+ em conjunto com uma associaçõa de chave primária do tipo
+ <literal><one-to-one></literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>sequence-identity</literal></term>
+ <listitem>
+ <para>
+ a specialized sequence generation strategy which utilizes a
+ database sequence for the actual value generation, but combines
+ this with JDBC3 getGeneratedKeys to actually return the generated
+ identifier value as part of the insert statement execution. This
+ strategy is only known to be supported on Oracle 10g drivers
+ targetted for JDK 1.4. Note comments on these insert statements
+ are disabled due to a bug in the Oracle drivers.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-hilo" revision="1">
+ <title>Algoritmo Hi/lo</title>
+ <para>
+ Os geradores <literal>hilo</literal> e <literal>seqhilo</literal> fornecem duas
+ implementações alternativas do algoritmo hi/lo, uma solução preferencial para a geração
+ de identificadores. A primeira implementação requer uma tabela especial do banco de
+ dados para manter o proximo valor "hi" disponível. A segunda utiliza uma seqüência
+ do estilo Oracle (quando suportado).
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+ <generator class="hilo">
+ <param name="table">hi_value</param>
+ <param name="column">next_value</param>
+ <param name="max_lo">100</param>
+ </generator>
+</id>]]></programlisting>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+ <generator class="seqhilo">
+ <param name="sequence">hi_value</param>
+ <param name="max_lo">100</param>
+ </generator>
+</id>]]></programlisting>
+
+ <para>
+ Infelizemente, voce não pode utilizar <literal>hilo</literal> quando estiver
+ fornecendo sia propria <literal>Connection</literal> para o Hibernate. Quando o
+ Hibernate está usando um datasource do servidor de aplicações para obter conexões
+ suportadas com JTA, você precisa configurar adequadamente o
+ <literal>hibernate.transaction.manager_lookup_class</literal>.
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-uuid">
+ <title>UUID algorithm</title>
+ <para>
+ O UUID contem: o endereço IP, hora de inicio da JVM (com precisão de um quarto
+ de segundo), a hora do sistema e um valor contador (unico dentro da JVM).
+ Não é possivel obter o endereço MAC ou um endereço de memória do código Java,
+ assim este é o melhor que pode ser feito sem utilizar JNI.
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-sequences">
+ <title>Colunas de identidade e sequencias</title>
+ <para>
+ Para bancos de dados que suportam colunas de identidade (DB2, MySQL, Sybase,
+ MS SQL), você pode utilizar uma geração de chave <literal>identity</literal>.
+ Para bancos de dados que suportam sequencias (DB2, Oracle, PostgreSQL, Interbase,
+ McKoi, SAP DB) voce pode utilizar a geração de chaves no estilo
+ <literal>sequence</literal>. As duas estratégias requerem duas consultas SQL
+ para inserir um novo objeto.
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="person_id">
+ <generator class="sequence">
+ <param name="sequence">person_id_sequence</param>
+ </generator>
+</id>]]></programlisting>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="person_id" unsaved-value="0">
+ <generator class="identity"/>
+</id>]]></programlisting>
+
+ <para>
+ Para desenvolvimento multi-plataforma, a estratégia <literal>native</literal>
+ irá escolher entre as estratégias i <literal>identity</literal>,
+ <literal>sequence</literal> e <literal>hilo</literal>, dependendo das
+ capacidades do banco de dados utilizado.
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-assigned">
+ <title>Identificadores especificados</title>
+ <para>
+ Se você quer que a aplicação especifique os identificadores
+ (em vez do Hibernate gerá-los) você deve utilizar o gerador
+ <literal>assigned</literal>. Este gerador especial irá utilizar o valor
+ do identificador especificado para a propriedade de identificação do objeto.
+ Este gerador é usado quando a chave primaria é a chave natural em vez de uma
+ surrogate key. Este é o comportamento padrão se você não especificar
+ um elemento <literal><generator></literal>.
+ </para>
+
+ <para>
+ Escolher o gerador <literal>assigned</literal> faz com que o Hibernate
+ utilize <literal>unsaved-value="undefined"</literal>, forçando o Hibernate
+ ir até o banco de dados para determinar se uma instância está transiente ou
+ desasociada, a menos que haja uma versão ou uma propriedade timestamp,
+ ou você pode definir <literal>Interceptor.isUnsaved()</literal>.
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-select">
+ <title>Chaves primárias geradas por triggers</title>
+ <para>
+ Apenas para sistemas legados (o Hibernate nao gera DDL com triggers).
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="person_id">
+ <generator class="select">
+ <param name="key">socialSecurityNumber</param>
+ </generator>
+</id>]]></programlisting>
+
+ <para>
+ No exemplo acima, há uma única propriedade com valor nomeada
+ <literal>socialSecurityNumber</literal> definida pela classe,
+ uma chave natural, e uma surrogate key nomeada
+ <literal>person_id</literal> cujo valor é gerado pro uma trigger.
+ </para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-compositeid" revision="3">
+ <title>composite-id</title>
+
+ <programlisting><![CDATA[<composite-id
+ name="propertyName"
+ class="ClassName"
+ mapped="true|false"
+ access="field|property|ClassName">
+ node="element-name|."
+
+ <key-property name="propertyName" type="typename" column="column_name"/>
+ <key-many-to-one name="propertyName class="ClassName" column="column_name"/>
+ ......
+</composite-id>]]></programlisting>
+
+ <para>
+ Para tabelas com uma chave composta, você pode mapear múltiplas propriedades
+ da classe como propriedades de identificação. O elemento
+ <literal><composite-id></literal> aceita o mapeamento da propriedade
+ <literal><key-property></literal> e mapeamentos
+ <literal><key-many-to-one></literal>como elements filhos.
+ </para>
+
+ <programlisting><![CDATA[<composite-id>
+ <key-property name="medicareNumber"/>
+ <key-property name="dependent"/>
+</composite-id>]]></programlisting>
+
+ <para>
+ Sua classe persistente <emphasis>precisa</emphasis> sobre escrever
+ <literal>equals()</literal> e <literal>hashCode()</literal> para implementar
+ identificadores compostos igualmente. E precisa também implementar
+ <literal>Serializable</literal>.
+ </para>
+
+ <para>
+ Infelizmente, esta solução para um identificador composto significa que um objeto
+ persistente é seu próprio identificador. Não há outro "handle" que o próprio objeto.
+ Você mesmo precisa instanciar uma instância de outra classe persistente e preencher
+ suas propriedades de identificação antes que você possa dar um <literal>load()</literal>
+ para o estado persistente associado com uma chave composta. Nos chamamos esta
+ solução de identificador composto <emphasis>embedded</emphasis> e não aconselhamos
+ para aplicações sérias.
+ </para>
+
+ <para>
+ Uma segunda solução é o que podemos chamar de identificador composto
+ <emphasis>mapped</emphasis> quando a propriedades de identificação nomeadas dentro do
+ elemento <literal><composite-id></literal> estão duplicadas tando na classe
+ persistente como em uma classe de identificação separada.
+ </para>
+
+ <programlisting><![CDATA[<composite-id class="MedicareId" mapped="true">
+ <key-property name="medicareNumber"/>
+ <key-property name="dependent"/>
+</composite-id>]]></programlisting>
+
+ <para>
+ No exemplo, ambas as classes de identificação compostas, <literal>MedicareId</literal>,
+ e a própria classe entidade tem propriedades nomeadas <literal>medicareNumber</literal>
+ e <literal>dependent</literal>. A classe identificadora precisa sobrepor
+ <literal>equals()</literal> e <literal>hashCode()</literal> e implementar
+ <literal>Serializable</literal>. A desvantagem desta solução é obvia –
+ duplicação de código.
+ </para>
+
+ <para>
+ Os seguintes atributos ão utilizados para especificar o mapeamento de
+ um identificador composto:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>mapped</literal> mapped (opcional, valor default <literal>false
+ </literal>): indica que um identificar composto mapeado é usado, e que as
+ propriedades de mapeamento contidas refere-se tanto a classe entidade e
+ a classe de identificação composta.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>class</literal> (opcional, mas requerida para um identificar composto
+ mapeado): A classe usada como um identificador composto.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Nós iremos descrever uma terceira e as vezes mais conveniente solução, onde o
+ identificador composto é implementado como uma classe componente na
+ <xref linkend="components-compositeid"/>. Os atributos descritos abaixo aplicam-se
+ apenas para esta solução:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>name</literal> (opcional, requerida para esta solução): Uma
+ propriedade do tipo componente que armazena o identificador composto
+ (veja capítulo 9)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>access</literal> (opcional - valor default <literal>property</literal>):
+ A estartégia Hibernate que deve ser utilizada para acessar o valor da propriedade.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>class</literal> (opcional - valor default para o tipo de propriedade
+ determiando por reflexão) : A classe componente utilizada como um identificador
+ composto (veja a próxima sessão).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Esta terceira solução, um <emphasis>componente de identificação</emphasis>, é o que nós
+ recomendamos para a maioria das aplicações.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-discriminator" revision="3">
+ <title>discriminator</title>
+
+ <para>
+ O elemento <literal><discriminator></literal> é necessário para persistência
+ polimórfica utilizando a estratégia de mapeamento table-per-class-hierarchy e declara
+ uma coluna discriminadora da tabela. A coluna discriminadora contem valores de marcação
+ que dizem a camada de persistência qual subclasse instanciar para uma linha particular.
+ Um restrito conjunto de tipos que podem ser utilizados: <literal>string</literal>,
+ <literal>character</literal>, <literal>integer</literal>, <literal>byte</literal>,
+ <literal>short</literal>, <literal>boolean</literal>,
+ <literal>yes_no</literal>, <literal>true_false</literal>.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="discriminator1" coords="2 60"/>
+ <area id="discriminator2" coords="3 60" />
+ <area id="discriminator3" coords="4 60" />
+ <area id="discriminator4" coords="5 60" />
+ <area id="discriminator5" coords="6 60" />
+ </areaspec>
+ <programlisting><![CDATA[<discriminator
+ column="discriminator_column"
+ type="discriminator_type"
+ force="true|false"
+ insert="true|false"
+ formula="arbitrary sql expression"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="discriminator1">
+ <para>
+ <literal>column</literal> (opcional - valor default <literal>class</literal>)
+ o nome da coluna discriminadora
+ </para>
+ </callout>
+ <callout arearefs="discriminator2">
+ <para>
+ <literal>type</literal> (opcional - valor default <literal>string</literal>)
+ o nome que indica o tipo Hibernate
+ </para>
+ </callout>
+ <callout arearefs="discriminator3">
+ <para>
+ <literal>force</literal> (opcional - valor default <literal>false</literal>)
+ "força" o Hibernate a especificar valores discriminadores permitidos mesmo
+ quando recuperando todas as instancias da classe root.
+ </para>
+ </callout>
+ <callout arearefs="discriminator4">
+ <para>
+ <literal>insert</literal> (opcional - valor default para <literal>true</literal>)
+ sete isto para <literal>false</literal> se sua coluna discriminadora é também
+ parte do identificador composto mapeado. (Diz ao Hibernate para não incluir a
+ coluna em comandos SQL <literal>INSERT</literal>s).
+ </para>
+ </callout>
+ <callout arearefs="discriminator5">
+ <para>
+ <literal>formula</literal> (opcional) uma expressão SQL arbitraria que é e
+ xecutada quando um tipo tem que ser avaliado. Permite discriminação baseada
+ em conteúdo.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Valores atuais de uma coluna discriminada são especificados pelo atributo
+ <literal>discriminator-value</literal> da <literal><class></literal>
+ e elementos da <literal><subclass></literal>.
+ </para>
+
+ <para>
+ O atributo <literal>force</literal> é util (apenas) em tabelas contendo linhas com
+ valores discriminadores "extras" que não estão mapeados para uma classe persistente.
+ Este não é geralmente o caso.
+ </para>
+
+ <para>
+ Usando o atributo <literal>formula</literal> voce pode declarar uma expressão SQL
+ arbitrária que sera utilizada para avaliar o tipo de uma linha :
+ </para>
+
+ <programlisting><![CDATA[<discriminator
+ formula="case when CLASS_TYPE in ('a', 'b', 'c') then 0 else 1 end"
+ type="integer"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-version" revision="4">
+ <title>version (optional)</title>
+
+ <para>
+ O elemento <literal><version></literal> é opcional e indica que a tabela
+ possui dados versionados. Isto é particularmente útil se você planeja utilizar
+ <emphasis>transações longas</emphasis> (veja abaixo):
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="version1" coords="2 70"/>
+ <area id="version2" coords="3 70"/>
+ <area id="version3" coords="4 70"/>
+ <area id="version4" coords="5 70"/>
+ <area id="version5" coords="6 70"/>
+ <area id="version6" coords="7 70"/>
+ <area id="version7" coords="8 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<version
+ column="version_column"
+ name="propertyName"
+ type="typename"
+ access="field|property|ClassName"
+ unsaved-value="null|negative|undefined"
+ generated="never|always"
+ insert="true|false"
+ node="element-name|@attribute-name|element/@attribute|."
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="version1">
+ <para>
+ <literal>column</literal> (opcional - default a a propriedade name): O nome da
+ coluna mantendo o numero da versão
+ </para>
+ </callout>
+ <callout arearefs="version2">
+ <para>
+ <literal>name</literal>: O nome da propriedade da classe persistente.
+ </para>
+ </callout>
+ <callout arearefs="version3">
+ <para>
+ <literal>type</literal> (opcional - valor default para <literal>integer</literal>):
+ O tipo do numero da versão
+ </para>
+ </callout>
+ <callout arearefs="version4">
+ <para>
+ <literal>access</literal> (opcional - valor default <literal>property</literal>):
+ A estratégia Hibernate que deve ser usada para acessar o valor da propriedade.
+ </para>
+ </callout>
+ <callout arearefs="version5">
+ <para>
+ <literal>unsaved-value</literal> (opcional – valor default para <literal>undefined
+ </literal>): Um valor para a propriedade versão que indica que uma instancia é
+ uma nova instanciada (unsaved), distinguindo de instancias desconectadas que foram
+ salvas ou carregadas em sessões anteriores. ((<literal>undefined</literal> especifica
+ que o valor da propriedade de identificação deve ser utilizado).
+ </para>
+ </callout>
+ <callout arearefs="version6">
+ <para>
+ <literal>generated</literal> (optional - defaults to <literal>never</literal>):
+ Specifies that this version property value is actually generated by the database.
+ See the discussion of <xref linkend="mapping-generated">generated properties</xref>.
+ <literal>generated</literal> (opcional - valor default <literal>never</literal>):
+ Especifica que valor para a propriedade versão é na verdade gerado pelo banco de
+ dados. Veja a discussão da Seção
+ <xref linkend="mapping-generated">generated properties</xref>.
+ </para>
+ </callout>
+ <callout arearefs="version7">
+ <para>
+ <literal>insert</literal> (opcional - valor default para <literal>true</literal>):
+ Especifica se a coluna de versão deve ser incluída no comando SQL de insert.
+ Pode ser configurado como <literal>false</literal> se a coluna do banco de dados
+ está definida com um valor default de <literal>0</literal>.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Números de versão podem ser dos tipos Hibernate <literal>long</literal>,
+ <literal>integer</literal>, <literal>short</literal>, <literal>timestamp</literal> ou
+ <literal>calendar</literal>.
+ </para>
+
+ <para>
+ A versão de uma propriedade timestamp nunca deve ser nula para uma instancia
+ desconectada, assim o Hibernate irá identificar qualquer instância com uma versão
+ nula ou timestamp como transiente, não importando qual estratégia para foi
+ especificada para <literal>unsaved-value</literal>. <emphasis>Declarando uma versão
+ nula ou a propriedade timestamp é um caminho fácil para tratar problemas com
+ reconexões transitivas no Hibernate, especialmente úteis para pessoas utilizando
+ identificadores assinaldados ou chaves compostas!</emphasis>
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-declaration-timestamp" revision="4" >
+ <title>timestamp (optional)</title>
+
+ <para>
+ O elemento opcional <literal><timestamp></literal> indica que uma tabela contém
+ dados timestamped. Isso tem por objetivo dar uma alternativa para versionamento. Timestamps
+ são por natureza uma implementação menos segura do locking otimista. Entretanto, algumas
+ vezes a aplicação pode usar timestamps em outros caminhos.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="timestamp1" coords="2 70"/>
+ <area id="timestamp2" coords="3 70" />
+ <area id="timestamp3" coords="4 70" />
+ <area id="timestamp4" coords="5 70" />
+ <area id="timestamp5" coords="6 70" />
+ <area id="timestamp6" coords="7 70" />
+ </areaspec>
+ <programlisting><![CDATA[<timestamp
+ column="timestamp_column"
+ name="propertyName"
+ access="field|property|ClassName"
+ unsaved-value="null|undefined"
+ source="vm|db"
+ generated="never|always"
+ node="element-name|@attribute-name|element/@attribute|."
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="timestamp1">
+ <para>
+ <literal>column</literal> (opcional - valor default para a propriedade name):
+ O nome da coluna que mantem o timestamp.
+ </para>
+ </callout>
+ <callout arearefs="timestamp2">
+ <para>
+ <literal>name</literal>: O nome da propriedade no estilo JavaBeans do
+ tipo <literal>Date</literal> ou <literal>Timestamp</literal> da classe
+ persistente Java.
+ </para>
+ </callout>
+ <callout arearefs="timestamp3">
+ <para>
+ <literal>access</literal> (opcional - valor default para <literal>property</literal>):
+ A estretagia Hibernate que deve ser utilizada para acessar o valor da propriedade.
+ </para>
+ </callout>
+ <callout arearefs="timestamp4">
+ <para>
+ <literal>unsaved-value</literal> (opcional - valor default <literal>null</literal>):
+ Uma propriedade para a versão de que indica que uma instância é uma nova instanciada
+ (unsaved), distinguindo-a de instancias desconectadas que foram salvas ou carregadas
+ em sessões previas. (<literal>undefined</literal> especifica que um valor de
+ propriedade de identificação deve ser utilizado)
+ </para>
+ </callout>
+ <callout arearefs="timestamp5">
+ <para>
+ <literal>source</literal> (opcional - valor default para <literal>vm</literal>):
+ De onde o Hibernate deve recuperar o valor timestamp? Do banco de dados ou da JVM
+ corrente? Timestamps baseados em banco de dados levam a um overhead porque o
+ Hibernate precisa acessar o banco de dados para determinar o "próximo valor", mas é
+ mais seguro para uso em ambientes de "cluster". Observe também, que nem todos
+ <literal>Dialect</literal>s suportam a recuperação do timestamp corrente do banco
+ de dados, enquando outros podem não ser seguros para utilização em bloqueios
+ pela falta de precisão (Oracle 8 por exemplo)
+ </para>
+ </callout>
+ <callout arearefs="timestamp6">
+ <para>
+ <literal>generated</literal> (opcional - valor default <literal>never</literal>):
+ Especifica que o valor da propriedade timestamp é gerado pelo banco de dados.
+ Veja a discussão <xref linkend="mapping-generated">generated properties</xref>.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Observe que <literal><timestamp></literal> é equivalente a
+ <literal><version type="timestamp"></literal>. E
+ <literal><timestamp source="db"></literal> é equivalente a
+ <literal><version type="dbtimestamp"></literal>.
+ </para>
+ </sect2>
+
+
+ <sect2 id="mapping-declaration-property" revision="4">
+ <title>property</title>
+
+ <para>
+ O elemento <literal><property></literal> declara uma propriedade
+ persistente de uma classe, no estilo JavaBean.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="property1" coords="2 70"/>
+ <area id="property2" coords="3 70"/>
+ <area id="property3" coords="4 70"/>
+ <areaset id="property4-5" coords="">
+ <area id="property4" coords='5 70'/>
+ <area id="property5" coords='6 70'/>
+ </areaset>
+ <area id="property6" coords="7 70"/>
+ <area id="property7" coords="8 70"/>
+ <area id="property8" coords="9 70"/>
+ <area id="property9" coords="10 70"/>
+ <area id="property10" coords="11 70"/>
+ <area id="property11" coords="12 70"/>
+ <area id="property12" coords="13 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<property
+ name="propertyName"
+ column="column_name"
+ type="typename"
+ update="true|false"
+ insert="true|false"
+ formula="arbitrary SQL expression"
+ access="field|property|ClassName"
+ lazy="true|false"
+ unique="true|false"
+ not-null="true|false"
+ optimistic-lock="true|false"
+ generated="never|insert|always"
+ node="element-name|@attribute-name|element/@attribute|."
+ index="index_name"
+ unique_key="unique_key_id"
+ length="L"
+ precision="P"
+ scale="S"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="property1">
+ <para>
+ <literal>name</literal>: o nome da propriedade, iniciando com letra minúscula.
+ </para>
+ </callout>
+ <callout arearefs="property2">
+ <para>
+ <literal>column</literal> (opcional - default para a propriedade name): o nome
+ da coluna mapeada do banco de dados, Isto pode também ser especificado pelo(s)
+ elemento(s) <literal><column></literal> aninhados.
+
+ </para>
+ </callout>
+ <callout arearefs="property3">
+ <para>
+ <literal>type</literal> (opcional): um nome que indica o tipo Hibernate.
+ </para>
+ </callout>
+ <callout arearefs="property4-5">
+ <para>
+ <literal>update, insert</literal> (opcional - valor default <literal>true</literal>):
+ especifica que as colunas mapeadas devem ser incluidas nas instruções SQL de
+ <literal>UPDATE</literal> e/ou <literal>INSERT</literal> . Setar ambas para to
+ <literal>false</literal> permite uma propridade "derivada" pura cujo valor é
+ inicializado de outra propriedade que mapeie a mesma coluna(s) ou por uma trigger
+ ou outra aplicação.
+ </para>
+ </callout>
+ <callout arearefs="property6">
+ <para>
+ <literal>formula</literal> (opcional): uma expressão SQL que definie o valor para
+ uma propriedade <emphasis>calculada</emphasis>. Propriedades calculadas nao tem
+ uma coluna de mapeamento para elas.
+ </para>
+ </callout>
+ <callout arearefs="property7">
+ <para>
+ <literal>access</literal> (opcional – valor default <literal>property</literal>):
+ A estratégia que o Hibernate deve utilizar para acessar o valor da propriedade
+ </para>
+ </callout>
+ <callout arearefs="property8">
+ <para>
+ <literal>lazy</literal> (opcional - valor default para <literal>false</literal>):
+ Especifica que esta propriedade deve ser trazida de forma "lazy" quando a
+ instancia da variável é acessada pela primeira vez (requer instrumentação
+ bytecode em tempo de criação).
+ </para>
+ </callout>
+ <callout arearefs="property9">
+ <para>
+ <literal>unique</literal> (opcional): Habilita a geração de DDL de uma
+ unica constraint para as colunas. Assim, permite que isto seja o
+ alvo de uma <literal>property-ref</literal>.
+ </para>
+ </callout>
+ <callout arearefs="property10">
+ <para>
+ <literal>not-null</literal> (opcional): Habilita a geração de DDL de uma
+ constraint de nulidade para as colunas.
+ </para>
+ </callout>
+ <callout arearefs="property11">
+ <para>
+ <literal>optimistic-lock</literal> (opcional - valor default <literal>true</literal>):
+ Especifica se mudanças para esta propriedade requerem ou não bloqueio otimista.
+ Em outras palavras, determina se um incremento de versão deve ocorrer quando
+ esta propriedade está suja.
+ </para>
+ </callout>
+ <callout arearefs="property12">
+ <para>
+ <literal>generated</literal> (opcional - valor default <literal>never</literal>):
+ Especifica que o valor da propriedade é na verdade gerado pelo banco de dados.
+ Veja a discussão da seção
+ <xref linkend="mapping-generated">generated properties</xref>.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <emphasis>typename</emphasis> pode ser:
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ The name of a Hibernate basic type (eg. <literal>integer, string, character,
+ date, timestamp, float, binary, serializable, object, blob</literal>).
+ O nome do tipo basico do Hibernate (ex., <literal>integer, string, character,
+ date, timestamp, float, binary, serializable, object, blob</literal>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ O nome da classe Java com um tipo básico default (ex. <literal>int, float,
+ char, java.lang.String, java.util.Date, java.lang.Integer, java.sql.Clob</literal>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ O nome da classe Java serializable
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ O nome da classe de um tipo customizado (ex. <literal>com.illflow.type.MyCustomType</literal>).
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ Se você não especificar um tipo, o Hibernate ira utilizar reflexão sobre a
+ propriedade nomeada para ter uma idéia do tipo Hibernate correto. O Hibernate ira
+ tentar interpretar o nome da classe retornada, usando as regras 2, 3 e 4 nesta ordem.
+ Entretanto, isto não é sempre suficiente Em certos casos, você ainda irá necessitar
+ do atributo <literal>type</literal>. (Por exemplo, para distinguir entre
+ <literal>Hibernate.DATE</literal> ou <literal>Hibernate.TIMESTAMP</literal>,
+ ou para espcificar uma tipo ciustomizado.)
+ </para>
+
+ <para>
+ O atributo <literal>access</literal> permite voce controlar como o Hibernate irá
+ acessar a propriedade em tempo de execução. Por default, o Hibernate irá chamar os
+ métodos get/set da propriedades. Se voce especificar <literal>access="field"</literal>,
+ o Hibernate ira bipassar os metodos get/set, acessnado o campo diretamente,
+ usando reflexão. Voc epode especificar sua própria estratégia para acesso da
+ propriedade criando uma classe que implemente a interface
+ <literal>org.hibernate.property.PropertyAccessor</literal>.
+ </para>
+
+ <para>
+ Um recurso especialmente poderoso é o de propriedades derivadas. Estas propriedades
+ são por definição read-only, e o valor da propriedade é calculado em tempo de execução.
+ Você declara este calculo como uma expressão SQL, que traduz para clausula
+ <literal>SELECT</literal> de uma subquery daquery SQL que carrega a instancia:
+ </para>
+
+ <programlisting><![CDATA[
+<property name="totalPrice"
+ formula="( SELECT SUM (li.quantity*p.price) FROM LineItem li, Product p
+ WHERE li.productId = p.productId
+ AND li.customerId = customerId
+ AND li.orderNumber = orderNumber )"/>]]></programlisting>
+
+ <para>
+ Observe que você pode referenciar as entidades da própria tabela,
+ através da não declaração de um alias para uma coluna particular (
+ <literal>customerId</literal> no exemplo dado). Observe tambem que voce pode usar o
+ mapeamento de elemento aninhado <literal><formula></literal>, se você não
+ gostar de usar o atributo.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-manytoone" revision="5">
+ <title>many-to-one</title>
+
+ <para>
+ Uma associação ordinária para outra classe persistente é declarada usando o
+ elemento <literal>many-to-one</literal>. O modelo relacional é uma
+ associação many-to-one: a uma chave estrangeira de uma tabela referenciando
+ a chave primaria da tabela destino.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="manytoone1" coords="2 70"/>
+ <area id="manytoone2" coords="3 70"/>
+ <area id="manytoone3" coords="4 70"/>
+ <area id="manytoone4" coords="5 70"/>
+ <area id="manytoone5" coords="6 70"/>
+ <areaset id="manytoone6-7" coords="">
+ <area id="manytoone6" coords='7 70'/>
+ <area id="manytoone7" coords='8 70'/>
+ </areaset>
+ <area id="manytoone8" coords="9 70"/>
+ <area id="manytoone9" coords="10 70"/>
+ <area id="manytoone10" coords="11 70"/>
+ <area id="manytoone11" coords="12 70"/>
+ <area id="manytoone12" coords="13 70"/>
+ <area id="manytoone13" coords="14 70"/>
+ <area id="manytoone14" coords="15 70"/>
+ <area id="manytoone15" coords="16 70"/>
+ <area id="manytoone16" coords="17 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<many-to-one
+ name="propertyName"
+ column="column_name"
+ class="ClassName"
+ cascade="cascade_style"
+ fetch="join|select"
+ update="true|false"
+ insert="true|false"
+ property-ref="propertyNameFromAssociatedClass"
+ access="field|property|ClassName"
+ unique="true|false"
+ not-null="true|false"
+ optimistic-lock="true|false"
+ lazy="proxy|no-proxy|false"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ formula="arbitrary SQL expression"
+ node="element-name|@attribute-name|element/@attribute|."
+ embed-xml="true|false"
+ index="index_name"
+ unique_key="unique_key_id"
+ foreign-key="foreign_key_name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="manytoone1">
+ <para>
+ <literal>name</literal>: O nome da propriedade.
+ </para>
+ </callout>
+ <callout arearefs="manytoone2">
+ <para>
+ <literal>column</literal> (opcional): O nome da coluna foreign key. Isto
+ pode também ser especificado através de elementos aninhados
+ <literal><column></literal>.
+ </para>
+ </callout>
+ <callout arearefs="manytoone3">
+ <para>
+ <literal>class</literal> (opcional – default para o tipo de propriedade
+ determinado pela reflexão). O nome da classe associada.
+ </para>
+ </callout>
+ <callout arearefs="manytoone4">
+ <para>
+ <literal>cascade</literal> (opcional): Especifica quais operações dever
+ ser em cascata do objeto pai para o objeto associado.
+ </para>
+ </callout>
+ <callout arearefs="manytoone5">
+ <para>
+ <literal>fetch</literal> (opcional - default para <literal>select</literal>):
+ Escolhe entre recuperação outer-join ou recuperação seqüencial.
+ </para>
+ </callout>
+ <callout arearefs="manytoone6-7">
+ <para>
+ <literal>update, insert</literal> (opcional - valor default <literal>true</literal>):
+ especifica que as colunas mapeadas dever ser incluidas em instruções SQL de
+ <literal>UPDATE</literal> e/ou <literal>INSERT</literal>. Setando ambas para
+ <literal>false</literal> você permite uma associação "derivada" pura cujos valores
+ são inicializados de algumas outras propriedades que mapeiam a mesma coluna ou
+ por uma trigger ou outra aplicação.
+ </para>
+ </callout>
+ <callout arearefs="manytoone8">
+ <para>
+ <literal>property-ref</literal>: (opcional) O nome da propriedade da classe associada
+ que faz a junção desta foreign key. Se não especificada, a chave primaria da
+ classe associada será utilizada.
+ </para>
+ </callout>
+ <callout arearefs="manytoone9">
+ <para>
+ <literal>access</literal> (opcional - valor default <literal>property</literal>): A
+ estrategia que o Hibernate deve utilizar para acessar o valor da propriedade.
+ </para>
+ </callout>
+ <callout arearefs="manytoone10">
+ <para>
+ <literal>unique</literal> (opcional): Habilita a geração DDL de uma constraint
+ unique para a coluna foreign-key. Alem disso, permite ser o alvo de uma
+ <literal>property-ref</literal>. Isso torna a associação multipla
+ efetivamente um para um.
+ </para>
+ </callout>
+ <callout arearefs="manytoone11">
+ <para>
+ <literal>not-null</literal> (opcional): Habilita a geração DDL de uma constraint de
+ nulidade para as foreign keys.
+ </para>
+ </callout>
+ <callout arearefs="manytoone12">
+ <para>
+ <literal>optimistic-lock</literal> (opcional - valor default <literal>true</literal>):
+ Especifica se mudanças desta propriedade requerem ou não travamento otimista.
+ Em outras palavras, determina se um incremento de versão deve ocorrer quando
+ esta propriedade está suja.
+ </para>
+ </callout>
+ <callout arearefs="manytoone13">
+ <para>
+ <literal>lazy</literal>(opcional – valor default <literal>proxy</literal>):
+ Por default, associações de ponto unico são envoltas em um proxie.
+ <literal>lazy="no-proxy"</literal> especifica que a propriedade deve ser
+ trazida de forma tardia quando a instancia da variável é acessada pela
+ primeira vez (requer instrumentação bytecode em tempo de criação)
+ <literal>lazy="false"</literal> especifica que a associação será
+ sempre recuperada fortemente.
+ </para>
+ </callout>
+ <callout arearefs="manytoone14">
+ <para>
+ <literal>not-found</literal> (opcional - valor default <literal>exception</literal>):
+ Especifica como as foreign keys que referenciam linhas ausentes serão tratadas:
+ <literal>ignore</literal> irá tratar a linha ausente como ama associaççao de null
+ </para>
+ </callout>
+ <callout arearefs="manytoone15">
+ <para>
+ <literal>entity-name</literal> (opcional): O nome da entidade da classe associada.
+ </para>
+ </callout>
+ </calloutlist>
+ <callout arearefs="manytoone16">
+ <para>
+ <literal>formula</literal> (optional): Uma expressão SQL que define um valor
+ para um foreign key <emphasis>computed</emphasis>.
+ </para>
+ </callout>
+ </programlistingco>
+
+ <para>
+ Setar o valor do atributo <literal>cascade</literal> para qualquer valor
+ significativo diferente de <literal>none</literal> irá propagar certas operações
+ ao objeto associado. Os valores significativos são os nomes das operações básicas
+ do Hibernate, <literal>persist, merge, delete, save-update, evict, replicate, lock,
+ refresh</literal>, assim como os valores especiais <literal>delete-orphan</literal>
+ e <literal>all</literal> e combinações de nomes de operações separadas por vírgula,
+ como por exemplo, <literal>cascade="persist,merge,evict"</literal> ou
+ <literal>cascade="all,delete-orphan"</literal>. Veja a seção
+ <xref linkend="objectstate-transitive"/> para uma explicação completa. Note que
+ associações valoradas simples (associações muitos-pra-um, e um-pra-um) não suportam
+ orphan delete.
+ </para>
+
+ <para>
+ Uma típica declaração <literal>muitos-pra-um</literal> se parece com esta:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="product" class="Product" column="PRODUCT_ID"/>]]></programlisting>
+
+ <para>
+ O atributo <literal>property-ref</literal> deve apenas ser usado para mapear dados
+ legados onde uma chave estrangeira se referencia a uma chave exclusiva da tabela
+ associada que não seja à chave primária. Este é um modelo relacional desagradável.
+ Por exemplo, suponha que a classe <literal>Product</literal> tenha um número
+ seqüencial exclusivo, que não é a chave primária. (O atributo <literal>unique</literal>
+ controla a geração de DDL do Hibernate com a ferramenta SchemaExport.)
+ </para>
+
+ <programlisting><![CDATA[<property name="serialNumber" unique="true" type="string" column="SERIAL_NUMBER"/>]]></programlisting>
+
+ <para>
+ Então o mapeamento para <literal>OrderItem</literal> poderia usar:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="product" property-ref="serialNumber" column="PRODUCT_SERIAL_NUMBER"/>]]></programlisting>
+
+ <para>
+ Porém, isto obviamente não é indicado, nunca.
+ </para>
+
+ <para>
+ Se a chave exclusiva referenciada engloba múltiplas propriedades da entidade associada,
+ você deve mapear as propriedades referenciadas dentro de um elemento chamado
+ <literal><properties></literal>
+
+ </para>
+
+ <para>
+ Se a chave exclusiva referenciada é a propriedade de um componente, você pode especificar
+ um caminho para a propriedade.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="owner" property-ref="identity.ssn" column="OWNER_SSN"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-onetoone" revision="3">
+ <title>one-to-one (um-pra-um)</title>
+
+ <para>
+ Uma associação um-pra-um para outra classe persistente é declarada usando
+ um elemento <literal>one-to-one </literal>.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="onetoone1" coords="2 70"/>
+ <area id="onetoone2" coords="3 70"/>
+ <area id="onetoone3" coords="4 70"/>
+ <area id="onetoone4" coords="5 70"/>
+ <area id="onetoone5" coords="6 70"/>
+ <area id="onetoone6" coords="7 70"/>
+ <area id="onetoone7" coords="8 70"/>
+ <area id="onetoone8" coords="9 70"/>
+ <area id="onetoone9" coords="10 70"/>
+ <area id="onetoone10" coords="11 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<one-to-one
+ name="propertyName"
+ class="ClassName"
+ cascade="cascade_style"
+ constrained="true|false"
+ fetch="join|select"
+ property-ref="propertyNameFromAssociatedClass"
+ access="field|property|ClassName"
+ formula="any SQL expression"
+ lazy="proxy|no-proxy|false"
+ entity-name="EntityName"
+ node="element-name|@attribute-name|element/@attribute|."
+ embed-xml="true|false"
+ foreign-key="foreign_key_name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="onetoone1">
+ <para>
+ <literal>name</literal>: O nome da propriedade.
+ </para>
+ </callout>
+ <callout arearefs="onetoone2">
+ <para>
+ <literal>class</literal> (opcional – default para o tipo da propriedade
+ definido via reflection): O nome da classe associada.
+ </para>
+ </callout>
+ <callout arearefs="onetoone3">
+ <para>
+ <literal>cascade</literal> (opcional): Especifica qual operação deve
+ ser cascateada do objeto pai para o objeto associado.
+ </para>
+ </callout>
+ <callout arearefs="onetoone4">
+ <para>
+ <literal>constrained</literal> (opcional): Especifica que uma chave estrangeira
+ constraint na chave primária da tabela mapeada referencia a tabela da classe
+ associada, Esta opção afeta a ordem em queh <literal>save()</literal> e
+ <literal>delete()</literal> são cascateadas, e determina se a associação
+ pode ser substituída (isto também é usado pela ferramenta schema export).
+ </para>
+ </callout>
+ <callout arearefs="onetoone5">
+ <para>
+ <literal>fetch</literal> ((opcional – valor default <literal>select</literal>):
+ Escolhe entre outer-join fetching ou sequential select fetching.
+ </para>
+ </callout>
+ <callout arearefs="onetoone6">
+ <para>
+ <literal>property-ref</literal>(opcional): O nome da propriedade da classe associada
+ que é ligada a chave primária desta classe. Se não for especificada, a chave primária
+ da classe associada é utilizada.
+ </para>
+ </callout>
+ <callout arearefs="onetoone7">
+ <para>
+ <literal>access</literal> (opcional - valor default padrão <literal>property</literal>):
+ A estratégia que o Hibernate pode usar para acessar o valor da propriedade.
+ </para>
+ </callout>
+ <callout arearefs="onetoone8">
+ <para>
+ <literal>formula</literal> (opcional): Quase todas associações um-pra-um mapeiam
+ para a chave primária da entidade dona. No caso raro, que não é o caso, você
+ pode especificar uma outra coluna, colunas ou expressões para juntar utilizando
+ uma formula SQL. (Veja <literal>org.hibernate.test.onetooneformula</literal>
+ para exemplo).
+ </para>
+ </callout>
+ <callout arearefs="onetoone9">
+ <para>
+ <literal>lazy</literal> (opcional – valor default <literal>proxy</literal>):
+ Por default, associações single point são proxied. <literal>lazy="no-proxy"</literal>
+ especifica que a propriedade deve ser fetched lazily quando o atributo é acessado
+ pela primeira vez (requer build-time bytecode instrumentation).
+ <literal>lazy="false"</literal> especifica que a associação vai sempre ser
+ avidamente fetched. <emphasis>Note que se <literal>constrained="false"</literal>,
+ proxing é impossível e o Hibernate vai ávido fetch a associação!</emphasis>
+ </para>
+ </callout>
+ <callout arearefs="onetoone10">
+ <para>
+ <literal>entity-name</literal> (opcional): O nome da entidade da classe associada.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Existem duas variedades de associações um-pra-um:
+ </para>
+ <itemizedlist>
+ <listitem><para>
+ associações de chave primária
+ </para></listitem>
+ <listitem><para>
+ associações de chave estrangeira exclusiva
+ </para></listitem>
+ </itemizedlist>
+
+ <para>
+ Associações de chave primária não necessitam de uma coluna extra de tabela; se duas
+ linhas são relacionadas pela associação então as duas linhas da tabela dividem a mesmo
+ valor da chave primária. Assim, se você quer que dois objetos sejam relacionados por
+ uma associação de chave primária, você deve ter certeza que eles são assinados com o
+ mesmo valor identificador!
+ </para>
+
+ <para>
+ Para uma associação de chave primária, adicione os seguintes mapeamentos em
+ <literal>Employee</literal> e <literal>Person</literal>, respectivamente.
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="person" class="Person"/>]]></programlisting>
+ <programlisting><![CDATA[<one-to-one name="employee" class="Employee" constrained="true"/>]]></programlisting>
+
+ <para>
+ Agora nós devemos assegurar que as chaves primárias de linhas relacionadas nas
+ tabelas PERSON e EMPLOYEE são iguais. Nós usamos uma estratégia especial de geração
+ de identificador do Hibernate chamada <literal>foreign</literal>:
+ </para>
+
+ <programlisting><![CDATA[<class name="person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="foreign">
+ <param name="property">employee</param>
+ </generator>
+ </id>
+ ...
+ <one-to-one name="employee"
+ class="Employee"
+ constrained="true"/>
+</class>]]></programlisting>
+
+ <para>
+ Uma nova instância de <literal>Person</literal> salva recentemente é então assinada
+ com o mesmo valor da chave primária da instância de <literal>employee</literal> referenciada
+ com a propriedade <literal>employee</literal> daquela <literal>Person</literal>.
+ </para>
+
+ <para>
+ Alternativamente, uma chave estrangeira com uma unique constraint, de
+ <literal>Employee</literal> para <literal>Person</literal>, pode ser expressa como:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="person" class="Person" column="PERSON_ID" unique="true"/>]]></programlisting>
+
+ <para>
+ E esta associação pode ser feita de forma bi-direcional adicionando o seguinte
+ no mapeamento de <literal>Person</literal>:
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="employee" class="Employee" property-ref="person"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-naturalid">
+ <title>natural-id</title>
+
+ <programlisting><![CDATA[<natural-id mutable="true|false"/>
+ <property ... />
+ <many-to-one ... />
+ ......
+</natural-id>]]></programlisting>
+
+ <para>
+ Embora nós recomendemos o uso de surrogate keys como chaves primárias, você deve
+ ainda identificar chaves naturais para todas as entidades. Uma chave natural é
+ uma propriedade ou combinação de propriedades que é exclusiva e não nula. Se não
+ pude ser modificada, melhor ainda. Mapeie as propriedades da chave natural dentro do
+ elemento <literal><natural-id></literal>. O Hibernate irá gerar a chave
+ exclusiva necessária e as constraints de nullability , e seu mapeamento será
+ apropriadamente auto documentado.
+ </para>
+
+ <para>
+ Nós recomendamos com enfase que você implemente <literal>equals()</literal> e
+ <literal>hashCode()</literal> para comparar as propriedades da chave natural da
+ entidade.
+ </para>
+
+ <para>
+ Este mapeamento não tem o objetivo de uso com entidades com natural chaves primárias.
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>mutable</literal> mutable (opcional, valor default<literal>false</literal>):
+ Por default, propriedades naturais identificadoras são consideradas imutáveis (constante).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-component" revision="2">
+ <title>componente, componente dinâmico</title>
+
+ <para>
+ O elemento<literal><component></literal> mapeia propriedades de um
+ objeto filho para colunas da tabela de uma classe pai. Componentes podem,
+ um após o outro, declarar suas próprias propriedades, componentes ou coleções.
+ Veja "Components" abaixo.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="component1" coords="2 45"/>
+ <area id="component2" coords="3 45"/>
+ <area id="component3" coords="4 45"/>
+ <area id="component4" coords="5 45"/>
+ <area id="component5" coords="6 45"/>
+ <area id="component6" coords="7 45"/>
+ <area id="component7" coords="8 45"/>
+ <area id="component8" coords="9 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<component
+ name="propertyName"
+ class="className"
+ insert="true|false"
+ update="true|false"
+ access="field|property|ClassName"
+ lazy="true|false"
+ optimistic-lock="true|false"
+ unique="true|false"
+ node="element-name|."
+>
+
+ <property ...../>
+ <many-to-one .... />
+ ........
+</component>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="component1">
+ <para>
+ <literal>name</literal>: O nome da propriedade.
+ </para>
+ </callout>
+ <callout arearefs="component2">
+ <para>
+ <literal>class</literal> (opcional – valor default para o tipo de
+ propriedade determinada por reflection): O nome da classe (filha) do
+ componente.
+ </para>
+ </callout>
+ <callout arearefs="component3">
+ <para>
+ <literal>insert</literal>: As colunas mapeadas aparecem nos
+ SQL de <literal>INSERT</literal>s?
+ </para>
+ </callout>
+ <callout arearefs="component4">
+ <para>
+ <literal>update</literal>: As colunas mapeadas aparecem nos
+ SQL de <literal>UPDATE</literal>s?
+ </para>
+ </callout>
+ <callout arearefs="component5">
+ <para>
+ <literal>access</literal> (opcional – valor default <literal>property</literal>):
+ A estratégia que o Hibernate pode usar para acessar o valor da propriedade.
+ </para>
+ </callout>
+ <callout arearefs="component6">
+ <para>
+ <literal>lazy</literal> (opcional - valor default <literal>false</literal>):
+ Especifica que este componente deve ser fetched lazily quando o atributo for
+ acessado pela primeira vez (requer build-time bytecode instrumentation).
+ </para>
+ </callout>
+ <callout arearefs="component7">
+ <para>
+ <literal>optimistic-lock</literal> (opcional – valor default <literal>true</literal>):
+ Especifica que atualizações para este componente requerem ou não aquisição
+ de um lock otimista. Em outras palavras, determina se uma versão de incremento deve
+ ocorrer quando esta propriedade estiver modificada.
+ </para>
+ </callout>
+ <callout arearefs="component8">
+ <para>
+ <literal>unique</literal> (opcional – valor default <literal>false</literal>):
+ Especifica que existe uma unique constraint em todas as colunas mapeadas do
+ componente.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ A tag filha <literal><property></literal> acrescenta a propriedade
+ de mapeamento da classe filha para colunas de uma tabela.
+ </para>
+
+ <para>
+ O elemento <literal><component></literal> permite um sub-elemento
+ <literal><parent></literal> mapeie uma propriedade da classe do componente
+ como uma referencia de volta para a entidade que o contém.
+ </para>
+
+ <para>
+ O elemento <literal><dynamic-component></literal> permite que um
+ <literal>Map</literal> possa ser mapeado como um componente onde os nomes das
+ propriedades referem-se para as chaves no mapa, veja
+ <xref linkend="components-dynamic"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-properties" revision="2">
+ <title>propriedades</title>
+
+ <para>
+ O elemento <literal><properties></literal> permite a definição de um grupo
+ com nome, lógico de propriedades de uma classe. O uso mais importante do construtor
+ é que este permite uma combinação de propriedades para ser o objetivo de uma
+ <literal>property-ref</literal>. É também um modo conveninente para definir uma
+ unique constraint de múltiplas colunas.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="properties1" coords="2 45"/>
+ <area id="properties2" coords="3 45"/>
+ <area id="properties3" coords="4 45"/>
+ <area id="properties4" coords="5 45"/>
+ <area id="properties5" coords="6 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<properties
+ name="logicalName"
+ insert="true|false"
+ update="true|false"
+ optimistic-lock="true|false"
+ unique="true|false"
+>
+
+ <property ...../>
+ <many-to-one .... />
+ ........
+</properties>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="properties1">
+ <para>
+ <literal>name</literal>:: O nome lógico do agrupamento –
+ <emphasis>não </emphasis> é o nome atual de propriedade.
+ </para>
+ </callout>
+ <callout arearefs="properties2">
+ <para>
+ <literal>insert</literal>: As colunas mapeadas aparecem nos
+ SQL de <literal>INSERT</literal>s?
+ </para>
+ </callout>
+ <callout arearefs="properties3">
+ <para>
+ <literal>update</literal>: As colunas mapeadas aparecem nos
+ SQL de <literal>UPDATE</literal>s?
+ </para>
+ </callout>
+ <callout arearefs="properties4">
+ <para>
+ <literal>optimistic-lock</literal> (opcional – valor default <literal>true</literal>):
+ Especifica que atualizações para estes componentes requerem ou não aquisição de um
+ lock otimista. Em outras palavras, determina se uma versão de incremento deve ocorrer
+ quando estas propriedades estiverem modificadas.
+ </para>
+ </callout>
+ <callout arearefs="properties5">
+ <para>
+ <literal>unique</literal> (opcional – valor defautl <literal>false</literal>):
+ Especifica que uma unique constraint existe em todas as colunas mapeadas do componente.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Por exemplo, se nós temos o seguinte mapeamento de <literal><properties></literal>:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="personNumber"/>
+ ...
+ <properties name="name"
+ unique="true" update="false">
+ <property name="firstName"/>
+ <property name="initial"/>
+ <property name="lastName"/>
+ </properties>
+</class>]]></programlisting>
+
+ <para>
+ Então nós podemos ter uma associação de dados herdados que referem a esta chave
+ exclusiva da tabela <literal>Person</literal>, ao invés de se referirem a chave
+ primária:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="person"
+ class="Person" property-ref="name">
+ <column name="firstName"/>
+ <column name="initial"/>
+ <column name="lastName"/>
+</many-to-one>]]></programlisting>
+
+ <para>
+ Nós não recomendamos o uso deste tipo de coisa fora do contexto de mapeamento de
+ dados herdados.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-subclass" revision="4">
+ <title>subclass (subclasse)</title>
+
+ <para>
+ Finalmente, a persistência polimórfica requer a declaração de cada subclasse
+ da classe de persistência raiz. Para a estratégia de mapeamento
+ table-per-class-hierarchy, a declaração <literal><subclass></literal>
+ deve ser usada.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="subclass1" coords="2 55"/>
+ <area id="subclass2" coords="3 55"/>
+ <area id="subclass3" coords="4 55"/>
+ <area id="subclass4" coords="5 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<subclass
+ name="ClassName"
+ discriminator-value="discriminator_value"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ entity-name="EntityName"
+ node="element-name"
+ extends="SuperclassName">
+
+ <property .... />
+ .....
+</subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="subclass1">
+ <para>
+ <literal>name</literal>: O nome de classe completamente qualificada da subclasse.
+ </para>
+ </callout>
+ <callout arearefs="subclass2">
+ <para>
+ <literal>discriminator-value</literal> (opcional – valor default o nome da classe):
+ Um valor que distingue subclasses individuais.
+ </para>
+ </callout>
+ <callout arearefs="subclass3">
+ <para>
+ <literal>proxy</literal> (opcional): Especifica a classe ou interface que
+ usará os proxies de inicialização atrasada.
+ </para>
+ </callout>
+ <callout arearefs="subclass4">
+ <para>
+ <literal>lazy</literal> (opcional, valor default <literal>true</literal>):
+ Configurar <literal>lazy="false"</literal> desabilitará o uso de
+ inicialização atrasada.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Cada subclasse deve declarar suas próprias propriedades persistentes e subclasses.
+ As propriedades <literal><version></literal> e <literal><id></literal>
+ são configuradas para serem herdades da classe raiz. Cada subclasse numa hierarquia
+ deve definir um único <literal>discriminator-value</literal>. Se nenhum for
+ especificado, o nome da classe Java completamente qualificada será usada.
+ </para>
+
+ <para>
+ Para informações sobre mapeamento de heranças, veja o <xref linkend="inheritance"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-joinedsubclass" revision="3">
+ <title>joined-subclass</title>
+
+ <para>
+ Alternativamente, cada subclasse pode ser mapeada para sua própria tabela
+ (Estratégia de mapeamento table-per-subclass). O estado herdado é devolvido
+ por associação com a tabela da superclasse. Nós usamos o elemento
+ <literal><joined-subclass></literal>.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="joinedsubclass1" coords="2 45"/>
+ <area id="joinedsubclass2" coords="3 45"/>
+ <area id="joinedsubclass3" coords="4 45"/>
+ <area id="joinedsubclass4" coords="5 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<joined-subclass
+ name="ClassName"
+ table="tablename"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ schema="schema"
+ catalog="catalog"
+ extends="SuperclassName"
+ persister="ClassName"
+ subselect="SQL expression"
+ entity-name="EntityName"
+ node="element-name">
+
+ <key .... >
+
+ <property .... />
+ .....
+</joined-subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="joinedsubclass1">
+ <para>
+ <literal>name</literal>: O nome da classe completamente qualificada da
+ subclasse.
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass2">
+ <para>
+ <literal>table</literal>: O nome da tabela da subclasse.
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass3">
+ <para>
+ <literal>proxy</literal> (opcional): Especifica a classe ou interface
+ para usar os proxies de recuperação atrasada.
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass4">
+ <para>
+ <literal>lazy</literal> (opcional, valor default <literal>true</literal>):
+ Fixanr <literal>lazy="false"</literal> desabilita o uso recuperação
+ atrasada.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ A coluna discriminator requerida para esta estratégia de mapeamento. Porém,
+ cada subclasse deve declarar uma coluna de tabela com o identificador do objeto
+ usando o elemento <literal><key></literal>. O mapeamento no início do
+ capítulo poderia ser re-escrito assim:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class name="Cat" table="CATS">
+ <id name="id" column="uid" type="long">
+ <generator class="hilo"/>
+ </id>
+ <property name="birthdate" type="date"/>
+ <property name="color" not-null="true"/>
+ <property name="sex" not-null="true"/>
+ <property name="weight"/>
+ <many-to-one name="mate"/>
+ <set name="kittens">
+ <key column="MOTHER"/>
+ <one-to-many class="Cat"/>
+ </set>
+ <joined-subclass name="DomesticCat" table="DOMESTIC_CATS">
+ <key column="CAT"/>
+ <property name="name" type="string"/>
+ </joined-subclass>
+ </class>
+
+ <class name="eg.Dog">
+ <!-- mapping for Dog could go here -->
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Para informações de mapeamentos de herança, veja <xref linkend="inheritance"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-unionsubclass" revision="2">
+ <title>union-subclass</title>
+
+ <para>
+ Uma terceira opção é mapear para tabelas apenas as classes concretas de uma
+ hierarquia de heranças, (a estratégia table-per-concrete-class) onde cada tabela
+ define todos os estados persistentes da classe, incluindo estados herdados.
+ No Hibernate, não é absolutamente necessário mapear explicitamente como hierarquia
+ de heranças. Você pode simplesmente mapear cada classe com uma declaração
+ <literal><class></literal> separada. Porém, se você deseja usar associações
+ polimórficas (por exemplo: uma associação para a superclasse de sua hierarquia),
+ você precisa usar o mapeamento <literal><union-subclass></literal>.
+
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="unionsubclass1" coords="2 45"/>
+ <area id="unionsubclass2" coords="3 45"/>
+ <area id="unionsubclass3" coords="4 45"/>
+ <area id="unionsubclass4" coords="5 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<union-subclass
+ name="ClassName"
+ table="tablename"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ schema="schema"
+ catalog="catalog"
+ extends="SuperclassName"
+ abstract="true|false"
+ persister="ClassName"
+ subselect="SQL expression"
+ entity-name="EntityName"
+ node="element-name">
+
+ <property .... />
+ .....
+</union-subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="unionsubclass1">
+ <para>
+ <literal>name</literal>: O nome da subclasse completamente qualificada.
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass2">
+ <para>
+ <literal>table</literal>: O nome da tabela da subclasse.
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass3">
+ <para>
+ <literal>proxy</literal> (optional): Specifies a class or interface to use
+ for lazy initializing proxies.
+
+ <literal>proxy</literal> (opcional): Especifica a classe ou interface para usar
+ os proxies de recuperação atrasada.
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass4">
+ <para>
+ <literal>lazy</literal> (optional, defaults to <literal>true</literal>): Setting
+ <literal>lazy="false"</literal> disables the use of lazy fetching.
+ <literal>lazy</literal> (opcional, valor default p<literal>true</literal>):
+ Fixando <literal>lazy="false"</literal> desabilita o uso da recuperação atrasada.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ A coluna discriminatõria não é requerida para esta estratégia de mapeamento.
+
+ </para>
+
+ <para>
+ Para informações sobre mapeamentos de herança, veja <xref linkend="inheritance"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-join" revision="3">
+ <title>join</title>
+
+ <para>
+ Usando o elemento <literal><join></literal>>, é possível mapear
+ propriedades de uma classe para várias tabelas.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="join1" coords="2 50"/>
+ <area id="join2" coords="3 50"/>
+ <area id="join3" coords="4 50"/>
+ <area id="join4" coords="5 50"/>
+ <area id="join5" coords="6 50"/>
+ <area id="join6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<join
+ table="tablename"
+ schema="owner"
+ catalog="catalog"
+ fetch="join|select"
+ inverse="true|false"
+ optional="true|false">
+
+ <key ... />
+
+ <property ... />
+ ...
+</join>]]></programlisting>
+
+ <calloutlist>
+ <callout arearefs="join1">
+ <para>
+ <literal>table</literal>: O nome da tabela associada.
+ </para>
+ </callout>
+ <callout arearefs="join2">
+ <para>
+ <literal>schema</literal> (opcional): Sobrepõe o nome do esquema
+ especificado pelo elemento raiz <literal><hibernate-mapping></literal>.
+ </para>
+ </callout>
+ <callout arearefs="join3">
+ <para>
+ <literal>catalog</literal> (opcional): Sobrepõe o nome do catálogo
+ especificado pelo elemento raiz<literal><hibernate-mapping></literal>.
+ </para>
+ </callout>
+ <callout arearefs="join4">
+ <para>
+ <literal>fetch</literal>(opcional – valor default <literal>join</literal>): Se setado
+ para <literal>join</literal>, o padrão, o Hibernate irá usar um inner join para
+ restaurar um <literal>join</literal> definido por uma classe ou suas subclasses e
+ uma outer join para um <literal>join</literal> definido por uma subclasse.
+ Se setado para <literal>select</literal>, então o Hibernate irá usar uma seleção
+ seqüencial para um <literal><join></literal> definida numa subclasse, que irá
+ ser emitido apenas se uma linha se concentrar para representar uma instância
+ da subclasse. Inner joins irá ainda ser usado para restaurar um
+ <literal><join></literal> definido pela classe e suas superclasses.
+ </para>
+ </callout>
+ <callout arearefs="join5">
+ <para>
+ <literal>inverse</literal> (opcional – valor default <literal>false</literal>):
+ Se habilitado, o Hibernate não irá tentar inserir ou atualizar as propriedades
+ definidas por este join.
+ </para>
+ </callout>
+ <callout arearefs="join6">
+ <para>
+ <literal>optional</literal> (opcional – valor default <literal>false</literal>):
+ Se habilitado, o Hibernate irá inserir uma linha apenas se as propriedades definidas
+ por esta junção não forem nulas e irá sempre usar uma outer join para
+ recuperar as propriedades.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Por exemplo, a informação de endereço para uma pessoa pode ser mapeada para uma
+ tabela separada (enquanto preservando o valor da semântica de tipos para
+ todas as propriedades):
+ </para>
+
+ <programlisting><![CDATA[<class name="Person"
+ table="PERSON">
+
+ <id name="id" column="PERSON_ID">...</id>
+
+ <join table="ADDRESS">
+ <key column="ADDRESS_ID"/>
+ <property name="address"/>
+ <property name="zip"/>
+ <property name="country"/>
+ </join>
+ ...]]></programlisting>
+
+ <para>
+ Esta característica é útil apenas para modelos de dados legados, nós recomendamos
+ menos tabelas do que classes e um modelo de domínio bem granulado. Porém, é
+ útil para ficar trocando entre estratégias de mapeamento de herança
+ numa hierarquia simples, como explicado mais a frente.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-key">
+ <title>key</title>
+
+ <para>
+ Nós vimos que o elemento <literal><key></literal> surgiu algumas vezes
+ até agora. Ele aparece em qualquer lugar que o elemento pai define uma junção
+ para a nova tabela, e define a chave estrangeira para a tabela associada, que
+ referencia a chave primária da tabela original.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="key1" coords="2 50"/>
+ <area id="key2" coords="3 50"/>
+ <area id="key3" coords="4 50"/>
+ <area id="key4" coords="5 50"/>
+ <area id="key5" coords="6 50"/>
+ <area id="key6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<key
+ column="columnname"
+ on-delete="noaction|cascade"
+ property-ref="propertyName"
+ not-null="true|false"
+ update="true|false"
+ unique="true|false"
+/>]]></programlisting>
+
+ <calloutlist>
+ <callout arearefs="key1">
+ <para>.
+ <literal>column</literal> (opcional): O nome da coluna da chave estrangeira.
+ Isto também pode ser especificado por aninhamento de elemento(s)
+ <literal><column></literal>.
+ </para>
+ </callout>
+ <callout arearefs="key2">
+ <para>
+ <literal>on-delete</literal> (opcional, valor default <literal>noaction</literal>):
+ Especifica se a constraint da chave estrangeira no banco de dados esta
+ habilitada para cascade delete .
+ </para>
+ </callout>
+ <callout arearefs="key3">
+ <para>
+ <literal>property-ref</literal> (opcional): Especifica que a chave estrangeira
+ se refere a colunas que não são chave primária da tabela original.
+ (Util para base de dados legadas.)
+ </para>
+ </callout>
+ <callout arearefs="key4">
+ <para>
+ <literal>not-null</literal> (opcional): Especifica que a coluna da chave
+ estrangeira não aceita valores nulos (isto é implícito em qualquer momento
+ que a chave estrangeira também fizer parte da chave primária).
+ </para>
+ </callout>
+ <callout arearefs="key5">
+ <para>
+ <literal>update</literal> (optional): Specifies that the foreign key should never
+ be updated (this is implied whenever the foreign key is also part of the primary
+ key).
+ <literal>update</literal> (opcional): Especifica que a chave estrangeira nunca
+ deve ser atualizada (isto é implícito em qualquer momento que a chave estrangeira
+ também fizer parte da chave primária).
+ </para>
+ </callout>
+ <callout arearefs="key6">
+ <para>
+ <literal>unique</literal> (opcional): Especifica que a chave estrangeira deve ter
+ uma constraint unique (sto é implícito em qualquer momento que a chave estrangeira
+ também fizer parte da chave primária).
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Nós recomendamos que para sistemas que a performance de delete seja importante, todas as
+ chaves deve ser definida <literal>on-delete="cascade"</literal>, e o Hibernate irá usar
+ uma constraint a nível de banco de dados <literal>ON CASCADE DELETE</literal>, ao invés
+ de muitas instruções <literal>DELETE</literal>. Esteja ciente que esta característica é
+ um atalho da estratégia usual de optimistic locking do Hibernate para dados versionados.
+ </para>
+
+ <para>
+ Os atributos <literal>not-null</literal> e <literal>update</literal> são úteis quando
+ estamos mapeamos uma associação unidirecional um para muitos. Se você mapear uma
+ asociação unidirecional um para muitos para uma chave estrangeira non-nullable, você
+ <emphasis>deve</emphasis> declarar a coluna chave usando
+ <literal><key not-null="true"></literal>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-column" revision="4">
+ <title>elementos column e formula</title>
+ <para>
+ Qualquer elemento de mapeamente que aceita um atributo <literal>column</literal> irá
+ aceitar alternativamente um subelemento <literal><column></literal>. Da mesma forma,
+ <literal>formula</literal> é uma alternativa para o atributo <literal>formula</literal>.
+ </para>
+
+ <programlisting><![CDATA[<column
+ name="column_name"
+ length="N"
+ precision="N"
+ scale="N"
+ not-null="true|false"
+ unique="true|false"
+ unique-key="multicolumn_unique_key_name"
+ index="index_name"
+ sql-type="sql_type_name"
+ check="SQL expression"
+ default="SQL expression"/>]]></programlisting>
+
+ <programlisting><![CDATA[<formula>SQL expression</formula>]]></programlisting>
+
+ <para>
+ O atributo <literal>column</literal> e <literal>formula</literal> podem até ser combinados
+ dentro da mesma propriedade ou associação mapeando para expressar,
+ por exemplo, associações exóticas.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="homeAddress" class="Address"
+ insert="false" update="false">
+ <column name="person_id" not-null="true" length="10"/>
+ <formula>'MAILING'</formula>
+</many-to-one>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-import">
+ <title>import</title>
+
+ <para>
+ Suponha que a sua aplicação tem duas classes persistentes com o mesmo nome, e você não quer
+ especificar o nome qualificado (do pacote) nas queries do Hibernate. As Classes devem
+ ser "importadas" explicitamente, de preferência contando com <literal>auto-import="true"</literal>.
+ Você pode até importar classes e interfaces que não estão explicitamente mapeadas.
+ </para>
+
+ <programlisting><![CDATA[<import class="java.lang.Object" rename="Universe"/>]]></programlisting>
+
+ <programlistingco>
+ <areaspec>
+ <area id="import1" coords="2 40"/>
+ <area id="import2" coords="3 40"/>
+ </areaspec>
+ <programlisting><![CDATA[<import
+ class="ClassName"
+ rename="ShortName"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="import1">
+ <para>
+ <literal>class</literal>: O nome qualificado (do pacote) de qualquer classe Java.
+ </para>
+ </callout>
+ <callout arearefs="import2">
+ <para>
+ <literal>rename</literal> (opcional – valor default, o nome da classe não
+ qualificada): Um nome que pode ser usado numa linguagem de consulta.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ </sect2>
+
+ <sect2 id="mapping-types-anymapping" revision="2">
+ <title>any</title>
+
+ <para>
+ Existe mais um tipo de propriedade de mapeamento. O elemento de mapeamento
+ <literal><any></literal> define uma associação polimórfica para classes de múltiplas tabelas.
+ Este tipo de mapeamento sempre requer mais de uma coluna. A primeira coluna possui o tipo da entidade
+ associada. A outra coluna que ficou possui o identificador. É impossível especificar uma restrição
+ de chave estrangeira para este tipo de associação, assim isto claramente não é visto
+ como um caminho usual para associações (polimórficas) de mapeamento. Você deve usar este mapeamento
+ apenas em casos muito especiais (exemplo: audit logs, dados de sessão do usuário, etc).
+
+ </para>
+
+ <para>
+ O atributo <literal>meta-type</literal> permite a aplicação especificar um tipo adaptado
+ que mapeia valores de colunas de banco de dados para classes persistentes que tem propriedades
+ identificadoras do tipo especificado através do <literal>id-type</literal>. Você deve especificar
+ o mapeamento de valores do meta-type para nome de classes.
+ </para>
+
+ <programlisting><![CDATA[<any name="being" id-type="long" meta-type="string">
+ <meta-value value="TBL_ANIMAL" class="Animal"/>
+ <meta-value value="TBL_HUMAN" class="Human"/>
+ <meta-value value="TBL_ALIEN" class="Alien"/>
+ <column name="table_name"/>
+ <column name="id"/>
+</any>]]></programlisting>
+
+ <programlistingco>
+ <areaspec>
+ <area id="any1" coords="2 50"/>
+ <area id="any2" coords="3 50"/>
+ <area id="any3" coords="4 50"/>
+ <area id="any4" coords="5 50"/>
+ <area id="any5" coords="6 50"/>
+ <area id="any6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<any
+ name="propertyName"
+ id-type="idtypename"
+ meta-type="metatypename"
+ cascade="cascade_style"
+ access="field|property|ClassName"
+ optimistic-lock="true|false"
+>
+ <meta-value ... />
+ <meta-value ... />
+ .....
+ <column .... />
+ <column .... />
+ .....
+</any>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="any1">
+ <para>
+ <literal>name</literal>: o nome da propriedade.
+ </para>
+ </callout>
+ <callout arearefs="any2">
+ <para>
+ <literal>id-type</literal>: o tipo identificador.
+ </para>
+ </callout>
+ <callout arearefs="any3">
+ <para>
+ <literal>meta-type</literal> (opcional – valor default <literal>string</literal>):
+ Qualquer tipo que é permitido para um mapeamento discriminador.
+ </para>
+ </callout>
+ <callout arearefs="any4">
+ <para>
+ <literal>cascade</literal> (opcional – valor default <literal>none</literal>):
+ o estilo do cascade.
+ </para>
+ </callout>
+ <callout arearefs="any5">
+ <para>
+ <literal>access</literal> (opcional – valor default <literal>property</literal>):
+ A estratégia que o hibernate deve usar para acessar o valor da propriedade.
+ </para>
+ </callout>
+ <callout arearefs="any6">
+ <para>
+ <literal>optimistic-lock</literal> (opcional - valor default<literal>true</literal>):
+ Especifica que as atualizações para esta propriedade requerem ou não aquisição da
+ trava otimista. Em outras palavras, define se uma versão de incremento deve ocorrer
+ se esta propriedade está modificada.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="mapping-types">
+ <title>Tipos do Hibernate</title>
+
+ <sect2 id="mapping-types-entitiesvalues" revision="1">
+ <title>Entidades e valores</title>
+
+ <para>
+ Para entender o comportamento de vários objetos em nível de linguagem de Java a
+ respeito do serviço de persistência, nós precisamos classificá-los em dois grupos.
+ </para>
+
+ <para>
+ Uma <emphasis>entidade </emphasis> existe independentemente de qualquer outro
+ objeto guardando referências para a entidade. Em contraste com o modelo usual de
+ Java que um objeto não referenciado é coletado pelo garbage collector. Entidades
+ devem ser explicitamente salvas ou deletada (exceto em operações de salvamento
+ ou deleção que possam ser executada em <emphasis>cascata</emphasis> de uma entidade
+ pai para seus filhos). Isto é diferente do modelo ODMG de persistência do objeto
+ por acessibilidade – e corresponde quase a como objetos de aplicações são
+ geralmente usados em grandes sistemas. Entidades suportam referências circulares
+ e comuns. Eles podem ser versionadas.
+ </para>
+
+ <para>
+ Uma entidade em estado persistente consiste de referências para outras entidades
+ e instâncias de tipos de <emphasis>valor</emphasis>. Valores são primitivos,
+ coleções (não o que tem dentro de uma coleção), componentes e certos objetos
+ imutáveis. Entidades distintas, valores (em coleções e componentes particulares)
+ <emphasis>são </emphasis> persistidos e apagados por acessibilidade. Visto que
+ objetos value (e primitivos) são persistidos e apagados junto com as entidades
+ que os contém e não podem ser versionados independentemente. Valores têm
+ identidade não independente, assim eles não podem ser comuns para duas
+ entidades ou coleções.
+
+ </para>
+
+ <para>
+ Até agora, nós estivemos usando o termo "classe persistente" para referir
+ a entidades. Nós iremos continuar a fazer isto. Falando a rigor, porém, nem todas
+ as classes definidas pelo usuário com estados persistentes são entidades. Um
+ <emphasis>componente</emphasis> é uma classe de usuário definida com valores
+ semânticos. Uma propriedade de Java de tipo <literal>java.lang.String</literal>
+ também tem um valor semêntico. Dada esta definição, nós podemos dizer que
+ todos os tipos (classes) fornecida pelo JDK tem tipo de valor semântico em Java,
+ enquanto que tipos definidos pelo usuário pode ser mapeados com entidade ou valor
+ de tipo semântico. Esta decisão pertence ao desenvolvedor da aplicação. Uma boa
+ dica para uma classe entidade em um modelo de domínio são referências comuns
+ para uma instância simples daquela classe, enquanto a composição ou agregação
+ geralmente se traduz para um valor de tipo.
+ </para>
+
+ <para>
+ Nós iremos rever ambos os conceitos durante toda a documentação.
+
+ </para>
+
+ <para>
+ O desafio pe mapear o sistema de tipo de Java (e a definição do desenvolvedor de
+ entidades e tipos de valor) para o sistema de tipo SQL/banco de dados. A ponte entre ambos
+ os sistemas é fornecido pelo Hibernate: para entidades que usam
+ <literal><class></literal>, <literal><subclass></literal> e assim por diante.
+ Para tipos de valores nós usamos <literal><property></literal>,
+ <literal><component></literal>, etc, geralmente com um atributo
+ <literal>type</literal>. O valor deste atributo é o nome de um <emphasis>tipo de
+ mapeamento</emphasis> do Hibernate. O Hibernate fornece muitos mapeamentos
+ (para tipos de valores do JDK padrão) ut of the box. Você pode escrever os seus
+ próprios tipos de mapeamentos e implementar sua estratégia de conversão adaptada,
+ como você verá adiante.
+ </para>
+
+ <para>
+ Todos os tipos internos do hibernate exceto coleções suportam semânticas nulas.
+
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-types-basictypes" revision="3">
+ <title>Valores de tipos básicos</title>
+
+ <para>
+ O tipos internos de mapeamentos básicos podem ser a grosso modo categorizado como:
+ <variablelist>
+ <varlistentry>
+ <term><literal>integer, long, short, float, double, character, byte,
+ boolean, yes_no, true_false</literal></term>
+ <listitem>
+ <para>
+ Tipos de mapeamentos de classes primitivas ou wrapper Java especificos
+ (vendor-specific) para tipos de coluna SQL. Boolean,
+ <literal>boolean, yes_no</literal> são todas codificações alternativas
+ para um <literal>boolean</literal> ou <literal>java.lang.Boolean</literal>
+ do Java.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>string</literal></term>
+ <listitem>
+ <para>
+ Um tipo de mapeamento de <literal>java.lang.String</literal> para
+ <literal>VARCHAR</literal> (ou <literal>VARCHAR2</literal> no Oracle).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>date, time, timestamp</literal></term>
+ <listitem>
+ <para>
+ Tipos de mapeamento de <literal>java.util.Date</literal> e suas
+ subclasses para os tipos SQL <literal>DATE</literal>,
+ <literal>TIME</literal> e <literal>TIMESTAMP</literal>
+ (ou equivalente).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>calendar, calendar_date</literal></term>
+ <listitem>
+ <para>
+ Tipo de mapeamento de <literal>java.util.Calendar</literal> para
+ os tipos SQL <literal>TIMESTAMP</literal> e
+ <literal>DATE</literal> (ou equivalente).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>big_decimal, big_integer</literal></term>
+ <listitem>
+ <para>
+ Tipo de mapeamento de <literal>java.math.BigDecimal</literal> and
+ <literal>java.math.BigInteger</literal> para <literal>NUMERIC</literal>
+ (ou <literal>NUMBER</literal> no Oracle).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>locale, timezone, currency</literal></term>
+ <listitem>
+ <para>
+ Tipos de mapeamentos de <literal>java.util.Locale</literal>,
+ <literal>java.util.TimeZone</literal> e <literal>java.util.Currency</literal>
+ para <literal>VARCHAR</literal> (ou <literal>VARCHAR2</literal> no Oracle).
+ Instâncias de f <literal>Locale</literal> e <literal>Currency</literal>
+ são mapeados para seus códigos ISO. Instâncias de <literal>TimeZone</literal>
+ são mapeados para seu <literal>ID</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>class</literal></term>
+ <listitem>
+ <para>
+ um tipo de mapeamento de <literal>java.lang.Class</literal> para
+ <literal>VARCHAR</literal> (ou <literal>VARCHAR2</literal> no
+ Oracle). Uma <literal>Class</literal> é mapeada pelo
+ seu nome qualificado (completo).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>binary</literal></term>
+ <listitem>
+ <para>
+ Mapeia arrays de bytes para um tipo binário de SQL apropriado.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>text</literal></term>
+ <listitem>
+ <para>
+ Maps long Java strings to a SQL <literal>CLOB</literal> or
+ <literal>TEXT</literal> type.
+ Mapeia strings longas de Java para um tipo SQL
+ <literal>CLOB</literal> ou <literal>TEXT</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>serializable</literal></term>
+ <listitem>
+ <para>
+ Mapeia tipos Java serializáveis para um tipo binário SQL apropriado.
+ Você pode também indicar o tipo <literal>serializable</literal> do
+ Hibernate com o nome da classe ou interface Java serializável que
+ não é padrão para um tipo básico.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>clob, blob</literal></term>
+ <listitem>
+ <para>
+ Tipos de mapeamentos para as classes JDBC <literal>java.sql.Clob</literal> and
+ <literal>java.sql.Blob</literal>. Estes tipos podem ser inconveniente para
+ algumas aplicações, visto que o objeto blob ou clob pode não ser reusado
+ fora de uma transação. (Além disso, o suporte de driver é imcompleto e
+ inconsistente.)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>imm_date, imm_time, imm_timestamp, imm_calendar, imm_calendar_date,
+ imm_serializable, imm_binary</literal>
+ </term>
+ <listitem>
+ <para>
+ Mapeando tipos para o que geralmente são consideradas tipos mutáveis de
+ Java, onde o Hibernate faz determinadas otimizações apropriadas somente
+ para tipos imutáveis de Java, e a aplicação trata o objeto como imutável.
+ Por exemplo, você não deve chamar <literal>Date.setTime()</literal> para
+ uma instância mapeada como <literal>imm_timestamp</literal>. Para mudar
+ o valor da propriedade, e ter a mudança feita persistente, a aplicação
+ deve atribuir um novo objeto (nonidentical) à propriedade.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+
+ <para>
+ Identificadores únicos das entidades e coleções podem ser de qualquer tipo
+ básico exceto <literal>binary</literal>, <literal>blob</literal> ou
+ <literal>clob</literal>. (Identificadores compostos também são permitidos,
+ veja abaixo.)
+ </para>
+
+ <para>
+ Os tipos de valores básicos têm suas constantes <literal>Type</literal>
+ correspondentes definidas em <literal>org.hibernate.Hibernate</literal>. Por exemplo,
+ <literal>Hibernate.STRING</literal> representa o tipo <literal>string</literal>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-types-custom" revision="2">
+ <title>Tipos de valores personalizados</title>
+
+ <para>
+ É relativamente fácil para desenvolvedores criar seus próprios tipos de valor.
+ Por exemplo, você pode querer persistir propriedades do tipo
+ <literal>java.lang.BigInteger</literal> para colunas <literal>VARCHAR</literal>. O
+ Hibernate não fornece um tipo correspondente para isso. Mas os tipos adaptados
+ não são limitados a mapeamento de uma propriedade (ou elemento de coleção) a uma
+ única coluna da tabela. Assim, por exemplo, você pôde ter uma propriedade Java
+ <literal>getName()</literal>/<literal>setName()</literal> do tipo
+ <literal>java.lang.String</literal> que é persistido para colunas
+ <literal>FIRST_NAME</literal>, <literal>INITIAL</literal>, <literal>SURNAME</literal>.
+
+ </para>
+
+ <para>
+ Para implementar um tipo personalizado, implemente <literal>org.hibernate.UserType</literal>
+ or <literal>org.hibernate.CompositeUserType</literal> e declare propriedades usando o nome
+ qualificado da classe do tipo. Veja <literal>org.hibernate.test.DoubleStringType</literal>
+ para ver o tipo das coisas que são possíveis.
+ </para>
+
+ <programlisting><![CDATA[<property name="twoStrings" type="org.hibernate.test.DoubleStringType">
+ <column name="first_string"/>
+ <column name="second_string"/>
+</property>]]></programlisting>
+
+ <para>
+ Observe o uso da tag <literal><column></literal> para mapear uma propriedade
+ para colunas múltiplas.
+ </para>
+
+ <para>
+ As interfaces <literal>CompositeUserType</literal>, <literal>EnhancedUserType</literal>,
+ <literal>UserCollectionType</literal>, e <literal>UserVersionType</literal>
+ fornecem suporte para usos mais especializados.
+ </para>
+
+ <para>
+ Você pode mesmo fornecer parâmetros a um <literal>UserType</literal> no arquivo de mapeamento.
+ Para isto, seu <literal>UserType</literal> deve implementar a interface
+ <literal>org.hibernate.usertype.ParameterizedType</literal>. Para fornecer parâmetros a seu
+ tipo personalizado, você pode usar o elemento <literal><type></literal> em seus
+ arquivos de mapeamento.
+ </para>
+
+ <programlisting><![CDATA[<property name="priority">
+ <type name="com.mycompany.usertypes.DefaultValueIntegerType">
+ <param name="default">0</param>
+ </type>
+</property>]]></programlisting>
+
+ <para>
+ O <literal>UserType</literal> pode agora recuperar o valor para o parâmetro chamado
+ <literal>default</literal> da <literal>Propriedade</literal> do passado a ele.
+ </para>
+
+ <para>
+ Se você usar freqüentemente um determinado <literal>UserType</literal>, pode ser útil definir
+ um nome mais curto para ele. Você pode fazer isto usando o elemento
+ <literal><typedef></literal>. Typedefs atribui um nome a um tipo personalizado, e pode também
+ conter uma lista de valores default de parâmetro se o tipo for parametrizado.
+ </para>
+
+ <programlisting><![CDATA[<typedef class="com.mycompany.usertypes.DefaultValueIntegerType" name="default_zero">
+ <param name="default">0</param>
+</typedef>]]></programlisting>
+
+ <programlisting><![CDATA[<property name="priority" type="default_zero"/>]]></programlisting>
+
+ <para>
+ It is also possible to override the parameters supplied in a typedef on a case-by-case basis
+ by using type parameters on the property mapping.
+ </para>
+
+ <para>
+ Even though Hibernate's rich range of built-in types and support for components means you
+ will very rarely <emphasis>need</emphasis> to use a custom type, it is nevertheless
+ considered good form to use custom types for (non-entity) classes that occur frequently
+ in your application. For example, a <literal>MonetaryAmount</literal> class is a good
+ candidate for a <literal>CompositeUserType</literal>, even though it could easily be mapped
+ as a component. One motivation for this is abstraction. With a custom type, your mapping
+ documents would be future-proofed against possible changes in your way of representing
+ monetary values.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="mapping-entityname">
+ <title>Mapping a class more than once</title>
+ <para>
+ It is possible to provide more than one mapping for a particular persistent class. In this
+ case you must specify an <emphasis>entity name</emphasis> do disambiguate between instances
+ of the two mapped entities. (By default, the entity name is the same as the class name.)
+ Hibernate lets you specify the entity name when working with persistent objects, when writing
+ queries, or when mapping associations to the named entity.
+ </para>
+
+ <programlisting><![CDATA[<class name="Contract" table="Contracts"
+ entity-name="CurrentContract">
+ ...
+ <set name="history" inverse="true"
+ order-by="effectiveEndDate desc">
+ <key column="currentContractId"/>
+ <one-to-many entity-name="HistoricalContract"/>
+ </set>
+</class>
+
+<class name="Contract" table="ContractHistory"
+ entity-name="HistoricalContract">
+ ...
+ <many-to-one name="currentContract"
+ column="currentContractId"
+ entity-name="CurrentContract"/>
+</class>]]></programlisting>
+
+ <para>
+ Notice how associations are now specified using <literal>entity-name</literal> instead of
+ <literal>class</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="mapping-quotedidentifiers">
+ <title>SQL quoted identifiers</title>
+ <para>
+ You may force Hibernate to quote an identifier in the generated SQL by enclosing the table or
+ column name in backticks in the mapping document. Hibernate will use the correct quotation
+ style for the SQL <literal>Dialect</literal> (usually double quotes, but brackets for SQL
+ Server and backticks for MySQL).
+ </para>
+
+ <programlisting><![CDATA[<class name="LineItem" table="`Line Item`">
+ <id name="id" column="`Item Id`"/><generator class="assigned"/></id>
+ <property name="itemNumber" column="`Item #`"/>
+ ...
+</class>]]></programlisting>
+
+ </sect1>
+
+
+ <sect1 id="mapping-alternatives">
+ <title>Metadata alternatives</title>
+
+ <para>
+ XML isn't for everyone, and so there are some alternative ways to define O/R mapping metadata in Hibernate.
+ </para>
+
+ <sect2 id="mapping-xdoclet">
+ <title>Using XDoclet markup</title>
+
+ <para>
+ Many Hibernate users prefer to embed mapping information directly in sourcecode using
+ XDoclet <literal>@hibernate.tags</literal>. We will not cover this approach in this
+ document, since strictly it is considered part of XDoclet. However, we include the
+ following example of the <literal>Cat</literal> class with XDoclet mappings.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+import java.util.Date;
+
+/**
+ * @hibernate.class
+ * table="CATS"
+ */
+public class Cat {
+ private Long id; // identifier
+ private Date birthdate;
+ private Cat mother;
+ private Set kittens
+ private Color color;
+ private char sex;
+ private float weight;
+
+ /*
+ * @hibernate.id
+ * generator-class="native"
+ * column="CAT_ID"
+ */
+ public Long getId() {
+ return id;
+ }
+ private void setId(Long id) {
+ this.id=id;
+ }
+
+ /**
+ * @hibernate.many-to-one
+ * column="PARENT_ID"
+ */
+ public Cat getMother() {
+ return mother;
+ }
+ void setMother(Cat mother) {
+ this.mother = mother;
+ }
+
+ /**
+ * @hibernate.property
+ * column="BIRTH_DATE"
+ */
+ public Date getBirthdate() {
+ return birthdate;
+ }
+ void setBirthdate(Date date) {
+ birthdate = date;
+ }
+ /**
+ * @hibernate.property
+ * column="WEIGHT"
+ */
+ public float getWeight() {
+ return weight;
+ }
+ void setWeight(float weight) {
+ this.weight = weight;
+ }
+
+ /**
+ * @hibernate.property
+ * column="COLOR"
+ * not-null="true"
+ */
+ public Color getColor() {
+ return color;
+ }
+ void setColor(Color color) {
+ this.color = color;
+ }
+ /**
+ * @hibernate.set
+ * inverse="true"
+ * order-by="BIRTH_DATE"
+ * @hibernate.collection-key
+ * column="PARENT_ID"
+ * @hibernate.collection-one-to-many
+ */
+ public Set getKittens() {
+ return kittens;
+ }
+ void setKittens(Set kittens) {
+ this.kittens = kittens;
+ }
+ // addKitten not needed by Hibernate
+ public void addKitten(Cat kitten) {
+ kittens.add(kitten);
+ }
+
+ /**
+ * @hibernate.property
+ * column="SEX"
+ * not-null="true"
+ * update="false"
+ */
+ public char getSex() {
+ return sex;
+ }
+ void setSex(char sex) {
+ this.sex=sex;
+ }
+}]]></programlisting>
+
+ <para>
+ See the Hibernate web site for more examples of XDoclet and Hibernate.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-annotations" revision="2">
+ <title>Using JDK 5.0 Annotations</title>
+
+ <para>
+ JDK 5.0 introduced XDoclet-style annotations at the language level, type-safe and
+ checked at compile time. This mechnism is more powerful than XDoclet annotations and
+ better supported by tools and IDEs. IntelliJ IDEA, for example, supports auto-completion
+ and syntax highlighting of JDK 5.0 annotations. The new revision of the EJB specification
+ (JSR-220) uses JDK 5.0 annotations as the primary metadata mechanism for entity beans.
+ Hibernate3 implements the <literal>EntityManager</literal> of JSR-220 (the persistence API),
+ support for mapping metadata is available via the <emphasis>Hibernate Annotations</emphasis>
+ package, as a separate download. Both EJB3 (JSR-220) and Hibernate3 metadata is supported.
+ </para>
+
+ <para>
+ This is an example of a POJO class annotated as an EJB entity bean:
+ </para>
+
+ <programlisting><![CDATA[@Entity(access = AccessType.FIELD)
+public class Customer implements Serializable {
+
+ @Id;
+ Long id;
+
+ String firstName;
+ String lastName;
+ Date birthday;
+
+ @Transient
+ Integer age;
+
+ @Embedded
+ private Address homeAddress;
+
+ @OneToMany(cascade=CascadeType.ALL)
+ @JoinColumn(name="CUSTOMER_ID")
+ Set<Order> orders;
+
+ // Getter/setter and business methods
+}]]></programlisting>
+
+ <para>
+ Note that support for JDK 5.0 Annotations (and JSR-220) is still work in progress and
+ not completed. Please refer to the Hibernate Annotations module for more details.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="mapping-generated" revision="1">
+ <title>Generated Properties</title>
+ <para>
+ Generated properties are properties which have their values generated by the
+ database. Typically, Hibernate applications needed to <literal>refresh</literal>
+ objects which contain any properties for which the database was generating values.
+ Marking properties as generated, however, lets the application delegate this
+ responsibility to Hibernate. Essentially, whenever Hibernate issues an SQL INSERT
+ or UPDATE for an entity which has defined generated properties, it immediately
+ issues a select afterwards to retrieve the generated values.
+ </para>
+ <para>
+ Properties marked as generated must additionally be non-insertable and non-updateable.
+ Only <xref linkend="mapping-declaration-version">versions</xref>,
+ <xref linkend="mapping-declaration-timestamp">timestamps</xref>, and
+ <xref linkend="mapping-declaration-property">simple properties</xref> can be marked as
+ generated.
+ </para>
+ <para>
+ <literal>never</literal> (the default) - means that the given property value
+ is not generated within the database.
+ </para>
+ <para>
+ <literal>insert</literal> - states that the given property value is generated on
+ insert, but is not regenerated on subsequent updates. Things like created-date would
+ fall into this category. Note that even thought
+ <xref linkend="mapping-declaration-version">version</xref> and
+ <xref linkend="mapping-declaration-timestamp">timestamp</xref> properties can
+ be marked as generated, this option is not available there...
+ </para>
+ <para>
+ <literal>always</literal> - states that the property value is generated both
+ on insert and on update.
+ </para>
+ </sect1>
+
+ <sect1 id="mapping-database-object">
+ <title>Auxiliary Database Objects</title>
+ <para>
+ Allows CREATE and DROP of arbitrary database objects, in conjunction with
+ Hibernate's schema evolution tools, to provide the ability to fully define
+ a user schema within the Hibernate mapping files. Although designed specifically
+ for creating and dropping things like triggers or stored procedures, really any
+ SQL command that can be run via a <literal>java.sql.Statement.execute()</literal>
+ method is valid here (ALTERs, INSERTS, etc). There are essentially two modes for
+ defining auxiliary database objects...
+ </para>
+ <para>
+ The first mode is to explicitly list the CREATE and DROP commands out in the mapping
+ file:
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <create>CREATE TRIGGER my_trigger ...</create>
+ <drop>DROP TRIGGER my_trigger</drop>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ <para>
+ The second mode is to supply a custom class which knows how to construct the
+ CREATE and DROP commands. This custom class must implement the
+ <literal>org.hibernate.mapping.AuxiliaryDatabaseObject</literal> interface.
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <definition class="MyTriggerDefinition"/>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ <para>
+ Additionally, these database objects can be optionally scoped such that they only
+ apply when certain dialects are used.
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <definition class="MyTriggerDefinition"/>
+ <dialect-scope name="org.hibernate.dialect.Oracle9Dialect"/>
+ <dialect-scope name="org.hibernate.dialect.OracleDialect"/>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ </sect1>
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/batch.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/batch.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/batch.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/batch.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,357 @@
+<chapter id="batch">
+ <title>Processamento de lotes</title>
+
+ <para>
+ Uma alternativa para inserir 100.000 linhas no banco de dados usando o Hibernate
+ pode ser a seguinte:
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+for ( int i=0; i<100000; i++ ) {
+ Customer customer = new Customer(.....);
+ session.save(customer);
+}
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ Isto irá falhar em algum lugar próximo a linha 50.000, lançando uma
+ <literal>OutOfMemoryException</literal>. Isso ocorre devido ao fato do Hibernate
+ fazer cache de todas as instâncias de <literal>Customer</literal> inseridas num
+ cachê em nível de sessão.
+ </para>
+
+ <para>
+ Neste capítulo veremos como contornar esse problema. Entretanto, se você vai realizar
+ processamento de lotes, é muito importante que você habilite o uso de lotes JDBC, se
+ você pretende obter um desempenho razoável. Defina o tamanho do lote JDBC em um
+ valor razoável (algo entre 10-50):
+ </para>
+
+<programlisting><![CDATA[hibernate.jdbc.batch_size 20]]></programlisting>
+
+ <para>
+ Você também pode querer rodar esse tipo de processamento de lotes com o cache
+ secundário completamente desabilitado:
+ </para>
+
+<programlisting><![CDATA[hibernate.cache.use_second_level_cache false]]></programlisting>
+
+ <para>
+ Mas isto não é absolutamente necessário, desde que nós possamos ajustar o
+ <literal>CacheMode</literal> para desabilitar a interação com o cache secundário.
+ </para>
+
+ <sect1 id="batch-inserts">
+ <title>Inserção de lotes</title>
+
+ <para>
+ Quando você estiver inserindo novos objetos persistentes, vocês deve executar
+ os métodos <literal>flush()</literal> e <literal>clear()</literal> regularmente
+ na sessão, para controlar o tamanho do cache primário.
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+for ( int i=0; i<100000; i++ ) {
+ Customer customer = new Customer(.....);
+ session.save(customer);
+ if ( i % 20 == 0 ) { //20, same as the JDBC batch size
+ //flush a batch of inserts and release memory:
+ session.flush();
+ session.clear();
+ }
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="batch-update" >
+ <title>Batch updates</title>
+
+ <para>
+ Para recuperar e atualizar informações a mesma idéia é válida. Adicionalmente,
+ pode precisar usar o <literal>scroll()</literal> para usar recursos no lado
+ do servidor em queries que retornam muita informação.
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+ScrollableResults customers = session.getNamedQuery("GetCustomers")
+ .setCacheMode(CacheMode.IGNORE)
+ .scroll(ScrollMode.FORWARD_ONLY);
+int count=0;
+while ( customers.next() ) {
+ Customer customer = (Customer) customers.get(0);
+ customer.updateStuff(...);
+ if ( ++count % 20 == 0 ) {
+ //flush a batch of updates and release memory:
+ session.flush();
+ session.clear();
+ }
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="batch-statelesssession">
+ <title>A interface StatelessSession</title>
+ <para>
+ Alternativamente, o Hibernate provê uma API orientada à comandos, usada para
+ transmitir um fluxo de dados de e para o banco de dados na forma de objetos soltos.
+ Uma <literal>StatelessSession</literal> não tem um contexto persistente associado e
+ não fornece muito das semânticas de alto nível para controle do ciclo de vida.
+ Em especial, uma StatelessSession não implemente o cache primário e nem interage
+ com o cache secundário ou query cache. Ele não implementa salvamento transacional
+ automatico ou checagem automática de mudanças. Operação realizadas usando uma
+ StatelessSession não fazem nenhum tipo de cascade com as instancias associadas.
+ As coleções são ignoradas por uma StatelessSession. Operações realizadas com um
+ StatelessSession ignoram a arquitetura de eventos e os interceptadores.
+ StatelessSession são vulneráveis aos efeitos do aliasing dos dados, devido a
+ falta do cache primário. Uma StatelessSession é uma abstração de baixo nível,
+ muito mais próxima do JDBC.
+ </para>
+
+<programlisting><![CDATA[StatelessSession session = sessionFactory.openStatelessSession();
+Transaction tx = session.beginTransaction();
+
+ScrollableResults customers = session.getNamedQuery("GetCustomers")
+ .scroll(ScrollMode.FORWARD_ONLY);
+while ( customers.next() ) {
+ Customer customer = (Customer) customers.get(0);
+ customer.updateStuff(...);
+ session.update(customer);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ Veja neste exempo, as instancias de <literal>Customer</literal> retornadas pela query
+ são imediatamente desvinculadas. Elas nunca serão assossiadas à um contexto persistente.
+ </para>
+
+ <para>
+ As operações <literal>insert(), update()</literal> e <literal>delete()</literal>
+ definidos pela interface <literal>StatelessSession</literal> são considerados
+ operações diretas no banco de dados (row-level operations), isso resulta em uma
+ execução imediata de comandos SQL <literal>INSERT, UPDATE</literal> ou
+ <literal>DELETE</literal> respectivamente. Devido a isso, eles possuem uma
+ semântica bem diferente das operações <literal>save(), saveOrUpdate()</literal>
+ ou <literal>delete()</literal> definidas na interface <literal>Session</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="batch-direct" revision="3">
+ <title>Operações no estilo DML</title>
+
+ <para>
+ Como já discutido, mapeamento objeto/relacional automático e transparente é conseguido
+ com a gerência do estado do objeto. Com isto o estado daquele objeto fica disponível na
+ memória, manipulando(usando as expressões SQL <literal>Data Manipulation Language</literal>
+ (SQL-style DML): <literal>INSERT</literal>, <literal>UPDATE</literal>, <literal>DELETE</literal>)
+ os dados diretamente no banco de dados não irá afetar o estado registrado em memória.
+ Entretanto, o Hibernate provê métodos para executar queries SQL-style DML, que são
+ totalmente executas com HQL (Hibernate Query Language)
+ (<xref linkend="queryhql">HQL</xref>).
+ </para>
+
+ <para>
+ A pseudo-sintaxe para expressões <literal>UPDATE</literal> e <literal>DELETE</literal> é:
+ <literal>( UPDATE | DELETE ) FROM? NomeEntidade (WHERE condições_where)?</literal>.
+ Algumas observações:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Na clausula from, a palavra chave FROM é opcional;
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Somente uma entidade pode ser chamada na clausula from; opcionalmente pode ter
+ um alias. Se o nome da entidade for possuir um alias, então qualquer propriedade
+ referenciada deve usar esse alias qualificado; se o nome da entidade não possuir
+ um alias, então nenhuma das propriedade precisa usar o acesso qualificado.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Na <xref linkend="queryhql-joins-forms">joins</xref> (ambas implícita ou explicita)
+ pode ser especificada em um bulk HQL query. Sub-queries podem ser usadas na clausula
+ where; as subqueries podem conter joins.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A clausula where também é opcional.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Como exemplo para executar um HQL <literal>UPDATE</literal>, use o
+ método <literal>Query.executeUpdate()</literal>(o método ganhou o nome
+ devido a sua familiaridade com o do JDBC
+ <literal>PreparedStatement.executeUpdate()</literal>):
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName";
+// or String hqlUpdate = "update Customer set name = :newName where name = :oldName";
+int updatedEntities = s.createQuery( hqlUpdate )
+ .setString( "newName", newName )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ HQL <literal>UPDATE</literal> statements, by default do not effect the
+ <xref linkend="mapping-declaration-version">version</xref>
+ or the <xref linkend="mapping-declaration-timestamp">timestamp</xref> property values
+ for the affected entities; this is in keeping with the EJB3 specification. However,
+ you can force Hibernate to properly reset the <literal>version</literal> or
+ <literal>timestamp</literal> property values through the use of a <literal>versioned update</literal>.
+ This is achieved by adding the <literal>VERSIONED</literal> keyword after the <literal>UPDATE</literal>
+ keyword.
+
+ </para>
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+String hqlVersionedUpdate = "update versioned Customer set name = :newName where name = :oldName";
+int updatedEntities = s.createQuery( hqlUpdate )
+ .setString( "newName", newName )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ Note that custom version types (<literal>org.hibernate.usertype.UserVersionType</literal>)
+ are not allowed in conjunction with a <literal>update versioned</literal> statement.
+ </para>
+
+ <para>
+
+ Para executar um HQL <literal>DELETE</literal>, use o mesmo método
+ <literal>Query.executeUpdate()</literal>:
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlDelete = "delete Customer c where c.name = :oldName";
+// or String hqlDelete = "delete Customer where name = :oldName";
+int deletedEntities = s.createQuery( hqlDelete )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ O valor <literal>int</literal> retornado pelo método <literal>Query.executeUpdate()</literal>
+ indica o numero de entidade afetadas pela operação. Lembre-se que isso pode estar ou não
+ relacionado ao número de linhas alteradas no banco de dados. Uma operação bulk HQL pode resultar
+ em várias expressões SQL reais a serem executadas, por exemplo, no caso de joined-subclass.
+ O número retornado indica a quantidade real de entidades afetadas pela expressão. Voltando
+ ao exemplo da joined-subclass, a exclusão de uma das subclasses pode resultar numa
+ exclusão em outra tabelas, não apenas na tabela para qual a subclasses está mapeada, mas
+ também tabela "root" e possivelmente nas tabelas joined-subclass num nível hierárquico
+ imediatamente abaixo.
+ </para>
+
+ <para>
+
+ A pseudo-sintaxe para o comando <literal>INSERT</literal> é:
+ <literal>INSERT INTO EntityName properties_list select_statement</literal>. Alguns
+ pontos a observar:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Apenas a forma INSERT INTO ... SELECT ... é suportada; INSERT INTO ... VALUES ...
+ não é suportada.
+ </para>
+ <para>
+ A lista de propriedade é análoga à <literal>especificação da coluna</literal>
+ do comando SQL <literal>INSERT</literal>. Para entidades envolvidas em mapeamentos,
+ apenas a propriedades definidas diretamente a nível da classe podem ser usandas na
+ properties_list. Propriedades da superclass não são permitidas; e as propriedades
+ da subclasse não faz sentido. Em outras palavras, os comandos
+ <literal>INSERT</literal> não são polimorficos.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ O camando select pode ser qualquer query HQL válida, que tenha um retorno compatível
+ com o tipo com o esperado pela inclusão. Atualmente, isto é verificado durante a compilação
+ da query, isto é melhor do que permitir que a verificação chegue ao banco de dados.
+ Entretanto perceba que isso pode causar problemas entre os <literal>Tipo</literal> do Hibernate
+ que são <emphasis>equivalentes</emphasis> em oposição a <emphasis>equal</emphasis>.
+ Isso pode causar problemas nas combinações entre a propriedade definida como
+ <literal>org.hibernate.type.DateType</literal>e um propriedade definida como
+ <literal>org.hibernate.type.TimestampType</literal>, embora o banco de dados não possa
+ fazer uma distinção ou possa ser capaz de manusear a conversão.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Para a propriedade id, a expressão insert oferece duas opções. Você pode especificar
+ qualquer propriedade id explicitamente no properties_list (em alguns casos esse valor
+ é obtido diretamente da expressão select) ou pode omitir do properties_list (nesse caso,
+ um valor gerado é usado). Essa ultima opção só é válida quando são usados geradores de ids
+ que operam no banco de dados; a tentativa de usar essa opção com geradores do tipo
+ "em memória" vai causar um exceção durante a etapa de parser. Veja a finalidades desta
+ discussão, os seguintes geradores operam com o banco de dados
+ <literal>org.hibernate.id.SequenceGenerator</literal> (e suas subclasses)
+ e qualquer implementação de <literal>org.hibernate.id.PostInsertIdentifierGenerator</literal>.
+ Aqui, a exceção mais notável é o <literal>org.hibernate.id.TableHiLoGenerator</literal>, que
+ não pode ser usado porque ele não dispõe de mecanismos para recuperar o seu valor.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ For properties mapped as either <literal>version</literal> or <literal>timestamp</literal>,
+ the insert statement gives you two options. You can either specify the property in the
+ properties_list (in which case its value is taken from the corresponding select expressions)
+ or omit it from the properties_list (in which case the <literal>seed value</literal> defined
+ by the <literal>org.hibernate.type.VersionType</literal> is used).
+
+ Para propriedades mapeadas como <literal>version</literal> ou <literal>timestamp</literal>,
+ a expressão insert oferece a você duas opções. Você pode especificar a propriedade na
+ properties_list (nesse caso o seu valor é obtido a partir da expressão select correspondente)
+ ou ele pode ser omitido da properties_list (neste caso o usa o <literal>valor semente</literal>
+ definido pela classe <literal>org.hibernate.type.VersionType</literal>).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Exemplo da execução de um HQL <literal>INSERT</literal>:
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlInsert = "insert into DelinquentAccount (id, name) select c.id, c.name from Customer c where ...";
+int createdEntities = s.createQuery( hqlInsert )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/best_practices.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/best_practices.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/best_practices.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/best_practices.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,225 @@
+<chapter id="best-practices" revision="3">
+ <title>Boas práticas</title>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>Escreva classes compactas e mapeie-as usando <literal><component></literal>.</term>
+ <listitem>
+ <para>
+ Use uma classe <literal>Endereco</literal> para encapsular <literal>rua</literal>,
+ <literal>bairro</literal>, <literal>estado</literal>, <literal>CEP</literal>. Isto promove
+ a reutilização de código e simplifica o refactoring.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Declare propriedades identificadoras em classes persistentes.</term>
+ <listitem>
+ <para>
+ O Hibernate constrói propriedades identificadoras opcionais. Existem todos os tipos
+ de razões que explicam porquê você deveria utilizá-las. Nós recomendamos que os
+ identificadores sejam 'sintéticos' (gerados, sem significado para o negocio).
+
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Identifique chaves naturais.</term>
+ <listitem>
+ <para>
+ Identifique chaves naturais para todas as entidades, e mapeie-as usando
+ <literal><natural-id></literal>. Implemente <literal>equals()</literal> e
+ <literal>hashCode()</literal> para comparar as propriedades que compõem a chave natural.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Coloque cada classe de mapeamento em seu próprio arquivo.</term>
+ <listitem>
+ <para>
+ Não use um único código de mapeamento monolítico. Mapeie <literal>com.eg.Foo</literal>
+ no arquivo <literal>com/eg/Foo.hbm.xml</literal>. Isto promove particularmente o bom
+ senso no time de desenvolvimento.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Carregue os mapeamentos como recursos.</term>
+ <listitem>
+ <para>
+ Faça o deploy dos mapeamentos junto com as classes que eles mapeiam.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Considere externalizar as strings de consultas.</term>
+ <listitem>
+ <para>
+ Esta é uma boa prática se suas consultas chamam funções SQL que não sejam ANSI.
+ Externalizar as strings de consultas para mapear arquivos irão tornar a aplicação
+ mais portável.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Use bind variables.</term>
+ <listitem>
+ <para>
+ Assim como em JDBC, sempre substitua valores não constantes por "?". Nunca use a manipulação
+ de strings para concatenar valores não constantes em uma consulta! Até melhor, considere
+ usar parâmetros nomeados nas consultas.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Não gerencie suas conexões JDBC.</term>
+ <listitem>
+ <para>
+ O Hibernate permite que a aplicação gerencie conexões JDBC. Esta abordagem deve ser considerada
+ um último recurso. Se você não pode usar os provedores de conexão embutidos, considere fazer
+ sua implementação a partir de <literal>org.hibernate.connection.ConnectionProvider</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Considere usar tipos customizados.</term>
+ <listitem>
+ <para>
+ Suponha que você tenha um tipo Java, de alguma biblioteca, que precisa ser persistido mas não
+ provê os acessórios necessários para mapeá-lo como um componente. Você deve implementar
+ <literal>org.hibernate.UserType</literal>. Esta abordagem livra o código da aplicação de
+ implementar transformações de/para o tipo Hibernate.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term> Use código manual JDBC nos gargalos.</term>
+ <listitem>
+ <para>
+ Nas áreas de desempenho crítico do sistema, alguns tipos de operações podem se beneficiar do
+ uso direto do JDBC. Mas por favor, espere até você <emphasis>saber </emphasis> se é um gargalo.
+ E não suponha que o uso direto do JDBC é necessariamente mais rápido. Se você precisar usar
+ diretamente o JDBC, vale a pena abrir uma <literal>Session</literal> do Hibernate e usar uma
+ conexão JDBC. De modo que você possa ainda usar a mesma estratégia de transação e ocultar
+ o provedor a conexão
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Entenda o <literal>Session</literal> flushing.</term>
+ <listitem>
+ <para>
+ De tempos em tempos a sessão sincroniza seu estado persistente com o banco de dados. O desempenho
+ será afetado se este processo ocorrer frequentemente. Você pode algumas vezes minimizar o fluxo
+ desnecessário desabilitando o fluxo automático ou até mesmo mudando a ordem das consultas e outras
+ operações em uma transação particular.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Em uma arquitetura de três camadas, considere o uso de objetos separados.</term>
+ <listitem>
+ <para>
+ When using a servlet / session bean architecture, you could pass persistent objects loaded in
+ the session bean to and from the servlet / JSP layer. Use a new session to service each request.
+ Use <literal>Session.merge()</literal> or <literal>Session.saveOrUpdate()</literal> to
+ synchronize objects with the database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>In a two tiered architecture, consider using long persistence contexts.</term>
+ <listitem>
+ <para>
+ Database Transactions have to be as short as possible for best scalability. However, it is often
+ necessary to implement long running <emphasis>application transactions</emphasis>, a single
+ unit-of-work from the point of view of a user. An application transaction might span several
+ client request/response cycles. It is common to use detached objects to implement application
+ transactions. An alternative, extremely appropriate in two tiered architecture, is to maintain
+ a single open persistence contact (session) for the whole life cycle of the application transaction
+ and simply disconnect from the JDBC connection at the end of each request and reconnect at the
+ beginning of the subsequent request. Never share a single session across more than one application
+ transaction, or you will be working with stale data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Don't treat exceptions as recoverable.</term>
+ <listitem>
+ <para>
+ This is more of a necessary practice than a "best" practice. When an exception occurs, roll back
+ the <literal>Transaction</literal> and close the <literal>Session</literal>. If you don't, Hibernate
+ can't guarantee that in-memory state accurately represents persistent state. As a special case of this,
+ do not use <literal>Session.load()</literal> to determine if an instance with the given identifier
+ exists on the database; use <literal>Session.get()</literal> or a query instead.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Prefer lazy fetching for associations.</term>
+ <listitem>
+ <para>
+ Use eager fetching sparingly. Use proxies and lazy collections for most associations to classes that
+ are not likely to be completely held in the second-level cache. For associations to cached classes,
+ where there is an a extremely high probability of a cache hit, explicitly disable eager fetching using
+ <literal>lazy="false"</literal>. When an join fetching is appropriate to a particular use
+ case, use a query with a <literal>left join fetch</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Use the <emphasis>open session in view</emphasis> pattern, or a disciplined
+ <emphasis>assembly phase</emphasis> to avoid problems with unfetched data.
+ </term>
+ <listitem>
+ <para>
+ Hibernate frees the developer from writing tedious <emphasis>Data Transfer Objects</emphasis> (DTO).
+ In a traditional EJB architecture, DTOs serve dual purposes: first, they work around the problem
+ that entity beans are not serializable; second, they implicitly define an assembly phase where
+ all data to be used by the view is fetched and marshalled into the DTOs before returning control
+ to the presentation tier. Hibernate eliminates the first purpose. However, you will still need
+ an assembly phase (think of your business methods as having a strict contract with the presentation
+ tier about what data is available in the detached objects) unless you are prepared to hold the
+ persistence context (the session) open across the view rendering process. This is not a limitation
+ of Hibernate! It is a fundamental requirement of safe transactional data access.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Consider abstracting your business logic from Hibernate.</term>
+ <listitem>
+ <para>
+ Hide (Hibernate) data-access code behind an interface. Combine the <emphasis>DAO</emphasis> and
+ <emphasis>Thread Local Session</emphasis> patterns. You can even have some classes persisted by
+ handcoded JDBC, associated to Hibernate via a <literal>UserType</literal>. (This advice is
+ intended for "sufficiently large" applications; it is not appropriate for an application with
+ five tables!)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Don't use exotic association mappings.</term>
+ <listitem>
+ <para>
+ Good usecases for a real many-to-many associations are rare. Most of the time you need
+ additional information stored in the "link table". In this case, it is much better to
+ use two one-to-many associations to an intermediate link class. In fact, we think that
+ most associations are one-to-many and many-to-one, you should be careful when using any
+ other association style and ask yourself if it is really neccessary.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Prefer bidirectional associations.</term>
+ <listitem>
+ <para>
+ Unidirectional associations are more difficult to query. In a large application, almost
+ all associations must be navigable in both directions in queries.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/collection_mapping.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/collection_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/collection_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/collection_mapping.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,1238 @@
+<chapter id="collections">
+ <title>Mapeamento de Coleções</title>
+
+ <sect1 id="collections-persistent" revision="3">
+ <title>Persistent collections</title>
+
+ <para>
+ Hibernate requires that persistent collection-valued fields be declared
+ as an interface type, for example:
+ </para>
+
+ <programlisting><![CDATA[public class Product {
+ private String serialNumber;
+ private Set parts = new HashSet();
+
+ public Set getParts() { return parts; }
+ void setParts(Set parts) { this.parts = parts; }
+ public String getSerialNumber() { return serialNumber; }
+ void setSerialNumber(String sn) { serialNumber = sn; }
+}]]></programlisting>
+
+ <para>
+ The actual interface might be <literal>java.util.Set</literal>,
+ <literal>java.util.Collection</literal>, <literal>java.util.List</literal>,
+ <literal>java.util.Map</literal>, <literal>java.util.SortedSet</literal>,
+ <literal>java.util.SortedMap</literal> or ... anything you like! (Where
+ "anything you like" means you will have to write an implementation of
+ <literal>org.hibernate.usertype.UserCollectionType</literal>.)
+ </para>
+
+ <para>
+ Notice how we initialized the instance variable with an instance of
+ <literal>HashSet</literal>. This is the best way to initialize collection
+ valued properties of newly instantiated (non-persistent) instances. When
+ you make the instance persistent - by calling <literal>persist()</literal>,
+ for example - Hibernate will actually replace the <literal>HashSet</literal>
+ with an instance of Hibernate's own implementation of <literal>Set</literal>.
+ Watch out for errors like this:
+ </para>
+
+ <programlisting><![CDATA[Cat cat = new DomesticCat();
+Cat kitten = new DomesticCat();
+....
+Set kittens = new HashSet();
+kittens.add(kitten);
+cat.setKittens(kittens);
+session.persist(cat);
+kittens = cat.getKittens(); // Okay, kittens collection is a Set
+(HashSet) cat.getKittens(); // Error!]]></programlisting>
+
+ <para>
+ The persistent collections injected by Hibernate behave like
+ <literal>HashMap</literal>, <literal>HashSet</literal>,
+ <literal>TreeMap</literal>, <literal>TreeSet</literal> or
+ <literal>ArrayList</literal>, depending upon the interface type.
+ </para>
+
+ <para>
+ Collections instances have the usual behavior of value types. They are
+ automatically persisted when referenced by a persistent object and
+ automatically deleted when unreferenced. If a collection is passed from one
+ persistent object to another, its elements might be moved from one table to
+ another. Two entities may not share a reference to the same collection
+ instance. Due to the underlying relational model, collection-valued properties
+ do not support null value semantics; Hibernate does not distinguish between
+ a null collection reference and an empty collection.
+ </para>
+
+ <para>
+ You shouldn't have to worry much about any of this. Use persistent collections
+ the same way you use ordinary Java collections. Just make sure you understand
+ the semantics of bidirectional associations (discussed later).
+ </para>
+
+ </sect1>
+
+ <sect1 id="collections-mapping" revision="4">
+ <title>Collection mappings</title>
+
+ <para>
+ The Hibernate mapping element used for mapping a collection depends upon
+ the type of the interface. For example, a <literal><set></literal>
+ element is used for mapping properties of type <literal>Set</literal>.
+ </para>
+
+ <programlisting><![CDATA[<class name="Product">
+ <id name="serialNumber" column="productSerialNumber"/>
+ <set name="parts">
+ <key column="productSerialNumber" not-null="true"/>
+ <one-to-many class="Part"/>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ Apart from <literal><set></literal>, there is also
+ <literal><list></literal>, <literal><map></literal>,
+ <literal><bag></literal>, <literal><array></literal> and
+ <literal><primitive-array></literal> mapping elements. The
+ <literal><map></literal> element is representative:
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="mappingcollection1" coords="2 65"/>
+ <area id="mappingcollection2" coords="3 65"/>
+ <area id="mappingcollection3" coords="4 65"/>
+ <area id="mappingcollection4" coords="5 65"/>
+ <area id="mappingcollection5" coords="6 65"/>
+ <area id="mappingcollection6" coords="7 65"/>
+ <area id="mappingcollection7" coords="8 65"/>
+ <area id="mappingcollection8" coords="9 65"/>
+ <area id="mappingcollection9" coords="10 65"/>
+ <area id="mappingcollection10" coords="11 65"/>
+ <area id="mappingcollection11" coords="12 65"/>
+ <area id="mappingcollection12" coords="13 65"/>
+ <area id="mappingcollection13" coords="14 65"/>
+ <area id="mappingcollection14" coords="15 65"/>
+ </areaspec>
+ <programlisting><![CDATA[<map
+ name="propertyName"
+ table="table_name"
+ schema="schema_name"
+ lazy="true|extra|false"
+ inverse="true|false"
+ cascade="all|none|save-update|delete|all-delete-orphan|delete-orphan"
+ sort="unsorted|natural|comparatorClass"
+ order-by="column_name asc|desc"
+ where="arbitrary sql where condition"
+ fetch="join|select|subselect"
+ batch-size="N"
+ access="field|property|ClassName"
+ optimistic-lock="true|false"
+ mutable="true|false"
+ node="element-name|."
+ embed-xml="true|false"
+>
+
+ <key .... />
+ <map-key .... />
+ <element .... />
+</map>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="mappingcollection1">
+ <para>
+ <literal>name</literal> the collection property name
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection2">
+ <para>
+ <literal>table</literal> (optional - defaults to property name) the
+ name of the collection table (not used for one-to-many associations)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection3">
+ <para>
+ <literal>schema</literal> (optional) the name of a table schema to
+ override the schema declared on the root element
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection4">
+ <para>
+ <literal>lazy</literal> (optional - defaults to <literal>true</literal>)
+ may be used to disable lazy fetching and specify that the association is
+ always eagerly fetched, or to enable "extra-lazy" fetching where most
+ operations do not initialize the collection (suitable for very large
+ collections)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection5">
+ <para>
+ <literal>inverse</literal> (optional - defaults to <literal>false</literal>)
+ mark this collection as the "inverse" end of a bidirectional association
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection6">
+ <para>
+ <literal>cascade</literal> (optional - defaults to <literal>none</literal>)
+ enable operations to cascade to child entities
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection7">
+ <para>
+ <literal>sort</literal> (optional) specify a sorted collection with
+ <literal>natural</literal> sort order, or a given comparator class
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection8">
+ <para>
+ <literal>order-by</literal> (optional, JDK1.4 only) specify a table column (or columns)
+ that define the iteration order of the <literal>Map</literal>, <literal>Set</literal>
+ or bag, together with an optional <literal>asc</literal> or <literal>desc</literal>
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection9">
+ <para>
+ <literal>where</literal> (optional) specify an arbitrary SQL <literal>WHERE</literal>
+ condition to be used when retrieving or removing the collection (useful if the
+ collection should contain only a subset of the available data)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection10">
+ <para>
+ <literal>fetch</literal> (optional, defaults to <literal>select</literal>) Choose
+ between outer-join fetching, fetching by sequential select, and fetching by sequential
+ subselect.
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection11">
+ <para>
+ <literal>batch-size</literal> (optional, defaults to <literal>1</literal>) specify a
+ "batch size" for lazily fetching instances of this collection.
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection12">
+ <para>
+ <literal>access</literal> (optional - defaults to <literal>property</literal>): The
+ strategy Hibernate should use for accessing the collection property value.
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection13">
+ <para>
+ <literal>optimistic-lock</literal> (optional - defaults to <literal>true</literal>):
+ Species that changes to the state of the collection results in increment of the
+ owning entity's version. (For one to many associations, it is often reasonable to
+ disable this setting.)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection14">
+ <para>
+ <literal>mutable</literal> (optional - defaults to <literal>true</literal>):
+ A value of <literal>false</literal> specifies that the elements of the
+ collection never change (a minor performance optimization in some cases).
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <sect2 id="collections-foreignkeys" >
+ <title>Collection foreign keys</title>
+
+ <para>
+ Collection instances are distinguished in the database by the foreign key of
+ the entity that owns the collection. This foreign key is referred to as the
+ <emphasis>collection key column</emphasis> (or columns) of the collection
+ table. The collection key column is mapped by the <literal><key></literal>
+ element.
+ </para>
+
+ <para>
+ There may be a nullability constraint on the foreign key column. For most
+ collections, this is implied. For unidirectional one to many associations,
+ the foreign key column is nullable by default, so you might need to specify
+ <literal>not-null="true"</literal>.
+ </para>
+
+ <programlisting><![CDATA[<key column="productSerialNumber" not-null="true"/>]]></programlisting>
+
+ <para>
+ The foreign key constraint may use <literal>ON DELETE CASCADE</literal>.
+ </para>
+
+ <programlisting><![CDATA[<key column="productSerialNumber" on-delete="cascade"/>]]></programlisting>
+
+ <para>
+ See the previous chapter for a full definition of the <literal><key></literal>
+ element.
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-elements" >
+ <title>Collection elements</title>
+
+ <para>
+ Collections may contain almost any other Hibernate type, including all basic types,
+ custom types, components, and of course, references to other entities. This is an
+ important distinction: an object in a collection might be handled with "value"
+ semantics (its life cycle fully depends on the collection owner) or it might be a
+ reference to another entity, with its own life cycle. In the latter case, only the
+ "link" between the two objects is considered to be state held by the collection.
+ </para>
+
+ <para>
+ The contained type is referred to as the <emphasis>collection element type</emphasis>.
+ Collection elements are mapped by <literal><element></literal> or
+ <literal><composite-element></literal>, or in the case of entity references,
+ with <literal><one-to-many></literal> or <literal><many-to-many></literal>.
+ The first two map elements with value semantics, the next two are used to map entity
+ associations.
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-indexed">
+ <title>Indexed collections</title>
+
+ <para>
+ All collection mappings, except those with set and bag semantics, need an
+ <emphasis>index column</emphasis> in the collection table - a column that maps to an
+ array index, or <literal>List</literal> index, or <literal>Map</literal> key. The
+ index of a <literal>Map</literal> may be of any basic type, mapped with
+ <literal><map-key></literal>, it may be an entity reference mapped with
+ <literal><map-key-many-to-many></literal>, or it may be a composite type,
+ mapped with <literal><composite-map-key></literal>. The index of an array or
+ list is always of type <literal>integer</literal> and is mapped using the
+ <literal><list-index></literal> element. The mapped column contains
+ sequential integers (numbered from zero, by default).
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="index1" coords="2 45"/>
+ <area id="index2" coords="3 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<list-index
+ column="column_name"
+ base="0|1|..."/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="index1">
+ <para>
+ <literal>column_name</literal> (required): The name of the column holding the
+ collection index values.
+ </para>
+ </callout>
+ <callout arearefs="index1">
+ <para>
+ <literal>base</literal> (optional, defaults to <literal>0</literal>): The value
+ of the index column that corresponds to the first element of the list or array.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <programlistingco>
+ <areaspec>
+ <area id="mapkey1" coords="2 45"/>
+ <area id="mapkey2" coords="3 45"/>
+ <area id="mapkey3" coords="4 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<map-key
+ column="column_name"
+ formula="any SQL expression"
+ type="type_name"
+ node="@attribute-name"
+ length="N"/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="mapkey1">
+ <para>
+ <literal>column</literal> (optional): The name of the column holding the
+ collection index values.
+ </para>
+ </callout>
+ <callout arearefs="mapkey2">
+ <para>
+ <literal>formula</literal> (optional): A SQL formula used to evaluate the
+ key of the map.
+ </para>
+ </callout>
+ <callout arearefs="mapkey3">
+ <para>
+ <literal>type</literal> (reguired): The type of the map keys.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <programlistingco>
+ <areaspec>
+ <area id="indexmanytomany1" coords="2 45"/>
+ <area id="indexmanytomany2" coords="3 45"/>
+ <area id="indexmanytomany3" coords="3 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<map-key-many-to-many
+ column="column_name"
+ formula="any SQL expression"
+ class="ClassName"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="indexmanytomany1">
+ <para>
+ <literal>column</literal> (optional): The name of the foreign key
+ column for the collection index values.
+ </para>
+ </callout>
+ <callout arearefs="indexmanytomany2">
+ <para>
+ <literal>formula</literal> (optional): A SQL formula used to evaluate the
+ foreign key of the map key.
+ </para>
+ </callout>
+ <callout arearefs="indexmanytomany3">
+ <para>
+ <literal>class</literal> (required): The entity class used as the map key.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+
+ <para>
+ If your table doesn't have an index column, and you still wish to use <literal>List</literal>
+ as the property type, you should map the property as a Hibernate <emphasis><bag></emphasis>.
+ A bag does not retain its order when it is retrieved from the database, but it may be
+ optionally sorted or ordered.
+ </para>
+
+ </sect2>
+
+ <para>
+ There are quite a range of mappings that can be generated for collections, covering
+ many common relational models. We suggest you experiment with the schema generation tool
+ to get a feeling for how various mapping declarations translate to database tables.
+ </para>
+
+ <sect2 id="collections-ofvalues" revision="2">
+ <title>Collections of values and many-to-many associations</title>
+
+ <para>
+ Any collection of values or many-to-many association requires a dedicated
+ <emphasis>collection table</emphasis> with a foreign key column or columns,
+ <emphasis>collection element column</emphasis> or columns and possibly
+ an index column or columns.
+ </para>
+
+ <para>
+ For a collection of values, we use the <literal><element></literal> tag.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="element1b" coords="2 50"/>
+ <area id="element2b" coords="3 50"/>
+ <area id="element3b" coords="4 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<element
+ column="column_name"
+ formula="any SQL expression"
+ type="typename"
+ length="L"
+ precision="P"
+ scale="S"
+ not-null="true|false"
+ unique="true|false"
+ node="element-name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="element1b">
+ <para>
+ <literal>column</literal> (optional): The name of the column holding the
+ collection element values.
+ </para>
+ </callout>
+ <callout arearefs="element2b">
+ <para>
+ <literal>formula</literal> (optional): An SQL formula used to evaluate the
+ element.
+ </para>
+ </callout>
+ <callout arearefs="element3b">
+ <para>
+ <literal>type</literal> (required): The type of the collection element.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ A <emphasis>many-to-many association</emphasis> is specified using the
+ <literal><many-to-many></literal> element.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="manytomany1" coords="2 60"/>
+ <area id="manytomany2" coords="3 60"/>
+ <area id="manytomany3" coords="4 60"/>
+ <area id="manytomany4" coords="5 60"/>
+ <area id="manytomany5" coords="6 60"/>
+ <area id="manytomany6" coords="7 60"/>
+ <area id="manytomany7" coords="8 60"/>
+ <area id="manytomany8" coords="9 60"/>
+ </areaspec>
+ <programlisting><![CDATA[<many-to-many
+ column="column_name"
+ formula="any SQL expression"
+ class="ClassName"
+ fetch="select|join"
+ unique="true|false"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ property-ref="propertyNameFromAssociatedClass"
+ node="element-name"
+ embed-xml="true|false"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="manytomany1">
+ <para>
+ <literal>column</literal> (optional): The name of the element foreign key column.
+ </para>
+ </callout>
+ <callout arearefs="manytomany2">
+ <para>
+ <literal>formula</literal> (optional): An SQL formula used to evaluate the element
+ foreign key value.
+ </para>
+ </callout>
+ <callout arearefs="manytomany3">
+ <para>
+ <literal>class</literal> (required): The name of the associated class.
+ </para>
+ </callout>
+ <callout arearefs="manytomany4">
+ <para>
+ <literal>fetch</literal> (optional - defaults to <literal>join</literal>):
+ enables outer-join or sequential select fetching for this association. This
+ is a special case; for full eager fetching (in a single <literal>SELECT</literal>)
+ of an entity and its many-to-many relationships to other entities, you would
+ enable <literal>join</literal> fetching not only of the collection itself,
+ but also with this attribute on the <literal><many-to-many></literal>
+ nested element.
+ </para>
+ </callout>
+ <callout arearefs="manytomany5">
+ <para>
+ <literal>unique</literal> (optional): Enable the DDL generation of a unique
+ constraint for the foreign-key column. This makes the association multiplicity
+ effectively one to many.
+ </para>
+ </callout>
+ <callout arearefs="manytomany6">
+ <para>
+ <literal>not-found</literal> (optional - defaults to <literal>exception</literal>):
+ Specifies how foreign keys that reference missing rows will be handled:
+ <literal>ignore</literal> will treat a missing row as a null association.
+ </para>
+ </callout>
+ <callout arearefs="manytomany7">
+ <para>
+ <literal>entity-name</literal> (optional): The entity name of the associated class,
+ as an alternative to <literal>class</literal>.
+ </para>
+ </callout>
+ <callout arearefs="manytomany8">
+ <para>
+ <literal>property-ref</literal>: (optional) The name of a property of the associated
+ class that is joined to this foreign key. If not specified, the primary key of
+ the associated class is used.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Some examples, first, a set of strings:
+ </para>
+
+ <programlisting><![CDATA[<set name="names" table="person_names">
+ <key column="person_id"/>
+ <element column="person_name" type="string"/>
+</set>]]></programlisting>
+
+ <para>
+ A bag containing integers (with an iteration order determined by the
+ <literal>order-by</literal> attribute):
+ </para>
+
+ <programlisting><![CDATA[<bag name="sizes"
+ table="item_sizes"
+ order-by="size asc">
+ <key column="item_id"/>
+ <element column="size" type="integer"/>
+</bag>]]></programlisting>
+
+ <para>
+ An array of entities - in this case, a many to many association:
+ </para>
+
+ <programlisting><![CDATA[<array name="addresses"
+ table="PersonAddress"
+ cascade="persist">
+ <key column="personId"/>
+ <list-index column="sortOrder"/>
+ <many-to-many column="addressId" class="Address"/>
+</array>]]></programlisting>
+
+ <para>
+ A map from string indices to dates:
+ </para>
+
+ <programlisting><![CDATA[<map name="holidays"
+ table="holidays"
+ schema="dbo"
+ order-by="hol_name asc">
+ <key column="id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ A list of components (discussed in the next chapter):
+ </para>
+
+ <programlisting><![CDATA[<list name="carComponents"
+ table="CarComponents">
+ <key column="carId"/>
+ <list-index column="sortOrder"/>
+ <composite-element class="CarComponent">
+ <property name="price"/>
+ <property name="type"/>
+ <property name="serialNumber" column="serialNum"/>
+ </composite-element>
+</list>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="collections-onetomany">
+ <title>One-to-many associations</title>
+
+ <para>
+ A <emphasis>one to many association</emphasis> links the tables of two classes
+ via a foreign key, with no intervening collection table. This mapping loses
+ certain semantics of normal Java collections:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ An instance of the contained entity class may not belong to more than
+ one instance of the collection
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ An instance of the contained entity class may not appear at more than
+ one value of the collection index
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ An association from <literal>Product</literal> to <literal>Part</literal> requires
+ existence of a foreign key column and possibly an index column to the <literal>Part</literal>
+ table. A <literal><one-to-many></literal> tag indicates that this is a one to many
+ association.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="onetomany1" coords="2 60"/>
+ <area id="onetomany2" coords="3 60"/>
+ <area id="onetomany3" coords="4 60"/>
+ </areaspec>
+ <programlisting><![CDATA[<one-to-many
+ class="ClassName"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ node="element-name"
+ embed-xml="true|false"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="onetomany1">
+ <para>
+ <literal>class</literal> (required): The name of the associated class.
+ </para>
+ </callout>
+ <callout arearefs="onetomany2">
+ <para>
+ <literal>not-found</literal> (optional - defaults to <literal>exception</literal>):
+ Specifies how cached identifiers that reference missing rows will be handled:
+ <literal>ignore</literal> will treat a missing row as a null association.
+ </para>
+ </callout>
+ <callout arearefs="onetomany3">
+ <para>
+ <literal>entity-name</literal> (optional): The entity name of the associated class,
+ as an alternative to <literal>class</literal>.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Notice that the <literal><one-to-many></literal> element does not need to
+ declare any columns. Nor is it necessary to specify the <literal>table</literal>
+ name anywhere.
+ </para>
+
+ <para>
+ <emphasis>Very important note:</emphasis> If the foreign key column of a
+ <literal><one-to-many></literal> association is declared <literal>NOT NULL</literal>,
+ you must declare the <literal><key></literal> mapping
+ <literal>not-null="true"</literal> or <emphasis>use a bidirectional association</emphasis>
+ with the collection mapping marked <literal>inverse="true"</literal>. See the discussion
+ of bidirectional associations later in this chapter.
+ </para>
+
+ <para>
+ This example shows a map of <literal>Part</literal> entities by name (where
+ <literal>partName</literal> is a persistent property of <literal>Part</literal>).
+ Notice the use of a formula-based index.
+ </para>
+
+ <programlisting><![CDATA[<map name="parts"
+ cascade="all">
+ <key column="productId" not-null="true"/>
+ <map-key formula="partName"/>
+ <one-to-many class="Part"/>
+</map>]]></programlisting>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="collections-advancedmappings">
+ <title>Advanced collection mappings</title>
+
+ <sect2 id="collections-sorted" revision="2">
+ <title>Sorted collections</title>
+
+ <para>
+ Hibernate supports collections implementing <literal>java.util.SortedMap</literal> and
+ <literal>java.util.SortedSet</literal>. You must specify a comparator in the mapping file:
+ </para>
+
+ <programlisting><![CDATA[<set name="aliases"
+ table="person_aliases"
+ sort="natural">
+ <key column="person"/>
+ <element column="name" type="string"/>
+</set>
+
+<map name="holidays" sort="my.custom.HolidayComparator">
+ <key column="year_id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ Allowed values of the <literal>sort</literal> attribute are <literal>unsorted</literal>,
+ <literal>natural</literal> and the name of a class implementing
+ <literal>java.util.Comparator</literal>.
+ </para>
+
+ <para>
+ Sorted collections actually behave like <literal>java.util.TreeSet</literal> or
+ <literal>java.util.TreeMap</literal>.
+ </para>
+
+ <para>
+ If you want the database itself to order the collection elements use the
+ <literal>order-by</literal> attribute of <literal>set</literal>, <literal>bag</literal>
+ or <literal>map</literal> mappings. This solution is only available under
+ JDK 1.4 or higher (it is implemented using <literal>LinkedHashSet</literal> or
+ <literal>LinkedHashMap</literal>). This performs the ordering in the SQL query,
+ not in memory.
+ </para>
+
+ <programlisting><![CDATA[<set name="aliases" table="person_aliases" order-by="lower(name) asc">
+ <key column="person"/>
+ <element column="name" type="string"/>
+</set>
+
+<map name="holidays" order-by="hol_date, hol_name">
+ <key column="year_id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ Note that the value of the <literal>order-by</literal> attribute is an SQL ordering, not
+ a HQL ordering!
+ </para>
+
+ <para>
+ Associations may even be sorted by some arbitrary criteria at runtime using a collection
+ <literal>filter()</literal>.
+ </para>
+
+ <programlisting><![CDATA[sortedUsers = s.createFilter( group.getUsers(), "order by this.name" ).list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="collections-bidirectional" revision="1">
+ <title>Bidirectional associations</title>
+
+ <para>
+ A <emphasis>bidirectional association</emphasis> allows navigation from both
+ "ends" of the association. Two kinds of bidirectional association are
+ supported:
+
+ <variablelist>
+ <varlistentry>
+ <term>one-to-many</term>
+ <listitem>
+ <para>
+ set or bag valued at one end, single-valued at the other
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>many-to-many</term>
+ <listitem>
+ <para>
+ set or bag valued at both ends
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+
+ <para>
+ You may specify a bidirectional many-to-many association simply by mapping two
+ many-to-many associations to the same database table and declaring one end as
+ <emphasis>inverse</emphasis> (which one is your choice, but it can not be an
+ indexed collection).
+ </para>
+
+ <para>
+ Here's an example of a bidirectional many-to-many association; each category can
+ have many items and each item can be in many categories:
+ </para>
+
+ <programlisting><![CDATA[<class name="Category">
+ <id name="id" column="CATEGORY_ID"/>
+ ...
+ <bag name="items" table="CATEGORY_ITEM">
+ <key column="CATEGORY_ID"/>
+ <many-to-many class="Item" column="ITEM_ID"/>
+ </bag>
+</class>
+
+<class name="Item">
+ <id name="id" column="ITEM_ID"/>
+ ...
+
+ <!-- inverse end -->
+ <bag name="categories" table="CATEGORY_ITEM" inverse="true">
+ <key column="ITEM_ID"/>
+ <many-to-many class="Category" column="CATEGORY_ID"/>
+ </bag>
+</class>]]></programlisting>
+
+ <para>
+ As mudanças feitas somente de um lado da associação <emphasis>não</emphasis> são
+ persistidas. Isto significa que o Hibernate tem duas representações na memória
+ para cada associação bidirecional, uma associação de A para B e uma outra
+ associação de B para A. Isto é mais fácil de compreender se você pensa
+ sobre o modelo do objetos do Java e como nós criamos um relacionamento muitos
+ para muitos em Java:
+ </para>
+
+ <programlisting><![CDATA[
+category.getItems().add(item); // The category now "knows" about the relationship
+item.getCategories().add(category); // The item now "knows" about the relationship
+
+session.persist(item); // The relationship won't be saved!
+session.persist(category); // The relationship will be saved]]></programlisting>
+
+ <para>
+ A outra ponta é usada salvar a representação em memória à base de dados.
+ </para>
+
+ <para>
+ Você pode definir uma associação bidirecional um para muitos através de uma associação
+ um-para-muitos indicando as mesmas colunas da tabela que à associação muitos-para-um e
+ declarando a propriedade <literal>inverse="true"</literal>
+
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ Mapear apenas uma das pontas da associação com <literal>inverse="true"</literal>
+ não afeta as operações em cascata, isso é um conceito ortogonal.
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-indexedbidirectional">
+ <title>Associações bidirecionais com coleções indexadas</title>
+ <para>
+ Uma associação bidirecional onde uma dos lados e representa pôr uma
+ <literal><list></literal> ou <literal><map></literal> requer uma consideração
+ especial. Se houver uma propriedade da classe filha que faça o mapeamento da coluna do
+ índice, sem problema, pode-se continuar usando <literal>inverse="true"</literal> no
+ mapeamento da coleção.
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <map name="children" inverse="true">
+ <key column="parent_id"/>
+ <map-key column="name"
+ type="string"/>
+ <one-to-many class="Child"/>
+ </map>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <property name="name"
+ not-null="true"/>
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ Mas, se não houver nenhuma propriedade na classe filha, não podemos ver essa associação
+ como verdadeiramente bidirecional (há uma informação disponível em um lado da associação
+ que não está disponível no extremo oposto). Nesse caso, nos não podemos mapear a coleção
+ usando <literal>inverse="true"</literal>. Nos devemos usar o seguinte mapeamento:
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <map name="children">
+ <key column="parent_id"
+ not-null="true"/>
+ <map-key column="name"
+ type="string"/>
+ <one-to-many class="Child"/>
+ </map>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ insert="false"
+ update="false"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ Veja que neste mapeamento, que um dos lado da associação, a coleção, é responsável pela
+ atualização da chave estrangeira. TODO: Isso realmente resulta em updates desnecessários ?.
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-ternary">
+ <title>Associações Ternárias</title>
+
+ <para>
+ Há três meios possíveis de se mapear uma associação ternária. Uma é usar um
+ <literal>Map</literal> com uma associação como seu índice:
+ </para>
+
+ <programlisting><![CDATA[<map name="contracts">
+ <key column="employer_id" not-null="true"/>
+ <map-key-many-to-many column="employee_id" class="Employee"/>
+ <one-to-many class="Contract"/>
+</map>]]></programlisting>
+
+ <programlisting><![CDATA[<map name="connections">
+ <key column="incoming_node_id"/>
+ <map-key-many-to-many column="outgoing_node_id" class="Node"/>
+ <many-to-many column="connection_id" class="Connection"/>
+</map>]]></programlisting>
+
+ <para>
+ A segunda maneira é simplesmente remodelar a associação das classes da entidade.
+ Esta é a maneira que nós usamos de uma maneira geral.
+ </para>
+
+ <para>
+ Uma alternativa final é usar os elementos compostos, que nós
+ discutiremos mais tarde.
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-idbag" revision="1">
+ <title><literal>Usando o <idbag></literal></title>
+
+ <para>
+ Se você concorda com nossa visão que chaves compostas são uma coisa ruim e que
+ as entidades devem ter identificadores sintéticos (surrogate keys), então você
+ deve estar achando um pouco estranho que as associações muitos para muitos
+ usando coleções de valores que nós mostramos estejam mapeadas com chaves
+ compostas! Bem, este ponto é bastante discutível; um simples tabela de associação
+ não parece se beneficiar muito de uma surrogate key (entretanto uma coleção de
+ valores compostos <emphasis>sim</emphasis>). Opcionalmente, o Hibernate prove
+ uma maneira de mapear uma associação muitos para muitos com uma coleção
+ de valores para uma tabela com uma surrogate key.
+ </para>
+
+ <para>
+ O elemento <literal><idbag></literal> permite mapear um <literal>List</literal>
+ (ou uma <literal>Collection</literal> com uma semântica de bag.
+ </para>
+
+<programlisting><![CDATA[<idbag name="lovers" table="LOVERS">
+ <collection-id column="ID" type="long">
+ <generator class="sequence"/>
+ </collection-id>
+ <key column="PERSON1"/>
+ <many-to-many column="PERSON2" class="Person" fetch="join"/>
+</idbag>]]></programlisting>
+
+ <para>
+ Como você pode ver, um <literal><idbag></literal> possui um gerador de id
+ sintético, igual uma classe de entidade! Uma surrogate key diferente é associada
+ para cada elemento de coleção. Porém, o Hibernate não prove nenhum mecanismo
+ para descobrir qual a surrogate key de uma linha em particular.
+ </para>
+
+ <para>
+ Note que o desempenho de atualização de um <literal><idbag></literal> é
+ <emphasis>much</emphasis> melhor que um <literal><bag></literal> normal!
+ O Hibernate pode localizar uma linha individual eficazmente e atualizar ou
+ deletar individualmente, como um list, map ou set.
+ </para>
+
+ <para>
+ Na implementação atual, a estratégia de geração de identificador <literal>native</literal>
+ não é suportada para identificadores de coleção usando o <literal><idbag></literal>.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <!--undocumenting this stuff -->
+
+ <!--sect1 id="collections-heterogeneous">
+ <title>Heterogeneous Associations</title>
+
+ <para>
+ The <literal><many-to-any></literal> and <literal><index-many-to-any></literal>
+ elements provide for true heterogeneous associations. These mapping elements work in the
+ same way as the <literal><any></literal> element - and should also be used
+ rarely, if ever.
+ </para>
+
+ </sect1-->
+
+ <sect1 id="collections-example" revision="1">
+ <title>Exemplos de coleções</title>
+
+ <para>
+ As seções anteriores são uma grande confusão. Assim sendo vejamos uma exemplo.
+ Essa classe:
+ </para>
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+
+public class Parent {
+ private long id;
+ private Set children;
+
+ public long getId() { return id; }
+ private void setId(long id) { this.id=id; }
+
+ private Set getChildren() { return children; }
+ private void setChildren(Set children) { this.children=children; }
+
+ ....
+ ....
+}]]></programlisting>
+
+ <para>
+ tem uma coleção de instancias de <literal>Child</literal>. Se
+ cada Child tiver no máximo um parent, o mapeamento natural é
+ uma associação um para muitos:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Esse mapeamento gera a seguinte definição de tabelas
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null primary key, name varchar(255), parent_id bigint )
+alter table child add constraint childfk0 (parent_id) references parent]]></programlisting>
+
+ <para>
+ Se o parent for <emphasis>obrigatório</emphasis>, use uma associação bidirecional
+ um para muitos:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ <many-to-one name="parent" class="Parent" column="parent_id" not-null="true"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Repare na constraint <literal>NOT NULL</literal>:
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null
+ primary key,
+ name varchar(255),
+ parent_id bigint not null )
+alter table child add constraint childfk0 (parent_id) references parent]]></programlisting>
+
+ <para>
+ Uma outra alternativa, no caso de você insistir que esta associação devea ser
+ unidirecional, você pode declarar a constraint como <literal>NOT NULL</literal>
+ na tag <literal><key></literal> do mapeamento:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children">
+ <key column="parent_id" not-null="true"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Por outro lado, se uma child puder ter os múltiplos parents, a associação
+ apropriada é muitos-para-muitos:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children" table="childset">
+ <key column="parent_id"/>
+ <many-to-many class="Child" column="child_id"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Definições das tabelas:
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null primary key, name varchar(255) )
+create table childset ( parent_id bigint not null,
+ child_id bigint not null,
+ primary key ( parent_id, child_id ) )
+alter table childset add constraint childsetfk0 (parent_id) references parent
+alter table childset add constraint childsetfk1 (child_id) references child]]></programlisting>
+
+ <para>
+ For more examples and a complete walk-through a parent/child relationship mapping,
+ see <xref linkend="example-parentchild"/>.
+ Para mais exemplos e um exemplo completo de mapeamento de relacionamento
+ de mestre/detalhe, veja <xref linkend="example-parentchild"/>.
+ </para>
+
+ <para>
+ Até mesmo o mapeamento de associações mais exóticas são possíveis, nós catalogaremos
+ todas as possibilidades no próximo capítulo.
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/component_mapping.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/component_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/component_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/component_mapping.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,413 @@
+<chapter id="components">
+ <title>Mapeamento de Componentes</title>
+
+ <para>
+ A noção de <emphasis>componente</emphasis> é reusada em vários contextos diferentes,
+ para propósitos diferentes, pelo Hibernate.
+
+
+ </para>
+
+ <sect1 id="components-dependentobjects" revision="2" >
+ <title>Objetos dependentes</title>
+
+ <para>
+ Um componente é um objeto contido que é persistido como um tipo de valor, não uma
+ referência de entidade. O termo "componente" refere-se à noção de composição da
+ orientação a objetos (não a componentes no nível de arquitetura). Por exemplo, você
+ pode modelar uma pessoa desta maneira:
+ </para>
+
+ <programlisting><![CDATA[public class Person {
+ private java.util.Date birthday;
+ private Name name;
+ private String key;
+ public String getKey() {
+ return key;
+ }
+ private void setKey(String key) {
+ this.key=key;
+ }
+ public java.util.Date getBirthday() {
+ return birthday;
+ }
+ public void setBirthday(java.util.Date birthday) {
+ this.birthday = birthday;
+ }
+ public Name getName() {
+ return name;
+ }
+ public void setName(Name name) {
+ this.name = name;
+ }
+ ......
+ ......
+}]]></programlisting>
+
+<programlisting><![CDATA[public class Name {
+ char initial;
+ String first;
+ String last;
+ public String getFirst() {
+ return first;
+ }
+ void setFirst(String first) {
+ this.first = first;
+ }
+ public String getLast() {
+ return last;
+ }
+ void setLast(String last) {
+ this.last = last;
+ }
+ public char getInitial() {
+ return initial;
+ }
+ void setInitial(char initial) {
+ this.initial = initial;
+ }
+}]]></programlisting>
+
+ <para>
+ Agora <literal>Name</literal> pode ser persistido como um componente
+ de <literal>Person</literal>. Note que <literal>Name</literal> define métodos
+ getter e setter para suas propriedades persistentes, mas não necessita declarar
+ nenhuma interface ou propriedades identificadoras.
+ </para>
+
+ <para>
+ Nosso mapeamento do Hibernate seria semelhante a isso
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Person" table="person">
+ <id name="Key" column="pid" type="string">
+ <generator class="uuid"/>
+ </id>
+ <property name="birthday" type="date"/>
+ <component name="Name" class="eg.Name"> <!-- class attribute optional -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </component>
+</class>]]></programlisting>
+
+ <para>
+ A tabela pessoa teria as seguintes colunas <literal>pid</literal>,
+ <literal>birthday</literal>,
+ <literal>initial</literal>,
+ <literal>first</literal> and
+ <literal>last</literal>.
+ </para>
+
+ <para>
+ Assim como todos tipos por valor, componentes não suportam referencias cruzadas. Em
+ outras palavras, duas pessoas poderiam possuir o mesmo nome, mas os dois objetos
+ pessoa poderiam conter dois objetos nome independentes, apenas com "o mesmo" por valor.
+ A semântica dos valores null de um componente são <emphasis>ad hoc</emphasis>. No
+ recarregameno do conteúdo do objeto, O Hibernate assumira que se todas as colunas
+ do componente são null, então todo o componente é null. Isto seria o certo para
+ a maioria dos propósitos.
+ </para>
+
+ <para>
+ As propriedades de um componente podem ser de qualquer tipo do Hibernate(collections,
+ associações muitos-para-um, outros componentes, etc). Componentes agrupados
+ <emphasis>não </emphasis> devem ser consideros um uso exótico. O Hibernate tem
+ a intenção de suportar um modelo de objetos muito bem granulado.
+ </para>
+
+ <para>
+ O elemento <literal><component></literal> permite um subelemento
+ <literal><parent></literal> que mapeia uma propriedade da classe componente
+ como uma referência de volta para a entidade que a contém.
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Person" table="person">
+ <id name="Key" column="pid" type="string">
+ <generator class="uuid"/>
+ </id>
+ <property name="birthday" type="date"/>
+ <component name="Name" class="eg.Name" unique="true">
+ <parent name="namedPerson"/> <!-- reference back to the Person -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </component>
+</class>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="components-incollections" revision="1">
+ <title>Collections de objetos dependentes</title>
+
+ <para>
+ Collections de componentes são suportadadas(ex. uma array de
+ tipo <literal>Name</literal>). Declare a sua collection de
+ componentes substituindo a tag<literal><element></literal>
+ pela tag <literal><composite-element></literal>.
+ </para>
+
+ <programlisting><![CDATA[<set name="someNames" table="some_names" lazy="true">
+ <key column="id"/>
+ <composite-element class="eg.Name"> <!-- class attribute required -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </composite-element>
+</set>]]></programlisting>
+
+ <para>
+ Nota: se você definir um <literal>Set</literal> de elementos compostos,
+ é muito importante implementar <literal>equals()</literal> e
+ <literal>hashCode()</literal> corretamente.
+ </para>
+
+ <para>
+ Elementos compostos podem conter componentes mas não collections. Se o
+ seu elemento composto contiver componentes , use a tag
+ <literal><nested-composite-element></literal> . Este é um caso
+ bastante exótico – uma collections de componentes que por si própria
+ possui componentes. Neste momento você deve estar se perguntando se
+ uma associação de um-para-muitos seria mais apropriada. Tente remodelar
+ o elemento composto como uma entidade – mas note que mesmo pensando
+ que o modelo Java é o mesmo, o modelo relacional e a semântica de
+ persistência ainda são diferentes.
+ </para>
+
+ <para>
+ Por favor, note que um mapeamento de elemento composto não suporta propriedades
+ capazes de serem null se você estiver usando um <literal><set></literal>.
+ O Hibernate tem que usar cada valor das colunas para identificar um registro
+ quando estiver deletando objetos (não existe coluna chave primária separada na
+ tabela de elemento composto), que não é possível com valores null.
+ Você tem que usar um dos dois, ou apenas propriedades não null em um elemento
+ composto ou escolher uma <literal><list></literal>,
+ <literal><map></literal>, <literal><bag></literal> ou
+ <literal><idbag></literal>.
+ </para>
+
+ <para>
+ Um caso especial de elemento composto é um elemento composto com um elemento
+ <literal><many-to-one></literal> aninhado. Um mapeamento como este
+ permite você a mapear colunas extras de uma tabela de associação de
+ muitos-para-muitos para a classe de elemento composto. A seguinte
+ associação de muitos-para-muitos de <literal>Order</literal> para um
+ <literal>Item</literal> onde <literal>purchaseDate</literal>,
+ <literal>price</literal> e <literal>quantity</literal> são propriedades
+ da associação:
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Order" .... >
+ ....
+ <set name="purchasedItems" table="purchase_items" lazy="true">
+ <key column="order_id">
+ <composite-element class="eg.Purchase">
+ <property name="purchaseDate"/>
+ <property name="price"/>
+ <property name="quantity"/>
+ <many-to-one name="item" class="eg.Item"/> <!-- class attribute is optional -->
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ Claro, que não pode ter uma referência para purchase no outro lado, para a
+ navegação da associação bidirecional. Lembre-se que componentes são tipos por
+ valor e não permitem referências compartilhadas. Uma classe <literal>Purchase</literal>
+ simples pode estar no set de uma classe <literal>Order</literal>, mas ela não
+ pode ser referenciada por <literal>Item</literal> no mesmo momento.
+ </para>
+
+ <para>Até mesmo associações ternárias (ou quaternária, etc) são possíveis:</para>
+
+
+ <programlisting><![CDATA[<class name="eg.Order" .... >
+ ....
+ <set name="purchasedItems" table="purchase_items" lazy="true">
+ <key column="order_id">
+ <composite-element class="eg.OrderLine">
+ <many-to-one name="purchaseDetails class="eg.Purchase"/>
+ <many-to-one name="item" class="eg.Item"/>
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ Elementos compostos podem aparecer em pesquisas usando a mesma
+ sintaxe assim como associações para outras entidades.
+ </para>
+
+ </sect1>
+
+ <sect1 id="components-asmapindex">
+ <title>Componentes como índices de Map</title>
+
+ <para>
+ O elemento <literal><composite-map-key></literal> permite você mapear
+ uma classe componente como uma chave de um <literal>Map</literal>. Tenha
+ certeza que você sobrescreveu <literal>hashCode()</literal> e
+ <literal>equals()</literal> corretamente na classe componente.
+ </para>
+ </sect1>
+
+ <sect1 id="components-compositeid" revision="1">
+ <title>. Componentes como identificadores compostos</title>
+
+ <para>
+ Você pode usar um componente como um identificador de uma classe entidade.
+ Sua classe componente deve satisfazer certos requisitos:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Ele deve implementar <literal>java.io.Serializable</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Ele deve re-implementar <literal>equals()</literal> e
+ <literal>hashCode()</literal>, consistentemente com a noção
+ de igualdade de chave composta do banco de dados.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <emphasis>Nota: no Hibernate 3, o segundo requisito não é um requisito absolutamente
+ necessário. Mas atenda ele de qualquer forma.</emphasis>
+ </para>
+
+ <para>
+ Você não pode usar um <literal>IdentifierGenerator</literal> para gerar chaves compostas.
+ Ao invés disso o aplicativo deve gerenciar seus próprios identificadores.
+ </para>
+
+ <para>
+ Use a tag <literal><composite-id></literal> (com elementos
+ <literal><key-property></literal> aninhados) no lugar da declaração
+ <literal><id></literal> de costume. Por exemplo, a classe
+ <literal>OrderLine</literal> possui uma chave primária que depende da
+ chave primária (composta) de <literal>Order</literal>.
+ </para>
+
+ <programlisting><![CDATA[<class name="OrderLine">
+
+ <composite-id name="id" class="OrderLineId">
+ <key-property name="lineId"/>
+ <key-property name="orderId"/>
+ <key-property name="customerId"/>
+ </composite-id>
+
+ <property name="name"/>
+
+ <many-to-one name="order" class="Order"
+ insert="false" update="false">
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </many-to-one>
+ ....
+
+</class>]]></programlisting>
+
+ <para>
+ Agora, qualquer chave estrangeira referenciando a tabela <literal>OrderLine</literal>
+ também serão compostas. Você deve declarar isto em seus mapeamentos para outras
+ classes. Uma associação para <literal>OrderLine</literal> seria mapeada dessa forma:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="orderLine" class="OrderLine">
+<!-- the "class" attribute is optional, as usual -->
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+</many-to-one>]]></programlisting>
+
+ <para>
+ (Note que a tag <literal><column></literal> é uma alternativa para o
+ atributo <literal>column</literal> por toda a parte.)
+
+
+ </para>
+
+ <para>
+ Uma associação <literal>many-to-many</literal> para <literal>many-to-many</literal>
+ também usa a chave estrangeira composta:
+ </para>
+
+ <programlisting><![CDATA[<set name="undeliveredOrderLines">
+ <key column name="warehouseId"/>
+ <many-to-many class="OrderLine">
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </many-to-many>
+</set>]]></programlisting>
+
+ <para>
+ A collection de <literal>OrderLine</literal>s em <literal>Order</literal> usaria:
+ </para>
+
+ <programlisting><![CDATA[<set name="orderLines" inverse="true">
+ <key>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </key>
+ <one-to-many class="OrderLine"/>
+</set>]]></programlisting>
+
+ <para>
+ (O elemento <literal><one-to-many></literal>, como de costume, não declara colunas.)
+
+
+ </para>
+
+ <para>
+ Se <literal>OrderLine</literal> possui uma collection, ela também tem uma
+ chave estrangeira composta.
+ </para>
+
+ <programlisting><![CDATA[<class name="OrderLine">
+ ....
+ ....
+ <list name="deliveryAttempts">
+ <key> <!-- a collection inherits the composite key type -->
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </key>
+ <list-index column="attemptId" base="1"/>
+ <composite-element class="DeliveryAttempt">
+ ...
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="components-dynamic" revision="1">
+ <title>Componentes Dinâmicos</title>
+
+ <para>
+ Você pode até mesmo mapear uma propriedade do tipo <literal>Map</literal>:
+ </para>
+
+ <programlisting><![CDATA[<dynamic-component name="userAttributes">
+ <property name="foo" column="FOO" type="string"/>
+ <property name="bar" column="BAR" type="integer"/>
+ <many-to-one name="baz" class="Baz" column="BAZ_ID"/>
+</dynamic-component>]]></programlisting>
+
+ <para>
+ A semântica de um mapeamento <literal><dynamic-component></literal> é idêntica
+ à <literal><component></literal>. A vantagem deste tipo de mapeamento é a
+ habilidade de determinar as propriedades atuais do bean no momento de deploy,
+ apenas editando o documento de mapeamento. A Manipulação em tempo de execução do
+ documento de mapeamento também é possível, usando o parser DOM. Até melhor,
+ você pode acessar (e mudar) o metamodelo configuration-time do Hibernate
+ através do objeto <literal>Configuration</literal>.
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/configuration.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/configuration.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/configuration.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/configuration.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,1789 @@
+<chapter id="session-configuration" revision="1">
+
+ <title>Configuração</title>
+
+ <para>
+ Devido ao fato de o Hibernate ser projetado para operar em vários ambientes diferentes,
+ há um grande número de parâmetros de configuração. Felizmente, a maioria tem valores default
+ lógicos e o Hibernate é distribuído com um arquivo <literal>hibernate.properties</literal>
+ de exemplo no <literal>etc/</literal> que mostra várias opções. Apenas coloque o arquivo
+ de exemplo no seu classpath e personalize-o.
+ </para>
+
+ <sect1 id="configuration-programmatic" revision="1">
+ <title>1.11 Configuração programática</title>
+
+ <para>
+ Uma instância de <literal>org.hibernate.cfg.Configuration</literal>
+ representa um conjunto inteiro de mapeamentos de tipos Java da aplicação para
+ um banco de dados SQL. O <literal>Configuration</literal> é usado para construir
+ uma <literal>SessionFactory</literal> (imutável). Os mapeamentos são compilados
+ a partir de arquivos de mapeamento XML.
+
+ </para>
+
+ <para>
+ Você pode obter uma instância <literal>Configuration</literal> intanciando-
+ o diretamente e especificando documentos de mapeamento XML. Se o arquivo
+ de mapeamento estão no classpath, use use <literal>addResource()</literal>:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addResource("Item.hbm.xml")
+ .addResource("Bid.hbm.xml");]]></programlisting>
+
+ <para>
+ Uma alternativa (às vezes melhor) é especificar a classe mapeada,
+ e permitir que o Hibernate encontre o documento de mapeamento para você:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addClass(org.hibernate.auction.Item.class)
+ .addClass(org.hibernate.auction.Bid.class);]]></programlisting>
+
+ <para>
+ Então o Hibernate procurará pelos arquivos de mapeamento chamados
+ <literal>/org/hibernate/auction/Item.hbm.xml</literal> e
+ <literal>/org/hibernate/auction/Bid.hbm.xml</literal> no classpath.
+ Esta abordagem elimina qualquer nome de arquivo de difícil compreensão.
+ </para>
+
+ <para>
+ Uma <literal>Configuration</literal> também permite você especificar
+ propriedades de configuração:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addClass(org.hibernate.auction.Item.class)
+ .addClass(org.hibernate.auction.Bid.class)
+ .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
+ .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
+ .setProperty("hibernate.order_updates", "true");]]></programlisting>
+
+ <para>
+ Este não é o único caminho para passar as propriedades de configuração
+ para o Hibernate. As várias opções incluem:
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ Passar uma instância de <literal>java.util.Properties</literal>
+ para <literal>Configuration.setProperties()</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Colocar <literal>hibernate.properties</literal> no diretório
+ raiz do classpath.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Determinar as propriedades do <literal>System</literal>
+ usando <literal>java -Dproperty=value</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Include <literal><property></literal> elements in
+ <literal>hibernate.cfg.xml</literal> (discussed later).
+ Incluir elementos <literal><property></literal> no
+ <literal>hibernate.cfg.xml</literal> (discutido mais tarde).
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ <literal>hibernate.properties</literal> é o caminho mais facil
+ se você quer começar mais rápido.
+ </para>
+
+ <para>
+ O <literal>Configuration</literal> é entendido como um objeto startup-time,
+ é descartado uma vez que a <literal>SessionFactory</literal> é criada.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-sessionfactory">
+ <title>Obtendo uma SessionFactory</title>
+
+ <para>
+ Quando todos os mapeamentos têm sido analisados pelo <literal>Configuration</literal>,
+ a aplicação deve obter uma factory para as instâncias da <literal>Session</literal>.
+ O objetivo desta factory é ser compartilhado por todas as threads da aplicação:
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sessions = cfg.buildSessionFactory();]]></programlisting>
+
+ <para>
+ Hibernate permite sua aplicação instanciar mais do que uma
+ <literal>SessionFactory</literal>. Isto é útil se você está usando mais
+ do que um banco de dados.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-hibernatejdbc" revision="1">
+ <title>Conexões JDBC</title>
+
+ <para>
+ Normalmente, você quer mandar criar a <literal>SessionFactory</literal> criar um
+ pool de conexões JDBC para você. Se você seguir essa abordagem, a abertura de uma
+ <literal>Session</literal> é tão simples quanto:
+
+ </para>
+
+ <programlisting><![CDATA[Session session = sessions.openSession(); // open a new Session]]></programlisting>
+
+ <para>
+ Assim que você fizer algo que requer o acesso ao banco de dados, uma
+ conexão JDBC será obtida do pool.
+ </para>
+
+ <para>
+ Para esse trabalho, nós necessitamos passar algumas propriedades da conexão JDBC
+ para o Hibernate. Todos os nomes de propriedades Hibernate e semânticas são definidas
+ <literal>org.hibernate.cfg.Environment</literal>. Nós iremos descrever agora
+ o mais importantes configurações de conexão JDBC.
+ </para>
+
+ <para>
+ O Hibernate obterá conexões( e pool) usando <literal>java.sql.DriverManager</literal>
+ se você determinar as seguintes propriedades:
+ </para>
+
+ <table frame="topbot">
+ <title>Propriedades JDBC Hibernate</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nome da Propriedade</entry>
+ <entry>Propósito</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.connection.driver_class</literal>
+ </entry>
+ <entry>
+ <emphasis>Classe driver jdbc</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.url</literal>
+ </entry>
+ <entry>
+ <emphasis>URL jdbc</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.username</literal>
+ </entry>
+ <entry>
+ <emphasis>Usuário do banco de dados</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.password</literal>
+ </entry>
+ <entry>
+ <emphasis>Senha do usuário do banco de dados</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.pool_size</literal>
+ </entry>
+ <entry>
+ <emphasis>Número máximo de connecxões no pool</emphasis>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ O algoritmo de pool de conexões do próprio Hibernate entretanto é completamente
+ rudimentar. A intenção dele e ajudar a iniciar e <emphasis>não para usar em um
+ sistema de produção</emphasis> ou até para testar desempenho. Você deveria usar
+ uma ferramente de pool de terceiros para conseguir melhor desempenho e estabilidade.
+ Apenas especifique a propriedade <literal>hibernate.connection.pool_size</literal>
+ com a definição do pool de conexões. Isto irá desligar o pool interno do Hibernate.
+ Por exemplo, você pode gostar de usar C3P0.
+ </para>
+
+ <para>
+ O C3P0 é um pool conexão JDBC de código aberto distribuído junto com
+ Hibernate no diretório <literal>lib</literal>. O Hibernate usará o
+ <literal>C3P0ConnectionProvider</literal> para o pool de conexão se
+ você configurar a propriedade <literal>hibernate.c3p0.*</literal>. Se você
+ gostar de usar Proxool consulte ao pacote <literal>hibernate.properties</literal>
+ e o web site do Hibernate para mais informações.
+ </para>
+
+ <para>
+ Aqui é um exemplo de arquivo <literal>hibernate.properties</literal> para C3P0:
+ </para>
+
+ <programlisting id="c3p0-configuration" revision="1"><![CDATA[hibernate.connection.driver_class = org.postgresql.Driver
+hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
+hibernate.connection.username = myuser
+hibernate.connection.password = secret
+hibernate.c3p0.min_size=5
+hibernate.c3p0.max_size=20
+hibernate.c3p0.timeout=1800
+hibernate.c3p0.max_statements=50
+hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
+
+ <para>
+ Para usar dentro de um servidor de aplicação, você deve configurar
+ o Hibernate para obter conexões de um application server
+ <literal>Datasource</literal> registrado no JNDI. Você necessitará
+ determinar pelo menos uma das seguintes propriedades:
+ </para>
+
+ <table frame="topbot">
+ <title>Propriedades do Datasource do Hibernate</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nome da Propriedade</entry>
+ <entry>Propósito</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.connection.datasource</literal>
+ </entry>
+ <entry>
+ <emphasis>Nome datasource JNDI</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.url</literal>
+ </entry>
+ <entry>
+ <emphasis>URL do fornecedor JNDI</emphasis> (opcional)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.class</literal>
+ </entry>
+ <entry>
+ <emphasis>Classe do JNDI <literal>InitialContextFactory</literal></emphasis> (opcional)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.username</literal>
+ </entry>
+ <entry>
+ <emphasis>Usuário do banco de dados</emphasis> (opcional)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.password</literal>
+ </entry>
+ <entry>
+ <emphasis>Senha do usuário do banco de dados</emphasis> (opcional)
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Eis um exemplo de arquivo <literal>hibernate.properties</literal> para
+ um servidor de aplicação fornecedor de datasources JNDI:
+ </para>
+
+ <programlisting><![CDATA[hibernate.connection.datasource = java:/comp/env/jdbc/test
+hibernate.transaction.factory_class = \
+ org.hibernate.transaction.JTATransactionFactory
+hibernate.transaction.manager_lookup_class = \
+ org.hibernate.transaction.JBossTransactionManagerLookup
+hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
+
+ <para>
+ Conexões JDBC obtidas de um datasource JNDI irão automaticamente irão participar
+ das transações gerenciadas pelo container no servidor de aplicação.
+ </para>
+
+ <para>
+ Arbitrariamente as propriedades de conexão podem ser acrescentandas ao
+ "<literal>hibernate.connnection</literal>" ao nome da propriedade. Por exemplo,
+ você deve especificar o <literal>charSet</literal> usando <literal>hibernate.connection.charSet</literal>.t.
+ </para>
+
+ <para>
+ Você pode definir sua própria estratégia de plugin para obter conexões JDBC implementando
+ a interface <literal>org.hibernate.connection.ConnectionProvider</literal>. Você pode
+ escolher uma implementação customizada setando <literal>hibernate.connection.provider_class</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-optional" revision="1">
+ <title>Propriedades opcionais de configuração</title>
+
+ <para>
+ Há um grande número de outras propriedades que controlam o comportamento do Hibernate
+ em tempo de execução. Todos são opcionais e tem valores default lógicos.
+ </para>
+
+ <para>
+ <emphasis>Aviso: algumas destas propriedades são somente a "nível de sistema".</emphasis>
+ Propriedades nível de sistema podem ser determinados somente via <literal>java -Dproperty=value</literal>
+ ou <literal>hibernate.properties</literal>. Elas <emphasis>não</emphasis>podem ser
+ configuradas por outras técnicas descritas abaixo.
+ </para>
+
+ <table frame="topbot" id="configuration-optional-properties" revision="8">
+ <title>Hibernate Configuration Properties</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nome da Propriedade</entry>
+ <entry>Propósito</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.dialect</literal>
+ </entry>
+ <entry>
+ O nome da classe de um <literal>Dialeto</literal>
+ que permite o Hibernate gerar SQL otimizado para um banco de
+ dados relacional em particular.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>full.classname.of.Dialect</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.show_sql</literal>
+ </entry>
+ <entry>
+ Escreve todas as instruções SQL no console. Esta é uma alternativa
+ a configurar a categoria de log <literal>org.hibernate.SQL</literal>
+ para <literal>debug</literal>.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.format_sql</literal>
+ </entry>
+ <entry>
+ Imprime o SQL formatado no log e console.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_schema</literal>
+ </entry>
+ <entry>
+ Qualifica no sql gerado, os nome das tabelas sem qualificar
+ com schena/tablespace dado
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>SCHEMA_NAME</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_catalog</literal>
+ </entry>
+ <entry>
+ Qualifica no sql gerado, os nome das tabelas sem qualificar
+ com catálogo dado
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>CATALOG_NAME</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.session_factory_name</literal>
+ </entry>
+ <entry>
+ O <literal>SessionFactory</literal> irá automaticamente
+ se ligar a este nome no JNDI depois de ter sido criado.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>jndi/composite/name</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.max_fetch_depth</literal>
+ </entry>
+ <entry>
+ Estabelece a "profundidade" máxima para árvore outer join fetch
+ para associações finais únicas(one-to-one,many-to-one).
+ Um <literal>0</literal> desativa por default a busca outer join.
+ <para>
+ <emphasis role="strong">eg.</emphasis>
+ Valores recomendados entre<literal>0</literal> e <literal>3</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_batch_fetch_size</literal>
+ </entry>
+ <entry>
+ Determina um tamanho default para busca de associações em lotes do Hibernate
+ <para>
+ <emphasis role="strong">eg.</emphasis>
+ Valores recomendados <literal>4</literal>, <literal>8</literal>,
+ <literal>16</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_entity_mode</literal>
+ </entry>
+ <entry>
+ Determina um modo default para representação de entidades
+ para todas as sessões abertas desta <literal>SessionFactory</literal>
+ <para>
+ <literal>dynamic-map</literal>, <literal>dom4j</literal>,
+ <literal>pojo</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.order_updates</literal>
+ </entry>
+ <entry>
+ Força o Hibernate a ordenar os updates SQL pelo valor da chave
+ primária dos itens a serem atualizados. Isto resultará em menos
+ deadlocks nas transações em sistemas altamente concorrente.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.generate_statistics</literal>
+ </entry>
+ <entry>
+ If enabled, Hibernate will collect statistics useful for
+ performance tuning.
+ Se habilitado, o Hibernate coletará estatísticas úties
+ para performance tuning dos bancos.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.use_identifer_rollback</literal>
+ </entry>
+ <entry>
+ Se habilitado, propriedades identificadoras geradas
+ serão zeradas para os valores default quando os
+ objetos forem apagados.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.use_sql_comments</literal>
+ </entry>
+ <entry>
+ Se ligado, o Hibernate irá gerar comentários dentro do SQL,
+ para facilitar o debugging, o valor default é <literal>false</literal>.
+ <para>
+ <emphasis role="strong">eg.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-jdbc-properties" revision="8">
+ <title>JDBC Hibernate e Propriedades de Conexão</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nome da Propriedade</entry>
+ <entry>Propósito</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.fetch_size</literal>
+ </entry>
+ <entry>
+ Um valor maior que zero determina o tamanho do fetch
+ do JDBC( chamadas <literal>Statement.setFetchSize()</literal>).
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.batch_size</literal>
+ </entry>
+ <entry>
+ Um valor maior que zero habilita uso de batch updates JDBC2 pelo Hibernate.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ valores recomentados entre <literal>5</literal> e <literal>30</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.batch_versioned_data</literal>
+ </entry>
+ <entry>
+ Sete esta propriedade como <literal>true</literal> se seu driver JDBC retorna
+ o número correto de linhas no <literal>executeBatch()</literal> ( É usualmente
+ seguro tornar esta opção ligada). O Hibernate então irá usar betched DML
+ para automaticamente versionar dados. <literal>false</literal> por default.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.factory_class</literal>
+ </entry>
+ <entry>
+ Escolher um <literal>Batcher</literal> customizado. Muitas
+ aplicações não irão necessitar desta propriedade de configuração
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>classname.of.BatcherFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.use_scrollable_resultset</literal>
+ </entry>
+ <entry>
+ Habilita o uso de JDBC2 scrollable resultsets pelo Hibernate.
+ Essa propriedade somente é necessaria quando se usa Conexeções
+ JDBC providas pelo usuário, caso contrário o Hibernate os os
+ metadados da conexão.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.use_streams_for_binary</literal>
+ </entry>
+ <entry>
+ Use streams para escrever/ler tipos <literal>binary</literal>
+ ou <literal>serializable</literal> para/a o JDBC( propriedade a nível de sistema).
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.use_get_generated_keys</literal>
+ </entry>
+ <entry>
+ Possibilita o uso <literal>PreparedStatement.getGeneratedKeys()</literal>
+ do JDBC3 para recuperar chaves geradas nativamente depois da inserçãp.
+ Requer driver JDBC3+ e JRE1.4+, determine para false se seu driver tem
+ problemas com gerador de indentificadores Hibernate. Por default, tente
+ determinar o driver capaz de usar metadados da conexão.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.provider_class</literal>
+ </entry>
+ <entry>
+ O nome da classe de um <literal>ConnectionProvider</literal> personalizado
+ o qual proverá conexões JDBC para o Hibernate.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>classname.of.ConnectionProvider</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.isolation</literal>
+ </entry>
+ <entry>
+ Determina o nível de isolamento de uma transação JDBC.
+ Verifique <literal>java.sql.Connection</literal> para valores
+ siginificativos mas note que a maior parte dos bancos de dados
+ não suportam todos os níveis de isolamento.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>1, 2, 4, 8</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.autocommit</literal>
+ </entry>
+ <entry>
+ Habilita autocommit para conexões no pool JDBC( não recomendado).
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.release_mode</literal>
+ </entry>
+ <entry>
+ Especifica quando o Hibernate deve liberar conexões JDBC. Por default,
+ uma conexão JDBC é retida até a sessão está explicitamente fechada
+ ou desconectada. Para um datasource JTA do servidor de aplicação, você deve
+ usar <literal>after_statement</literal> para forçar s liberação da conexões
+ depois de todas as chamadas JDBC. Para uma conexão não-JTA, freqüentemente
+ faz sentido liberar a conexão ao fim de cada transação, usando
+ <literal>after_transaction</literal>. <literal>auto</literal> escolheremos
+ <literal>after_statement</literal> para as estratégias de transaçãoes JTA e CMT
+ e <literal>after_transaction</literal> para as estratégias de transação JDBC
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>auto</literal> (default) | <literal>on_close</literal> |
+ <literal>after_transaction</literal> | <literal>after_statement</literal>
+ </para>
+ <para>
+ Note that this setting only affects <literal>Session</literal>s returned from
+ <literal>SessionFactory.openSession</literal>. For <literal>Session</literal>s
+ obtained through <literal>SessionFactory.getCurrentSession</literal>, the
+ <literal>CurrentSessionContext</literal> implementation configured for use
+ controls the connection release mode for those <literal>Session</literal>s.
+ See <xref linkend="architecture-current-session"/>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.<emphasis><propertyName></emphasis></literal>
+ </entry>
+ <entry>
+ Passa a propriedade JDBC <literal>propertyName</literal>
+ para <literal>DriverManager.getConnection()</literal>.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.<emphasis><propertyName></emphasis></literal>
+ </entry>
+ <entry>
+ Passar a propriedade <literal>propertyName</literal> para
+ o <literal>InitialContextFactory</literal> JNDI.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-cache-properties" revision="7">
+ <title>Propriedades de Cachê do Hibernate</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nome da Propriedade</entry>
+ <entry>Propósito</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.cache.provider_class</literal>
+ </entry>
+ <entry>
+ O nome da classe de um <literal>CacheProvider</literal> customizado.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>classname.of.CacheProvider</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_minimal_puts</literal>
+ </entry>
+ <entry>
+ Otimizar operação de cachê de segundo nível para minimizar escritas,
+ ao custo de leituras mais frequantes. Esta configuração é mais útil
+ para cachês clusterizados e, no Hibernate3, é habilitado por default
+ para implementações de cachê clusterizar.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_query_cache</literal>
+ </entry>
+ <entry>
+ Habilita a cache de consultas, Mesmo assim, consultas individuais ainda tem que ser
+ habilitadas para o cache.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_second_level_cache</literal>
+ </entry>
+ <entry>
+ May be used to completely disable the second level cache, which is enabled
+ by default for classes which specify a <literal><cache></literal>
+ mapping.
+ Pode ser usada para desabilitar completamente ocache de segundo nível,
+ o qual está habilitado por default para classes que especificam
+ um mapeamento <literal><cache></literal>.
+
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.query_cache_factory</literal>
+ </entry>
+ <entry>
+ O nome de uma classe que implementa a interface
+ <literal>QueryCache</literal> personalizada, por
+ default, um <literal>StandardQueryCache</literal>
+ criado automaticamente.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>classname.of.QueryCache</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.region_prefix</literal>
+ </entry>
+ <entry>
+ Um prefixo para usar nos nomes da área especial
+ do cachê de segundo nível.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>prefix</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_structured_entries</literal>
+ </entry>
+ <entry>
+ Forces Hibernate to store data in the second-level cache
+ in a more human-friendly format.
+ Força o Hibernate armazenar dados no cachê se segundo
+ nível em um formato mais legivel.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-transaction-properties" revision="9">
+ <title>Propriedades de Transação do Hibernate</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nome da Propriedade</entry>
+ <entry>Propósito</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.factory_class</literal>
+ </entry>
+ <entry>
+ O nome da clase de um a <literal>TransactionFactory</literal>
+ para usar com API <literal>Transaction</literal>
+ ( por default JDBCTransactionFactory).
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>classname.of.TransactionFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>jta.UserTransaction</literal>
+ </entry>
+ <entry>
+ Um nome JNDI usado pelo <literal>JTATransactionFactory</literal>
+ para obter uma <literal>UserTransaction</literal> JTA a partir
+ do servidor de aplicação.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>jndi/composite/name</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.manager_lookup_class</literal>
+ </entry>
+ <entry>
+ O nome da classe de um <literal>TransactionManagerLookup</literal>
+ – requerido quando caching a nível JVM esta habilitado ou quando
+ estivermos usando um generator hilo em um ambiente JTA.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>classname.of.TransactionManagerLookup</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.flush_before_completion</literal>
+ </entry>
+ <entry>
+ Se habilitado, a sessão será automaticamente limpa antes da fase de
+ conclusão da transação. É preferivel a gerência interna e
+ automática do contexto da sessão, veja
+ <xref linkend="architecture-current-session"/>
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.auto_close_session</literal>
+ </entry>
+ <entry>
+ Se habilitado, a sessão será automaticamente fechada após a fase de
+ conclusão da transação. É preferivel a gerência interna e
+ automática do contexto da sessão, veja
+ <xref linkend="architecture-current-session"/>
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-misc-properties" revision="10">
+ <title>Propriedades Variadas</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nome da Propriedade</entry>
+ <entry>Propósito</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.current_session_context_class</literal>
+ </entry>
+ <entry>
+ Forneçe uma estratégia (personalizada) para extensão
+ da <literal>Session</literal> "corrente". Veja
+ <xref linkend="architecture-current-session"/> para
+ mais informação sobre estratégias internas.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>jta</literal> | <literal>thread</literal> |
+ <literal>managed</literal> | <literal>custom.Class</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.query.factory_class</literal>
+ </entry>
+ <entry>
+ Escolha a implementação de análise HQL.
+ <para>
+ <emphasis role="strong">eg.</emphasis>
+ <literal>org.hibernate.hql.ast.ASTQueryTranslatorFactory</literal> or
+ <literal>org.hibernate.hql.classic.ClassicQueryTranslatorFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.query.substitutions</literal>
+ </entry>
+ <entry>
+ Mapeamento a partir de símbolos em consultas HQL para
+ símbolos SQL( símbolos devem ser funções ou nome literais
+ , por exemplo).
+ <para>
+ <emphasis role="strong">eg.</emphasis>
+ <literal>hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.hbm2ddl.auto</literal>
+ </entry>
+ <entry>
+ Automaticamente valida ou exporta schema DDL para o banco de
+ dados quando o <literal>SessionFactory</literal> é criads.
+ Com <literal>create-drop</literal>, o schema do banco de dados
+ será excluido quando a <literal>create-drop</literal> for
+ fechada esplicitamente.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>validate</literal> | <literal>update</literal> |
+ <literal>create</literal> | <literal>create-drop</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cglib.use_reflection_optimizer</literal>
+ </entry>
+ <entry>
+ Habilita o uso de CGLIB em vez de reflexão em tempo de execução
+ ( propriedade a nível de sistema). Reflexão pode algumas vezes ser ú
+ til quando controlar erros, note que o Hibernate sempre irá requerer a CGLIB
+ mesmo se você desligar o otimizador. Você não pode determinar esta
+ propriedade no hibernate.cfg.xml.
+ <para>
+ <emphasis role="strong">Ex.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="configuration-optional-dialects" revision="1">
+ <title>Dialetos SQL</title>
+
+ <para>
+ Você deve sempre determinar a propriedade <literal>hibernate.dialect</literal>
+ para a subclasse de <literal>org.hibernate.dialect.Dialect</literal> correta de seu
+ banco de dados. Se você especificar um dialeto, Hibernate usará defaults lógicos
+ para qualquer um das outras propriedades listadas abaixo, reduzindo o esforço de
+ especificá-los manualmente.
+ </para>
+
+ <table frame="topbot" id="sql-dialects" revision="2">
+ <title>Hibernate SQL Dialects (<literal>hibernate.dialect</literal>)</title>
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>RDBMS</entry>
+ <entry>Dialect</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>DB2</entry> <entry><literal>org.hibernate.dialect.DB2Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>DB2 AS/400</entry> <entry><literal>org.hibernate.dialect.DB2400Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>DB2 OS390</entry> <entry><literal>org.hibernate.dialect.DB2390Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>PostgreSQL</entry> <entry><literal>org.hibernate.dialect.PostgreSQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL</entry> <entry><literal>org.hibernate.dialect.MySQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL with InnoDB</entry> <entry><literal>org.hibernate.dialect.MySQLInnoDBDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL with MyISAM</entry> <entry><literal>org.hibernate.dialect.MySQLMyISAMDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Oracle (any version)</entry> <entry><literal>org.hibernate.dialect.OracleDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Oracle 9i/10g</entry> <entry><literal>org.hibernate.dialect.Oracle9Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>Sybase</entry> <entry><literal>org.hibernate.dialect.SybaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Sybase Anywhere</entry> <entry><literal>org.hibernate.dialect.SybaseAnywhereDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Microsoft SQL Server</entry> <entry><literal>org.hibernate.dialect.SQLServerDialect</literal></entry>
+ </row>
+ <row>
+ <entry>SAP DB</entry> <entry><literal>org.hibernate.dialect.SAPDBDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Informix</entry> <entry><literal>org.hibernate.dialect.InformixDialect</literal></entry>
+ </row>
+ <row>
+ <entry>HypersonicSQL</entry> <entry><literal>org.hibernate.dialect.HSQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Ingres</entry> <entry><literal>org.hibernate.dialect.IngresDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Progress</entry> <entry><literal>org.hibernate.dialect.ProgressDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Mckoi SQL</entry> <entry><literal>org.hibernate.dialect.MckoiDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Interbase</entry> <entry><literal>org.hibernate.dialect.InterbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Pointbase</entry> <entry><literal>org.hibernate.dialect.PointbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>FrontBase</entry> <entry><literal>org.hibernate.dialect.FrontbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Firebird</entry> <entry><literal>org.hibernate.dialect.FirebirdDialect</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-outerjoin" revision="4">
+ <title>Recuperação por união externa (Outer Join Fetching)</title>
+
+ <para>
+ Se seu banco de dados suporta Recuperação por união externa (Outer Join Fetching) no estilo ANSI,
+ Oracle ou Sybase, A recuperação por união externa (Outer Join Fetching) frequentemente aumentará
+ o desempenho limitando o número de chamadas (round trips) ao banco de dados( ao custo de
+ possivelmente mais trabalho desempenhado pelo próprio banco de dados). A recuperação por
+ união externa (Outer Join Fetching)permite um gráfico completo de objetos conectados
+ por muitos-para-um, um-para-muitos, muitos-para-muitos e associações um-para-um para ser
+ recuperadas em um simples instrução SQL SELECT .
+
+ </para>
+
+ <para>
+ A recuperação por união externa (Outer Join Fetching) pode ser desabilitado
+ <emphasis>globalmente</emphasis> setando a propriedade
+ <literal>hibernate.max_fetch_depth</literal> para <literal>0</literal>.
+ Uma valor 1 ou maior habilita o outer join fetching para associações um-para-um
+ e muitos-para-umos cujos quais tem sido mapeado com <literal>fetch="join"</literal>.
+ </para>
+
+ <para>
+ Veja <xref linkend="performance-fetching"/> para mais informações.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-binarystreams" revision="1">
+ <title>Fluxos Binários (Binary Streams)</title>
+
+ <para>
+ O Oracle limita o tamanho de arrays de <literal>byte</literal> que pode ser
+ passado para/de o driver JDBC. Se você desejar usar grandes instâncias de
+ tipos <literal>binary</literal> ou <literal>serializable</literal>, você
+ deve habilitar <literal>hibernate.jdbc.use_streams_for_binary</literal>.
+ <emphasis>Essa é uma configuração que só pode ser feita a nível de sistema.</emphasis>
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-cacheprovider" revision="2">
+ <title>Cachê de segundo nível e query</title>
+
+ <para>
+ As propriedades prefixadas pelo <literal>hibernate.cache</literal>
+ permite você usar um sistema de cachê de segundo nível
+ em um processo executado em clustercom Hibernate.
+ Veja <xref linkend="performance-cache"/> para mais detalhes.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-querysubstitution">
+ <title>Substituições na Linguagem de Consulta</title>
+
+ <para>
+ Você pode definir novos símbolos de consulta Hibernate usando
+ <literal>hibernate.query.substitutions</literal>.
+ Por exemplo:
+ </para>
+
+ <programlisting>hibernate.query.substitutions true=1, false=0</programlisting>
+
+ <para>
+ Faria com que os símbolos <literal>true</literal> e <literal>false</literal>
+ passasem a ser traduzidos para literais inteiro no SQL gerado.
+ </para>
+
+ <programlisting>hibernate.query.substitutions toLowercase=LOWER</programlisting>
+
+ <para>
+ permitirá você renomear a função <literal>LOWER</literal> no SQL.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-statistics" revision="2">
+ <title>Estatísticas do Hibernate</title>
+
+ <para>
+ If you enable <literal>hibernate.generate_statistics</literal>, Hibernate will
+ expose a number of metrics that are useful when tuning a running system via
+ <literal>SessionFactory.getStatistics()</literal>. Hibernate can even be configured
+ to expose these statistics via JMX. Read the Javadoc of the interfaces in
+ <literal>org.hibernate.stats</literal> for more information.
+
+ Se você habilitar <literal>hibernate.generate_statistics</literal>, o Hibernate
+ exibirá um número de métricas bastante útil ao ajustar um sistema via
+ <literal>SessionFactory.getStatistics()</literal>. O Hibernate pode até ser
+ configurado para exibir essas estatísticas via JMX. Leia o Javadoc da interface
+ <literal>org.hibernate.stats</literal> para mais informações.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="configuration-logging">
+ <title>Logging</title>
+
+ <para>
+ Hibernate registra vários eventos usando Apache commons-logging.
+ </para>
+
+ <para>
+ O serviço commons-logging direcionará a saída para o Apache Log4j
+ ( se você incluir <literal>log4j.jar</literal>r no seu classpath) ou
+ JDK1.4 logging( se estiver em uso JDK1.4 ou maior). Você pode fazer o
+ download do Log4j a partir de <literal>http://jakarta.apache.org</literal>.
+ Para usar Log4j você necessitará colocar um arquivo
+ <literal>log4j.properties</literal> no seu classpath, um exemplo de arquivo
+ de propriedades é distribuído com o Hibernate no diretório
+ <literal>src/</literal>.
+
+ </para>
+
+ <para>
+ We strongly recommend that you familiarize yourself with Hibernate's log
+ messages. A lot of work has been put into making the Hibernate log as
+ detailed as possible, without making it unreadable. It is an essential
+ troubleshooting device. The most interesting log categories are the
+ following:
+
+ Nós recomendamos enfaticamente que você se familiarize-se com mensagens de
+ log do Hibernate. Uma parte do trabalho tem sido posto em fazer o log
+ Hibernate tão detalhado quanto possível, sem fazê-lo ilegível.
+ É um essencial dispositivos de controle de erros. As categorias de log
+ mais interessantes são as seguintes:
+ </para>
+
+ <table frame="topbot" id="log-categories" revision="2">
+ <title>Categorias de Log do Hibernate</title>
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>Categoria</entry>
+ <entry>Função</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>org.hibernate.SQL</literal></entry>
+ <entry>Registra todas as instruções SQL DML a medida que elas são executadas</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.type</literal></entry>
+ <entry>Registra todos os parâmetros JDBC</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.tool.hbm2ddl</literal></entry>
+ <entry>Registra todas as instruções SQL DDL a medida que elas são executadas</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.pretty</literal></entry>
+ <entry>
+ Log the state of all entities (max 20 entities) associated
+ with the session at flush time
+ Registra o estado de todas as entidades (máximo 20 entidades)
+ associadas a session no momento da limpeza (flush).
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.cache</literal></entry>
+ <entry>Registra todas as atividades de cachê de segundo nível</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction</literal></entry>
+ <entry>Registra atividades relacionada a transação</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.jdbc</literal></entry>
+ <entry>Registra todas as requisições de recursos JDBC</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.hql.ast.AST</literal></entry>
+ <entry>
+ Registra instruções SQL e HQL durante a análise da consultas
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.secure</literal></entry>
+ <entry>Registra todas as requisições de autorização JAAS</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate</literal></entry>
+ <entry>
+ Registra tudo ( uma parte das informações, mas muito
+ útil para controle de erros )
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Quando desenvolver aplicações com Hibernate, você deve quase sempre trabalhar com
+ debug <literal>debug</literal> para a categoria <literal>org.hibernate.SQL</literal>,
+ ou, alternativamente, a com a propriedade <literal>hibernate.show_sql</literal> habilitada.
+ </para>
+
+
+ </sect1>
+
+ <sect1 id="configuration-namingstrategy">
+ <title>Implementado uma <literal>NamingStrategy</literal></title>
+
+ <para>
+ A interface <literal>org.hibernate.cfg.NamingStrategy</literal> permite você
+ especificar um "padrão de nomeação" para objetos do banco de dados e elementos schema.
+ </para>
+
+ <para>
+ Você deve criar regras para a geração automaticamente de identificadores
+ do banco de dados a partir de identificadores Java ou para processar
+ colunas "computadas" e nomes de tabelas dado o arquivo de mapeamento
+ para nomes "físicos" de tabelas e colunas. Esta característica ajuda a
+ reduzir a verbosidade do documento de mapeamento, eliminando interferências
+ repetitivas( <literal>TBL_</literal>prefixos, por exemplo). A estratégia
+ default usada pelo Hibernate é completamente mínima.
+ </para>
+
+ <para>
+ Você pode especificar uma estratégia diferente ao chamar
+ <literal>Configuration.setNamingStrategy()</literal> antes de adicionar
+ os mapeamentos:
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration()
+ .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
+ .addFile("Item.hbm.xml")
+ .addFile("Bid.hbm.xml")
+ .buildSessionFactory();]]></programlisting>
+
+ <para>
+ <literal>org.hibernate.cfg.ImprovedNamingStrategy</literal> é uma estratégia
+ interna que pode ser um ponto de começo útil para algumas aplicações.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-xmlconfig" revision="2">
+ <title>Arquivo de configuração XML</title>
+
+ <para>
+ Uma maneira alternativa de configuração é especificar uma configuração completa
+ em um arquivo chamado <literal>hibernate.cfg.xml</literal>. Este arquivo pode
+ ser usado como um substituto para o arquivo <literal>hibernate.properties</literal>
+ ou, se ambos estão presentes, sobrescrever propriedades.
+ </para>
+
+ <para>
+ The XML configuration file is by default expected to be in the root o
+ your <literal>CLASSPATH</literal>. Here is an example:
+ O arquivo XML de configuração é por default esperado para estar na
+ raiz do seu <literal>CLASSPATH</literal>. Veja um exemplo:
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <!-- a SessionFactory instance listed as /jndi/name -->
+ <session-factory
+ name="java:hibernate/SessionFactory">
+
+ <!-- properties -->
+ <property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
+ <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
+ <property name="show_sql">false</property>
+ <property name="transaction.factory_class">
+ org.hibernate.transaction.JTATransactionFactory
+ </property>
+ <property name="jta.UserTransaction">java:comp/UserTransaction</property>
+
+ <!-- mapping files -->
+ <mapping resource="org/hibernate/auction/Item.hbm.xml"/>
+ <mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
+
+ <!-- cache settings -->
+ <class-cache class="org.hibernate.auction.Item" usage="read-write"/>
+ <class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
+ <collection-cache collection="org.hibernate.auction.Item.bids" usage="read-write"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ Como você pode ver, a vantagem deste enfoque é a externalização dos nomes dos
+ arquivos de mapeamento para configuração. O <literal>hibernate.cfg.xml</literal>
+ também é mais conveniente caso você tenha que ajustar o cache do Hibernate.
+ Note que a escolha é sua em usar <literal>hibernate.properties</literal> ou
+ <literal>hibernate.cfg.xml</literal>, ambos são equivalente, à exceção dos benefícios
+ acima mencionados de usar a sintaxe de XML.
+ </para>
+
+ <para>
+ Com a configuração do XML, iniciar o Hibernate é então tão simples como
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration().configure().buildSessionFactory();]]></programlisting>
+
+ <para>
+ You can pick a different XML configuration file using
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration()
+ .configure("catdb.cfg.xml")
+ .buildSessionFactory();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="configuration-j2ee" revision="1">
+ <title>Integração com servidores de aplicação J2EE</title>
+
+ <para>
+ O Hibernate tem os seguintes pontos da integração para o infraestrutura de J2EE:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>DataSources gerenciados pelo container</emphasis>: O Hibernate pode
+ usar conexões JDBC gerenciadas pelo Container e fornecidas pela JNDI. Geralmente,
+ um <literal>TransactionManager</literal> compatível com JTA e um
+ <literal>ResourceManager</literal> cuidam do gerenciamento da transação ( CMT ),
+ especialmente em transações distribuídas manipuladas através de vários DataSources.
+ Naturalmente, você também pode demarcar os limites das transações programaticamente (BMT)
+ ou você poderia querer usar a API opcional do Hibernate <literal>Transaction</literal>
+ para esta manter seu código portável.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Ligação (binding) automática a JNDI</emphasis>: O Hibernate pode
+ associar sua <literal>SessionFactory</literal> a JNDI depois de iniciado.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Ligação (binding) Session na JTA:</emphasis>
+ A <literal>Session</literal> do Hibernate pode automaticamente ser ligada
+ ao escopo da transações JTA. Simplesmente localizando a <literal>SessionFactory</literal>
+ da JNDI e obtendo a<literal>Session</literal> corrente. Deixe o Hibernate cuidar
+ da limpeza e encerramento da <literal>Session</literal> quando as transações JTA
+ terminarem. A Demarcação de transação pode ser declarativa (CMT) ou
+ programática(BMT/Transação do usuário).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>JMX deployment:</emphasis> Se você usa um JMX servidor de
+ aplicações capaz (ex. Jboss AS), você pode fazer a instação do Hibernate
+ como um Mbean controlado. Isto evita ter que iniciar uma linha de
+ código para construir sua <literal>SessionFactory</literal> de uma
+ <literal>Configuration</literal>. O container iniciará seu
+ <literal>HibernateService</literal>, e idealmente também cuidará
+ das dependências de serviços (DataSources, têm que estar disponíveis
+ antes do Hibernate iniciar, etc.).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Dependendo em seu ambiente, você poderia ter que ajustar a opção de configuração
+ <literal>hibernate.connection.aggressive_release</literal> para verdadeiro ( true ),
+ se seu servidor de aplicações lançar exeções "retenção de conecção".
+ </para>
+
+ <sect2 id="configuration-optional-transactionstrategy" revision="3">
+ <title>Configuração de estratégia de transação</title>
+
+ <para>
+ A API Hibernate <literal>Session</literal> é independente de qualquer sistema de
+ demarcação de transação em sua arquitetura. Se você deixar o Hibernate usar
+ a JDBC diretamente, através de um pool de conexões, você pode inicializar e
+ encerrar suas transações chamando a API JDBC. Se você rodar em um servidor de
+ aplicações J2EE, você poderá usar transações controladas por beans e chamar
+ a API JTA e <literal>UserTransaction</literal> quando necessário.
+
+ </para>
+
+ <para>
+ Para manter seu código portável entre estes dois ( e outros ) ambientes, recomendamos
+ a API Hibernate <literal>Transaction</literal>, que envolve e esconde o sistema subjacente.
+ Você tem que especificar um classe construtora para <literal>Transaction</literal> instanciar
+ ajustando a propriedade de configuração do <literal>hibernate.transaction.factory_class</literal>.
+
+ </para>
+
+ <para>
+ Existem três escolhas (internas) padrões:
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term><literal>org.hibernate.transaction.JDBCTransactionFactory</literal></term>
+ <listitem>
+ <para>delegada as transações (JDBC)a bases de dados (Padrão)</para>
+
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>org.hibernate.transaction.JTATransactionFactory</literal></term>
+ <listitem>
+ <para>
+ delegada a transação a um container gerenciador se a transação
+ existente estiver de acordo neste contexto (ex: método bean sessão EJB),
+ se não uma nova transação é iniciada e uma transação controlado por
+ um bean é usada.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>org.hibernate.transaction.CMTTransactionFactory</literal></term>
+ <listitem>
+ <para>delega para um container gerenciador de transações JTA</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Você também pode definir suas próprias estratégias de transação ( para um serviço de
+ transação CORBA por exemplo).
+ </para>
+
+ <para>
+ Algumas características no Hibernate (ex., o cache de segundo nível, sessões contextuais
+ com JTA, etc.) requerem acesso a JTA <literal>TransactionManager</literal> em um ambiente
+ controlado. Em um servidor de aplicação você tem que especificar como o Hibernate pode
+ obter uma referência para a <literal>TransactionManager</literal>, pois o J2EE não
+ padronize um mecanismo simples :
+ </para>
+
+ <table frame="topbot" id="jtamanagerlookup" revision="1">
+ <title>Gerenciadores de transações JTA</title>
+ <tgroup cols="2">
+ <colspec colwidth="2.5*"/>
+ <colspec colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Transaction Factory</entry>
+ <entry align="center">Application Server</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>org.hibernate.transaction.JBossTransactionManagerLookup</literal></entry>
+ <entry align="center">JBoss</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.WeblogicTransactionManagerLookup</literal></entry>
+ <entry align="center">Weblogic</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.WebSphereTransactionManagerLookup</literal></entry>
+ <entry align="center">WebSphere</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</literal></entry>
+ <entry align="center">WebSphere 6</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.OrionTransactionManagerLookup</literal></entry>
+ <entry align="center">Orion</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.ResinTransactionManagerLookup</literal></entry>
+ <entry align="center">Resin</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.JOTMTransactionManagerLookup</literal></entry>
+ <entry align="center">JOTM</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.JOnASTransactionManagerLookup</literal></entry>
+ <entry align="center">JOnAS</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.JRun4TransactionManagerLookup</literal></entry>
+ <entry align="center">JRun4</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.BESTransactionManagerLookup</literal></entry>
+ <entry align="center">Borland ES</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-jndi" revision="3">
+ <title><literal>SessionFactory</literal> ligada a JNDI</title>
+
+ <para>
+ Uma <literal>SessionFactory</literal> de Hibernate ligada a JNDI pode simplificar
+ a localização da fabrica e a criação de novas <literal>Session</literal>s.
+ Observe que isto não relacionado a um <literal>Datasource</literal> ligado
+ a JNDI, simplemente ambos usam o mesmo registro!
+ </para>
+
+ <para>
+ If you wish to have the <literal>SessionFactory</literal> bound to a JNDI namespace, specify
+ a name (eg. <literal>java:hibernate/SessionFactory</literal>) using the property
+ <literal>hibernate.session_factory_name</literal>. If this property is omitted, the
+ <literal>SessionFactory</literal> will not be bound to JNDI. (This is especially useful in
+ environments with a read-only JNDI default implementation, e.g. Tomcat.)
+ </para>
+
+ <para>
+ When binding the <literal>SessionFactory</literal> to JNDI, Hibernate will use the values of
+ <literal>hibernate.jndi.url</literal>, <literal>hibernate.jndi.class</literal> to instantiate
+ an initial context. If they are not specified, the default <literal>InitialContext</literal>
+ will be used.
+ </para>
+
+ <para>
+ Hibernate will automatically place the <literal>SessionFactory</literal> in JNDI after
+ you call <literal>cfg.buildSessionFactory()</literal>. This means you will at least have
+ this call in some startup code (or utility class) in your application, unless you use
+ JMX deployment with the <literal>HibernateService</literal> (discussed later).
+ </para>
+
+ <para>
+ If you use a JNDI <literal>SessionFactory</literal>, an EJB or any other class may
+ obtain the <literal>SessionFactory</literal> using a JNDI lookup.
+ </para>
+
+ <para>
+ We recommend that you bind the <literal>SessionFactory</literal> to JNDI in
+ a managend environment and use a <literal>static</literal> singleton otherwise.
+ To shield your application code from these details, we also recommend to hide the
+ actual lookup code for a <literal>SessionFactory</literal> in a helper class,
+ such as <literal>HibernateUtil.getSessionFactory()</literal>. Note that such a
+ class is also a convenient way to startup Hibernate—see chapter 1.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-j2ee-currentsession" revision="4">
+ <title>Current Session context management with JTA</title>
+
+ <para>
+ The easiest way to handle <literal>Session</literal>s and transactions is
+ Hibernates automatic "current" <literal>Session</literal> management.
+ See the discussion of <xref linkend="architecture-current-session">current sessions</xref>.
+ Using the <literal>"jta"</literal> session context, if there is no Hibernate
+ <literal>Session</literal> associated with the current JTA transaction, one will
+ be started and associated with that JTA transaction the first time you call
+ <literal>sessionFactory.getCurrentSession()</literal>. The <literal>Session</literal>s
+ retrieved via <literal>getCurrentSession()</literal> in <literal>"jta"</literal> context
+ will be set to automatically flush before the transaction completes, close
+ after the transaction completes, and aggressively release JDBC connections
+ after each statement. This allows the <literal>Session</literal>s to
+ be managed by the life cycle of the JTA transaction to which it is associated,
+ keeping user code clean of such management concerns. Your code can either use
+ JTA programmatically through <literal>UserTransaction</literal>, or (recommended
+ for portable code) use the Hibernate <literal>Transaction</literal> API to set
+ transaction boundaries. If you run in an EJB container, declarative transaction
+ demarcation with CMT is preferred.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-j2ee-jmx" revision="1">
+ <title>JMX deployment</title>
+
+ <para>
+ The line <literal>cfg.buildSessionFactory()</literal> still has to be executed
+ somewhere to get a <literal>SessionFactory</literal> into JNDI. You can do this
+ either in a <literal>static</literal> initializer block (like the one in
+ <literal>HibernateUtil</literal>) or you deploy Hibernate as a <emphasis>managed
+ service</emphasis>.
+ </para>
+
+ <para>
+ Hibernate is distributed with <literal>org.hibernate.jmx.HibernateService</literal>
+ for deployment on an application server with JMX capabilities, such as JBoss AS.
+ The actual deployment and configuration is vendor specific. Here is an example
+ <literal>jboss-service.xml</literal> for JBoss 4.0.x:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<server>
+
+<mbean code="org.hibernate.jmx.HibernateService"
+ name="jboss.jca:service=HibernateFactory,name=HibernateFactory">
+
+ <!-- Required services -->
+ <depends>jboss.jca:service=RARDeployer</depends>
+ <depends>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>
+
+ <!-- Bind the Hibernate service to JNDI -->
+ <attribute name="JndiName">java:/hibernate/SessionFactory</attribute>
+
+ <!-- Datasource settings -->
+ <attribute name="Datasource">java:HsqlDS</attribute>
+ <attribute name="Dialect">org.hibernate.dialect.HSQLDialect</attribute>
+
+ <!-- Transaction integration -->
+ <attribute name="TransactionStrategy">
+ org.hibernate.transaction.JTATransactionFactory</attribute>
+ <attribute name="TransactionManagerLookupStrategy">
+ org.hibernate.transaction.JBossTransactionManagerLookup</attribute>
+ <attribute name="FlushBeforeCompletionEnabled">true</attribute>
+ <attribute name="AutoCloseSessionEnabled">true</attribute>
+
+ <!-- Fetching options -->
+ <attribute name="MaximumFetchDepth">5</attribute>
+
+ <!-- Second-level caching -->
+ <attribute name="SecondLevelCacheEnabled">true</attribute>
+ <attribute name="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>
+ <attribute name="QueryCacheEnabled">true</attribute>
+
+ <!-- Logging -->
+ <attribute name="ShowSqlEnabled">true</attribute>
+
+ <!-- Mapping files -->
+ <attribute name="MapResources">auction/Item.hbm.xml,auction/Category.hbm.xml</attribute>
+
+</mbean>
+
+</server>]]></programlisting>
+
+ <para>
+ This file is deployed in a directory called <literal>META-INF</literal> and packaged
+ in a JAR file with the extension <literal>.sar</literal> (service archive). You also need
+ to package Hibernate, its required third-party libraries, your compiled persistent classes,
+ as well as your mapping files in the same archive. Your enterprise beans (usually session
+ beans) may be kept in their own JAR file, but you may include this EJB JAR file in the
+ main service archive to get a single (hot-)deployable unit. Consult the JBoss AS
+ documentation for more information about JMX service and EJB deployment.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/events.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/events.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/events.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/events.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,271 @@
+<chapter id="events">
+ <title>Interceptadores e Eventos</title>
+
+ <para>
+ É muito útil quando a aplicação precisa executar alguma "coisa" no momento em
+ que o Hibernate executa uma de suas ações. Isso permite a implementação de
+ certas funções genéricas, assim como permite estender as funcionalidades do
+ Hibernate
+ </para>
+
+ <sect1 id="objectstate-interceptors" revision="3">
+ <title>Interceptadores</title>
+
+ <para>
+ A interface <literal>Interceptor</literal> permite fornecer informações da session para o
+ aplicativo, permitindo ao aplicativo inspecionar e/ou manipular as propriedades de um
+ objeto persistente antes de ser salvo, atualizado, excluído ou salvo. Um dos possíveis usos é
+ gerar informações de auditoria. Por exemplo, o seguinte <literal>Interceptor</literal> seta
+ automaticamente o atributo <literal>createTimestamp</literal> quando um
+ <literal>Auditable</literal> é criada e atualiza o atributo <literal>lastUpdateTimestamp</literal>
+ quando um <literal>Auditable</literal> é atualizado.
+ </para>
+
+ <para>
+ Você pode implementar <literal>Auditable</literal> diretamente ou pode estender
+ <literal>EmptyInterceptor</literal>, sendo que a segunda é considerada a melhor opção.
+ </para>
+
+ <programlisting><![CDATA[package org.hibernate.test;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.Transaction;
+import org.hibernate.type.Type;
+
+public class AuditInterceptor extends EmptyInterceptor {
+
+ private int updates;
+ private int creates;
+ private int loads;
+
+ public void onDelete(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+ // do nothing
+ }
+
+ public boolean onFlushDirty(Object entity,
+ Serializable id,
+ Object[] currentState,
+ Object[] previousState,
+ String[] propertyNames,
+ Type[] types) {
+
+ if ( entity instanceof Auditable ) {
+ updates++;
+ for ( int i=0; i < propertyNames.length; i++ ) {
+ if ( "lastUpdateTimestamp".equals( propertyNames[i] ) ) {
+ currentState[i] = new Date();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean onLoad(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+ if ( entity instanceof Auditable ) {
+ loads++;
+ }
+ return false;
+ }
+
+ public boolean onSave(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if ( entity instanceof Auditable ) {
+ creates++;
+ for ( int i=0; i<propertyNames.length; i++ ) {
+ if ( "createTimestamp".equals( propertyNames[i] ) ) {
+ state[i] = new Date();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void afterTransactionCompletion(Transaction tx) {
+ if ( tx.wasCommitted() ) {
+ System.out.println("Creations: " + creates + ", Updates: " + updates, "Loads: " + loads);
+ }
+ updates=0;
+ creates=0;
+ loads=0;
+ }
+
+}]]></programlisting>
+
+ <para>
+ Os interceptadores podem ser aplicados em dois diferentes escopos:
+ No escopo da <literal>Session</literal> e no escopo
+ <literal>SessionFactory</literal>.
+ </para>
+
+ <para>
+ Um interceptador no escopo da <literal>Session</literal> é definido quando
+ uma sessão é aberta usando o método sobrecarregado da SessionFactory.openSession()
+ que aceita um <literal>Interceptor</literal> como parâmetro.
+ </para>
+
+ <programlisting><![CDATA[Session session = sf.openSession( new AuditInterceptor() );]]></programlisting>
+
+ <para>
+ Um interceptador no escopo da <literal>SessionFactory</literal> é definido no objeto
+ <literal>Configuration</literal> antes da <literal>SessionFactory</literal> ser instanciada.
+ Nesse caso, o interceptador fornecido será aplicado para todas as sessões abertas por aquela
+ <literal>SessionFactory</literal>; Isso apenas não ocorrerá caso seja especificado um
+ interceptador no momento em que a sessão for aberta. Um interceptador no escopo de
+ <literal>SessionFactory</literal> deve ser thread safe, tomando-se o cuidado de não
+ armazenar atributos de estado específicos da sessão, pois, provavelmente, múltiplas
+ sessões irão utilizar esse interceptador simultaneamente.
+ </para>
+
+ <programlisting><![CDATA[new Configuration().setInterceptor( new AuditInterceptor() );]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="objectstate-events" revision="4">
+ <title>Sistema de Eventos</title>
+
+ <para>
+ Se você precisa executar uma ação em determinados eventos da camada de persistência,
+ você também pode usar a arquitetura de <emphasis>event</emphasis> do Hibernate3.
+ Um evento do sistema pode ser utilizado como complemento ou em
+ substituição a um interceptador.
+ </para>
+
+ <para>
+ Essencialmente todos os métodos da interface <literal>Session</literal> possuem um evento
+ correlacionado. Se você tiver um <literal>LoadEvent</literal>, um <literal>LoadEvent</literal>,
+ etc (consulte o DTD do XML de configuração ou o pacote <literal>org.hibernate.event</literal>
+ para a lista completa dos tipos de eventos). Quando uma requisição é feita em um desses métodos,
+ a <literal>Session</literal> do hibernate gera um evento apropriado e o envia para o listener
+ de evento correspondente àquele tipo de evento. Esses listeners implementam a mesma lógica
+ que aqueles métodos, trazendo os mesmos resultados. Entretanto, você é livre para implementar
+ uma customização de um desses listeners (isto é, o <literal>LoadEvent</literal> é processado
+ pela implementação registrada da interface <literal>LoadEventListener</literal>), então sua
+ implementação vai ficar responsável por processar qualquer requisição <literal>load()</literal>
+ feita pela <literal>Session</literal>.
+ </para>
+
+ <para>
+ Para todos os efeitos esses listeners deve ser considerados singletons; ou seja, eles são
+ compartilhados entre as requisições, e assim sendo, não devem salvar nenhum estado das
+ variáveis instanciadas.
+ </para>
+
+ <para>
+ Um listener personalizado deve implementar a interface referente ao evento a ser
+ processado e/ou deve estender a classes base equivalente (ou mesmo os listeners padrões
+ usados pelo Hibernate, eles não são declarados como finais com esse objetivo). O listener
+ personalizado pode ser registrado programaticamente no objeto <literal>Configuration</literal>,
+ ou declarativamente no XML de configuração do Hibernate (o registro do listener no propertie
+ de configuração não é suportado). Aqui temos um exemplo de como carregar um listener
+ personalizado:
+ </para>
+
+ <programlisting><![CDATA[public class MyLoadListener implements LoadEventListener {
+ // this is the single method defined by the LoadEventListener interface
+ public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType)
+ throws HibernateException {
+ if ( !MySecurity.isAuthorized( event.getEntityClassName(), event.getEntityId() ) ) {
+ throw MySecurityException("Unauthorized access");
+ }
+ }
+}]]></programlisting>
+
+ <para>
+ Você também precisa adicionar uma entrada no XML de configuração do Hibernate para
+ registrar declarativamente qual listener deve se utilizado em conjunto com o listener
+ padrão:
+ </para>
+
+<programlisting><![CDATA[<hibernate-configuration>
+ <session-factory>
+ ...
+ <event type="load">
+ <listener class="com.eg.MyLoadListener"/>
+ <listener class="org.hibernate.event.def.DefaultLoadEventListener"/>
+ </event>
+ </session-factory>
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ Ou, você pode registrar o listener programaticamente:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration();
+LoadEventListener[] stack = { new MyLoadListener(), new DefaultLoadEventListener() };
+cfg.EventListeners().setLoadEventListeners(stack);]]></programlisting>
+
+ <para>
+ Listeners registrados declarativamente não compartilham da mesma instancia. Se o mesmo
+ nome da classe é utilizado em vários elementos e <literal><listener/></literal>,
+ cada um vai resultar em uma instancia separada dessa classe. Se você tem a necessidade
+ de compartilhar uma instancia de um listener entre diversos tipos de listeners você
+ deve registrar o listener programaticamente.
+
+ </para>
+
+ <para>
+ Mas porque implementar uma interface e definir o tipo específico durante a configuração?
+ Bem, um listener pode implementar vários listeners de evento. Com o tipo sendo definido
+ durante o registro, fica fácil ligar ou desligar listeners personalizados durante
+ a configuração.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-decl-security" revision="2">
+ <title>Hibernate declarative security</title>
+ <para>
+ Usually, declarative security in Hibernate applications is managed in a session facade
+ layer. Now, Hibernate3 allows certain actions to be permissioned via JACC, and authorized
+ via JAAS. This is optional functionality built on top of the event architecture.
+ </para>
+
+ <para>
+ First, you must configure the appropriate event listeners, to enable the use of JAAS
+ authorization.
+ </para>
+
+ <programlisting><![CDATA[<listener type="pre-delete" class="org.hibernate.secure.JACCPreDeleteEventListener"/>
+<listener type="pre-update" class="org.hibernate.secure.JACCPreUpdateEventListener"/>
+<listener type="pre-insert" class="org.hibernate.secure.JACCPreInsertEventListener"/>
+<listener type="pre-load" class="org.hibernate.secure.JACCPreLoadEventListener"/>]]></programlisting>
+
+ <para>
+ Note that <literal><listener type="..." class="..."/></literal> is just a shorthand
+ for <literal><event type="..."><listener class="..."/></event></literal>
+ when there is exactly one listener for a particular event type.
+ </para>
+
+ <para>
+ Next, still in <literal>hibernate.cfg.xml</literal>, bind the permissions to roles:
+ </para>
+
+ <programlisting><![CDATA[<grant role="admin" entity-name="User" actions="insert,update,read"/>
+<grant role="su" entity-name="User" actions="*"/>]]></programlisting>
+
+ <para>
+ The role names are the roles understood by your JACC provider.
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_mappings.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/example_mappings.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_mappings.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_mappings.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,678 @@
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<chapter id="example-mappings">
+ <title>Exemplo: Vários Mapeamentos</title>
+
+ <para>
+ Este capitulo mostra algums mapeamentos de associações mais complexos.
+ </para>
+
+ <sect1 id="example-mappings-emp">
+ <title>Employer/Employee</title>
+
+ <para>
+ O modelo de seguinte relacionamento entre <literal>Employer</literal> e
+ <literal>Employee</literal> utiliza uma entidade de classe atual (<literal>Employment</literal>)
+ para representar a associação. Isto é feito porque pode-ser ter mais do que um período de
+ trabalho para as duas partes envolvidas. Outros Componentes são usados para modelar
+ valores monetários e os nomes do empregado.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/EmployerEmployee.png" format="PNG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/EmployerEmployee.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ Abaixo o código de um possível mapeamento:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Employer" table="employers">
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employer_id_seq</param>
+ </generator>
+ </id>
+ <property name="name"/>
+ </class>
+
+ <class name="Employment" table="employment_periods">
+
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employment_id_seq</param>
+ </generator>
+ </id>
+ <property name="startDate" column="start_date"/>
+ <property name="endDate" column="end_date"/>
+
+ <component name="hourlyRate" class="MonetaryAmount">
+ <property name="amount">
+ <column name="hourly_rate" sql-type="NUMERIC(12, 2)"/>
+ </property>
+ <property name="currency" length="12"/>
+ </component>
+
+ <many-to-one name="employer" column="employer_id" not-null="true"/>
+ <many-to-one name="employee" column="employee_id" not-null="true"/>
+
+ </class>
+
+ <class name="Employee" table="employees">
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employee_id_seq</param>
+ </generator>
+ </id>
+ <property name="taxfileNumber"/>
+ <component name="name" class="Name">
+ <property name="firstName"/>
+ <property name="initial"/>
+ <property name="lastName"/>
+ </component>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ E abaixo o esquema da tabela gerado pelo <literal>SchemaExport</literal>.
+ </para>
+
+ <programlisting><![CDATA[create table employers (
+ id BIGINT not null,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+create table employment_periods (
+ id BIGINT not null,
+ hourly_rate NUMERIC(12, 2),
+ currency VARCHAR(12),
+ employee_id BIGINT not null,
+ employer_id BIGINT not null,
+ end_date TIMESTAMP,
+ start_date TIMESTAMP,
+ primary key (id)
+)
+
+create table employees (
+ id BIGINT not null,
+ firstName VARCHAR(255),
+ initial CHAR(1),
+ lastName VARCHAR(255),
+ taxfileNumber VARCHAR(255),
+ primary key (id)
+)
+
+alter table employment_periods
+ add constraint employment_periodsFK0 foreign key (employer_id) references employers
+alter table employment_periods
+ add constraint employment_periodsFK1 foreign key (employee_id) references employees
+create sequence employee_id_seq
+create sequence employment_id_seq
+create sequence employer_id_seq]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-mappings-authorwork">
+ <title>Author/Work</title>
+
+ <para>
+ Considere o seguinte modelo de relacionamento entre <literal>Work</literal>,
+ <literal>Author</literal> e <literal>Person</literal>. Nós representamos o relacionamento
+ entre <literal>Work</literal> e <literal>Author</literal> como uma associação
+ muitos-para-muitos. Nós escolhemos representar o relacionamento entre <literal>Author</literal>
+ e <literal>Person</literal> como uma associação um-para-um. Outra possibilidade seria ter
+ <literal>Author</literal> extendendo <literal>Person</literal>.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/AuthorWork.png" format="PNG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/AuthorWork.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ O mapeamento do código seguinte representa corretamente estes relacionamentos:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Work" table="works" discriminator-value="W">
+
+ <id name="id" column="id">
+ <generator class="native"/>
+ </id>
+ <discriminator column="type" type="character"/>
+
+ <property name="title"/>
+ <set name="authors" table="author_work">
+ <key column name="work_id"/>
+ <many-to-many class="Author" column name="author_id"/>
+ </set>
+
+ <subclass name="Book" discriminator-value="B">
+ <property name="text"/>
+ </subclass>
+
+ <subclass name="Song" discriminator-value="S">
+ <property name="tempo"/>
+ <property name="genre"/>
+ </subclass>
+
+ </class>
+
+ <class name="Author" table="authors">
+
+ <id name="id" column="id">
+ <!-- The Author must have the same identifier as the Person -->
+ <generator class="assigned"/>
+ </id>
+
+ <property name="alias"/>
+ <one-to-one name="person" constrained="true"/>
+
+ <set name="works" table="author_work" inverse="true">
+ <key column="author_id"/>
+ <many-to-many class="Work" column="work_id"/>
+ </set>
+
+ </class>
+
+ <class name="Person" table="persons">
+ <id name="id" column="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ There are four tables in this mapping. <literal>works</literal>,
+ <literal>authors</literal> and <literal>persons</literal> hold work, author
+ and person data respectively. <literal>author_work</literal> is an association
+ table linking authors to works. Heres the table schema, as generated by
+ <literal>SchemaExport</literal>.
+ Existem quatro tabelas neste mapeamento. <literal>works</literal>,
+ <literal>authors</literal> e <literal>persons</literal> recebem os dados de work,
+ author e person, respectivamente. <literal>author_work</literal> é uma tabela de
+ associação que liga authors à works. Abaixo o esquema das tabelas, gerados pelo
+ <literal>SchemaExport</literal>.
+ </para>
+
+ <programlisting><![CDATA[create table works (
+ id BIGINT not null generated by default as identity,
+ tempo FLOAT,
+ genre VARCHAR(255),
+ text INTEGER,
+ title VARCHAR(255),
+ type CHAR(1) not null,
+ primary key (id)
+)
+
+create table author_work (
+ author_id BIGINT not null,
+ work_id BIGINT not null,
+ primary key (work_id, author_id)
+)
+
+create table authors (
+ id BIGINT not null generated by default as identity,
+ alias VARCHAR(255),
+ primary key (id)
+)
+
+create table persons (
+ id BIGINT not null generated by default as identity,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+alter table authors
+ add constraint authorsFK0 foreign key (id) references persons
+alter table author_work
+ add constraint author_workFK0 foreign key (author_id) references authors
+alter table author_work
+ add constraint author_workFK1 foreign key (work_id) references works]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-mappings-customerorderproduct">
+ <title>Customer/Order/Product</title>
+
+ <para>
+ Agora considere um modelo de relacionamento entre <literal>Customer</literal>,
+ <literal>Order</literal> e <literal>LineItem</literal> e <literal>Product</literal>.
+ Existe uma associação um-para-muitos entre <literal>Customer</literal> e
+ <literal>Order</literal>, mas como devemos representar <literal>Order</literal> /
+ <literal>LineItem</literal> / <literal>Product</literal>? Eu escolhi mapear LineItem
+ como uma classe de associação representando a associação muitos-para-muitos entre
+ <literal>Order</literal> and <literal>Product</literal>. No Hibernate, isto é conhecido
+ como um elemento composto.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/CustomerOrderProduct.png" format="PNG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/CustomerOrderProduct.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ O código do mapeamento:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Customer" table="customers">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ <set name="orders" inverse="true">
+ <key column="customer_id"/>
+ <one-to-many class="Order"/>
+ </set>
+ </class>
+
+ <class name="Order" table="orders">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="date"/>
+ <many-to-one name="customer" column="customer_id"/>
+ <list name="lineItems" table="line_items">
+ <key column="order_id"/>
+ <list-index column="line_number"/>
+ <composite-element class="LineItem">
+ <property name="quantity"/>
+ <many-to-one name="product" column="product_id"/>
+ </composite-element>
+ </list>
+ </class>
+
+ <class name="Product" table="products">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="serialNumber"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>customers</literal>, <literal>orders</literal>, <literal>line_items</literal> e
+ <literal>products</literal> recebem os dados de customer, order, line_item e product,
+ respectivamente. <literal>line_items</literal> também atua como uma tabela de associação
+ ligando orders com products.
+ </para>
+
+ <programlisting><![CDATA[create table customers (
+ id BIGINT not null generated by default as identity,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+create table orders (
+ id BIGINT not null generated by default as identity,
+ customer_id BIGINT,
+ date TIMESTAMP,
+ primary key (id)
+)
+
+create table line_items (
+ line_number INTEGER not null,
+ order_id BIGINT not null,
+ product_id BIGINT,
+ quantity INTEGER,
+ primary key (order_id, line_number)
+)
+
+create table products (
+ id BIGINT not null generated by default as identity,
+ serialNumber VARCHAR(255),
+ primary key (id)
+)
+
+alter table orders
+ add constraint ordersFK0 foreign key (customer_id) references customers
+alter table line_items
+ add constraint line_itemsFK0 foreign key (product_id) references products
+alter table line_items
+ add constraint line_itemsFK1 foreign key (order_id) references orders]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="misc">
+ <title>Exemplos variados de mapeamento</title>
+
+ <para>
+ Todos estes exemplos são retirados do conjunto de testes do Hibernate.
+ Lá, você encontrará vários outros exemplos úteis de mapeamentos.
+ Verifique o diretorio <literal>test</literal> da distribuição do Hibernate.
+ </para>
+
+ <para>TODO: put words around this stuff</para>
+
+ <sect2 id="example-mappings-typed-onetone">
+ <title>Associação um-para-um "Tipadas"</title>
+<programlisting><![CDATA[<class name="Person">
+ <id name="name"/>
+ <one-to-one name="address"
+ cascade="all">
+ <formula>name</formula>
+ <formula>'HOME'</formula>
+ </one-to-one>
+ <one-to-one name="mailingAddress"
+ cascade="all">
+ <formula>name</formula>
+ <formula>'MAILING'</formula>
+ </one-to-one>
+</class>
+
+<class name="Address" batch-size="2"
+ check="addressType in ('MAILING', 'HOME', 'BUSINESS')">
+ <composite-id>
+ <key-many-to-one name="person"
+ column="personName"/>
+ <key-property name="type"
+ column="addressType"/>
+ </composite-id>
+ <property name="street" type="text"/>
+ <property name="state"/>
+ <property name="zip"/>
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-composite-key">
+ <title>Exemplo de chave composta</title>
+<programlisting><![CDATA[<class name="Customer">
+
+ <id name="customerId"
+ length="10">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="name" not-null="true" length="100"/>
+ <property name="address" not-null="true" length="200"/>
+
+ <list name="orders"
+ inverse="true"
+ cascade="save-update">
+ <key column="customerId"/>
+ <index column="orderNumber"/>
+ <one-to-many class="Order"/>
+ </list>
+
+</class>
+
+<class name="Order" table="CustomerOrder" lazy="true">
+ <synchronize table="LineItem"/>
+ <synchronize table="Product"/>
+
+ <composite-id name="id"
+ class="Order$Id">
+ <key-property name="customerId" length="10"/>
+ <key-property name="orderNumber"/>
+ </composite-id>
+
+ <property name="orderDate"
+ type="calendar_date"
+ not-null="true"/>
+
+ <property name="total">
+ <formula>
+ ( select sum(li.quantity*p.price)
+ from LineItem li, Product p
+ where li.productId = p.productId
+ and li.customerId = customerId
+ and li.orderNumber = orderNumber )
+ </formula>
+ </property>
+
+ <many-to-one name="customer"
+ column="customerId"
+ insert="false"
+ update="false"
+ not-null="true"/>
+
+ <bag name="lineItems"
+ fetch="join"
+ inverse="true"
+ cascade="save-update">
+ <key>
+ <column name="customerId"/>
+ <column name="orderNumber"/>
+ </key>
+ <one-to-many class="LineItem"/>
+ </bag>
+
+</class>
+
+<class name="LineItem">
+
+ <composite-id name="id"
+ class="LineItem$Id">
+ <key-property name="customerId" length="10"/>
+ <key-property name="orderNumber"/>
+ <key-property name="productId" length="10"/>
+ </composite-id>
+
+ <property name="quantity"/>
+
+ <many-to-one name="order"
+ insert="false"
+ update="false"
+ not-null="true">
+ <column name="customerId"/>
+ <column name="orderNumber"/>
+ </many-to-one>
+
+ <many-to-one name="product"
+ insert="false"
+ update="false"
+ not-null="true"
+ column="productId"/>
+
+</class>
+
+<class name="Product">
+ <synchronize table="LineItem"/>
+
+ <id name="productId"
+ length="10">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="description"
+ not-null="true"
+ length="200"/>
+ <property name="price" length="3"/>
+ <property name="numberAvailable"/>
+
+ <property name="numberOrdered">
+ <formula>
+ ( select sum(li.quantity)
+ from LineItem li
+ where li.productId = productId )
+ </formula>
+ </property>
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-composite-key-manytomany">
+ <title>Mmuitos-para-muitos com atributo de chave composta compartilhada</title>
+<programlisting><![CDATA[<class name="User" table="`User`">
+ <composite-id>
+ <key-property name="name"/>
+ <key-property name="org"/>
+ </composite-id>
+ <set name="groups" table="UserGroup">
+ <key>
+ <column name="userName"/>
+ <column name="org"/>
+ </key>
+ <many-to-many class="Group">
+ <column name="groupName"/>
+ <formula>org</formula>
+ </many-to-many>
+ </set>
+</class>
+
+<class name="Group" table="`Group`">
+ <composite-id>
+ <key-property name="name"/>
+ <key-property name="org"/>
+ </composite-id>
+ <property name="description"/>
+ <set name="users" table="UserGroup" inverse="true">
+ <key>
+ <column name="groupName"/>
+ <column name="org"/>
+ </key>
+ <many-to-many class="User">
+ <column name="userName"/>
+ <formula>org</formula>
+ </many-to-many>
+ </set>
+</class>
+]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-content-discrimination">
+ <title>Conteúdo baseado em descriminação</title>
+<programlisting><![CDATA[<class name="Person"
+ discriminator-value="P">
+
+ <id name="id"
+ column="person_id"
+ unsaved-value="0">
+ <generator class="native"/>
+ </id>
+
+
+ <discriminator
+ type="character">
+ <formula>
+ case
+ when title is not null then 'E'
+ when salesperson is not null then 'C'
+ else 'P'
+ end
+ </formula>
+ </discriminator>
+
+ <property name="name"
+ not-null="true"
+ length="80"/>
+
+ <property name="sex"
+ not-null="true"
+ update="false"/>
+
+ <component name="address">
+ <property name="address"/>
+ <property name="zip"/>
+ <property name="country"/>
+ </component>
+
+ <subclass name="Employee"
+ discriminator-value="E">
+ <property name="title"
+ length="20"/>
+ <property name="salary"/>
+ <many-to-one name="manager"/>
+ </subclass>
+
+ <subclass name="Customer"
+ discriminator-value="C">
+ <property name="comments"/>
+ <many-to-one name="salesperson"/>
+ </subclass>
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-association-alternatekeys" revision="2">
+ <title>Associações em chaves alternativas</title>
+<programlisting><![CDATA[<class name="Person">
+
+ <id name="id">
+ <generator class="hilo"/>
+ </id>
+
+ <property name="name" length="100"/>
+
+ <one-to-one name="address"
+ property-ref="person"
+ cascade="all"
+ fetch="join"/>
+
+ <set name="accounts"
+ inverse="true">
+ <key column="userId"
+ property-ref="userId"/>
+ <one-to-many class="Account"/>
+ </set>
+
+ <property name="userId" length="8"/>
+
+</class>
+
+<class name="Address">
+
+ <id name="id">
+ <generator class="hilo"/>
+ </id>
+
+ <property name="address" length="300"/>
+ <property name="zip" length="5"/>
+ <property name="country" length="25"/>
+ <many-to-one name="person" unique="true" not-null="true"/>
+
+</class>
+
+<class name="Account">
+ <id name="accountId" length="32">
+ <generator class="uuid"/>
+ </id>
+
+ <many-to-one name="user"
+ column="userId"
+ property-ref="userId"/>
+
+ <property name="type" not-null="true"/>
+
+</class>]]></programlisting>
+ </sect2>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_parentchild.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/example_parentchild.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_parentchild.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_parentchild.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,361 @@
+<chapter id="example-parentchild">
+ <title>Example: Parent/Child</title>
+
+ <para>
+ One of the very first things that new users try to do with Hibernate is to model a parent / child type
+ relationship. There are two different approaches to this. For various reasons the most convenient
+ approach, especially for new users, is to model both <literal>Parent</literal> and <literal>Child</literal>
+ as entity classes with a <literal><one-to-many></literal> association from <literal>Parent</literal>
+ to <literal>Child</literal>. (The alternative approach is to declare the <literal>Child</literal> as a
+ <literal><composite-element></literal>.) Now, it turns out that default semantics of a one to many
+ association (in Hibernate) are much less close to the usual semantics of a parent / child relationship than
+ those of a composite element mapping. We will explain how to use a <emphasis>bidirectional one to many
+ association with cascades</emphasis> to model a parent / child relationship efficiently and elegantly.
+ It's not at all difficult!
+ </para>
+
+ <sect1 id="example-parentchild-collections">
+ <title>A note about collections</title>
+
+ <para>
+ Hibernate collections are considered to be a logical part of their owning entity; never of the
+ contained entities. This is a crucial distinction! It has the following consequences:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ When we remove / add an object from / to a collection, the version number of the collection owner
+ is incremented.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If an object that was removed from a collection is an instance of a value type (eg, a composite
+ element), that object will cease to be persistent and its state will be completely removed from
+ the database. Likewise, adding a value type instance to the collection will cause its state to be
+ immediately persistent.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ On the other hand, if an entity is removed from a collection (a one-to-many or many-to-many
+ association), it will not be deleted, by default. This behaviour is completely consistent - a
+ change to the internal state of another entity should not cause the associated entity to vanish!
+ Likewise, adding an entity to a collection does not cause that entity to become persistent, by
+ default.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Instead, the default behaviour is that adding an entity to a collection merely creates a link between
+ the two entities, while removing it removes the link. This is very appropriate for all sorts of cases.
+ Where it is not appropriate at all is the case of a parent / child relationship, where the life of the
+ child is bound to the life cycle of the parent.
+ </para>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-bidir">
+ <title>Bidirectional one-to-many</title>
+
+ <para>
+ Suppose we start with a simple <literal><one-to-many></literal> association from
+ <literal>Parent</literal> to <literal>Child</literal>.
+ </para>
+
+ <programlisting><![CDATA[<set name="children">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ If we were to execute the following code
+ </para>
+
+ <programlisting><![CDATA[Parent p = .....;
+Child c = new Child();
+p.getChildren().add(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ <para>
+ Hibernate would issue two SQL statements:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>an <literal>INSERT</literal> to create the record for <literal>c</literal></para>
+ </listitem>
+ <listitem>
+ <para>
+ an <literal>UPDATE</literal> to create the link from <literal>p</literal> to
+ <literal>c</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ This is not only inefficient, but also violates any <literal>NOT NULL</literal> constraint on the
+ <literal>parent_id</literal> column. We can fix the nullability constraint violation by specifying
+ <literal>not-null="true"</literal> in the collection mapping:
+ </para>
+
+ <programlisting><![CDATA[<set name="children">
+ <key column="parent_id" not-null="true"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ However, this is not the recommended solution.
+ </para>
+ <para>
+ The underlying cause of this behaviour is that the link (the foreign key <literal>parent_id</literal>)
+ from <literal>p</literal> to <literal>c</literal> is not considered part of the state of the
+ <literal>Child</literal> object and is therefore not created in the <literal>INSERT</literal>. So the
+ solution is to make the link part of the <literal>Child</literal> mapping.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="parent" column="parent_id" not-null="true"/>]]></programlisting>
+
+ <para>
+ (We also need to add the <literal>parent</literal> property to the <literal>Child</literal> class.)
+ </para>
+
+ <para>
+ Now that the <literal>Child</literal> entity is managing the state of the link, we tell the collection
+ not to update the link. We use the <literal>inverse</literal> attribute.
+ </para>
+
+ <programlisting><![CDATA[<set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ The following code would be used to add a new <literal>Child</literal>
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+c.setParent(p);
+p.getChildren().add(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ <para>
+ And now, only one SQL <literal>INSERT</literal> would be issued!
+ </para>
+
+ <para>
+ To tighten things up a bit, we could create an <literal>addChild()</literal> method of
+ <literal>Parent</literal>.
+ </para>
+
+ <programlisting><![CDATA[public void addChild(Child c) {
+ c.setParent(this);
+ children.add(c);
+}]]></programlisting>
+
+ <para>
+ Now, the code to add a <literal>Child</literal> looks like
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+p.addChild(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-cascades">
+ <title>Cascading life cycle</title>
+
+ <para>
+ The explicit call to <literal>save()</literal> is still annoying. We will address this by
+ using cascades.
+ </para>
+
+ <programlisting><![CDATA[<set name="children" inverse="true" cascade="all">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ This simplifies the code above to
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+p.addChild(c);
+session.flush();]]></programlisting>
+
+ <para>
+ Similarly, we don't need to iterate over the children when saving or deleting a <literal>Parent</literal>.
+ The following removes <literal>p</literal> and all its children from the database.
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+session.delete(p);
+session.flush();]]></programlisting>
+
+ <para>
+ However, this code
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = (Child) p.getChildren().iterator().next();
+p.getChildren().remove(c);
+c.setParent(null);
+session.flush();]]></programlisting>
+
+ <para>
+ will not remove <literal>c</literal> from the database; it will ony remove the link to <literal>p</literal>
+ (and cause a <literal>NOT NULL</literal> constraint violation, in this case). You need to explicitly
+ <literal>delete()</literal> the <literal>Child</literal>.
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = (Child) p.getChildren().iterator().next();
+p.getChildren().remove(c);
+session.delete(c);
+session.flush();]]></programlisting>
+
+ <para>
+ Now, in our case, a <literal>Child</literal> can't really exist without its parent. So if we remove
+ a <literal>Child</literal> from the collection, we really do want it to be deleted. For this, we must
+ use <literal>cascade="all-delete-orphan"</literal>.
+ </para>
+
+ <programlisting><![CDATA[<set name="children" inverse="true" cascade="all-delete-orphan">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ Note: even though the collection mapping specifies <literal>inverse="true"</literal>, cascades are
+ still processed by iterating the collection elements. So if you require that an object be saved,
+ deleted or updated by cascade, you must add it to the collection. It is not enough to simply call
+ <literal>setParent()</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-update">
+ <title>Cascades and <literal>unsaved-value</literal></title>
+
+ <para>
+ Suppose we loaded up a <literal>Parent</literal> in one <literal>Session</literal>, made some changes
+ in a UI action and wish to persist these changes in a new session by calling <literal>update()</literal>.
+ The <literal>Parent</literal> will contain a collection of childen and, since cascading update is enabled,
+ Hibernate needs to know which children are newly instantiated and which represent existing rows in the
+ database. Lets assume that both <literal>Parent</literal> and <literal>Child</literal> have genenerated
+ identifier properties of type <literal>Long</literal>. Hibernate will use the identifier and
+ version/timestamp property value to determine which of the children are new. (See
+ <xref linkend="objectstate-saveorupdate"/>.) <emphasis>In Hibernate3, it is no longer necessary to specify
+ an <literal>unsaved-value</literal> explicitly.</emphasis>
+ </para>
+
+ <para>
+ The following code will update <literal>parent</literal> and <literal>child</literal> and insert
+ <literal>newChild</literal>.
+ </para>
+
+ <programlisting><![CDATA[//parent and child were both loaded in a previous session
+parent.addChild(child);
+Child newChild = new Child();
+parent.addChild(newChild);
+session.update(parent);
+session.flush();]]></programlisting>
+
+ <para>
+ Well, that's all very well for the case of a generated identifier, but what about assigned identifiers
+ and composite identifiers? This is more difficult, since Hibernate can't use the identifier property to
+ distinguish between a newly instantiated object (with an identifier assigned by the user) and an
+ object loaded in a previous session. In this case, Hibernate will either use the timestamp or version
+ property, or will actually query the second-level cache or, worst case, the database, to see if the
+ row exists.
+ </para>
+
+ <!-- undocumenting
+ <para>
+ There is one further possibility. The <literal>Interceptor</literal> method named
+ <literal>isUnsaved()</literal> lets the application implement its own strategy for distinguishing
+ newly instantiated objects. For example, you could define a base class for your persistent classes.
+ </para>
+
+ <programlisting><![CDATA[public class Persistent {
+ private boolean _saved = false;
+ public void onSave() {
+ _saved=true;
+ }
+ public void onLoad() {
+ _saved=true;
+ }
+ ......
+ public boolean isSaved() {
+ return _saved;
+ }
+}]]></programlisting>
+
+ <para>
+ (The <literal>saved</literal> property is non-persistent.)
+ Now implement <literal>isUnsaved()</literal>, along with <literal>onLoad()</literal>
+ and <literal>onSave()</literal> as follows.
+ </para>
+
+ <programlisting><![CDATA[public Boolean isUnsaved(Object entity) {
+ if (entity instanceof Persistent) {
+ return new Boolean( !( (Persistent) entity ).isSaved() );
+ }
+ else {
+ return null;
+ }
+}
+
+public boolean onLoad(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if (entity instanceof Persistent) ( (Persistent) entity ).onLoad();
+ return false;
+}
+
+public boolean onSave(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if (entity instanceof Persistent) ( (Persistent) entity ).onSave();
+ return false;
+}]]></programlisting>
+
+ <para>
+ Don't worry; in Hibernate3 you don't need to write any of this kind of code if you don't want to.
+ </para>
+ -->
+ </sect1>
+
+ <sect1 id="example-parentchild-conclusion">
+ <title>Conclusion</title>
+
+ <para>
+ There is quite a bit to digest here and it might look confusing first time around. However, in practice,
+ it all works out very nicely. Most Hibernate applications use the parent / child pattern in many places.
+ </para>
+
+ <para>
+ We mentioned an alternative in the first paragraph. None of the above issues exist in the case of
+ <literal><composite-element></literal> mappings, which have exactly the semantics of a parent / child
+ relationship. Unfortunately, there are two big limitations to composite element classes: composite elements
+ may not own collections, and they should not be the child of any entity other than the unique parent.
+ </para>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_weblog.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/example_weblog.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_weblog.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_weblog.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,430 @@
+<chapter id="example-weblog">
+ <title>Example: Weblog Application</title>
+
+ <sect1 id="example-weblog-classes">
+ <title>Persistent Classes</title>
+
+ <para>
+ The persistent classes represent a weblog, and an item posted
+ in a weblog. They are to be modelled as a standard parent/child
+ relationship, but we will use an ordered bag, instead of a set.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+import java.util.List;
+
+public class Blog {
+ private Long _id;
+ private String _name;
+ private List _items;
+
+ public Long getId() {
+ return _id;
+ }
+ public List getItems() {
+ return _items;
+ }
+ public String getName() {
+ return _name;
+ }
+ public void setId(Long long1) {
+ _id = long1;
+ }
+ public void setItems(List list) {
+ _items = list;
+ }
+ public void setName(String string) {
+ _name = string;
+ }
+}]]></programlisting>
+
+ <programlisting><![CDATA[package eg;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+
+public class BlogItem {
+ private Long _id;
+ private Calendar _datetime;
+ private String _text;
+ private String _title;
+ private Blog _blog;
+
+ public Blog getBlog() {
+ return _blog;
+ }
+ public Calendar getDatetime() {
+ return _datetime;
+ }
+ public Long getId() {
+ return _id;
+ }
+ public String getText() {
+ return _text;
+ }
+ public String getTitle() {
+ return _title;
+ }
+ public void setBlog(Blog blog) {
+ _blog = blog;
+ }
+ public void setDatetime(Calendar calendar) {
+ _datetime = calendar;
+ }
+ public void setId(Long long1) {
+ _id = long1;
+ }
+ public void setText(String string) {
+ _text = string;
+ }
+ public void setTitle(String string) {
+ _title = string;
+ }
+}]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-weblog-mappings">
+ <title>Hibernate Mappings</title>
+
+ <para>
+ The XML mappings should now be quite straightforward.
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class
+ name="Blog"
+ table="BLOGS">
+
+ <id
+ name="id"
+ column="BLOG_ID">
+
+ <generator class="native"/>
+
+ </id>
+
+ <property
+ name="name"
+ column="NAME"
+ not-null="true"
+ unique="true"/>
+
+ <bag
+ name="items"
+ inverse="true"
+ order-by="DATE_TIME"
+ cascade="all">
+
+ <key column="BLOG_ID"/>
+ <one-to-many class="BlogItem"/>
+
+ </bag>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class
+ name="BlogItem"
+ table="BLOG_ITEMS"
+ dynamic-update="true">
+
+ <id
+ name="id"
+ column="BLOG_ITEM_ID">
+
+ <generator class="native"/>
+
+ </id>
+
+ <property
+ name="title"
+ column="TITLE"
+ not-null="true"/>
+
+ <property
+ name="text"
+ column="TEXT"
+ not-null="true"/>
+
+ <property
+ name="datetime"
+ column="DATE_TIME"
+ not-null="true"/>
+
+ <many-to-one
+ name="blog"
+ column="BLOG_ID"
+ not-null="true"/>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-weblog-code">
+ <title>Hibernate Code</title>
+
+ <para>
+ The following class demonstrates some of the kinds of things
+ we can do with these classes, using Hibernate.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.tool.hbm2ddl.SchemaExport;
+
+public class BlogMain {
+
+ private SessionFactory _sessions;
+
+ public void configure() throws HibernateException {
+ _sessions = new Configuration()
+ .addClass(Blog.class)
+ .addClass(BlogItem.class)
+ .buildSessionFactory();
+ }
+
+ public void exportTables() throws HibernateException {
+ Configuration cfg = new Configuration()
+ .addClass(Blog.class)
+ .addClass(BlogItem.class);
+ new SchemaExport(cfg).create(true, true);
+ }
+
+ public Blog createBlog(String name) throws HibernateException {
+
+ Blog blog = new Blog();
+ blog.setName(name);
+ blog.setItems( new ArrayList() );
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.persist(blog);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return blog;
+ }
+
+ public BlogItem createBlogItem(Blog blog, String title, String text)
+ throws HibernateException {
+
+ BlogItem item = new BlogItem();
+ item.setTitle(title);
+ item.setText(text);
+ item.setBlog(blog);
+ item.setDatetime( Calendar.getInstance() );
+ blog.getItems().add(item);
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.update(blog);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return item;
+ }
+
+ public BlogItem createBlogItem(Long blogid, String title, String text)
+ throws HibernateException {
+
+ BlogItem item = new BlogItem();
+ item.setTitle(title);
+ item.setText(text);
+ item.setDatetime( Calendar.getInstance() );
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ Blog blog = (Blog) session.load(Blog.class, blogid);
+ item.setBlog(blog);
+ blog.getItems().add(item);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return item;
+ }
+
+ public void updateBlogItem(BlogItem item, String text)
+ throws HibernateException {
+
+ item.setText(text);
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.update(item);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ }
+
+ public void updateBlogItem(Long itemid, String text)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ BlogItem item = (BlogItem) session.load(BlogItem.class, itemid);
+ item.setText(text);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ }
+
+ public List listAllBlogNamesAndItemCounts(int max)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ List result = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "select blog.id, blog.name, count(blogItem) " +
+ "from Blog as blog " +
+ "left outer join blog.items as blogItem " +
+ "group by blog.name, blog.id " +
+ "order by max(blogItem.datetime)"
+ );
+ q.setMaxResults(max);
+ result = q.list();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return result;
+ }
+
+ public Blog getBlogAndAllItems(Long blogid)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ Blog blog = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "from Blog as blog " +
+ "left outer join fetch blog.items " +
+ "where blog.id = :blogid"
+ );
+ q.setParameter("blogid", blogid);
+ blog = (Blog) q.uniqueResult();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return blog;
+ }
+
+ public List listBlogsAndRecentItems() throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ List result = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "from Blog as blog " +
+ "inner join blog.items as blogItem " +
+ "where blogItem.datetime > :minDate"
+ );
+
+ Calendar cal = Calendar.getInstance();
+ cal.roll(Calendar.MONTH, false);
+ q.setCalendar("minDate", cal);
+
+ result = q.list();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return result;
+ }
+}]]></programlisting>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/filters.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/filters.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/filters.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/filters.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,128 @@
+<chapter id="filters">
+ <title>Filtrando dados</title>
+
+ <para>
+ O Hibernate3 provê um novo método inovador para manusear dados com regras de "visibilidade".
+ Um <emphasis>Filtro do Hibernate</emphasis> é um filtro global, nomeado e parametrizado que pode
+ se habilitado ou não dentro de um Session do Hibernate.
+ </para>
+
+ <sect1 id="objectstate-filters">
+ <title>Filtros do Hibernate</title>
+
+ <para>
+ O Hibernate tem a habilidade de pré definir os critérios do filtro e anexar esses filtros no
+ nível da classe e no nível da coleção. Um critério do filtro é a habilidade de definir uma
+ cláusula restritiva muito semelhante ao atributo "where" disponível para a classe e várias
+ coleções. A não ser que essas condições de filtros podem ser parametrizadas. A aplicação
+ pode, então, fazer uma decisão em tempo de execução se os filtros definidos devem estar
+ habilitados e quais valores seus parâmetros devem ter. Os filtros podem ser usados como
+ Views de bancos de dados, mas com parametros internos à aplicação.
+ </para>
+
+ <para>
+ Para usar esses filtros, eles primeiramente devem ser definidos e anexados aos elementos do
+ mapeamento apropriados. Para definir um filtro, use o elemento <literal><filter-def/></literal>
+ dentro do elemento <literal><hibernate-mapping/></literal>:
+ </para>
+
+ <programlisting><![CDATA[<filter-def name="myFilter">
+ <filter-param name="myFilterParam" type="string"/>
+</filter-def>]]></programlisting>
+
+ <para>
+ Então esse filtro pode ser anexo à uma classe:
+ </para>
+
+ <programlisting><![CDATA[<class name="myClass" ...>
+ ...
+ <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/>
+</class>]]></programlisting>
+
+ <para>
+ ou em uma coleção:
+ </para>
+
+ <programlisting><![CDATA[<set ...>
+ <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/>
+</set>]]></programlisting>
+
+ <para>
+ ou mesmo para ambos (ou muitos de cada) ao mesmo tempo.
+ </para>
+
+ <para>
+ Os métodos na <literal>Session</literal> são: <literal>enableFilter(String filterName)</literal>,
+ <literal>getEnabledFilter(String filterName)</literal>, e <literal>disableFilter(String filterName)</literal>.
+ Por padrão, os filtros não são habilitados dentro de qualquer session; Eles devem ser explicitamente
+ habilitados usando o método <literal>Session.enabledFilter()</literal>, que retorna uma instância da
+ interface <literal>Filter</literal>. Usando o filtro simples definido acima, o código se pareceria
+ com o seguinte:
+ </para>
+
+ <programlisting><![CDATA[session.enableFilter("myFilter").setParameter("myFilterParam", "some-value");]]></programlisting>
+
+ <para>
+ Veja que os métodos da interface org.hibernate.Filter permite o encadeamento de funções, comum à maioria das funções do Hibernate.
+ </para>
+
+ <para>
+ Um exemplo completo, usando dados temporais com um padrão efetivo de registro de datas:
+ </para>
+
+ <programlisting><![CDATA[<filter-def name="effectiveDate">
+ <filter-param name="asOfDate" type="date"/>
+</filter-def>
+
+<class name="Employee" ...>
+...
+ <many-to-one name="department" column="dept_id" class="Department"/>
+ <property name="effectiveStartDate" type="date" column="eff_start_dt"/>
+ <property name="effectiveEndDate" type="date" column="eff_end_dt"/>
+...
+ <!--
+ Note that this assumes non-terminal records have an eff_end_dt set to
+ a max db date for simplicity-sake
+ -->
+ <filter name="effectiveDate"
+ condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
+</class>
+
+<class name="Department" ...>
+...
+ <set name="employees" lazy="true">
+ <key column="dept_id"/>
+ <one-to-many class="Employee"/>
+ <filter name="effectiveDate"
+ condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ Para garantir que você sempre tenha registro efetivos, simplesmente habilite o filtro
+ na session antes de recuperar os dados dos empregados:
+ </para>
+
+<programlisting><![CDATA[Session session = ...;
+session.enabledFilter("effectiveDate").setParameter("asOfDate", new Date());
+List results = session.createQuery("from Employee as e where e.salary > :targetSalary")
+ .setLong("targetSalary", new Long(1000000))
+ .list();
+]]></programlisting>
+
+ <para>
+ No HQL acima, mesmo que mencionamos apenas uma restrição de salário nos resultados, por causa
+ do filtro habilitado, a consulta retornará apenas os funcionários ativos cujo salário é maior
+ que um milhão de dólares.
+ </para>
+
+ <para>
+ Nota: se você planeja usar filtros com outer join (por HQL ou por load fetching) seja cuidadoso
+ na direção da expressão de condição. É mais seguro configura-lo com para um left outer join;
+ geralmente, coloque o parâmetro primeiro seguido pelo nome da coluna após o operador.
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/inheritance_mapping.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/inheritance_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/inheritance_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/inheritance_mapping.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,501 @@
+<chapter id="inheritance">
+ <title>Mapeamento de Herança</title>
+
+ <sect1 id="inheritance-strategies" revision="3">
+ <title> As três estratégias</title>
+
+ <para>
+ O Hibernate suporta as três estratégias básicas de mapeamento de herança:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ tabela por hierarquia de classes
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ tabela por subclasse
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ tabela por classe concreta
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Adicionalmente, o Hibernate suporta uma quarta, um tipo levemente
+ diferente de polimorfismo:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ polimorfismo implícito
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ É possível usar diferentes estratégias de mapeamento para diferentes
+ ramificações da mesma hierarquia de herança, e então fazer uso do
+ polimorfismo implícito para alcançar polimorfismo através da
+ hierarquia completa. De qualquer forma, O Hibernate não suporta a
+ mistura de mapeamentos <literal><subclass></literal>,
+ and <literal><joined-subclass></literal> e
+ <literal><union-subclass></literal> dentro do mesmo elemento
+ raiz <literal><class></literal>. É possível usar junto às estratégias
+ tabela por hierarquia e a tabela por subclasse, abaixo do mesmo elemento
+ <literal><class></literal>, combinando os elementos
+ <literal><subclass></literal> e <literal><join></literal>
+ (veja abaixo).
+
+ </para>
+
+ <para>
+ É possível definir mapeamentos <literal>subclass</literal>, <literal>union-subclass</literal>,
+ e <literal>joined-subclass</literal> em documentos de mapeamento separados, diretamente abaixo de
+ <literal>hibernate-mapping</literal>. Isso permite a você estender uma hierarquia de classes
+ apenas adicionando um novo arquivo de mapeamento. Você deve especificar um atributo
+ <literal>extends</literal> no mapeamento da subclasse, nomeando uma superclasse previamente
+ mapeada. Nota: Anteriormente esta característica fazia o ordenamento dos documentos de
+ mapeamento importantes. Desde o Hibernate3, o ordenamento dos arquivos de mapeamento não
+ importa quando usamos a palavra chave extends. O ordenamento dentro de um arquivo de mapeamento
+ simples ainda necessita ser definido como superclasse antes de subclasse.
+ </para>
+
+ <programlisting><![CDATA[
+ <hibernate-mapping>
+ <subclass name="DomesticCat" extends="Cat" discriminator-value="D">
+ <property name="name" type="string"/>
+ </subclass>
+ </hibernate-mapping>]]></programlisting>
+
+
+ <sect2 id="inheritance-tableperclass" >
+ <title>Tabela por hierarquia de classes</title>
+
+ <para>
+ Suponha que tenhamos uma interface <literal>Payment</literal>, com sua
+ implementação <literal>CreditCardPayment</literal>, <literal>CashPayment</literal>,
+ <literal>ChequePayment</literal>. O mapeamento da tabela por hierarquia
+ seria parecido com:
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ ...
+ </subclass>
+ <subclass name="ChequePayment" discriminator-value="CHEQUE">
+ ...
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ Exactly one table is required. There is one big limitation of this mapping
+ strategy: columns declared by the subclasses, such as <literal>CCTYPE</literal>,
+ may not have <literal>NOT NULL</literal> constraints.
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tablepersubclass">
+ <title>Tabela por subclasse</title>
+
+ <para>
+ Um mapeamento de tabela por subclasse seria parecido com:
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="CashPayment" table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </joined-subclass>
+</class>]]></programlisting>
+
+ <para>
+ Quatro tabelas são necessárias. As três tabelas subclasses possuem
+ associação de chave primária para a tabela de superclasse
+ (então o modelo relacional é atualmente uma associação de
+ um-para-um).
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tablepersubclass-discriminator" revision="2">
+ <title>Tabela por subclasse, usando um discriminador</title>
+
+ <para>
+ Note que a implementação de tabela por subclasse do Hibernate não
+ necessita de coluna de discriminador. Outro mapeador objeto/relacional
+ usa uma implementação diferente de tabela por subclasse, que necessita
+ uma coluna com o tipo discriminador na tabela da superclasse. A
+ abordagem escolhida pelo Hibernate é muito mais difícil de implementar,
+ porém de forma argumentável mais correto de um ponto de vista relacional.
+ Se você deseja utilizar uma coluna discriminadora com a estratégia
+ tabela por subclasse, você pode combinar o uso de
+ <literal><subclass></literal> e <literal><join></literal>,
+ dessa maneira:
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+ <join table="CREDIT_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ <join table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="ChequePayment" discriminator-value="CHEQUE">
+ <join table="CHEQUE_PAYMENT" fetch="select">
+ <key column="PAYMENT_ID"/>
+ ...
+ </join>
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ The optional <literal>fetch="select"</literal> declaration tells Hibernate
+ not to fetch the <literal>ChequePayment</literal> subclass data using an
+ outer join when querying the superclass.
+A declaração opcional fetch=”select” diz ao Hibernate para não buscar os dados da subclasse ChequePayment, quando usar um outer join pesquisando pela superclasse.
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-mixing-tableperclass-tablepersubclass">
+ <title>. Misturando tabela por hierarquia de classes com tabela por subclasse</title>
+
+ <para>
+ Você pode até mesmo misturar a estratégia de tabela por hierarquia e
+ tabela por subclasse usando esta abordagem:
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+ <join table="CREDIT_PAYMENT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ ...
+ </subclass>
+ <subclass name="ChequePayment" discriminator-value="CHEQUE">
+ ...
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ Para qualquer uma dessas estratégias de mapeamento, uma associação
+ polimórfica para a classe raiz <literal>Payment</literal> deve ser
+ mapeada usando <literal><many-to-one></literal>.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="payment" column="PAYMENT_ID" class="Payment"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="inheritance-tableperconcrete" revision="2">
+ <title>Tabela por classe concreta</title>
+
+ <para>
+ Existem duas formas que poderíamos usar a respeito da estratégia de
+ mapeamento de tabela por classe concreta. A primeira é usar
+ <literal><union-subclass></literal>..
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="sequence"/>
+ </id>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </union-subclass>
+ <union-subclass name="CashPayment" table="CASH_PAYMENT">
+ ...
+ </union-subclass>
+ <union-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+ ...
+ </union-subclass>
+</class>]]></programlisting>
+
+ <para>
+ Três tabelas estão envolvidas para as subclasses. Cada tabela define
+ colunas para todas as propriedades da classe, incluindo propriedades herdadas.
+ </para>
+
+ <para>
+ A limitação dessa abordagem é que se uma propriedade é mapeada na
+ superclasse, o nome da coluna deve ser o mesmo em todas as tabelas das
+ subclasses. (Nós devemos melhorar isto em um futuro release do Hibernate).
+ A estratégia do gerador de identidade não é permitida em união de
+ subclasses(union-subclass) herdadas, na verdade a fonte de chave
+ primária deve ser compartilhada através de todas subclasses unidas da
+ hierarquia.
+
+ </para>
+
+ <para>
+ Se sua superclasse é abstrata, mapeie ela com <literal>abstract="true"</literal>.
+ Claro, que se ela não for abstrata, uma tabela (padrão para <literal>PAYMENT</literal>
+ no exemplo acima) adicional é necessária para segurar as instâncias da superclasse.
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tableperconcreate-polymorphism">
+ <title>Tabela por classe concreta, usando polimorfismo implícito</title>
+
+ <para>
+ Uma abordagem alternativa é fazer uso de polimorfismo implícito:
+ </para>
+
+ <programlisting><![CDATA[<class name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <id name="id" type="long" column="CREDIT_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CREDIT_AMOUNT"/>
+ ...
+</class>
+
+<class name="CashPayment" table="CASH_PAYMENT">
+ <id name="id" type="long" column="CASH_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CASH_AMOUNT"/>
+ ...
+</class>
+
+<class name="ChequePayment" table="CHEQUE_PAYMENT">
+ <id name="id" type="long" column="CHEQUE_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CHEQUE_AMOUNT"/>
+ ...
+</class>]]></programlisting>
+
+ <para>
+ Veja que em nenhum lugar mencionamos a interface <literal>Payment</literal>
+ explicitamente. Também preste atenção que propriedades de <literal>Payment</literal>
+ são mapeadas em cada uma das subclasses. Se você quer evitar duplicação,
+ considere usar entidades de XML (ex. (e.g. <literal>[ <!ENTITY allproperties
+ SYSTEM "allproperties.xml"> ]</literal> na declaração do <literal>DOCTYPE</literal>
+ e <literal>&allproperties;</literal> no mapeamento).
+ </para>
+
+ <para>
+ A desvantagem dessa abordagem é que o Hibernate não gera <literal>UNION</literal>s
+ SQL quando executa pesquisas polimórficas.
+ </para>
+
+ <para>
+ Para essa estratégia, uma associação polimórfica para <literal>Payment</literal>
+ geralmente é mapeada usando <literal><any></literal>.
+ </para>
+
+ <programlisting><![CDATA[<any name="payment" meta-type="string" id-type="long">
+ <meta-value value="CREDIT" class="CreditCardPayment"/>
+ <meta-value value="CASH" class="CashPayment"/>
+ <meta-value value="CHEQUE" class="ChequePayment"/>
+ <column name="PAYMENT_CLASS"/>
+ <column name="PAYMENT_ID"/>
+</any>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="inheritace-mixingpolymorphism">
+ <title>Misturando polimorfismo implícito com outros mapeamentos de herança</title>
+
+ <para>
+ Ainda existe uma coisa para ser observada com respeito a este mapeamento.
+ Desde que as subclasses sejam mapeadas em seu próprio elemento
+ <literal><class></literal> (e desde que <literal>Payment</literal> seja
+ apenas uma interface), cada uma das subclasses pode ser facilmente parte de uma
+ outra hierarquia de herança! (E você ainda pode usar pesquisas polimórficas
+ em cima da interface <literal>Payment</literal>.)
+
+ </para>
+
+ <programlisting><![CDATA[<class name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <id name="id" type="long" column="CREDIT_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="CREDIT_CARD" type="string"/>
+ <property name="amount" column="CREDIT_AMOUNT"/>
+ ...
+ <subclass name="MasterCardPayment" discriminator-value="MDC"/>
+ <subclass name="VisaPayment" discriminator-value="VISA"/>
+</class>
+
+<class name="NonelectronicTransaction" table="NONELECTRONIC_TXN">
+ <id name="id" type="long" column="TXN_ID">
+ <generator class="native"/>
+ </id>
+ ...
+ <joined-subclass name="CashPayment" table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="amount" column="CASH_AMOUNT"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="amount" column="CHEQUE_AMOUNT"/>
+ ...
+ </joined-subclass>
+</class>]]></programlisting>
+
+ <para>
+ Mais uma vez, nós não mencionamos <literal>Payment</literal> explicitamente.
+ Se nós executarmos uma pesquisa em cima da interface <literal>Payment</literal> –
+ por exemplo, <literal>from Payment</literal> – o Hibernate retorna
+ automaticamente instâncias de <literal>CreditCardPayment</literal> (e suas
+ subclasses, desde que elas também implementem <literal>Payment</literal>),
+ <literal>CashPayment</literal> e <literal>ChequePayment</literal> mas
+ não as instâncias de <literal>NonelectronicTransaction</literal>.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="inheritance-limitations">
+ <title>Limitações</title>
+
+ <para>
+ Existem certas limitações para a abordagem do "polimorfismo implícito"
+ comparada com a estratégia de mapeamento da tabela por classe concreta.
+ Existe uma limitação um tanto menos restritiva para mapeamentos
+ <literal><union-subclass></literal>.
+
+ </para>
+
+ <para>
+ A tabela seguinte demonstra as limitações do mapeamento de tabela
+ por classe concreta e do polimorfismo implícito no Hibernate.
+ </para>
+
+ <table frame="topbot">
+ <title>Features of inheritance mappings</title>
+ <tgroup cols='8' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="1*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <colspec colname='c6' colwidth="1*"/>
+ <colspec colname='c7' colwidth="1*"/>
+ <colspec colname='c8' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Estratégia de Herança</entry>
+ <entry>muitos-para-um Polimórfico</entry>
+ <entry>um-para-um Polimórfico</entry>
+ <entry>um-para-muitos Polimórfico</entry>
+ <entry>muitos-para-muitos Polimórfico</entry>
+ <entry><literal>load()/get()</literal> Polimórfico </entry>
+ <entry>Pesquisas Polimórficas</entry>
+ <entry>Joins polimórficos</entry>
+ <entry>Outer join fetching</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>table per class-hierarchy</entry>
+ <entry><literal><many-to-one></literal></entry>
+ <entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal></entry>
+ <entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class, id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment p</literal></entry>
+ <entry><emphasis>supported</emphasis></entry>
+ </row>
+ <row>
+ <entry>table per subclass</entry>
+ <entry><literal><many-to-one></literal></entry>
+ <entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal></entry>
+ <entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class, id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment p</literal></entry>
+ <entry><emphasis>supported</emphasis></entry>
+ </row>
+ <row>
+ <entry>table per concrete-class (union-subclass)</entry>
+ <entry><literal><many-to-one></literal></entry>
+ <entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal> (for <literal>inverse="true"</literal> only)</entry>
+ <entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class, id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment p</literal></entry>
+ <entry><emphasis>supported</emphasis></entry>
+ </row>
+ <row>
+ <entry>table per concrete class (implicit polymorphism)</entry>
+ <entry><literal><any></literal></entry>
+ <entry><emphasis>not supported</emphasis></entry>
+ <entry><emphasis>not supported</emphasis></entry>
+ <entry><literal><many-to-any></literal></entry>
+ <entry><literal>s.createCriteria(Payment.class).add( Restrictions.idEq(id) ).uniqueResult()</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><emphasis>not supported</emphasis></entry>
+ <entry><emphasis>not supported</emphasis></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/performance.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/performance.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/performance.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/performance.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,1384 @@
+<chapter id="performance">
+ <title>Aumentando a performance</title>
+
+ <sect1 id="performance-fetching" revision="2">
+ <title>Estratégias de Fetching</title>
+
+ <para>
+ Uma <emphasis>estratégia de fetching</emphasis> é a estratégia que o Hibernate
+ irá usar para buscar objetos associados se a aplicação precisar navegar pela associação.
+ Estratégias de Fetch podem ser declaradas nos metadados de mapeamento O/R, ou sobrescritos
+ por uma query HQL ou query com <literal>Criteria</literal>.
+ </para>
+
+ <para>
+ Hibernate3 define as seguintes estratégias de fetching:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Join fetching</emphasis> - o Hibernate busca o objeto
+ ou coleção associada no mesmo <literal>SELECT</literal>, usando um
+ <literal>OUTER JOIN</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Select fetching</emphasis> - um segundo <literal>SELECT</literal> é
+ usado para buscar a entidade ou coleção associada. A menos que você desabilite
+ lazy fetching especificando <literal>lazy="false"</literal>, esse segundo SELECT
+ será executado apenas quando você acessar a associação.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Subselect fetching</emphasis> - um segundo <literal>SELECT</literal> será
+ usado para buscar as coleções associadas de todas as entidades buscadas na query ou
+ fetch anterior. A menos que você desabilite lazy fetching especificando
+ <literal>lazy="false"</literal>, esse segundo SELECT será executado apenas quando
+ você acessar a associação.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Batch fetching</emphasis> - uma opção de otimização para o Select
+ Fetching – O Hibernate busca um lote de instâncias ou entidades usando um único
+ <literal>SELECT</literal>, especificando uma lista de chaves primárias ou chaves
+ estrangeiras.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ O Hibernate distingue também entre:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Immediate fetching</emphasis> - uma associação, coleção ou atributo é buscado
+ como ela é carregada (Qual SQL é usado). Não se confuda com eles! Nós usamos fetch para melhorar a performance. Nós podemos usar lazy para definir um contrato para qual dado é sempre disponível em qualquer instância desanexada de uma classe qualquer.
+ imediatamente, quando o pai é carregado.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Lazy collection fetching</emphasis> - a coleção é buscada quando a
+ aplicação invoca uma operação sobre aquela coleção (Esse é o padrão para coleções)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>"Extra-lazy" collection fetching</emphasis> - elementos individuais de uma
+ coleção são acessados do banco de dados quando preciso. O Hibernate tenta não buscar
+ a coleção inteira dentro da memória ao menos que seja absolutamente preciso.
+ (indicado para coleções muito grandes)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Proxy fetching</emphasis> - uma associação de um valor é carregada quando um método
+ diferente do getter do identificador é invocado sobre o objeto associado.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>"No-proxy" fetching</emphasis> - uma associação de um valor é carregada quando
+ a variável da instância é carregada. Comparada com a proxy fetching, esse método é menos
+ preguiçoso (lazy)(a associação é carregada somente quando o identificador é acessada)
+ mas é mais transparente, já que não há proxies visíveis para a aplicação.
+ Esse método requer instrumentação de bytecodes em build-time e é raramente necessário.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Lazy attribute fetching</emphasis> - um atributo ou associação de um valor é
+ carregada quanto a varíavel da instância é acessada. Esse método requer instrumentação
+ de bytecodes em build-time e é raramente necessário.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Nós temos aqui duas noções ortogonais: <emphasis>quando</emphasis> a associação é carregada e
+ <emphasis>como </emphasis> ela é carregada (Qual SQL é usado). Não se confuda com eles! Nós
+ usamos <literal>fetch</literal> para melhorar a performance. Nós podemos usar lazy para
+ definir um contrato para qual dado é sempre disponível em qualquer instância desconectada
+ de uma classe qualquer.
+ </para>
+
+ <sect2 id="performance-fetching-lazy">
+ <title>Inicializando coleções e proxies</title>
+
+ <para>
+ Por padrão, o Hibernate3 usa busca preguiçosa para coleções e busca preguiçosa
+ com proxy para associações de um valor. Esses padrões fazem sentido para quase
+ todas as associações em quase todas a aplicações.
+ </para>
+
+ <para>
+ <emphasis>Veja:</emphasis> se voce setar
+ <literal>hibernate.default_batch_fetch_size</literal>, O Hibernate irá usar otimização
+ de carregamento em lote para o carregamento preguiçoso(Essa otimização pode ser também
+ habilitada em um nível mais fino).
+ </para>
+
+ <para>
+ Porém, a busca preguiçosa tem um problema que você precisar saber. Acesso a associações
+ preguiçosas fora do contexto de uma sessão aberta do Hibernate irá resultar numa exceção.
+ Por exemplo:
+ </para>
+
+ <programlisting><![CDATA[s = sessions.openSession();
+Transaction tx = s.beginTransaction();
+
+User u = (User) s.createQuery("from User u where u.name=:userName")
+ .setString("userName", userName).uniqueResult();
+Map permissions = u.getPermissions();
+
+tx.commit();
+s.close();
+
+Integer accessLevel = (Integer) permissions.get("accounts"); // Error!]]></programlisting>
+
+ <para>
+ Como a coleção de permissões não foi inicializada quando a <literal>Session</literal>
+ foi fechada, a coleção não poderá carregar o seu estado. O Hibernate não suporta
+ inicialização preguiçosa para objetos desconectados. Para consertar isso, é necessário
+ mover o código que carrega a coleção para antes da transação ser comitada.
+ </para>
+
+ <para>
+ Alternativamente, nós podemos usar uma coleção ou associação não preguiçosa,
+ especificando <literal>lazy="false"</literal> para o mapeamento da associação.
+ Porém, é pretendido que a inicialização preguiçosa seja usada por quase todas as
+ coleções e associações. Se você definir muitas associações não preguiçosas em seu
+ modelo de objetos, o Hibernate irá precisar carregar o banco de dados inteiro na memória
+ em cada transação!
+ </para>
+
+ <para>
+ Por outro lado, nós geralmente escolhemos join fetching (que é não preguiçosa por natureza)
+ ao invés de select fetching em uma transação particular. Nós iremos ver como customizar
+ a estratégoa de busca. No Hibernate3, os mecanismos para escolher a estratégia de fetching
+ são identicos para as associações simples e para coleções.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-custom" revision="4">
+ <title>Personalizando as estratégias de busca</title>
+
+ <para>
+ O select fetching (o padrão) é extremamente vunerável para N+1 problemas em select,
+ então nós iremos querer habilitar o join fetching no documento de mapeamento:
+ </para>
+
+ <programlisting><![CDATA[<set name="permissions"
+ fetch="join">
+ <key column="userId"/>
+ <one-to-many class="Permission"/>
+</set]]></programlisting>
+
+ <programlisting><![CDATA[<many-to-one name="mother" class="Cat" fetch="join"/>]]></programlisting>
+
+ <para>
+ A estratégia de <literal>fetch</literal> definida no documento de mapeamento afeta:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ recupera via <literal>get()</literal> ou <literal>load()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Recuperações que acontecem implicitamente quando navegamos por uma associação
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Criteria</literal> queries
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ buscas por HQL se buscar por <literal>subselect</literal> for usado
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Independentemente da estratégia de busca que você usar, o grafo não preguiçoso definido
+ será garantidamente carregado na memória. Note que isso irá resultar em diversos selects
+ imediatos sendo usados em um HQL em particular.
+ </para>
+
+ <para>
+ Usualmente não usamos documentos de mapeamento para customizar as buscas. Ao invés disso,
+ nós deixamos o comportamento padrão e sobrescrevemos isso em uma transação em particular,
+ usando <literal>left join fetch</literal> no HQL. Isso diz ao Hibernate para buscar a associação
+ inteira no primeiro select, usando um outer join. Na API de busca <literal>Criteria</literal>,
+ você irá usar <literal>setFetchMode(FetchMode.JOIN)</literal>.
+ </para>
+
+ <para>
+ Se você quiser mudar a estratégia de busca usada pelo <literal>get()</literal>
+ ou <literal>load()</literal>, simplesmente use uma query <literal>Criteria</literal>,
+ por exemplo:
+ </para>
+
+ <programlisting><![CDATA[User user = (User) session.createCriteria(User.class)
+ .setFetchMode("permissions", FetchMode.JOIN)
+ .add( Restrictions.idEq(userId) )
+ .uniqueResult();]]></programlisting>
+
+ <para>
+ (Isto é o equivalente do Hibernate para o que algumas soluções ORM chamam de "plano de busca")
+ </para>
+
+ <para>
+ Um meio totalmente diferente de evitar problemas com selects N+1 é usar um cache de segundo nível.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-proxies" revision="2">
+ <title>Proxies de associação single-ended</title>
+
+ <para>
+ A recuperação preguiçosa para coleções é implementada usando uma implementação
+ própria do Hibernate para coleções persistentes. Porém, um mecanismo diferente é
+ necessário para comportamento preguiçoso para associações de um lado só. A entidade
+ alvo da associação precisa usar um proxy. O Hibernate implementa proxies para inicialização
+ preguiçosa em objetos persistentes usando manipulação de bytecode
+ (via a excelente biblioteca CGLIB).
+ </para>
+
+ <para>
+ Por padrão, o Hibernate3 gera proxies (na inicialização) para todas as classes
+ persistentes que usem eles para habilitar recuperaçãopreguiçosa de associações
+ <literal>many-to-one</literal> e <literal>one-to-one</literal>.
+ </para>
+
+ <para>
+ O arquivo de mapeamento deve declaram uma interface para usar como interface de proxy
+ para aquela classe, com o atributo <literal>proxy</literal>. Por padrão, o Hibernate usa
+ uma subclasse dessa classe. <emphasis>Note que a classe a ser usada via proxy precisa
+ implementar o construtor padrão com pelo menos visibilidade de package. Nós recomendamos
+ esse construtor para todas as classes persistentes!</emphasis>
+ </para>
+
+ <para>
+ Existe alguns truques que você deve saber quando extender esse comportamento para classes
+ polimórficas, dessa maneira:
+ </para>
+
+ <programlisting><![CDATA[<class name="Cat" proxy="Cat">
+ ......
+ <subclass name="DomesticCat">
+ .....
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ Primeiramente, instâncias de <literal>Cat</literal> nunca seráo convertidas
+ para <literal>DomesticCat</literal>, mesmo que a instância em questão seja uma
+ estância de <literal>DomesticCat</literal>:
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(Cat.class, id); // instantiate a proxy (does not hit the db)
+if ( cat.isDomesticCat() ) { // hit the db to initialize the proxy
+ DomesticCat dc = (DomesticCat) cat; // Error!
+ ....
+}]]></programlisting>
+
+ <para>
+ É possível quebrar o proxy <literal>==</literal>.
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(Cat.class, id); // instantiate a Cat proxy
+DomesticCat dc =
+ (DomesticCat) session.load(DomesticCat.class, id); // acquire new DomesticCat proxy!
+System.out.println(cat==dc); // false]]></programlisting>
+
+ <para>
+ Porém a situação não é tão ruim como parece. Mesmo quando temos duas referências para
+ objetos proxies diferentes, a instância deles será o mesmo objeto
+ </para>
+
+ <programlisting><![CDATA[cat.setWeight(11.0); // hit the db to initialize the proxy
+System.out.println( dc.getWeight() ); // 11.0]]></programlisting>
+
+ <para>
+ Terceiro, Você não pode usar um proxy CGLIB em uma classe <literal>final</literal>
+ ou com qualquer método <literal>final</literal>.
+ </para>
+
+ <para>
+ Finalmente, se o seu objeto persistente adquirir qualquer recursto durante a instanciação
+ (em inicializadores ou construtor padrão), então esses recursos serão adquiridos pelo proxy
+ também. A classe de proxy é uma subclasse da classe persistente.
+ </para>
+
+ <para>
+ Esses problemas são todos devido a limitação fundamental do modelo de herança simples do Java.
+ Se você quiser evitar esse problemas em suas classes persistentes você deve imeplementar uma
+ interface que declare seus métodos de negócio. Você deve especificar essas interfaces no arquivo
+ de mapeamento. Ex:
+ </para>
+
+ <programlisting><![CDATA[<class name="CatImpl" proxy="Cat">
+ ......
+ <subclass name="DomesticCatImpl" proxy="DomesticCat">
+ .....
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ onde <literal>CatImpl</literal> implementa a interface <literal>Cat</literal> e
+ <literal>DomesticCatImpl</literal> implementa a interface <literal>DomesticCat</literal>.
+ Então proxies para instâncias de <literal>Cat</literal> e <literal>DomesticCat</literal>
+ serão retornadas por <literal>load()</literal> ou <literal>iterate()</literal>.
+ (Note que <literal>list()</literal> geralmente não retorna proxies).
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(CatImpl.class, catid);
+Iterator iter = session.createQuery("from CatImpl as cat where cat.name='fritz'").iterate();
+Cat fritz = (Cat) iter.next();]]></programlisting>
+
+ <para>
+ Relacionamentos são também carregados preguiçosamente. Isso significa que você precisa declarar
+ qualquer propriedade como sendo do tipo <literal>Cat</literal>, e não <literal>CatImpl</literal>.
+ </para>
+
+ <para>
+ Algumas operações <emphasis>não</emphasis> requerem inicialização por proxy:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>equals()</literal>, se a classe persistente não sobrescrever
+ <literal>equals()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>hashCode()</literal>, se a classe persistente não sobrescrever
+ <literal>hashCode()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ O método getter do identificador
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ O Hibernate irá detectar classes persistentes que sobrescrevem
+ <literal>equals()</literal> ou <literal>hashCode()</literal>.
+ </para>
+
+ <para>
+ Escolhendo <literal>lazy="no-proxy"</literal> ao invés do padrão
+ <literal>lazy="proxy"</literal>, podemos evitar problemas associados com typecasting.
+ Porém, iremos precisar de instrumentação de bytecode em tempo de compilação e todas
+ as operações irão resultar em iniciazações de proxy imediatas.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-initialization" revision="1">
+ <title>Inicializando coleções e proxies</title>
+
+ <para>
+ Será lançada uma <literal>LazyInitializationException</literal> se uma coleção não inicializada
+ ou proxy é acessado fora do escopo da <literal>Session</literal>, isto é, quando a entidade que
+ contém a coleção ou tem a referência ao proxy estiver no estado destachado.
+ </para>
+
+ <para>
+ Algumas vezes precisamos garantir qie o proxy ou coleção é inicializado antes de se fechar a
+ <literal>Session</literal>. Claro que sempre podemos forçar a inicialização chamando
+ <literal>cat.getSex()</literal> ou <literal>cat.getKittens().size()</literal>, por exemplo.
+ Mas isto parece confuso para quem lê o código e não é conveniente para códigos genéricos.
+ </para>
+
+ <para>
+ Os métodos estáticos <literal>Hibernate.initialize()</literal> e <literal>Hibernate.isInitialized()</literal>
+ possibilitam a aplicação uma maneira conveniente de trabalhar com coleções inicializadas preguiçosamente e
+ proxies. <literal>Hibernate.initialize(cat)</literal> irá forçar a inicialização de um proxy,
+ <literal>cat</literal>, contanto que a <literal>Session</literal> esteja ainda aberta.
+ <literal>Hibernate.initialize( cat.getKittens() )</literal> tem um efeito similar para a coleção de
+ kittens.
+ </para>
+
+ <para>
+ Outra opção é manter a <literal>Session</literal> aberta até que todas as coleções e
+ proxies necessários sejam carregados. Em algumas arquiteturas de aplicações, particularmente
+ onde o código que acessa os dados usando Hibernate e o código que usa os dados estão em diferentes
+ camadas da aplicação ou diferentes processos físicos, será um problema garantir que a
+ <literal>Session</literal> esteja aberta quando uma coleção for inicializada. Existem dois
+ caminhos básicos para lidar com esse problema:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Em aplicações web, um filtro servlet pode ser usado para fechar a
+ <literal>Session</literal> somente no final da requisição do usuário, já que a
+ renderização da visão estará completa (o pattern <emphasis>Open Session In View</emphasis>).
+ Claro, que isto cria a necessidade de um correto manuseio de exceções na infraestrutura
+ de sua aplicação. É vitalmente importante que a <literal>Session</literal> esteja fechada
+ e a transação terminada antes de retornar para o usuário, mesmo que uma exceção ocorra
+ durante a renderização da view. Veja o Wiki do Hibernate para exemplos do pattern
+ "Open Session In View"
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Em uma aplicação com uma camada de negócios separada, a lógica de negócios deve
+ "preparar" todas as coleções que serão usadas pela camada web antes de retornar.
+ Isto sgnifica que a camada de negócios deve carregar todos os dados e retorná-los
+ já inicializados para a camada de apresentação. Usualmente a aplicação chama
+ <literal>Hibernate.initialize()</literal> para cada coleção que será usada pela
+ camada web (essa chamada de método deve ocorrer antes da sessão ser fechada ou
+ retornar a coleção usando uma consulta Hibernate com uma cláusula <literal>FETCH</literal>
+ ou um <literal>FetchMode.JOIN</literal> na <literal>Criteria</literal>. Fica muito
+ mais fácil se você adotar o pattern <emphasis>Command</emphasis> ao invés do
+ <emphasis>Session Facade</emphasis>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Você também pode anexar um objeto prevaimente carregado em uma nova
+ <literal>Session</literal> <literal>merge()</literal> or <literal>lock()</literal>
+ antes de acessar coleções não inicializadas (ou outros proxies). O Hibernate não faz
+ e certamente <literal>não deve</literal> isso automaticamente pois isso introduziria
+ semantica em transações ad hoc.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ As vezes você não quer inicializar uma coleção muito grande, mas precisa de algumas
+ informações (como o tamanho) ou alguns de seus dados.
+ </para>
+
+ <para>
+ Você pode usar um filtro de coleção para saber seu tamanho sem a inicializar:
+ </para>
+
+ <programlisting><![CDATA[( (Integer) s.createFilter( collection, "select count(*)" ).list().get(0) ).intValue()]]></programlisting>
+
+ <para>
+ O método <literal>createFilter()</literal> é usado também para retornar algus dados de uma
+ coleção eficientemente sem precisar inicializar a coleção inteira:
+ </para>
+
+ <programlisting><![CDATA[s.createFilter( lazyCollection, "").setFirstResult(0).setMaxResults(10).list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-batch">
+ <title>Usando busca em lote</title>
+
+ <para>
+ O Hibernate pode fazer uso eficiente de busca em lote, isto é, o Hibernate pode carregar diversos
+ proxies não inicializados se um proxy é acessado (ou coleções. A busca em lote é uma otimização da
+ estratégia de select fetching). Existe duas maneiras em que você pode usar busca em lote: no nível
+ da classe ou no nível da coleção.
+ </para>
+
+ <para>
+ A recuperação em lote para classes/entidades é mais fácil de entender. Imagine que você tem a seguinte
+ situação em tempo de execução: Você tem 25 instâncias de <literal>Cat</literal> carregadas em uma
+ <literal>Session</literal>, cada <literal>Cat</literal> tem uma referência ao seu <literal>owner</literal>,
+ que é da classe <literal>Person</literal>. A classe <literal>Person</literal> é mapeada com um proxy,
+ <literal>lazy="true"</literal>. Se você iterar sobre todos os Cat's e chamar <literal>getOwner()</literal>
+ em cada, o Hibernate irá por padrão executar 25 comandos <literal>SELECT()</literal>, para buscar os
+ proxies de owners. Você pode melhorar esse comportamento especificando um <literal>batch-size</literal>
+ no mapeamento da classe <literal>Person</literal>:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person" batch-size="10">...</class>]]></programlisting>
+
+ <para>
+ O Hibernate irá executar agora apenas três consultas, buscando por vez, 10, 10 e 5 Person.
+ </para>
+
+ <para>
+ Você também pode habilitar busca em lote de uma coleção. Por exemplo, se cada <literal>Person</literal>
+ tem uma coleção preguiçosa de <literal>Cat</literal>s, e 10 pessoas estão já carregados em uma
+ <literal>Sesssion</literal>, serão gerados 10 <literal>SELECT</literal>s ao se iterar todas as
+ pessoas, um para cada chamada de <literal>getCats()</literal>.. Se você habilitar busca em lote
+ para a coleção de <literal>cats</literal> no mapeamento da classe <literal>Person</literal>,
+ o Hibernate pode fazer uma pré carga das coleções:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <set name="cats" batch-size="3">
+ ...
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ Com um <literal>batch-size</literal> de 3, o Hibernate irá carregar 3, 3, 3, 1 coleções em 4
+ <literal>SELECT</literal>s. Novamente, o valor do atributo depende do número esperado de coleções
+ não inicialiadas em determinada <literal>Session</literal>.
+ </para>
+
+ <para>
+ A busca em lote de coleções é particularmente útil quando você tem uma árvore encadeada de
+ items, ex. o típico padrão bill-of-materials (Se bem que um <emphasis>conjunto encadeado</emphasis>
+ ou <emphasis>caminho materializado </emphasis> pode ser uma opção melhor para árvores com mais
+ leitura)
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-subselect">
+ <title>Usando subselect fetching</title>
+
+ <para>
+ Se uma coleção ou proxy simples precisa ser recuperado, o Hibernate carrega todos eles
+ rodando novamente a query original em um subselect. Isso funciona da mesma maneira que busca
+ em lote, sem carregar tanto.
+ </para>
+
+ <!-- TODO: Write more about this -->
+
+ </sect2>
+
+ <sect2 id="performance-fetching-lazyproperties">
+ <title>Usando busca preguiçosa de propriedade</title>
+
+ <para>
+ O Hibernate3 suporta a carga posterior de propriedades individuais. Essa técnica de otimização
+ também conhecida como <emphasis>fetch groups</emphasis>. Veja que isso é mais uma funcionalidade
+ de marketing já que na prática, é mais importante otimização nas leituras dos registros do
+ que na leitura das colunas. Porém, carregar apenas algumas propriedades de uma classe pode
+ ser útil em casos extremos, onde tabelas legadas podem ter centenas de colunas e o modelo
+ de dados não pode ser melhorado.
+ </para>
+
+ <para>
+ Para habilitar a carga posterior de propriedade, é preciso setar o atributo
+ <literal>lazy</literal> no seu mapeamento de propriedade:
+ </para>
+
+ <programlisting><![CDATA[<class name="Document">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name" not-null="true" length="50"/>
+ <property name="summary" not-null="true" length="200" lazy="true"/>
+ <property name="text" not-null="true" length="2000" lazy="true"/>
+</class>]]></programlisting>
+
+ <para>
+ A carga posterior de propriedades requer instrumentação de bytecode! Se suas classes
+ persistentes não forem melhoradas, o Hibernate irá ignorar silenciosamente essa
+ configuração e usará busca imediatamente.
+ </para>
+
+ <para>
+ Para instrumentação de bytecode, use a seguinte tarefa do Ant:
+ </para>
+
+ <programlisting><![CDATA[<target name="instrument" depends="compile">
+ <taskdef name="instrument" classname="org.hibernate.tool.instrument.InstrumentTask">
+ <classpath path="${jar.path}"/>
+ <classpath path="${classes.dir}"/>
+ <classpath refid="lib.class.path"/>
+ </taskdef>
+
+ <instrument verbose="true">
+ <fileset dir="${testclasses.dir}/org/hibernate/auction/model">
+ <include name="*.class"/>
+ </fileset>
+ </instrument>
+</target>]]></programlisting>
+
+ <para>
+ A different (better?) way to avoid unnecessary column reads, at least for
+ read-only transactions is to use the projection features of HQL or Criteria
+ queries. This avoids the need for buildtime bytecode processing and is
+ certainly a prefered solution.
+ </para>
+
+ <para>
+ You may force the usual eager fetching of properties using <literal>fetch all
+ properties</literal> in HQL.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="performance-cache" revision="1">
+ <title>The Second Level Cache</title>
+
+ <para>
+ A Hibernate <literal>Session</literal> is a transaction-level cache of persistent data. It is
+ possible to configure a cluster or JVM-level (<literal>SessionFactory</literal>-level) cache on
+ a class-by-class and collection-by-collection basis. You may even plug in a clustered cache. Be
+ careful. Caches are never aware of changes made to the persistent store by another application
+ (though they may be configured to regularly expire cached data).
+ </para>
+
+ <para revision="1">
+ You have the option to tell Hibernate which caching implementation to use by
+ specifying the name of a class that implements <literal>org.hibernate.cache.CacheProvider</literal>
+ using the property <literal>hibernate.cache.provider_class</literal>. Hibernate
+ comes bundled with a number of built-in integrations with open-source cache providers
+ (listed below); additionally, you could implement your own and plug it in as
+ outlined above. Note that versions prior to 3.2 defaulted to use EhCache as the
+ default cache provider; that is no longer the case as of 3.2.
+ </para>
+
+ <table frame="topbot" id="cacheproviders" revision="1">
+ <title>Cache Providers</title>
+ <tgroup cols='5' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="3*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Cache</entry>
+ <entry>Provider class</entry>
+ <entry>Type</entry>
+ <entry>Cluster Safe</entry>
+ <entry>Query Cache Supported</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Hashtable (not intended for production use)</entry>
+ <entry><literal>org.hibernate.cache.HashtableCacheProvider</literal></entry>
+ <entry>memory</entry>
+ <entry></entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry>EHCache</entry>
+ <entry><literal>org.hibernate.cache.EhCacheProvider</literal></entry>
+ <entry>memory, disk</entry>
+ <entry></entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry>OSCache</entry>
+ <entry><literal>org.hibernate.cache.OSCacheProvider</literal></entry>
+ <entry>memory, disk</entry>
+ <entry></entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry>SwarmCache</entry>
+ <entry><literal>org.hibernate.cache.SwarmCacheProvider</literal></entry>
+ <entry>clustered (ip multicast)</entry>
+ <entry>yes (clustered invalidation)</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>JBoss TreeCache</entry>
+ <entry><literal>org.hibernate.cache.TreeCacheProvider</literal></entry>
+ <entry>clustered (ip multicast), transactional</entry>
+ <entry>yes (replication)</entry>
+ <entry>yes (clock sync req.)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="performance-cache-mapping" revision="2">
+ <title>Cache mappings</title>
+
+ <para>
+ The <literal><cache></literal> element of a class or collection mapping has the
+ following form:
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="cache1" coords="2 70"/>
+ <area id="cache2" coords="3 70"/>
+ <area id="cache3" coords="4 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<cache
+ usage="transactional|read-write|nonstrict-read-write|read-only"
+ region="RegionName"
+ include="all|non-lazy"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="cache1">
+ <para>
+ <literal>usage</literal> (required) specifies the caching strategy:
+ <literal>transactional</literal>,
+ <literal>read-write</literal>,
+ <literal>nonstrict-read-write</literal> or
+ <literal>read-only</literal>
+ </para>
+ </callout>
+ <callout arearefs="cache2">
+ <para>
+ <literal>region</literal> (optional, defaults to the class or
+ collection role name) specifies the name of the second level cache
+ region
+ </para>
+ </callout>
+ <callout arearefs="cache3">
+ <para>
+ <literal>include</literal> (optional, defaults to <literal>all</literal>)
+ <literal>non-lazy</literal> specifies that properties of the entity mapped
+ with <literal>lazy="true"</literal> may not be cached when attribute-level
+ lazy fetching is enabled
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Alternatively (preferrably?), you may specify <literal><class-cache></literal> and
+ <literal><collection-cache></literal> elements in <literal>hibernate.cfg.xml</literal>.
+ </para>
+
+ <para>
+ The <literal>usage</literal> attribute specifies a <emphasis>cache concurrency strategy</emphasis>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-cache-readonly">
+ <title>Strategy: read only</title>
+
+ <para>
+ If your application needs to read but never modify instances of a persistent class, a
+ <literal>read-only</literal> cache may be used. This is the simplest and best performing
+ strategy. It's even perfectly safe for use in a cluster.
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Immutable" mutable="false">
+ <cache usage="read-only"/>
+ ....
+</class>]]></programlisting>
+
+ </sect2>
+
+
+ <sect2 id="performance-cache-readwrite">
+ <title>Strategy: read/write</title>
+
+ <para>
+ If the application needs to update data, a <literal>read-write</literal> cache might be appropriate.
+ This cache strategy should never be used if serializable transaction isolation level is required.
+ If the cache is used in a JTA environment, you must specify the property
+ <literal>hibernate.transaction.manager_lookup_class</literal>, naming a strategy for obtaining the
+ JTA <literal>TransactionManager</literal>. In other environments, you should ensure that the transaction
+ is completed when <literal>Session.close()</literal> or <literal>Session.disconnect()</literal> is called.
+ If you wish to use this strategy in a cluster, you should ensure that the underlying cache implementation
+ supports locking. The built-in cache providers do <emphasis>not</emphasis>.
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Cat" .... >
+ <cache usage="read-write"/>
+ ....
+ <set name="kittens" ... >
+ <cache usage="read-write"/>
+ ....
+ </set>
+</class>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-cache-nonstrict">
+ <title>Strategy: nonstrict read/write</title>
+
+ <para>
+ If the application only occasionally needs to update data (ie. if it is extremely unlikely that two
+ transactions would try to update the same item simultaneously) and strict transaction isolation is
+ not required, a <literal>nonstrict-read-write</literal> cache might be appropriate. If the cache is
+ used in a JTA environment, you must specify <literal>hibernate.transaction.manager_lookup_class</literal>.
+ In other environments, you should ensure that the transaction is completed when
+ <literal>Session.close()</literal> or <literal>Session.disconnect()</literal> is called.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-cache-transactional">
+ <title>Strategy: transactional</title>
+
+ <para>
+ The <literal>transactional</literal> cache strategy provides support for fully transactional cache
+ providers such as JBoss TreeCache. Such a cache may only be used in a JTA environment and you must
+ specify <literal>hibernate.transaction.manager_lookup_class</literal>.
+ </para>
+
+ </sect2>
+
+ <para>
+ None of the cache providers support all of the cache concurrency strategies. The following table shows
+ which providers are compatible with which concurrency strategies.
+ </para>
+
+ <table frame="topbot">
+ <title>Cache Concurrency Strategy Support</title>
+ <tgroup cols='5' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="1*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Cache</entry>
+ <entry>read-only</entry>
+ <entry>nonstrict-read-write</entry>
+ <entry>read-write</entry>
+ <entry>transactional</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Hashtable (not intended for production use)</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>EHCache</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>OSCache</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>SwarmCache</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>JBoss TreeCache</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>yes</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="performance-sessioncache" revision="2">
+ <title>Managing the caches</title>
+
+ <para>
+ Whenever you pass an object to <literal>save()</literal>, <literal>update()</literal>
+ or <literal>saveOrUpdate()</literal> and whenever you retrieve an object using
+ <literal>load()</literal>, <literal>get()</literal>, <literal>list()</literal>,
+ <literal>iterate()</literal> or <literal>scroll()</literal>, that object is added
+ to the internal cache of the <literal>Session</literal>.
+ </para>
+ <para>
+ When <literal>flush()</literal> is subsequently called, the state of that object will
+ be synchronized with the database. If you do not want this synchronization to occur or
+ if you are processing a huge number of objects and need to manage memory efficiently,
+ the <literal>evict()</literal> method may be used to remove the object and its collections
+ from the first-level cache.
+ </para>
+
+ <programlisting><![CDATA[ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set
+while ( cats.next() ) {
+ Cat cat = (Cat) cats.get(0);
+ doSomethingWithACat(cat);
+ sess.evict(cat);
+}]]></programlisting>
+
+ <para>
+ The <literal>Session</literal> also provides a <literal>contains()</literal> method to determine
+ if an instance belongs to the session cache.
+ </para>
+
+ <para>
+ To completely evict all objects from the session cache, call <literal>Session.clear()</literal>
+ </para>
+
+ <para>
+ For the second-level cache, there are methods defined on <literal>SessionFactory</literal> for
+ evicting the cached state of an instance, entire class, collection instance or entire collection
+ role.
+ </para>
+
+ <programlisting><![CDATA[sessionFactory.evict(Cat.class, catId); //evict a particular Cat
+sessionFactory.evict(Cat.class); //evict all Cats
+sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
+sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections]]></programlisting>
+
+ <para>
+ The <literal>CacheMode</literal> controls how a particular session interacts with the second-level
+ cache.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>CacheMode.NORMAL</literal> - read items from and write items to the second-level cache
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.GET</literal> - read items from the second-level cache, but don't write to
+ the second-level cache except when updating data
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.PUT</literal> - write items to the second-level cache, but don't read from
+ the second-level cache
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.REFRESH</literal> - write items to the second-level cache, but don't read from
+ the second-level cache, bypass the effect of <literal>hibernate.cache.use_minimal_puts</literal>, forcing
+ a refresh of the second-level cache for all items read from the database
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ To browse the contents of a second-level or query cache region, use the <literal>Statistics</literal>
+ API:
+ </para>
+
+ <programlisting><![CDATA[Map cacheEntries = sessionFactory.getStatistics()
+ .getSecondLevelCacheStatistics(regionName)
+ .getEntries();]]></programlisting>
+
+ <para>
+ You'll need to enable statistics, and, optionally, force Hibernate to keep the cache entries in a
+ more human-understandable format:
+ </para>
+
+ <programlisting><![CDATA[hibernate.generate_statistics true
+hibernate.cache.use_structured_entries true]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="performance-querycache" revision="1">
+ <title>The Query Cache</title>
+
+ <para>
+ Query result sets may also be cached. This is only useful for queries that are run
+ frequently with the same parameters. To use the query cache you must first enable it:
+ </para>
+
+ <programlisting><![CDATA[hibernate.cache.use_query_cache true]]></programlisting>
+
+ <para>
+ This setting causes the creation of two new cache regions - one holding cached query
+ result sets (<literal>org.hibernate.cache.StandardQueryCache</literal>), the other
+ holding timestamps of the most recent updates to queryable tables
+ (<literal>org.hibernate.cache.UpdateTimestampsCache</literal>). Note that the query
+ cache does not cache the state of the actual entities in the result set; it caches
+ only identifier values and results of value type. So the query cache should always be
+ used in conjunction with the second-level cache.
+ </para>
+
+ <para>
+ Most queries do not benefit from caching, so by default queries are not cached. To
+ enable caching, call <literal>Query.setCacheable(true)</literal>. This call allows
+ the query to look for existing cache results or add its results to the cache when
+ it is executed.
+ </para>
+
+ <para>
+ If you require fine-grained control over query cache expiration policies, you may
+ specify a named cache region for a particular query by calling
+ <literal>Query.setCacheRegion()</literal>.
+ </para>
+
+ <programlisting><![CDATA[List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger")
+ .setEntity("blogger", blogger)
+ .setMaxResults(15)
+ .setCacheable(true)
+ .setCacheRegion("frontpages")
+ .list();]]></programlisting>
+
+ <para>
+ If the query should force a refresh of its query cache region, you should call
+ <literal>Query.setCacheMode(CacheMode.REFRESH)</literal>. This is particularly useful
+ in cases where underlying data may have been updated via a separate process (i.e.,
+ not modified through Hibernate) and allows the application to selectively refresh
+ particular query result sets. This is a more efficient alternative to eviction of
+ a query cache region via <literal>SessionFactory.evictQueries()</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="performance-collections">
+ <title>Understanding Collection performance</title>
+
+ <para>
+ We've already spent quite some time talking about collections.
+ In this section we will highlight a couple more issues about
+ how collections behave at runtime.
+ </para>
+
+ <sect2 id="performance-collections-taxonomy">
+ <title>Taxonomy</title>
+
+ <para>Hibernate defines three basic kinds of collections:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>collections of values</para>
+ </listitem>
+ <listitem>
+ <para>one to many associations</para>
+ </listitem>
+ <listitem>
+ <para>many to many associations</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ This classification distinguishes the various table and foreign key
+ relationships but does not tell us quite everything we need to know
+ about the relational model. To fully understand the relational structure
+ and performance characteristics, we must also consider the structure of
+ the primary key that is used by Hibernate to update or delete collection
+ rows. This suggests the following classification:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>indexed collections</para>
+ </listitem>
+ <listitem>
+ <para>sets</para>
+ </listitem>
+ <listitem>
+ <para>bags</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ All indexed collections (maps, lists, arrays) have a primary key consisting
+ of the <literal><key></literal> and <literal><index></literal>
+ columns. In this case collection updates are usually extremely efficient -
+ the primary key may be efficiently indexed and a particular row may be efficiently
+ located when Hibernate tries to update or delete it.
+ </para>
+
+ <para>
+ Sets have a primary key consisting of <literal><key></literal> and element
+ columns. This may be less efficient for some types of collection element, particularly
+ composite elements or large text or binary fields; the database may not be able to index
+ a complex primary key as efficently. On the other hand, for one to many or many to many
+ associations, particularly in the case of synthetic identifiers, it is likely to be just
+ as efficient. (Side-note: if you want <literal>SchemaExport</literal> to actually create
+ the primary key of a <literal><set></literal> for you, you must declare all columns
+ as <literal>not-null="true"</literal>.)
+ </para>
+
+ <para>
+ <literal><idbag></literal> mappings define a surrogate key, so they are
+ always very efficient to update. In fact, they are the best case.
+ </para>
+
+ <para>
+ Bags are the worst case. Since a bag permits duplicate element values and has no
+ index column, no primary key may be defined. Hibernate has no way of distinguishing
+ between duplicate rows. Hibernate resolves this problem by completely removing
+ (in a single <literal>DELETE</literal>) and recreating the collection whenever it
+ changes. This might be very inefficient.
+ </para>
+
+ <para>
+ Note that for a one-to-many association, the "primary key" may not be the physical
+ primary key of the database table - but even in this case, the above classification
+ is still useful. (It still reflects how Hibernate "locates" individual rows of the
+ collection.)
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-collections-mostefficientupdate">
+ <title>Lists, maps, idbags and sets are the most efficient collections to update</title>
+
+ <para>
+ From the discussion above, it should be clear that indexed collections
+ and (usually) sets allow the most efficient operation in terms of adding,
+ removing and updating elements.
+ </para>
+
+ <para>
+ There is, arguably, one more advantage that indexed collections have over sets for
+ many to many associations or collections of values. Because of the structure of a
+ <literal>Set</literal>, Hibernate doesn't ever <literal>UPDATE</literal> a row when
+ an element is "changed". Changes to a <literal>Set</literal> always work via
+ <literal>INSERT</literal> and <literal>DELETE</literal> (of individual rows). Once
+ again, this consideration does not apply to one to many associations.
+ </para>
+
+ <para>
+ After observing that arrays cannot be lazy, we would conclude that lists, maps and
+ idbags are the most performant (non-inverse) collection types, with sets not far
+ behind. Sets are expected to be the most common kind of collection in Hibernate
+ applications. This is because the "set" semantics are most natural in the relational
+ model.
+ </para>
+
+ <para>
+ However, in well-designed Hibernate domain models, we usually see that most collections
+ are in fact one-to-many associations with <literal>inverse="true"</literal>. For these
+ associations, the update is handled by the many-to-one end of the association, and so
+ considerations of collection update performance simply do not apply.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-collections-mostefficentinverse">
+ <title>Bags and lists are the most efficient inverse collections</title>
+
+ <para>
+ Just before you ditch bags forever, there is a particular case in which bags (and also lists)
+ are much more performant than sets. For a collection with <literal>inverse="true"</literal>
+ (the standard bidirectional one-to-many relationship idiom, for example) we can add elements
+ to a bag or list without needing to initialize (fetch) the bag elements! This is because
+ <literal>Collection.add()</literal> or <literal>Collection.addAll()</literal> must always
+ return true for a bag or <literal>List</literal> (unlike a <literal>Set</literal>). This can
+ make the following common code much faster.
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) sess.load(Parent.class, id);
+Child c = new Child();
+c.setParent(p);
+p.getChildren().add(c); //no need to fetch the collection!
+sess.flush();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-collections-oneshotdelete">
+ <title>One shot delete</title>
+
+ <para>
+ Occasionally, deleting collection elements one by one can be extremely inefficient. Hibernate
+ isn't completely stupid, so it knows not to do that in the case of an newly-empty collection
+ (if you called <literal>list.clear()</literal>, for example). In this case, Hibernate will
+ issue a single <literal>DELETE</literal> and we are done!
+ </para>
+
+ <para>
+ Suppose we add a single element to a collection of size twenty and then remove two elements.
+ Hibernate will issue one <literal>INSERT</literal> statement and two <literal>DELETE</literal>
+ statements (unless the collection is a bag). This is certainly desirable.
+ </para>
+
+ <para>
+ However, suppose that we remove eighteen elements, leaving two and then add thee new elements.
+ There are two possible ways to proceed
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>delete eighteen rows one by one and then insert three rows</para>
+ </listitem>
+ <listitem>
+ <para>remove the whole collection (in one SQL <literal>DELETE</literal>) and insert
+ all five current elements (one by one)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate isn't smart enough to know that the second option is probably quicker in this case.
+ (And it would probably be undesirable for Hibernate to be that smart; such behaviour might
+ confuse database triggers, etc.)
+ </para>
+
+ <para>
+ Fortunately, you can force this behaviour (ie. the second strategy) at any time by discarding
+ (ie. dereferencing) the original collection and returning a newly instantiated collection with
+ all the current elements. This can be very useful and powerful from time to time.
+ </para>
+
+ <para>
+ Of course, one-shot-delete does not apply to collections mapped <literal>inverse="true"</literal>.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="performance-monitoring" revision="1">
+ <title>Monitoring performance</title>
+
+ <para>
+ Optimization is not much use without monitoring and access to performance numbers.
+ Hibernate provides a full range of figures about its internal operations.
+ Statistics in Hibernate are available per <literal>SessionFactory</literal>.
+ </para>
+
+ <sect2 id="performance-monitoring-sf" revision="2">
+ <title>Monitoring a SessionFactory</title>
+
+ <para>
+ You can access <literal>SessionFactory</literal> metrics in two ways.
+ Your first option is to call <literal>sessionFactory.getStatistics()</literal> and
+ read or display the <literal>Statistics</literal> yourself.
+ </para>
+
+ <para>
+ Hibernate can also use JMX to publish metrics if you enable the
+ <literal>StatisticsService</literal> MBean. You may enable a single MBean for all your
+ <literal>SessionFactory</literal> or one per factory. See the following code for
+ minimalistic configuration examples:
+ </para>
+
+ <programlisting><![CDATA[// MBean service registration for a specific SessionFactory
+Hashtable tb = new Hashtable();
+tb.put("type", "statistics");
+tb.put("sessionFactory", "myFinancialApp");
+ObjectName on = new ObjectName("hibernate", tb); // MBean object name
+
+StatisticsService stats = new StatisticsService(); // MBean implementation
+stats.setSessionFactory(sessionFactory); // Bind the stats to a SessionFactory
+server.registerMBean(stats, on); // Register the Mbean on the server]]></programlisting>
+
+
+<programlisting><![CDATA[// MBean service registration for all SessionFactory's
+Hashtable tb = new Hashtable();
+tb.put("type", "statistics");
+tb.put("sessionFactory", "all");
+ObjectName on = new ObjectName("hibernate", tb); // MBean object name
+
+StatisticsService stats = new StatisticsService(); // MBean implementation
+server.registerMBean(stats, on); // Register the MBean on the server]]></programlisting>
+
+ <para>
+ TODO: This doesn't make sense: In the first case, we retrieve and use the MBean directly. In the second one, we must give
+ the JNDI name in which the session factory is held before using it. Use
+ <literal>hibernateStatsBean.setSessionFactoryJNDIName("my/JNDI/Name")</literal>
+ </para>
+ <para>
+ You can (de)activate the monitoring for a <literal>SessionFactory</literal>
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ at configuration time, set <literal>hibernate.generate_statistics</literal> to <literal>false</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>
+ at runtime: <literal>sf.getStatistics().setStatisticsEnabled(true)</literal>
+ or <literal>hibernateStatsBean.setStatisticsEnabled(true)</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Statistics can be reset programatically using the <literal>clear()</literal> method.
+ A summary can be sent to a logger (info level) using the <literal>logSummary()</literal>
+ method.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-monitoring-metrics" revision="1">
+ <title>Metrics</title>
+
+ <para>
+ Hibernate provides a number of metrics, from very basic to the specialized information
+ only relevant in certain scenarios. All available counters are described in the
+ <literal>Statistics</literal> interface API, in three categories:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Metrics related to the general <literal>Session</literal> usage, such as
+ number of open sessions, retrieved JDBC connections, etc.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Metrics related to he entities, collections, queries, and caches as a
+ whole (aka global metrics),
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Detailed metrics related to a particular entity, collection, query or
+ cache region.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ For exampl,e you can check the cache hit, miss, and put ratio of entities, collections
+ and queries, and the average time a query needs. Beware that the number of milliseconds
+ is subject to approximation in Java. Hibernate is tied to the JVM precision, on some
+ platforms this might even only be accurate to 10 seconds.
+ </para>
+
+ <para>
+ Simple getters are used to access the global metrics (i.e. not tied to a particular entity,
+ collection, cache region, etc.). You can access the metrics of a particular entity, collection
+ or cache region through its name, and through its HQL or SQL representation for queries. Please
+ refer to the <literal>Statistics</literal>, <literal>EntityStatistics</literal>,
+ <literal>CollectionStatistics</literal>, <literal>SecondLevelCacheStatistics</literal>,
+ and <literal>QueryStatistics</literal> API Javadoc for more information. The following
+ code shows a simple example:
+ </para>
+
+ <programlisting><![CDATA[Statistics stats = HibernateUtil.sessionFactory.getStatistics();
+
+double queryCacheHitCount = stats.getQueryCacheHitCount();
+double queryCacheMissCount = stats.getQueryCacheMissCount();
+double queryCacheHitRatio =
+ queryCacheHitCount / (queryCacheHitCount + queryCacheMissCount);
+
+log.info("Query Hit ratio:" + queryCacheHitRatio);
+
+EntityStatistics entityStats =
+ stats.getEntityStatistics( Cat.class.getName() );
+long changes =
+ entityStats.getInsertCount()
+ + entityStats.getUpdateCount()
+ + entityStats.getDeleteCount();
+log.info(Cat.class.getName() + " changed " + changes + "times" );]]></programlisting>
+
+ <para>
+ To work on all entities, collections, queries and region caches, you can retrieve
+ the list of names of entities, collections, queries and region caches with the
+ following methods: <literal>getQueries()</literal>, <literal>getEntityNames()</literal>,
+ <literal>getCollectionRoleNames()</literal>, and
+ <literal>getSecondLevelCacheRegionNames()</literal>.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/persistent_classes.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/persistent_classes.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/persistent_classes.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/persistent_classes.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,531 @@
+<chapter id="persistent-classes" revision="2">
+ <title>Persistent Classes</title>
+
+ <para>
+ Persistent classes are classes in an application that implement the entities
+ of the business problem (e.g. Customer and Order in an E-commerce application).
+ Not all instances of a persistent class are considered to be in the persistent
+ state - an instance may instead be transient or detached.
+ </para>
+
+ <para>
+ Hibernate works best if these classes follow some simple rules, also known
+ as the Plain Old Java Object (POJO) programming model. However, none of these
+ rules are hard requirements. Indeed, Hibernate3 assumes very little about
+ the nature of your persistent objects. You may express a domain model in other
+ ways: using trees of <literal>Map</literal> instances, for example.
+ </para>
+
+ <sect1 id="persistent-classes-pojo">
+ <title>A simple POJO example</title>
+
+ <para>
+ Most Java applications require a persistent class representing felines.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+import java.util.Date;
+
+public class Cat {
+ private Long id; // identifier
+
+ private Date birthdate;
+ private Color color;
+ private char sex;
+ private float weight;
+ private int litterId;
+
+ private Cat mother;
+ private Set kittens = new HashSet();
+
+ private void setId(Long id) {
+ this.id=id;
+ }
+ public Long getId() {
+ return id;
+ }
+
+ void setBirthdate(Date date) {
+ birthdate = date;
+ }
+ public Date getBirthdate() {
+ return birthdate;
+ }
+
+ void setWeight(float weight) {
+ this.weight = weight;
+ }
+ public float getWeight() {
+ return weight;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+ void setColor(Color color) {
+ this.color = color;
+ }
+
+ void setSex(char sex) {
+ this.sex=sex;
+ }
+ public char getSex() {
+ return sex;
+ }
+
+ void setLitterId(int id) {
+ this.litterId = id;
+ }
+ public int getLitterId() {
+ return litterId;
+ }
+
+ void setMother(Cat mother) {
+ this.mother = mother;
+ }
+ public Cat getMother() {
+ return mother;
+ }
+ void setKittens(Set kittens) {
+ this.kittens = kittens;
+ }
+ public Set getKittens() {
+ return kittens;
+ }
+
+ // addKitten not needed by Hibernate
+ public void addKitten(Cat kitten) {
+ kitten.setMother(this);
+ kitten.setLitterId( kittens.size() );
+ kittens.add(kitten);
+ }
+}]]></programlisting>
+
+ <para>
+ There are four main rules to follow here:
+ </para>
+
+
+ <sect2 id="persistent-classes-pojo-constructor" revision="1">
+ <title>Implement a no-argument constructor</title>
+
+ <para>
+ <literal>Cat</literal> has a no-argument constructor. All persistent classes must
+ have a default constructor (which may be non-public) so that Hibernate can instantiate
+ them using <literal>Constructor.newInstance()</literal>. We strongly recommend having a
+ default constructor with at least <emphasis>package</emphasis> visibility for runtime proxy
+ generation in Hibernate.
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-identifier" revision="2">
+ <title>Provide an identifier property (optional)</title>
+
+ <para>
+ <literal>Cat</literal> has a property called <literal>id</literal>. This property
+ maps to the primary key column of a database table. The property might have been called
+ anything, and its type might have been any primitive type, any primitive "wrapper"
+ type, <literal>java.lang.String</literal> or <literal>java.util.Date</literal>. (If
+ your legacy database table has composite keys, you can even use a user-defined class
+ with properties of these types - see the section on composite identifiers later.)
+ </para>
+
+ <para>
+ The identifier property is strictly optional. You can leave them off and let Hibernate
+ keep track of object identifiers internally. We do not recommend this, however.
+ </para>
+
+ <para>
+ In fact, some functionality is available only to classes which declare an
+ identifier property:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Transitive reattachment for detached objects (cascade update or cascade
+ merge) - see <xref linkend="objectstate-transitive"/>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.saveOrUpdate()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.merge()</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ We recommend you declare consistently-named identifier properties on persistent
+ classes. We further recommend that you use a nullable (ie. non-primitive) type.
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-final">
+ <title>Prefer non-final classes (optional)</title>
+ <para>
+ A central feature of Hibernate, <emphasis>proxies</emphasis>, depends upon the
+ persistent class being either non-final, or the implementation of an interface
+ that declares all public methods.
+ </para>
+ <para>
+ You can persist <literal>final</literal> classes that do not implement an interface
+ with Hibernate, but you won't be able to use proxies for lazy association fetching -
+ which will limit your options for performance tuning.
+ </para>
+ <para>
+ You should also avoid declaring <literal>public final</literal> methods on the
+ non-final classes. If you want to use a class with a <literal>public final</literal>
+ method, you must explicitly disable proying by setting <literal>lazy="false"</literal>.
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-accessors" revision="2">
+ <title>Declare accessors and mutators for persistent fields (optional)</title>
+
+ <para>
+ <literal>Cat</literal> declares accessor methods for all its persistent fields.
+ Many other ORM tools directly persist instance variables. We believe it is
+ better to provide an indirection between the relational schema and internal
+ data structures of the class. By default, Hibernate persists JavaBeans style
+ properties, and recognizes method names of the form <literal>getFoo</literal>,
+ <literal>isFoo</literal> and <literal>setFoo</literal>. You may switch to direct
+ field access for particular properties, if needed.
+ </para>
+
+ <para>
+ Properties need <emphasis>not</emphasis> be declared public - Hibernate can
+ persist a property with a default, <literal>protected</literal> or
+ <literal>private</literal> get / set pair.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-inheritance">
+ <title>Implementing inheritance</title>
+
+ <para>
+ A subclass must also observe the first and second rules. It inherits its
+ identifier property from the superclass, <literal>Cat</literal>.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+public class DomesticCat extends Cat {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+ protected void setName(String name) {
+ this.name=name;
+ }
+}]]></programlisting>
+ </sect1>
+
+ <sect1 id="persistent-classes-equalshashcode" revision="1">
+ <title>Implementing <literal>equals()</literal> and <literal>hashCode()</literal></title>
+
+ <para>
+ You have to override the <literal>equals()</literal> and <literal>hashCode()</literal>
+ methods if you
+ </para>
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ intend to put instances of persistent classes in a <literal>Set</literal>
+ (the recommended way to represent many-valued associations)
+ <emphasis>and</emphasis>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ intend to use reattachment of detached instances
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate guarantees equivalence of persistent identity (database row) and Java identity
+ only inside a particular session scope. So as soon as we mix instances retrieved in
+ different sessions, we must implement <literal>equals()</literal> and
+ <literal>hashCode()</literal> if we wish to have meaningful semantics for
+ <literal>Set</literal>s.
+ </para>
+
+ <para>
+ The most obvious way is to implement <literal>equals()</literal>/<literal>hashCode()</literal>
+ by comparing the identifier value of both objects. If the value is the same, both must
+ be the same database row, they are therefore equal (if both are added to a <literal>Set</literal>,
+ we will only have one element in the <literal>Set</literal>). Unfortunately, we can't use that
+ approach with generated identifiers! Hibernate will only assign identifier values to objects
+ that are persistent, a newly created instance will not have any identifier value! Furthermore,
+ if an instance is unsaved and currently in a <literal>Set</literal>, saving it will assign
+ an identifier value to the object. If <literal>equals()</literal> and <literal>hashCode()</literal>
+ are based on the identifier value, the hash code would change, breaking the contract of the
+ <literal>Set</literal>. See the Hibernate website for a full discussion of this problem. Note
+ that this is not a Hibernate issue, but normal Java semantics of object identity and equality.
+ </para>
+
+ <para>
+ We recommend implementing <literal>equals()</literal> and <literal>hashCode()</literal>
+ using <emphasis>Business key equality</emphasis>. Business key equality means that the
+ <literal>equals()</literal> method compares only the properties that form the business
+ key, a key that would identify our instance in the real world (a
+ <emphasis>natural</emphasis> candidate key):
+ </para>
+
+ <programlisting><![CDATA[public class Cat {
+
+ ...
+ public boolean equals(Object other) {
+ if (this == other) return true;
+ if ( !(other instanceof Cat) ) return false;
+
+ final Cat cat = (Cat) other;
+
+ if ( !cat.getLitterId().equals( getLitterId() ) ) return false;
+ if ( !cat.getMother().equals( getMother() ) ) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = getMother().hashCode();
+ result = 29 * result + getLitterId();
+ return result;
+ }
+
+}]]></programlisting>
+
+ <para>
+ Note that a business key does not have to be as solid as a database
+ primary key candidate (see <xref linkend="transactions-basics-identity"/>).
+ Immutable or unique properties are usually good
+ candidates for a business key.
+ </para>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-dynamicmodels">
+ <title>Dynamic models</title>
+
+ <para>
+ <emphasis>Note that the following features are currently considered
+ experimental and may change in the near future.</emphasis>
+ </para>
+
+ <para>
+ Persistent entities don't necessarily have to be represented as POJO classes
+ or as JavaBean objects at runtime. Hibernate also supports dynamic models
+ (using <literal>Map</literal>s of <literal>Map</literal>s at runtime) and the
+ representation of entities as DOM4J trees. With this approach, you don't
+ write persistent classes, only mapping files.
+ </para>
+
+ <para>
+ By default, Hibernate works in normal POJO mode. You may set a default entity
+ representation mode for a particular <literal>SessionFactory</literal> using the
+ <literal>default_entity_mode</literal> configuration option (see
+ <xref linkend="configuration-optional-properties"/>.
+ </para>
+
+ <para>
+ The following examples demonstrates the representation using <literal>Map</literal>s.
+ First, in the mapping file, an <literal>entity-name</literal> has to be declared
+ instead of (or in addition to) a class name:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class entity-name="Customer">
+
+ <id name="id"
+ type="long"
+ column="ID">
+ <generator class="sequence"/>
+ </id>
+
+ <property name="name"
+ column="NAME"
+ type="string"/>
+
+ <property name="address"
+ column="ADDRESS"
+ type="string"/>
+
+ <many-to-one name="organization"
+ column="ORGANIZATION_ID"
+ class="Organization"/>
+
+ <bag name="orders"
+ inverse="true"
+ lazy="false"
+ cascade="all">
+ <key column="CUSTOMER_ID"/>
+ <one-to-many class="Order"/>
+ </bag>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+
+ Note that even though associations are declared using target class names,
+ the target type of an associations may also be a dynamic entity instead
+ of a POJO.
+ </para>
+
+ <para>
+ After setting the default entity mode to <literal>dynamic-map</literal>
+ for the <literal>SessionFactory</literal>, we can at runtime work with
+ <literal>Map</literal>s of <literal>Map</literal>s:
+ </para>
+
+ <programlisting><![CDATA[Session s = openSession();
+Transaction tx = s.beginTransaction();
+Session s = openSession();
+
+// Create a customer
+Map david = new HashMap();
+david.put("name", "David");
+
+// Create an organization
+Map foobar = new HashMap();
+foobar.put("name", "Foobar Inc.");
+
+// Link both
+david.put("organization", foobar);
+
+// Save both
+s.save("Customer", david);
+s.save("Organization", foobar);
+
+tx.commit();
+s.close();]]></programlisting>
+
+ <para>
+ The advantages of a dynamic mapping are quick turnaround time for prototyping
+ without the need for entity class implementation. However, you lose compile-time
+ type checking and will very likely deal with many exceptions at runtime. Thanks
+ to the Hibernate mapping, the database schema can easily be normalized and sound,
+ allowing to add a proper domain model implementation on top later on.
+ </para>
+
+ <para>
+ Entity representation modes can also be set on a per <literal>Session</literal>
+ basis:
+ </para>
+
+ <programlisting><![CDATA[Session dynamicSession = pojoSession.getSession(EntityMode.MAP);
+
+// Create a customer
+Map david = new HashMap();
+david.put("name", "David");
+dynamicSession.save("Customer", david);
+...
+dynamicSession.flush();
+dynamicSession.close()
+...
+// Continue on pojoSession
+]]></programlisting>
+
+
+ <para>
+ Please note that the call to <literal>getSession()</literal> using an
+ <literal>EntityMode</literal> is on the <literal>Session</literal> API, not the
+ <literal>SessionFactory</literal>. That way, the new <literal>Session</literal>
+ shares the underlying JDBC connection, transaction, and other context
+ information. This means you don't have tocall <literal>flush()</literal>
+ and <literal>close()</literal> on the secondary <literal>Session</literal>, and
+ also leave the transaction and connection handling to the primary unit of work.
+ </para>
+
+ <para>
+ More information about the XML representation capabilities can be found
+ in <xref linkend="xml"/>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-tuplizers" revision="0">
+ <title>Tuplizers</title>
+
+ <para>
+ <literal>org.hibernate.tuple.Tuplizer</literal>, and its sub-interfaces, are responsible
+ for managing a particular representation of a piece of data, given that representation's
+ <literal>org.hibernate.EntityMode</literal>. If a given piece of data is thought of as
+ a data structure, then a tuplizer is the thing which knows how to create such a data structure
+ and how to extract values from and inject values into such a data structure. For example,
+ for the POJO entity mode, the correpsonding tuplizer knows how create the POJO through its
+ constructor and how to access the POJO properties using the defined property accessors.
+ There are two high-level types of Tuplizers, represented by the
+ <literal>org.hibernate.tuple.EntityTuplizer</literal> and <literal>org.hibernate.tuple.ComponentTuplizer</literal>
+ interfaces. <literal>EntityTuplizer</literal>s are responsible for managing the above mentioned
+ contracts in regards to entities, while <literal>ComponentTuplizer</literal>s do the same for
+ components.
+ </para>
+
+ <para>
+ Users may also plug in their own tuplizers. Perhaps you require that a <literal>java.util.Map</literal>
+ implementation other than <literal>java.util.HashMap</literal> be used while in the
+ dynamic-map entity-mode; or perhaps you need to define a different proxy generation strategy
+ than the one used by default. Both would be achieved by defining a custom tuplizer
+ implementation. Tuplizers definitions are attached to the entity or component mapping they
+ are meant to manage. Going back to the example of our customer entity:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+ <class entity-name="Customer">
+ <!--
+ Override the dynamic-map entity-mode
+ tuplizer for the customer entity
+ -->
+ <tuplizer entity-mode="dynamic-map"
+ class="CustomMapTuplizerImpl"/>
+
+ <id name="id" type="long" column="ID">
+ <generator class="sequence"/>
+ </id>
+
+ <!-- other properties -->
+ ...
+ </class>
+</hibernate-mapping>
+
+
+public class CustomMapTuplizerImpl
+ extends org.hibernate.tuple.DynamicMapEntityTuplizer {
+ // override the buildInstantiator() method to plug in our custom map...
+ protected final Instantiator buildInstantiator(
+ org.hibernate.mapping.PersistentClass mappingInfo) {
+ return new CustomMapInstantiator( mappingInfo );
+ }
+
+ private static final class CustomMapInstantiator
+ extends org.hibernate.tuple.DynamicMapInstantitor {
+ // override the generateMap() method to return our custom map...
+ protected final Map generateMap() {
+ return new CustomMap();
+ }
+ }
+}]]></programlisting>
+
+
+ </sect1>
+
+ <para>
+ TODO: Document user-extension framework in the property and proxy packages
+ </para>
+
+</chapter>
+
Added: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/preface.xml
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/preface.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/preface.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,120 @@
+<?xml version='1.0' encoding="iso-8859-1"?>
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<preface id="preface" revision="2">
+ <title>Pref�cio</title>
+
+ <para>
+ Trabalhando com software orientado a objetos e banco de dados relacional, podemos
+ ter alguns inc�modos hoje em dia em ambientes empresariais. Hibernate � uma ferramenta
+ que mapeia o objeto/relacional para o ambiente Java. O termo de mapeamento de
+ objeto/relacional (ou ORM � Object/Relational Mapping) se refere a t�cnica de mapear
+ uma representa��o de dados de um modelo de objeto para dados de modelo
+ relacional com o esquema baseado em SQL
+ </para>
+
+ <para>
+ O Hibernate n�o somente cuida do mapeamento de classes em Java
+ para tabelas de banco de dados (e de tipos de dados em Java para tipos de dados em SQL), como tamb�m
+ fornece facilidade de consultas e recupera��o de dados, podendo tamb�m reduzir significantemente o
+ tempo de desenvolvimento gasto com a manipula��o manual de dados no SQL e JDBC.
+ </para>
+
+ <para>
+ O objetivo do Hibernate � de aliviar o desenvolvedor de 95 por cento das tarefas de programa��o
+ relacionadas aos dados comuns de persist�ncia. O Hibernate talvez n�o seja a melhor solu��o para
+ aplica��es de dados-data-centric que somente usa stored-procedures para implementar a l�gica
+ de neg�cio no banco de dados, isto � muito utilizado com o dom�nio de modelos orientado a objetos e
+ l�gicas de neg�cio em camadas do meio (middle-tier) baseadas em Java. Por�m, o Hibernate
+ poder� certamente ajuda-lo a remover ou encapsular o c�digo SQL de um vendedor espec�fico,
+ ajudando tamb�m com a tarefa comum da tradu��o do resultado ajustado de uma representa��o
+ para um gr�fico de objetos.
+ </para>
+
+ <para>
+ Se voc� for novo no Hibernate e no mapeamento Objeto/Relacional, ou at� mesmo em Java,
+ por favor, siga os seguintes passos.
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ Leia <xref linkend="tutorial"/> para um tutorial com instru��es passo-a-passo.
+ O c�digo fonte para do tutorial est� inclu�do na distribui��o no diret�rio
+ <literal>doc/reference/tutorial/</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Leia o <xref linkend="architecture"/> para entender o ambiente onde o Hibernate pode ser utilizado.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ D� uma olhada no diret�rio de exemplo <literal>eg/</literal> da distribui��o
+ do Hibernate, ele cont�m uma simples aplica��o standalone.
+ Copie seu driver JDBC para o diret�rio <literal>lib/</literal> e edite o arquivo
+ <literal>etc/hibernate.properties</literal>, especificando corretamente os valores
+ para seu banco de dados. Usando o prompt de commando no diretorio de distribuicao,
+ digite <literal>ant eg</literal> (usando Ant), ou no Windows, digite
+ <literal>build eg</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Use esta documenta��o de referencia como sua fonte primaria de informa��o.
+ Considere ler tamb�m o livro <emphasis>Java Persistence with Hibernate</emphasis>
+ (http://www.manning.com/bauer2) caso voc� precise de mais ajuda com o
+ desenvolvimento de aplica��es ou caso prefira um tutorial passo-a-passo.
+ Tamb�m visite o site http://caveatemptor.hibernate.org e fa�a o download
+ da aplica��o de exemplo do Java Persistence with Hibernate.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ FAQs (perguntas feitas com mais freq��ncia) est�o respondidas no site do Hibernate
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Demonstra��es, exemplos e tutorials est�o dispon�veis no site do Hibernate.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A �rea da comunidade no site do Hibernate � uma boa fonte de recursos
+ para padr�es de projeto e v�rias solu��es de integra��o (Tomcat, JBoss AS, Struts, EJB, etc.).
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ Caso voc� tenha d�vidas, use o f�rum dos usu�rios encontrado no site do Hibernate.
+ N�s tamb�m fornecemos um sistema para controle de bug�s (JIRA) para relat�rios de erros
+ e requisi��es de features. Se voc� est� interessado no desenvolvimento do Hibernate,
+ junte-se a lista de e-mail dos desenvolvedores.
+ </para>
+
+ <para>
+ Suporte comercial de desenvolvimento, suporte de produ��o e treinamento para o Hibernate
+ est� dispon�vel atrav�s do JBoss Inc. (veja http://www.hibernate.org/SupportTraining).
+ O Hibernate � um Projeto Profissional de C�digo Aberto e um componente cr�tico da su�te
+ de produtos JBoss Enterprise Middleware System (JEMS).
+ </para>
+
+</preface>
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_criteria.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/query_criteria.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_criteria.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_criteria.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,436 @@
+<chapter id="querycriteria">
+ <title>Consultas por critérios</title>
+
+ <para>
+ O Hibernate provê uma intuitiva e extensível API de critério de query.
+ </para>
+
+ <sect1 id="querycriteria-creating">
+ <title>Criando uma instancia <literal>Criteria</literal></title>
+
+ <para>
+ A interface <literal>org.hibernate.Criteria</literal> representa a query
+ ao invés de uma classe persistente particular. A sessão é uma fábrica para
+ intancias de <literal>Criteria</literal> .
+ </para>
+
+ <programlisting><![CDATA[Criteria crit = sess.createCriteria(Cat.class);
+crit.setMaxResults(50);
+List cats = crit.list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-narrowing">
+ <title>Limitando o result set</title>
+
+ <para>
+ Um critério individual de query é uma instancia da interface
+ <literal>org.hibernate.criterion.Criterion</literal>. A classe
+ <literal>org.hibernate.criterion.Restrictions</literal> define
+ os métodos da fábrica para obter certos tipos pré fabricados
+ de <literal>Criterion</literal>.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .add( Restrictions.between("weight", minWeight, maxWeight) )
+ .list();]]></programlisting>
+
+ <para>
+ Restrições podem ser logicamente agrupadas.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .add( Restrictions.or(
+ Restrictions.eq( "age", new Integer(0) ),
+ Restrictions.isNull("age")
+ ) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
+ .add( Restrictions.disjunction()
+ .add( Restrictions.isNull("age") )
+ .add( Restrictions.eq("age", new Integer(0) ) )
+ .add( Restrictions.eq("age", new Integer(1) ) )
+ .add( Restrictions.eq("age", new Integer(2) ) )
+ ) )
+ .list();]]></programlisting>
+
+ <para>
+ Existe um grande número de critérios pré fabricados (subclasses de
+ <literal>Restrictions</literal>), mas um é especialmente útil pois
+ permite especificar o SQL diretamente.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.sqlRestriction("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) )
+ .list();]]></programlisting>
+
+ <para>
+ O parametro <literal>{alias}</literal> será substituido pelo alias da entidade procurada.
+ </para>
+
+ <para>
+ Uma maneira alternativa de obter um critério é pegá-lo de uma instancia de
+ <literal>Property</literal>. Você pode criar uma <literal>Property</literal>
+ chamando <literal>Property.forName()</literal>.
+ </para>
+
+ <programlisting><![CDATA[
+Property age = Property.forName("age");
+List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.disjunction()
+ .add( age.isNull() )
+ .add( age.eq( new Integer(0) ) )
+ .add( age.eq( new Integer(1) ) )
+ .add( age.eq( new Integer(2) ) )
+ ) )
+ .add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-ordering">
+ <title>Ordering the results</title>
+
+ <para>
+ You may order the results using <literal>org.hibernate.criterion.Order</literal>.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "F%")
+ .addOrder( Order.asc("name") )
+ .addOrder( Order.desc("age") )
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Property.forName("name").like("F%") )
+ .addOrder( Property.forName("name").asc() )
+ .addOrder( Property.forName("age").desc() )
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-associations" revision="2">
+ <title>Associations</title>
+
+ <para>
+ You may easily specify constraints upon related entities by navigating
+ associations using <literal>createCriteria()</literal>.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "F%") )
+ .createCriteria("kittens")
+ .add( Restrictions.like("name", "F%") )
+ .list();]]></programlisting>
+
+ <para>
+ note that the second <literal>createCriteria()</literal> returns a new
+ instance of <literal>Criteria</literal>, which refers to the elements of
+ the <literal>kittens</literal> collection.
+ </para>
+
+ <para>
+ The following, alternate form is useful in certain circumstances.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .createAlias("kittens", "kt")
+ .createAlias("mate", "mt")
+ .add( Restrictions.eqProperty("kt.name", "mt.name") )
+ .list();]]></programlisting>
+
+ <para>
+ (<literal>createAlias()</literal> does not create a new instance of
+ <literal>Criteria</literal>.)
+ </para>
+
+ <para>
+ Note that the kittens collections held by the <literal>Cat</literal> instances
+ returned by the previous two queries are <emphasis>not</emphasis> pre-filtered
+ by the criteria! If you wish to retrieve just the kittens that match the
+ criteria, you must use a <literal>ResultTransformer</literal>.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .createCriteria("kittens", "kt")
+ .add( Restrictions.eq("name", "F%") )
+ .setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP)
+ .list();
+Iterator iter = cats.iterator();
+while ( iter.hasNext() ) {
+ Map map = (Map) iter.next();
+ Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
+ Cat kitten = (Cat) map.get("kt");
+}]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-dynamicfetching" revision="1">
+ <title>Dynamic association fetching</title>
+
+ <para>
+ You may specify association fetching semantics at runtime using
+ <literal>setFetchMode()</literal>.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .setFetchMode("mate", FetchMode.EAGER)
+ .setFetchMode("kittens", FetchMode.EAGER)
+ .list();]]></programlisting>
+
+ <para>
+ This query will fetch both <literal>mate</literal> and <literal>kittens</literal>
+ by outer join. See <xref linkend="performance-fetching"/> for more information.
+ </para>
+
+ </sect1>
+
+ <sect1 id="querycriteria-examples">
+ <title>Example queries</title>
+
+ <para>
+ The class <literal>org.hibernate.criterion.Example</literal> allows
+ you to construct a query criterion from a given instance.
+ </para>
+
+ <programlisting><![CDATA[Cat cat = new Cat();
+cat.setSex('F');
+cat.setColor(Color.BLACK);
+List results = session.createCriteria(Cat.class)
+ .add( Example.create(cat) )
+ .list();]]></programlisting>
+
+ <para>
+ Version properties, identifiers and associations are ignored. By default,
+ null valued properties are excluded.
+ </para>
+
+ <para>
+ You can adjust how the <literal>Example</literal> is applied.
+ </para>
+
+ <programlisting><![CDATA[Example example = Example.create(cat)
+ .excludeZeroes() //exclude zero valued properties
+ .excludeProperty("color") //exclude the property named "color"
+ .ignoreCase() //perform case insensitive string comparisons
+ .enableLike(); //use like for string comparisons
+List results = session.createCriteria(Cat.class)
+ .add(example)
+ .list();]]></programlisting>
+
+ <para>
+ You can even use examples to place criteria upon associated objects.
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .add( Example.create(cat) )
+ .createCriteria("mate")
+ .add( Example.create( cat.getMate() ) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-projection">
+ <title>Projections, aggregation and grouping</title>
+ <para>
+ The class <literal>org.hibernate.criterion.Projections</literal> is a
+ factory for <literal>Projection</literal> instances. We apply a
+ projection to a query by calling <literal>setProjection()</literal>.
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.rowCount() )
+ .add( Restrictions.eq("color", Color.BLACK) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount() )
+ .add( Projections.avg("weight") )
+ .add( Projections.max("weight") )
+ .add( Projections.groupProperty("color") )
+ )
+ .list();]]></programlisting>
+
+ <para>
+ There is no explicit "group by" necessary in a criteria query. Certain
+ projection types are defined to be <emphasis>grouping projections</emphasis>,
+ which also appear in the SQL <literal>group by</literal> clause.
+ </para>
+
+ <para>
+ An alias may optionally be assigned to a projection, so that the projected value
+ may be referred to in restrictions or orderings. Here are two different ways to
+ do this:
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
+ .addOrder( Order.asc("colr") )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.groupProperty("color").as("colr") )
+ .addOrder( Order.asc("colr") )
+ .list();]]></programlisting>
+
+ <para>
+ The <literal>alias()</literal> and <literal>as()</literal> methods simply wrap a
+ projection instance in another, aliased, instance of <literal>Projection</literal>.
+ As a shortcut, you can assign an alias when you add the projection to a
+ projection list:
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount(), "catCountByColor" )
+ .add( Projections.avg("weight"), "avgWeight" )
+ .add( Projections.max("weight"), "maxWeight" )
+ .add( Projections.groupProperty("color"), "color" )
+ )
+ .addOrder( Order.desc("catCountByColor") )
+ .addOrder( Order.desc("avgWeight") )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Domestic.class, "cat")
+ .createAlias("kittens", "kit")
+ .setProjection( Projections.projectionList()
+ .add( Projections.property("cat.name"), "catName" )
+ .add( Projections.property("kit.name"), "kitName" )
+ )
+ .addOrder( Order.asc("catName") )
+ .addOrder( Order.asc("kitName") )
+ .list();]]></programlisting>
+
+ <para>
+ You can also use <literal>Property.forName()</literal> to express projections:
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Property.forName("name") )
+ .add( Property.forName("color").eq(Color.BLACK) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount().as("catCountByColor") )
+ .add( Property.forName("weight").avg().as("avgWeight") )
+ .add( Property.forName("weight").max().as("maxWeight") )
+ .add( Property.forName("color").group().as("color" )
+ )
+ .addOrder( Order.desc("catCountByColor") )
+ .addOrder( Order.desc("avgWeight") )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-detachedqueries">
+ <title>Detached queries and subqueries</title>
+ <para>
+ The <literal>DetachedCriteria</literal> class lets you create a query outside the scope
+ of a session, and then later execute it using some arbitrary <literal>Session</literal>.
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria query = DetachedCriteria.forClass(Cat.class)
+ .add( Property.forName("sex").eq('F') );
+
+Session session = ....;
+Transaction txn = session.beginTransaction();
+List results = query.getExecutableCriteria(session).setMaxResults(100).list();
+txn.commit();
+session.close();]]></programlisting>
+
+ <para>
+ A <literal>DetachedCriteria</literal> may also be used to express a subquery. Criterion
+ instances involving subqueries may be obtained via <literal>Subqueries</literal> or
+ <literal>Property</literal>.
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)
+ .setProjection( Property.forName("weight").avg() );
+session.createCriteria(Cat.class)
+ .add( Property.forName("weight").gt(avgWeight) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)
+ .setProjection( Property.forName("weight") );
+session.createCriteria(Cat.class)
+ .add( Subqueries.geAll("weight", weights) )
+ .list();]]></programlisting>
+
+ <para>
+ Even correlated subqueries are possible:
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")
+ .setProjection( Property.forName("weight").avg() )
+ .add( Property.forName("cat2.sex").eqProperty("cat.sex") );
+session.createCriteria(Cat.class, "cat")
+ .add( Property.forName("weight").gt(avgWeightForSex) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <!--TODO: ResultSetTransformer + aliasing. AliasToBeanTransformer allow returning arbitrary
+ user objects - similar to setResultClass in JDO2. General use of ResultTransformer
+ could also be explained. -->
+
+ <sect1 id="query-criteria-naturalid">
+ <title>Queries by natural identifier</title>
+
+ <para>
+ For most queries, including criteria queries, the query cache is not very efficient,
+ because query cache invalidation occurs too frequently. However, there is one special
+ kind of query where we can optimize the cache invalidation algorithm: lookups by a
+ constant natural key. In some applications, this kind of query occurs frequently.
+ The criteria API provides special provision for this use case.
+ </para>
+
+ <para>
+ First, you should map the natural key of your entity using
+ <literal><natural-id></literal>, and enable use of the second-level cache.
+ </para>
+
+ <programlisting><![CDATA[<class name="User">
+ <cache usage="read-write"/>
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <natural-id>
+ <property name="name"/>
+ <property name="org"/>
+ </natural-id>
+ <property name="password"/>
+</class>]]></programlisting>
+
+ <para>
+ Note that this functionality is not intended for use with entities with
+ <emphasis>mutable</emphasis> natural keys.
+ </para>
+
+ <para>
+ Next, enable the Hibernate query cache.
+ </para>
+
+ <para>
+ Now, <literal>Restrictions.naturalId()</literal> allows us to make use of
+ the more efficient cache algorithm.
+ </para>
+
+ <programlisting><![CDATA[session.createCriteria(User.class)
+ .add( Restrictions.naturalId()
+ .set("name", "gavin")
+ .set("org", "hb")
+ ).setCacheable(true)
+ .uniqueResult();]]></programlisting>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_hql.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/query_hql.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_hql.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_hql.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,1162 @@
+858
+
+<chapter id="queryhql">
+ <title>HQL: A linguagem de Queries do Hibernate</title>
+
+ <para>
+ O Hibernate vem com uma poderosa linguagem que é (intencionalmente) muito parecida
+ com o SQL. Mas não seja enganado pela sintaxe; a HQL é totalmente orientada à objetos,
+ requer conhecimentos de herança, polimorfismo e associações.
+ </para>
+
+ <sect1 id="queryhql-casesensitivity">
+ <title>Case Sensitíve</title>
+
+ <para>
+ As Queries não são case-sensitive, exceto pelo nomes das classes e propriedades Java.
+ <literal>sELEct</literal> e o mesmo que
+ <literal>SELECT</literal> mas
+ <literal>org.hibernate.eg.FOO</literal> não é
+ <literal>org.hibernate.eg.Foo</literal> e
+ <literal>foo.barSet</literal> não é
+ <literal>foo.BARSET</literal>.
+
+ </para>
+
+ <para>
+ Esse manual usa as palavras chave HQL em letras minúsculas. Alguns usuários acham que
+ com letras maiúsculas as queries ficam mais legíveis, mas nós achamos essa convenção feia
+ dentro do código Java.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-from">
+ <title>A clausula from</title>
+
+ <para>
+ A mais simples query possível do Hibernate é a assim:
+ </para>
+
+ <programlisting><![CDATA[from eg.Cat]]></programlisting>
+
+ <para>
+ Ela irá retornar todas as instancias da classe <literal>eg.Cat</literal>.
+ Necessariamente não precisamos qualificar o nome da classe, pois é realizado
+ <literal>auto-import</literal> por padrão. Por isso na maior parte do tempos
+ nós simplesmente escrevemos:
+ </para>
+
+ <programlisting><![CDATA[from Cat]]></programlisting>
+
+ <para>
+ Na maior parte do tempo, você precisará atribuir um <emphasis>alias</emphasis>,
+ desde que você queira se referia ao <literal>Cat</literal> em outras partes da
+ query.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat]]></programlisting>
+
+ <para>
+ Essa query atribui um alias a <literal>cat</literal> para as instancias de
+ <literal>Cat</literal>, então nós podemos usar esse alias depois na query.
+ A palavra chave as é opcional; poderíamos escrever assim:
+ </para>
+
+ <programlisting><![CDATA[from Cat cat]]></programlisting>
+
+ <para>
+ Múltiplas classes pode ser envolvidas, resultando em um produto cartesiano ou "cross" join.
+ </para>
+
+ <programlisting><![CDATA[from Formula, Parameter]]></programlisting>
+ <programlisting><![CDATA[from Formula as form, Parameter as param]]></programlisting>
+
+ <para>
+ É considerada uma boa prática os nomes dos aliases começarem com letra minúscula,
+ aderente com os padrões Java para variáveis locais (ex: <literal>domesticCat</literal>).
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-joins" revision="2">
+ <title>Associações e joins</title>
+
+ <para>
+ Nós também podemos querer atribuir aliases em uma entidade associada, ou mesmo
+ em elementos de uma coleção de valores, usando um <literal>join</literal>.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join cat.mate as mate
+ left outer join cat.kittens as kitten]]></programlisting>
+
+ <programlisting><![CDATA[from Cat as cat left join cat.mate.kittens as kittens]]></programlisting>
+
+ <programlisting><![CDATA[from Formula form full join form.parameter param]]></programlisting>
+
+ <para>
+ Os tipos de joins suportados foram inspirados no SQL ANSI:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>inner join</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>left outer join</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>right outer join</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>full join</literal> (geralmente não é útil)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The <literal>inner join</literal>, <literal>left outer join</literal> and
+ <literal>right outer join</literal> constructs may be abbreviated.
+ As construções <literal>inner join</literal>, <literal>left outer join</literal> e
+ <literal>right outer join</literal> podem ser abreviadas.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ join cat.mate as mate
+ left join cat.kittens as kitten]]></programlisting>
+
+ <para>
+ Você pode fornecer condições extras de join usando a palavra
+ chave do HQL <literal>with</literal>.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ left join cat.kittens as kitten
+ <literal>with</literal> kitten.bodyWeight > 10.0]]></programlisting>
+
+ <para>
+ Adicionalmente, um "fetch" join permite que associações ou coleções de valores
+ sejam inicializadas junto com o objeto pai, usando apenas um select. Isso é
+ muito útil no caso das coleções. Isso efetivamente sobre escreve as declarações
+ outer join e lazy do arquivo mapeamento para associações e coleções.
+ Veja a seção <xref linkend="performance-fetching"/> para mais informações.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join <literal>fetch</literal>cat.mate
+ left join <literal>fetch</literal>cat.kittens]]></programlisting>
+
+ <para>
+ Usualmente, um <literal>fetch</literal>join não precisa atribuir um alias, pois o objeto associado não
+ deve ser usado na clausula <literal>where</literal> (ou em qualquer outra clausula).
+ Também, os objetos associados não são retornados diretamente nos resultados da query.
+ Ao invés disso, eles devem ser acessados usando o objeto pai. A única razão que nós
+ podemos necessitar de um alias é quando fazemos um fech join recursivamente em uma
+ coleção adicional:
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join <literal>fetch</literal>cat.mate
+ left join <literal>fetch</literal>cat.kittens child
+ left join <literal>fetch</literal>child.kittens]]></programlisting>
+
+ <para>
+ Observe que a construção <literal>fetch</literal> não deve ser usada em queries invocadas usando
+ <literal>iterate()</literal> (embora possa ser usado com <literal>scroll()</literal>). O
+ <literal>fetch</literal> também não deve ser usado junto com o <literal>setMaxResults()</literal> ou
+ <literal>setFirstResult()</literal> pois essas operações são baseadas nas linhas retornadas, que
+ normalmente contem duplicidade devido ao fetching das coleções, então o número de linhas pode não
+ ser o que você espera.
+
+ O <literal>fetch</literal> não deve ser usado junto com uma condição <literal>with</literal> em
+ uma condição <literal>with</literal> ad hoc. É possível que seja criado um produto cartesiano pelo
+ join fetching em mais do que uma coleção em uma query, então tome cuidado nesses casos. Um join
+ fetching em varias coleções pode trazer resultados inesperados para mapeamentos do tipo bag, tome
+ cuidado na hora de formular queries como essas. Finalmente, observe o seguinte, o
+ <literal>full join fetch</literal> e <literal>right join fetch</literal> não são significativos.
+ </para>
+
+ <para>
+
+ Se está usando o nível de propriedade lazy (<literal>com</literal> instrumentação de bytecode), é possível
+ forçar o Hibernate a <literal>buscar</literal> as propriedades lazy imediatamente (na primeira query),
+ usando <literal>fetch all properties </literal>.
+ </para>
+
+ <programlisting><![CDATA[from Document <literal>fetch</literal>all properties order by name]]></programlisting>
+ <programlisting><![CDATA[from Document doc <literal>fetch</literal>all properties where lower(doc.name) like '%cats%']]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-joins-forms">
+ <title>Formas e sintaxe de joins</title>
+
+ <para>
+ O HQL suporta duas formas de associação para união: <literal>implícita</literal> e <literal>explicita</literal>.
+ </para>
+
+ <para>
+ As queries apresentadas na seção anterior usam a forma <literal>explicita</literal>, onde a
+ palavra chave "join" é explicitamente usada na clausula "from". Essa é a forma recomendada.
+ </para>
+
+ <para>
+ A forma <literal>implícita</literal> não usa a palavra chave "join". Entretanto, as associações
+ são diferenciadas usando pontuação ("." - dotnation). Uniões implícitas podem aparecer em
+ qualquer das clausulas HQL. A união <literal>implícita</literal> resulta em declarações
+ SQL que contem inner joins.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.mate.name like '%s%']]></programlisting>
+ </sect1>
+
+ <sect1 id="queryhql-select">
+ <title>Clausula select</title>
+
+ <para>
+ A clausula <literal>select</literal> seleciona quais obetos e propriedades retornam
+ no resultado da query. Considere:
+ </para>
+
+ <programlisting><![CDATA[select mate
+from Cat as cat
+ inner join cat.mate as mate]]></programlisting>
+
+ <para>
+ A query selecionará <literal>mate</literal>s (companheiros), de outros <literal>Cat</literal>s.
+ Atualmente, podemos expressar a query de forma mais compacta como:
+ </para>
+
+ <programlisting><![CDATA[select cat.mate from Cat cat]]></programlisting>
+
+ <para>
+ Queries podem retornar propriedades de qualquer tipo de valor, incluindo propriedades de tipo de componente:
+
+ </para>
+
+ <programlisting><![CDATA[select cat.name from DomesticCat cat
+where cat.name like 'fri%']]></programlisting>
+
+ <programlisting><![CDATA[select cust.name.firstName from Customer as cust]]></programlisting>
+
+ <para>
+ Queries podem retornar múltiplos objetos e/ou propriedades como um array do
+ tipo Object[],
+ </para>
+
+ <programlisting><![CDATA[select mother, offspr, mate.name
+from DomesticCat as mother
+ inner join mother.mate as mate
+ left outer join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ ou como um <literal>List</literal>,
+ </para>
+
+ <programlisting><![CDATA[select new list(mother, offspr, mate.name)
+from DomesticCat as mother
+ inner join mother.mate as mate
+ left outer join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ ou como um objeto Java typesafe,
+ </para>
+
+ <programlisting><![CDATA[select new Family(mother, mate, offspr)
+from DomesticCat as mother
+ join mother.mate as mate
+ left join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ assumindo que a classe <literal>Family</literal> tenha um construtor apropriado.
+ </para>
+
+ <para>
+ Pode-se designar referencias a expressões selecionadas, <literal>as</literal>:
+ </para>
+
+ <programlisting><![CDATA[select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n
+from Cat cat]]></programlisting>
+
+ <para>
+ Isto é bem mais útil quando usado junto <literal>com</literal> <literal>select new map</literal>:
+ </para>
+
+ <programlisting><![CDATA[select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n )
+from Cat cat]]></programlisting>
+
+ <para>
+ Esta query retorna um <literal>Map</literal> de referencias para valores selecionados.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-aggregation">
+ <title>Funções de agregação</title>
+
+ <para>
+ As queries HQL podem retornar o resultado de funções agregadas nas propriedades.
+ </para>
+
+ <programlisting><![CDATA[select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)
+from Cat cat]]></programlisting>
+
+<!-- NO LONGER SUPPORTED
+ <para>
+ Collections may also appear inside aggregate functions in the <literal>select</literal>
+ clause.
+ </para>
+
+ <programlisting><![CDATA[select cat, count( elements(cat.kittens) )
+from Cat cat group by cat]]></programlisting>
+-->
+
+ <para>
+ As funções agregadas suportadas são:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>avg(...), sum(...), min(...), max(...)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>count(*)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>count(...), count(distinct ...), count(all...)</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Pode-se usar operadores aritiméticos, concatenação e funções SQL
+ reconhecidas na clausula select:
+ </para>
+
+ <programlisting><![CDATA[select cat.weight + sum(kitten.weight)
+from Cat cat
+ join cat.kittens kitten
+group by cat.id, cat.weight]]></programlisting>
+
+ <programlisting><![CDATA[select firstName||' '||initial||' '||upper(lastName) from Person]]></programlisting>
+
+ <para>
+ As palavras <literal>distinct</literal> e <literal>all</literal> podem ser usadas e têm
+ a mesma semântica como no SQL.
+ </para>
+
+ <programlisting><![CDATA[select distinct cat.name from Cat cat
+
+select count(distinct cat.name), count(cat) from Cat cat]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-polymorphism">
+ <title>Queries polimórficas</title>
+
+ <para>
+ A query:
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat]]></programlisting>
+
+ <para>
+ retorna instancias não só de <literal>Cat</literal>, mas também de subclasses como
+ <literal>DomesticCat</literal>. As queries do Hibernate podem nomear qualquer classe Java
+ ou interface na clausula <literal>from</literal>. A query retornará instancias de toda classe
+ persistente que extenda a determinada classe ou implemente a determinada interface. A query
+ , a seguir, pode retornar todo objeto persistente:
+ </para>
+
+ <programlisting><![CDATA[from java.lang.Object o]]></programlisting>
+
+ <para>
+ A interface <literal>Named</literal> pode ser implementada por várias classes persistentes:
+ </para>
+
+ <programlisting><![CDATA[from Named n, Named m where n.name = m.name]]></programlisting>
+
+ <para>
+ Note que as duas últimas queries requerem mais de um SQL SELECT . Isto significa que a clausula
+ <literal>order by</literal> não ordena corretamente todo o resultado. (Isso também significa que
+ você não pode chamar essas queries usando <literal>Query.scroll()</literal>.)
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-where">
+ <title>A clausula where</title>
+
+ <para>
+ A clausula <literal>where</literal> permite estreitar a lista de instancias retornada.
+ Se não houver referencia alguma, pode-se referir a propriedades pelo nome:
+ </para>
+
+ <programlisting><![CDATA[from Cat where name='Fritz']]></programlisting>
+
+ <para>
+ Se houver uma referência, use o nome da propriedade qualificada:
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.name='Fritz']]></programlisting>
+
+ <para>
+ retorna instancias de <literal>Cat</literal> com nome ‘Fritz’.
+ </para>
+
+ <programlisting><![CDATA[select foo
+from Foo foo, Bar bar
+where foo.startDate = bar.date]]></programlisting>
+
+ <para>
+ retornará todas as instancias de <literal>Foo</literal>, para cada
+ um que tiver uma instancia de <literal>bar</literal> com a propriedade
+ <literal>date</literal> igual a propriedade
+ <literal>startDate</literal> de
+ <literal>Foo</literal>. Expressões de filtro compostas fazem da
+ clausula <literal>where</literal>, extremamente poderosa. Consideremos:
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.mate.name is not null]]></programlisting>
+
+ <para>
+ Esta query traduzida para uma query SQL <literal>com</literal> uma tabela (inner) join. Se fosse
+ escrever algo como:
+ </para>
+
+ <programlisting><![CDATA[from Foo foo
+where foo.bar.baz.customer.address.city is not null]]></programlisting>
+
+ <para>
+ Poderia-se terminar <literal>com</literal> uma query que necessitasse de join de quatro tabelas,
+ no SQL.
+ </para>
+
+ <para>
+ O operador <literal>=</literal> pode ser uasdo para comparar não apenas propriedades,
+ mas também instancias:
+ </para>
+
+ <programlisting><![CDATA[from Cat cat, Cat rival where cat.mate = rival.mate]]></programlisting>
+
+ <programlisting><![CDATA[select cat, mate
+from Cat cat, Cat mate
+where cat.mate = mate]]></programlisting>
+
+ <para>
+ A propriedade especial (lowercase) <literal>id</literal> pode ser usada para referenciar
+ o identificador único de um objeto. (Pode-se usar também o nome de sua propriedade)
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.id = 123
+
+from Cat as cat where cat.mate.id = 69]]></programlisting>
+
+ <para>
+ A Segunda query é eficiente. Nenhuma união de tabelas é necessária!
+ </para>
+
+ <para>
+ As propriedades de identificadores compostas também podem ser usadas. Suponha que
+ <literal>Person</literal> tenha um identificador composto que consiste de
+ <literal>country</literal> e <literal>medicareNumber</literal>.
+ </para>
+
+ <programlisting><![CDATA[from bank.Person person
+where person.id.country = 'AU'
+ and person.id.medicareNumber = 123456]]></programlisting>
+
+ <programlisting><![CDATA[from bank.Account account
+where account.owner.id.country = 'AU'
+ and account.owner.id.medicareNumber = 123456]]></programlisting>
+
+ <para>
+ Mais uma vez, a Segunda query não precisa de nenhum join de tabela.
+ </para>
+
+ <para>
+ Assim mesmo, a propriedade especial <literal>class</literal> acessa o valor discriminador da
+ instancia, no caso de persistência polimórfica. O nome de uma classe Java inclusa em uma
+ clausula "where", será traduzida para seu valor descriminante.
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.class = DomesticCat]]></programlisting>
+
+ <para>
+ Pode-se também especificar as propriedades dos components ou tipos de usuário composto
+ (e de componentes de componentes). Nunca tente usar uma expressão de filtro que termine na propriedade
+ de um tipo de componente (ao contrário de uma propriedade de um componente). Por exemplo,
+ se store.owner é uma entidade <literal>com</literal> um componente <literal>address</literal>.
+ </para>
+
+ <programlisting><![CDATA[store.owner.address.city // okay
+store.owner.address // error!]]></programlisting>
+
+ <para>
+ Um tipo "any" tem as propriedades <literal>id</literal> e <literal>class</literal> especiais,
+ nôs permitindo expressar um join da seguinte forma (onde <literal>AuditLog.item</literal> é
+ uma propriedade mapeada <literal>com</literal> <literal><any></literal>)
+ </para>
+
+ <programlisting><![CDATA[from AuditLog log, Payment payment
+where log.item.class = 'Payment' and log.item.id = payment.id]]></programlisting>
+
+ <para>
+ Veja que <literal>log.item.class</literal> e <literal>payment.class</literal> podem
+ referir-se a valores de colunas de banco de dados completamente diferentes, na query acima.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-expressions">
+ <title>Expressões</title>
+
+ <para>
+ As expressões permitidas na cláusula <literal>where</literal> inclui a maioria
+ das coisas que você poderia escrever no SQL:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ operadores matemáticos <literal>+, -, *, /</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ operadores de comparação binários <literal>=, >=, <=, <>, !=, like</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ operadores lógicos <literal>and, or, not</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ parenteses <literal>( )</literal>, indicating grouping
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>in</literal>,
+ <literal>not in</literal>,
+ <literal>between</literal>,
+ <literal>is null</literal>,
+ <literal>is not null</literal>,
+ <literal>is empty</literal>,
+ <literal>is not empty</literal>,
+ <literal>member of</literal> and
+ <literal>not member of</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ case "simples" , <literal>case ... when ... then ... else ... end</literal>, and
+ "searched" case, <literal>case when ... then ... else ... end</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ concatenação de string <literal>...||...</literal> ou <literal>concat(...,...)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>current_date()</literal>, <literal>current_time()</literal>,
+ <literal>current_timestamp()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>second(...)</literal>, <literal>minute(...)</literal>,
+ <literal>hour(...)</literal>, <literal>day(...)</literal>,
+ <literal>month(...)</literal>, <literal>year(...)</literal>,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ qualquer funcao ou operador definida pela EJB-QL 3.0: <literal>substring(), trim(),
+ lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>coalesce()</literal> and <literal>nullif()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>str()</literal> para converter valores numericos ou temporais para string
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>cast(... as ...)</literal>, onde o segundo argumento é o nome do tipo
+ hibernate, e<literal>extract(... from ...)</literal> se ANSI
+ <literal>cast()</literal> e <literal>extract()</literal> é suportado pele
+ banco de dados usado
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A função HQL <literal>index()</literal> , que se aplicam a referencias de
+ coleçôes associadas e indexadas
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ As funções hql que retornam expressões de coleções de valores:
+ <literal>size(), minelement(), maxelement(), minindex(), maxindex()</literal>,
+ <literal>junto</literal> com o elemento especial, <literal>elements()</literal>,
+ e funções de <literal>índice</literal> que podem ser quantificadas usando
+ <literal>some, all, exists, any, in</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Qualquer funçâo escalar pelo bando de dados como <literal>sign()</literal>,
+ <literal>trunc()</literal>, <literal>rtrim()</literal>, <literal>sin()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Parametros posicionais ao estilo JDBC <literal>?</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Parametros nomeados <literal>:name</literal>, <literal>:start_date</literal>, <literal>:x1</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Literais SQL <literal>'foo'</literal>, <literal>69</literal>, <literal>6.66E+2</literal>,
+ <literal>'1970-01-01 10:00:01.0'</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Constantes Java <literal>public static final</literal> <literal>ex: Color.TABBY</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>in</literal> e <literal>between</literal> podem ser usadas da seguinte maneira:
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name between 'A' and 'B']]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )]]></programlisting>
+
+ <para>
+ e as formas negativas podem ser escritas
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name not between 'A' and 'B']]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )]]></programlisting>
+
+ <para>
+ Likewise, <literal>is null</literal> and <literal>is not null</literal> may be used to test
+ for null values.
+ Assim mesmo, , <literal>is null</literal> e <literal>is not null</literal> podem ser usados
+ para testar valores nulos.
+ </para>
+
+ <para>
+ Booleanos podem ser facilmente usados em expressões, declarando as substituições da HQL query,
+ na configuração do Hibernate
+ </para>
+
+ <programlisting><![CDATA[<property name="hibernate.query.substitutions">true 1, false 0</property>]]></programlisting>
+
+ <para>
+ Isso irá substituir as palavras chave <literal>true</literal> e <literal>false</literal>
+ <literal>pelos</literal> literais <literal>1</literal> e <literal>0</literal> na tradução do HQL para SQL.
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.alive = true]]></programlisting>
+
+ <para>
+ Pode-se testar o tamanho de uma coleção <literal>com</literal> a propriedade especial <literal>size</literal>,
+ ou a função especial <literal>size()</literal>.
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.kittens.size > 0]]></programlisting>
+
+ <programlisting><![CDATA[from Cat cat where size(cat.kittens) > 0]]></programlisting>
+
+ <para>
+ Para coleções indexadas, você pode se referir aos índices máximo e mínimo, usando
+ as funções <literal>minindex</literal> e <literal>maxindex</literal>. Similarmente,
+ pode-se referir aos elementos máximo e mínimo de uma coleção de tipos básicos usando
+ as funções <literal>minelement</literal> e <literal>maxelement</literal>.
+ </para>
+
+ <programlisting><![CDATA[from Calendar cal where maxelement(cal.holidays) > current_date]]></programlisting>
+
+ <programlisting><![CDATA[from Order order where maxindex(order.items) > 100]]></programlisting>
+
+ <programlisting><![CDATA[from Order order where minelement(order.items) > 10000]]></programlisting>
+
+ <para>
+ As funções SQL <literal>any, some, all, exists, in</literal> são suportadas quando passado o
+ elemento ou o conjunto de índices de uma coleção (<literal>elements</literal> e
+ <literal>indices</literal> de funções), ou o resultado de uma subquery (veja abaixo).
+ </para>
+
+ <programlisting><![CDATA[select mother from Cat as mother, Cat as kit
+where kit in elements(foo.kittens)]]></programlisting>
+
+ <programlisting><![CDATA[select p from NameList list, Person p
+where p.name = some elements(list.names)]]></programlisting>
+
+ <programlisting><![CDATA[from Cat cat where exists elements(cat.kittens)]]></programlisting>
+
+ <programlisting><![CDATA[from Player p where 3 > all elements(p.scores)]]></programlisting>
+
+ <programlisting><![CDATA[from Show show where 'fizard' in indices(show.acts)]]></programlisting>
+
+ <para>
+ Note que essas construções - <literal>size</literal>, <literal>elements</literal>,
+ <literal>indices</literal>, <literal>minindex</literal>, <literal>maxindex</literal>,
+ <literal>minelement</literal>, <literal>maxelement</literal>–
+ só podem ser usados na clausula where do Hibernate3.
+ </para>
+
+ <para>
+ Elementos de coleções com índice (arrays, lists, maps), podem ser referenciadas
+ pelo índice (apenas na clausula where):
+ </para>
+
+ <programlisting><![CDATA[from Order order where order.items[0].id = 1234]]></programlisting>
+
+ <programlisting><![CDATA[select person from Person person, Calendar calendar
+where calendar.holidays['national day'] = person.birthDay
+ and person.nationality.calendar = calendar]]></programlisting>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11]]></programlisting>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ maxindex(order.items) ] = item and order.id = 11]]></programlisting>
+
+ <para>
+ A expressão entre colchetes <literal>[]</literal>, pode ser até uma expressão aritimética.
+ </para>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ size(order.items) - 1 ] = item]]></programlisting>
+
+ <para>
+ O HQL também provê a função interna <literal>index()</literal>, para elementos de
+ associação um-pra-muitos ou coleção de valores.
+ </para>
+
+ <programlisting><![CDATA[select item, index(item) from Order order
+ join order.items item
+where index(item) < 5]]></programlisting>
+
+ <para>
+ Funções escalares SQL, suportadas pelo banco de dados subjacente.
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where upper(cat.name) like 'FRI%']]></programlisting>
+
+ <para>
+ Se ainda ainda não está totalmente convencido, pense o quão maior e menos legível poderia
+ ser a query a seguir, em SQL:
+ </para>
+
+ <programlisting><![CDATA[select cust
+from Product prod,
+ Store store
+ inner join store.customers cust
+where prod.name = 'widget'
+ and store.location.name in ( 'Melbourne', 'Sydney' )
+ and prod = all elements(cust.currentOrder.lineItems)]]></programlisting>
+
+ <para>
+ <emphasis>Hint:</emphasis> something like
+ </para>
+
+ <programlisting><![CDATA[SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order
+FROM customers cust,
+ stores store,
+ locations loc,
+ store_customers sc,
+ product prod
+WHERE prod.name = 'widget'
+ AND store.loc_id = loc.id
+ AND loc.name IN ( 'Melbourne', 'Sydney' )
+ AND sc.store_id = store.id
+ AND sc.cust_id = cust.id
+ AND prod.id = ALL(
+ SELECT item.prod_id
+ FROM line_items item, orders o
+ WHERE item.order_id = o.id
+ AND cust.current_order = o.id
+ )]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-ordering">
+ <title>A clausula order by</title>
+
+ <para>
+ A lista retornada pela query pode ser ordenada por qualquer propriedade da classe ou componente retornado:
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat
+order by cat.name asc, cat.weight desc, cat.birthdate]]></programlisting>
+
+ <para>
+ As opções <literal>asc</literal> ou <literal>desc</literal> indicam ordem crescente ou decrescente,
+ respectivamente.
+ </para>
+ </sect1>
+
+ <sect1 id="queryhql-grouping">
+ <title>A clausula group by</title>
+
+ <para>
+ Uma query que retorne valores agregados, podem ser agrupados por qualquer propriedade de uma classe
+ ou componente retornado:
+ </para>
+
+ <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat)
+from Cat cat
+group by cat.color]]></programlisting>
+
+ <programlisting><![CDATA[select foo.id, avg(name), max(name)
+from Foo foo join foo.names name
+group by foo.id]]></programlisting>
+
+ <para>
+ Uma clausula <literal>having</literal> também é permitida.
+ </para>
+
+ <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat)
+from Cat cat
+group by cat.color
+having cat.color in (eg.Color.TABBY, eg.Color.BLACK)]]></programlisting>
+
+ <para>
+ Funções SQL e funções agregadas são permitidas nas clausulas
+ <literal>having</literal> e <literal>order by</literal>, se suportadas pelo banco
+ de dados subjacente (ex: não no MySQL).
+ </para>
+
+ <programlisting><![CDATA[select cat
+from Cat cat
+ join cat.kittens kitten
+group by cat
+having avg(kitten.weight) > 100
+order by count(kitten) asc, sum(kitten.weight) desc]]></programlisting>
+
+ <para>
+ Note que, nem a clausula <literal>group by</literal> ou
+ <literal>order by</literal>, podem conter expressões aritiméticas.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-subqueries" revision="2">
+ <title>Subqueries</title>
+
+ <para>
+ Para bancos de dados que suportem subselects, o Hibernate suporta subqueries dentro de queries.
+ Uma subquery precisa estar entre parênteses (normalmente uma chamada de função agregada SQL).
+ Mesmo subqueries co-relacionadas (subqueries que fazem referência à alias de outras queries),
+ são aceitas.
+ </para>
+
+ <programlisting><![CDATA[from Cat as fatcat
+where fatcat.weight > (
+ select avg(cat.weight) from DomesticCat cat
+)]]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat as cat
+where cat.name = some (
+ select name.nickName from Name as name
+)]]></programlisting>
+
+ <programlisting><![CDATA[from Cat as cat
+where not exists (
+ from Cat as mate where mate.mate = cat
+)]]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat as cat
+where cat.name not in (
+ select name.nickName from Name as name
+)]]></programlisting>
+
+ <programlisting><![CDATA[select cat.id, (select max(kit.weight) from cat.kitten kit)
+from Cat as cat]]></programlisting>
+
+ <para>
+ Note que HQL subqueries podem aparecer apenas dentro de clausulas select ou where.
+ </para>
+
+ <para>
+ Para subqueries <literal>com</literal> mais de uma expressão na lista do select, pode-se usar um construtor
+ de tuplas:
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+where not ( cat.name, cat.color ) in (
+ select cat.name, cat.color from DomesticCat cat
+)]]></programlisting>
+
+ <para>
+ Veja que em alguns bancos de dados (mas não o Oracle ou HSQL), pode-se usar construtores
+ de tuplas em outros contextos. Por exemplo quando buscando componentes ou tipos de usuário composto.
+ </para>
+
+ <programlisting><![CDATA[from Person where name = ('Gavin', 'A', 'King')]]></programlisting>
+
+ <para>
+ Qual é equivalente ao mais verbalizado:
+ </para>
+
+ <programlisting><![CDATA[from Person where name.first = 'Gavin' and name.initial = 'A' and name.last = 'King')]]></programlisting>
+
+ <para>
+ Há duas razões boas que você pode não querer fazer este tipo de coisa: primeira, não
+ é completamente portável entre plataformas de banco de dados; segunda, a query agora é
+ dependente da ordem de propriedades no documento de mapeamento.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-examples">
+ <title>Exemplos de HQL</title>
+
+ <para>
+ As queries do Hibernate, podem ser muito poderosas e complexas. De fato, o poder da linguagem de
+ querie é um dos pontos principais na distribuição do Hibernate. Aqui temos algumas queries de exemplo,
+ muito similares a queries que usei em um projeto recente. Note que a maioria das queries que você
+ irá escrever, são mais simples que estas.
+ </para>
+
+ <para>
+ A query a seguir retorna o id de order, numero de itens e o valor total do order para todos os
+ orders não pagos para um freguês particular e valor total mínimo dado, ordenando os resultados por
+ valor total. Ao determinar os preços, é usado o catalogo corrente. A query SQL resultante,
+ usando tabelas <literal>ORDER</literal>, <literal>ORDER_LINE</literal>, <literal>PRODUCT</literal>,
+ <literal>CATALOG</literal> e <literal>PRICE</literal>, tem quatro inner joins e um
+ (não correlacionado) subselect.
+ </para>
+
+ <programlisting><![CDATA[select order.id, sum(price.amount), count(item)
+from Order as order
+ join order.lineItems as item
+ join item.product as product,
+ Catalog as catalog
+ join catalog.prices as price
+where order.paid = false
+ and order.customer = :customer
+ and price.product = product
+ and catalog.effectiveDate < sysdate
+ and catalog.effectiveDate >= all (
+ select cat.effectiveDate
+ from Catalog as cat
+ where cat.effectiveDate < sysdate
+ )
+group by order
+having sum(price.amount) > :minAmount
+order by sum(price.amount) desc]]></programlisting>
+
+ <para>
+ Que monstro! Atualmente, na vida real, eu não sou muito afeiçoado a subqueries, então
+ minha query seria mais parecida com isto:
+ </para>
+
+ <programlisting><![CDATA[select order.id, sum(price.amount), count(item)
+from Order as order
+ join order.lineItems as item
+ join item.product as product,
+ Catalog as catalog
+ join catalog.prices as price
+where order.paid = false
+ and order.customer = :customer
+ and price.product = product
+ and catalog = :currentCatalog
+group by order
+having sum(price.amount) > :minAmount
+order by sum(price.amount) desc]]></programlisting>
+
+ <para>
+ A próxima query conta o número de pagamentos em cada status, tirando todos os pagamentos com
+ status <literal>AWAITING_APPROVAL</literal>, onde a mais recente mudança de status foi feita
+ pelo usuário corrente. Traduz-se para uma query SQL <literal>com</literal> dois inner joins e
+ um subselect correlacionado, nas tabelas <literal>PAYMENT</literal>,
+ <literal>PAYMENT_STATUS</literal> e <literal>PAYMENT_STATUS_CHANGE</literal> .
+ </para>
+
+ <programlisting><![CDATA[select count(payment), status.name
+from Payment as payment
+ join payment.currentStatus as status
+ join payment.statusChanges as statusChange
+where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
+ or (
+ statusChange.timeStamp = (
+ select max(change.timeStamp)
+ from PaymentStatusChange change
+ where change.payment = payment
+ )
+ and statusChange.user <> :currentUser
+ )
+group by status.name, status.sortOrder
+order by status.sortOrder]]></programlisting>
+
+ <para>
+ Se eu tivesse mapeado a Collection <literal>statusChanges</literal> como um List, ao invés de um
+ Set, a query teria sido muito mais simples de escrever.
+ </para>
+
+ <programlisting><![CDATA[select count(payment), status.name
+from Payment as payment
+ join payment.currentStatus as status
+where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
+ or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :currentUser
+group by status.name, status.sortOrder
+order by status.sortOrder]]></programlisting>
+
+ <para>
+ A próxima query usa a função <literal>isNull()</literal> do MS SQL Server, para retornar
+ todas as contas e pagamentos não pagos para a organização, para cada usuário corrente
+ pertencente. Traduz-se para uma query SQL <literal>com</literal> três inner joins,
+ um outer join e um subselect nas tabelas <literal>ACCOUNT</literal>, <literal>PAYMENT</literal>,
+ <literal>PAYMENT_STATUS</literal>,<literal>ACCOUNT_TYPE</literal>,
+ <literal>ORGANIZATION</literal> e <literal>ORG_USER</literal> .
+ </para>
+
+ <programlisting><![CDATA[select account, payment
+from Account as account
+ left outer join account.payments as payment
+where :currentUser in elements(account.holder.users)
+ and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
+order by account.type.sortOrder, account.accountNumber, payment.dueDate]]></programlisting>
+
+ <para>
+ Para alguns bancos de dados, precisaremos eleminar o subselect (correlacionado).
+ </para>
+
+ <programlisting><![CDATA[select account, payment
+from Account as account
+ join account.holder.users as user
+ left outer join account.payments as payment
+where :currentUser = user
+ and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
+order by account.type.sortOrder, account.accountNumber, payment.dueDate]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-bulk" revision="2">
+ <title>update e delete em lote</title>
+
+ <para>
+ Agora o HQL suporta declarações, <literal>update</literal>,
+ <literal>delete</literal> e <literal>insert ... select ...</literal>
+ Veja <xref linkend="batch-direct"/>, para mais detalhes.
+ </para>
+ </sect1>
+
+ <sect1 id="queryhql-tipstricks">
+ <title>Dicas e Truques</title>
+
+ <para>
+ Pode-se contar o número de resultados da query, sem realmente retorna-los.
+ </para>
+
+ <programlisting><![CDATA[( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue()]]></programlisting>
+
+ <para>
+ Para ordenar um resultado pelo tamanho de uma Collection, use a query a seguir.
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User as usr
+ left join usr.messages as msg
+group by usr.id, usr.name
+order by count(msg)]]></programlisting>
+
+ <para>
+ Se seu banco de dados suporta subselects, pode-se colocar uma condição sobre
+ tamanho de seleção na cláusula where da sua query:
+ </para>
+
+ <programlisting><![CDATA[from User usr where size(usr.messages) >= 1]]></programlisting>
+
+ <para>
+ Se seu banco de dados não suporta subselects, use a query a seguir:
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User usr.name
+ join usr.messages msg
+group by usr.id, usr.name
+having count(msg) >= 1]]></programlisting>
+
+ <para>
+ Com essa solução não se pode retornar um <literal>User</literal> <literal>com</literal> sem
+ nenhuma menssagem, por causa do "inner join", a forma a seguir também é útil.
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User as usr
+ left join usr.messages as msg
+group by usr.id, usr.name
+having count(msg) = 0]]></programlisting>
+
+ <para>
+ As propriedades de um JavaBean podem ser limitadas à parâmetros nomeados da query:
+ </para>
+
+ <programlisting><![CDATA[Query q = s.createQuery("from foo Foo as foo where foo.name=:name and foo.size=:size");
+q.setProperties(fooBean); // fooBean has getName() and getSize()
+List foos = q.list();]]></programlisting>
+
+ <para>
+ As Collections são paginaveis, usando a interface <literal>Query</literal> <literal>com</literal> um filtro:
+ </para>
+
+ <programlisting><![CDATA[Query q = s.createFilter( collection, "" ); // the trivial filter
+q.setMaxResults(PAGE_SIZE);
+q.setFirstResult(PAGE_SIZE * pageNumber);
+List page = q.list();]]></programlisting>
+
+ <para>
+ Os elementos da Collection podem ser ordenados ou agrupados
+ usando um filtro de query:
+ </para>
+
+ <programlisting><![CDATA[Collection orderedCollection = s.filter( collection, "order by this.amount" );
+Collection counts = s.filter( collection, "select this.type, count(this) group by this.type" );]]></programlisting>
+
+ <para>
+ Pode-se achar o tamanho de uma Collection sem inicializa-la:
+ </para>
+
+ <programlisting><![CDATA[( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue();]]></programlisting>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_sql.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/query_sql.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_sql.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_sql.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,783 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<chapter id="querysql" revision="2">
+ <title>Native SQL</title>
+
+ <para>You may also express queries in the native SQL dialect of your
+ database. This is useful if you want to utilize database specific features
+ such as query hints or the <literal>CONNECT</literal> keyword in Oracle. It
+ also provides a clean migration path from a direct SQL/JDBC based
+ application to Hibernate.</para>
+
+ <para>Hibernate3 allows you to specify handwritten SQL (including stored
+ procedures) for all create, update, delete, and load operations.</para>
+
+ <sect1 id="querysql-creating" revision="4">
+ <title>Using a <literal>SQLQuery</literal></title>
+
+ <para>Execution of native SQL queries is controlled via the
+ <literal>SQLQuery</literal> interface, which is obtained by calling
+ <literal>Session.createSQLQuery()</literal>. The following describes how
+ to use this API for querying.</para>
+
+ <sect2>
+ <title>Scalar queries</title>
+
+ <para>The most basic SQL query is to get a list of scalars
+ (values).</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS").list();
+sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").list();
+]]></programlisting>
+
+ <para>These will both return a List of Object arrays (Object[]) with
+ scalar values for each column in the CATS table. Hibernate will use
+ ResultSetMetadata to deduce the actual order and types of the returned
+ scalar values.</para>
+
+ <para>To avoid the overhead of using
+ <literal>ResultSetMetadata</literal> or simply to be more explicit in
+ what is returned one can use <literal>addScalar()</literal>.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS")
+ .addScalar("ID", Hibernate.LONG)
+ .addScalar("NAME", Hibernate.STRING)
+ .addScalar("BIRTHDATE", Hibernate.DATE)
+]]></programlisting>
+
+ <para>This query specified:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the SQL query string</para>
+ </listitem>
+
+ <listitem>
+ <para>the columns and types to return</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>This will still return Object arrays, but now it will not use
+ <literal>ResultSetMetdata</literal> but will instead explicitly get the
+ ID, NAME and BIRTHDATE column as respectively a Long, String and a Short
+ from the underlying resultset. This also means that only these three
+ columns will be returned, even though the query is using
+ <literal>*</literal> and could return more than the three listed
+ columns.</para>
+
+ <para>It is possible to leave out the type information for all or some
+ of the scalars.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS")
+ .addScalar("ID", Hibernate.LONG)
+ .addScalar("NAME")
+ .addScalar("BIRTHDATE")
+]]></programlisting>
+
+ <para>This is essentially the same query as before, but now
+ <literal>ResultSetMetaData</literal> is used to decide the type of NAME
+ and BIRTHDATE where as the type of ID is explicitly specified.</para>
+
+ <para>How the java.sql.Types returned from ResultSetMetaData is mapped
+ to Hibernate types is controlled by the Dialect. If a specific type is
+ not mapped or does not result in the expected type it is possible to
+ customize it via calls to <literal>registerHibernateType</literal> in
+ the Dialect.</para>
+ </sect2>
+
+ <sect2>
+ <title>Entity queries</title>
+
+ <para>The above queries were all about returning scalar values,
+ basically returning the "raw" values from the resultset. The following
+ shows how to get entity objects from a native sql query via
+ <literal>addEntity()</literal>.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS").addEntity(Cat.class);
+sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").addEntity(Cat.class);
+]]></programlisting>
+
+ <para>This query specified:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the SQL query string</para>
+ </listitem>
+
+ <listitem>
+ <para>the entity returned by the query</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Assuming that Cat is mapped as a class with the columns ID, NAME
+ and BIRTHDATE the above queries will both return a List where each
+ element is a Cat entity.</para>
+
+ <para>If the entity is mapped with a <literal>many-to-one</literal> to
+ another entity it is required to also return this when performing the
+ native query, otherwise a database specific "column not found" error
+ will occur. The additional columns will automatically be returned when
+ using the * notation, but we prefer to be explicit as in the following
+ example for a <literal>many-to-one</literal> to a
+ <literal>Dog</literal>:</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE, DOG_ID FROM CATS").addEntity(Cat.class);
+]]></programlisting>
+
+ <para>This will allow cat.getDog() to function properly.</para>
+ </sect2>
+
+ <sect2>
+ <title>Handling associations and collections</title>
+
+ <para>It is possible to eagerly join in the <literal>Dog</literal> to
+ avoid the possible extra roundtrip for initializing the proxy. This is
+ done via the <literal>addJoin()</literal> method, which allows you to
+ join in an association or collection.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT c.ID, NAME, BIRTHDATE, DOG_ID, D_ID, D_NAME FROM CATS c, DOGS d WHERE c.DOG_ID = d.D_ID")
+ .addEntity("cat", Cat.class)
+ .addJoin("cat.dog");
+]]></programlisting>
+
+ <para>In this example the returned <literal>Cat</literal>'s will have
+ their <literal>dog</literal> property fully initialized without any
+ extra roundtrip to the database. Notice that we added a alias name
+ ("cat") to be able to specify the target property path of the join. It
+ is possible to do the same eager joining for collections, e.g. if the
+ <literal>Cat</literal> had a one-to-many to <literal>Dog</literal>
+ instead.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE, D_ID, D_NAME, CAT_ID FROM CATS c, DOGS d WHERE c.ID = d.CAT_ID")
+ .addEntity("cat", Cat.class)
+ .addJoin("cat.dogs");
+]]></programlisting>
+
+ <p>At this stage we are reaching the limits of what is possible with
+ native queries without starting to enhance the sql queries to make them
+ usable in Hibernate; the problems starts to arise when returning
+ multiple entities of the same type or when the default alias/column
+ names are not enough.</p>
+ </sect2>
+
+ <sect2>
+ <title>Returning multiple entities</title>
+
+ <para>Until now the result set column names are assumed to be the same
+ as the column names specified in the mapping document. This can be
+ problematic for SQL queries which join multiple tables, since the same
+ column names may appear in more than one table.</para>
+
+ <para>Column alias injection is needed in the following query (which
+ most likely will fail):</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT c.*, m.* FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
+ .addEntity("cat", Cat.class)
+ .addEntity("mother", Cat.class)
+]]></programlisting>
+
+ <para>The intention for this query is to return two Cat instances per
+ row, a cat and its mother. This will fail since there is a conflict of
+ names since they are mapped to the same column names and on some
+ databases the returned column aliases will most likely be on the form
+ "c.ID", "c.NAME", etc. which are not equal to the columns specificed in
+ the mappings ("ID" and "NAME").</para>
+
+ <para>The following form is not vulnerable to column name
+ duplication:</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT {cat.*}, {mother.*} FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
+ .addEntity("cat", Cat.class)
+ .addEntity("mother", Cat.class)
+]]></programlisting>
+
+ <para>This query specified:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the SQL query string, with placeholders for Hibernate to
+ inject column aliases</para>
+ </listitem>
+
+ <listitem>
+ <para>the entities returned by the query</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The {cat.*} and {mother.*} notation used above is a shorthand for
+ "all properties". Alternatively, you may list the columns explicity, but
+ even in this case we let Hibernate inject the SQL column aliases for
+ each property. The placeholder for a column alias is just the property
+ name qualified by the table alias. In the following example, we retrieve
+ Cats and their mothers from a different table (cat_log) to the one
+ declared in the mapping metadata. Notice that we may even use the
+ property aliases in the where clause if we like.</para>
+
+ <programlisting><![CDATA[String sql = "SELECT ID as {c.id}, NAME as {c.name}, " +
+ "BIRTHDATE as {c.birthDate}, MOTHER_ID as {c.mother}, {mother.*} " +
+ "FROM CAT_LOG c, CAT_LOG m WHERE {c.mother} = c.ID";
+
+List loggedCats = sess.createSQLQuery(sql)
+ .addEntity("cat", Cat.class)
+ .addEntity("mother", Cat.class).list()
+]]></programlisting>
+
+ <sect3 id="querysql-aliasreferences" revision="2">
+ <title>Alias and property references</title>
+
+ <para>For most cases the above alias injection is needed, but for
+ queries relating to more complex mappings like composite properties,
+ inheritance discriminators, collections etc. there are some specific
+ aliases to use to allow Hibernate to inject the proper aliases.</para>
+
+ <para>The following table shows the different possibilities of using
+ the alias injection. Note: the alias names in the result are examples,
+ each alias will have a unique and probably different name when
+ used.</para>
+
+ <table frame="topbot" id="aliasinjection-summary">
+ <title>Alias injection names</title>
+
+ <tgroup cols="3">
+ <colspec colwidth="1*" />
+
+ <colspec colwidth="1*" />
+
+ <colspec colwidth="2.5*" />
+
+ <thead>
+ <row>
+ <entry>Description</entry>
+
+ <entry>Syntax</entry>
+
+ <entry>Example</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>A simple property</entry>
+
+ <entry><literal>{[aliasname].[propertyname]</literal></entry>
+
+ <entry><literal>A_NAME as {item.name}</literal></entry>
+ </row>
+
+ <row>
+ <entry>A composite property</entry>
+
+ <entry><literal>{[aliasname].[componentname].[propertyname]}</literal></entry>
+
+ <entry><literal>CURRENCY as {item.amount.currency}, VALUE as
+ {item.amount.value}</literal></entry>
+ </row>
+
+ <row>
+ <entry>Discriminator of an entity</entry>
+
+ <entry><literal>{[aliasname].class}</literal></entry>
+
+ <entry><literal>DISC as {item.class}</literal></entry>
+ </row>
+
+ <row>
+ <entry>All properties of an entity</entry>
+
+ <entry><literal>{[aliasname].*}</literal></entry>
+
+ <entry><literal>{item.*}</literal></entry>
+ </row>
+
+ <row>
+ <entry>A collection key</entry>
+
+ <entry><literal>{[aliasname].key}</literal></entry>
+
+ <entry><literal>ORGID as {coll.key}</literal></entry>
+ </row>
+
+ <row>
+ <entry>The id of an collection</entry>
+
+ <entry><literal>{[aliasname].id}</literal></entry>
+
+ <entry><literal>EMPID as {coll.id}</literal></entry>
+ </row>
+
+ <row>
+ <entry>The element of an collection</entry>
+
+ <entry><literal>{[aliasname].element}</literal></entry>
+
+ <entry><literal>XID as {coll.element}</literal></entry>
+ </row>
+
+ <row>
+ <entry>roperty of the element in the collection</entry>
+
+ <entry><literal>{[aliasname].element.[propertyname]}</literal></entry>
+
+ <entry><literal>NAME as {coll.element.name}</literal></entry>
+ </row>
+
+ <row>
+ <entry>All properties of the element in the collection</entry>
+
+ <entry><literal>{[aliasname].element.*}</literal></entry>
+
+ <entry><literal>{coll.element.*}</literal></entry>
+ </row>
+
+ <row>
+ <entry>All properties of the the collection</entry>
+
+ <entry><literal>{[aliasname].*}</literal></entry>
+
+ <entry><literal>{coll.*}</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Returning non-managed entities</title>
+
+ <para>It is possible to apply a ResultTransformer to native sql queries. Allowing it to e.g. return non-managed entities.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT NAME, BIRTHDATE FROM CATS")
+ .setResultTransformer(Transformers.aliasToBean(CatDTO.class))]]></programlisting>
+
+ <para>This query specified:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the SQL query string</para>
+ </listitem>
+
+ <listitem>
+ <para>a result transformer</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The above query will return a list of <literal>CatDTO</literal> which has been instantiated and injected the values of NAME and BIRTHNAME into its corresponding
+ properties or fields.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Handling inheritance</title>
+
+ <para>Native sql queries which query for entities that is mapped as part
+ of an inheritance must include all properties for the baseclass and all
+ it subclasses.</para>
+ </sect2>
+
+ <sect2>
+ <title>Parameters</title>
+
+ <para>Native sql queries support positional as well as named
+ parameters:</para>
+
+ <programlisting><![CDATA[Query query = sess.createSQLQuery("SELECT * FROM CATS WHERE NAME like ?").addEntity(Cat.class);
+List pusList = query.setString(0, "Pus%").list();
+
+query = sess.createSQLQuery("SELECT * FROM CATS WHERE NAME like :name").addEntity(Cat.class);
+List pusList = query.setString("name", "Pus%").list(); ]]></programlisting>
+ </sect2>
+
+
+
+ </sect1>
+
+ <sect1 id="querysql-namedqueries" revision="3">
+ <title>Named SQL queries</title>
+
+ <para>Named SQL queries may be defined in the mapping document and called
+ in exactly the same way as a named HQL query. In this case, we do
+ <emphasis>not</emphasis> need to call
+ <literal>addEntity()</literal>.</para>
+
+ <programlisting><![CDATA[<sql-query name="persons">
+ <return alias="person" class="eg.Person"/>
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex}
+ FROM PERSON person
+ WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+ <programlisting><![CDATA[List people = sess.getNamedQuery("persons")
+ .setString("namePattern", namePattern)
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ <para>The <literal><return-join></literal> and
+ <literal><load-collection></literal> elements are used to join
+ associations and define queries which initialize collections,
+ respectively.</para>
+
+ <programlisting><![CDATA[<sql-query name="personsWith">
+ <return alias="person" class="eg.Person"/>
+ <return-join alias="address" property="person.mailingAddress"/>
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex},
+ address.STREET AS {address.street},
+ address.CITY AS {address.city},
+ address.STATE AS {address.state},
+ address.ZIP AS {address.zip}
+ FROM PERSON person
+ JOIN ADDRESS address
+ ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
+ WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+ <para>A named SQL query may return a scalar value. You must declare the
+ column alias and Hibernate type using the
+ <literal><return-scalar></literal> element:</para>
+
+ <programlisting><![CDATA[<sql-query name="mySqlQuery">
+ <return-scalar column="name" type="string"/>
+ <return-scalar column="age" type="long"/>
+ SELECT p.NAME AS name,
+ p.AGE AS age,
+ FROM PERSON p WHERE p.NAME LIKE 'Hiber%'
+</sql-query>]]></programlisting>
+
+ <para>You can externalize the resultset mapping informations in a
+ <literal><resultset></literal> element to either reuse them accross
+ several named queries or through the
+ <literal>setResultSetMapping()</literal> API.</para>
+
+ <programlisting><![CDATA[<resultset name="personAddress">
+ <return alias="person" class="eg.Person"/>
+ <return-join alias="address" property="person.mailingAddress"/>
+</resultset>
+
+<sql-query name="personsWith" resultset-ref="personAddress">
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex},
+ address.STREET AS {address.street},
+ address.CITY AS {address.city},
+ address.STATE AS {address.state},
+ address.ZIP AS {address.zip}
+ FROM PERSON person
+ JOIN ADDRESS address
+ ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
+ WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+ <para>You can alternatively use the resultset mapping information in your
+ hbm files directly in java code.</para>
+
+ <programlisting><![CDATA[List cats = sess.createSQLQuery(
+ "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id"
+ )
+ .setResultSetMapping("catAndKitten")
+ .list();]]></programlisting>
+
+ <sect2 id="propertyresults">
+ <title>Using return-property to explicitly specify column/alias
+ names</title>
+
+ <para>With <literal><return-property></literal> you can explicitly
+ tell Hibernate what column aliases to use, instead of using the
+ <literal>{}</literal>-syntax to let Hibernate inject its own
+ aliases.</para>
+
+ <programlisting><![CDATA[<sql-query name="mySqlQuery">
+ <return alias="person" class="eg.Person">
+ <return-property name="name" column="myName"/>
+ <return-property name="age" column="myAge"/>
+ <return-property name="sex" column="mySex"/>
+ </return>
+ SELECT person.NAME AS myName,
+ person.AGE AS myAge,
+ person.SEX AS mySex,
+ FROM PERSON person WHERE person.NAME LIKE :name
+</sql-query>
+]]></programlisting>
+
+ <para><literal><return-property></literal> also works with
+ multiple columns. This solves a limitation with the
+ <literal>{}</literal>-syntax which can not allow fine grained control of
+ multi-column properties.</para>
+
+ <programlisting><![CDATA[<sql-query name="organizationCurrentEmployments">
+ <return alias="emp" class="Employment">
+ <return-property name="salary">
+ <return-column name="VALUE"/>
+ <return-column name="CURRENCY"/>
+ </return-property>
+ <return-property name="endDate" column="myEndDate"/>
+ </return>
+ SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer},
+ STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},
+ REGIONCODE as {emp.regionCode}, EID AS {emp.id}, VALUE, CURRENCY
+ FROM EMPLOYMENT
+ WHERE EMPLOYER = :id AND ENDDATE IS NULL
+ ORDER BY STARTDATE ASC
+</sql-query>]]></programlisting>
+
+ <para>Notice that in this example we used
+ <literal><return-property></literal> in combination with the
+ <literal>{}</literal>-syntax for injection. Allowing users to choose how
+ they want to refer column and properties.</para>
+
+ <para>If your mapping has a discriminator you must use
+ <literal><return-discriminator></literal> to specify the
+ discriminator column.</para>
+ </sect2>
+
+ <sect2 id="sp_query" revision="1">
+ <title>Using stored procedures for querying</title>
+
+ <para>Hibernate 3 introduces support for queries via stored procedures
+ and functions. Most of the following documentation is equivalent for
+ both. The stored procedure/function must return a resultset as the first
+ out-parameter to be able to work with Hibernate. An example of such a
+ stored function in Oracle 9 and higher is as follows:</para>
+
+ <programlisting><![CDATA[CREATE OR REPLACE FUNCTION selectAllEmployments
+ RETURN SYS_REFCURSOR
+AS
+ st_cursor SYS_REFCURSOR;
+BEGIN
+ OPEN st_cursor FOR
+ SELECT EMPLOYEE, EMPLOYER,
+ STARTDATE, ENDDATE,
+ REGIONCODE, EID, VALUE, CURRENCY
+ FROM EMPLOYMENT;
+ RETURN st_cursor;
+ END;]]></programlisting>
+
+ <para>To use this query in Hibernate you need to map it via a named
+ query.</para>
+
+ <programlisting><![CDATA[<sql-query name="selectAllEmployees_SP" callable="true">
+ <return alias="emp" class="Employment">
+ <return-property name="employee" column="EMPLOYEE"/>
+ <return-property name="employer" column="EMPLOYER"/>
+ <return-property name="startDate" column="STARTDATE"/>
+ <return-property name="endDate" column="ENDDATE"/>
+ <return-property name="regionCode" column="REGIONCODE"/>
+ <return-property name="id" column="EID"/>
+ <return-property name="salary">
+ <return-column name="VALUE"/>
+ <return-column name="CURRENCY"/>
+ </return-property>
+ </return>
+ { ? = call selectAllEmployments() }
+</sql-query>]]></programlisting>
+
+ <para>Notice stored procedures currently only return scalars and
+ entities. <literal><return-join></literal> and
+ <literal><load-collection></literal> are not supported.</para>
+
+ <sect3 id="querysql-limits-storedprocedures" revision="1">
+ <title>Rules/limitations for using stored procedures</title>
+
+ <para>To use stored procedures with Hibernate the procedures/functions
+ have to follow some rules. If they do not follow those rules they are
+ not usable with Hibernate. If you still want to use these procedures
+ you have to execute them via <literal>session.connection()</literal>.
+ The rules are different for each database, since database vendors have
+ different stored procedure semantics/syntax.</para>
+
+ <para>Stored procedure queries can't be paged with
+ <literal>setFirstResult()/setMaxResults()</literal>.</para>
+
+ <para>Recommended call form is standard SQL92: <literal>{ ? = call
+ functionName(<parameters>) }</literal> or <literal>{ ? = call
+ procedureName(<parameters>}</literal>. Native call syntax is not
+ supported.</para>
+
+ <para>For Oracle the following rules apply:</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ A fun��p deve retornar um result set. O primeiro par�metro da procedure
+ dever ser uma <literal>SA�DA</literal> que retorne um result set. Isto � feito
+ usando o tipo a <literal>SYS_REFCURSOR</literal> no Oracle 9 ou 10. No Oracle �
+ necess�rio definir o tipo <literal>REF CURSOR</literal>, veja a documenta��o do Oracle.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>For Sybase or MS SQL server the following rules apply:</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ A procedure deve retornar um result set. Veja que este servidor pode retornar
+ m�ltiplos result sets e update counts. O Hibernate ira iterar os resultados e
+ pegar o primeiro resultado que � o valor de retorno do result set.
+ O resto ser� descartado.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Se voc� habilitar <literal>SET NOCOUNT ON</literal> na sua procedure, ela
+ provavelmente ser� mais eficiente. Mas, isto n�o � obrigat�rio</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 id="querysql-cud">
+ <title>SQL customizado para create, update e delete</title>
+
+ <para>Hibernate3 can use custom SQL statements for create, update, and
+ delete operations. The class and collection persisters in Hibernate
+ already contain a set of configuration time generated strings (insertsql,
+ deletesql, updatesql etc.). The mapping tags
+ <literal><sql-insert></literal>,
+ <literal><sql-delete></literal>, and
+ <literal><sql-update></literal> override these strings:
+
+ Hibernate3 pode usar SQL customizado para opera��es de create, update e delete.
+ A persist�ncia de classe e collection no hibernate j� contem alguma strings
+ de configura��es (insertsql, deletesql, updatesql etc.).
+ O mapaemento das tags
+ <literal><sql-insert></literal>,
+ <literal><sql-delete></literal>, e
+ <literal><sql-update></literal>
+ sobreecreve essas strings:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ? )</sql-insert>
+ <sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete>
+</class>]]></programlisting>
+
+ <para>
+ O SQL � executado diretamente no seu banco de dados, ent�o voc� pode usar qualquer
+ linguagem que quiser. Isto com certeza reduzira a portabilidade do seu mapeamento se
+ voc� utilizar um SQL para um banco de dados especifico.
+ </para>
+
+ <para>
+ Stored Procedures s�o suportadas se o atributo the
+ <literal>callable</literal> estiver ativado:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <sql-insert callable="true">{call createPerson (?, ?)}</sql-insert>
+ <sql-delete callable="true">{? = call deletePerson (?)}</sql-delete>
+ <sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update>
+</class>]]></programlisting>
+
+ <para>
+ A ordem de posi��es dos par�metros s�o vitais, pois eles devem estar na mesma seq��ncia
+ esperada pelo Hibernate.
+ </para>
+
+ <para>Voc� pode ver a ordem esperada ativando o debug logging no n�vel
+ <literal>org.hibernate.persister.entity</literal>. Com este n�vel ativado, o Hibernate
+ ir� imprimir o SQL est�tico que foi usado para create, update, delete, etc.
+ Entidades. (Para ver a seq��ncia esperada, lembre-se de n�o incluir seu SQL
+ customizado no arquivo de mapeamento, pois ele ir� sobreecreve o SQL
+ est�tico gerado pelo Hibernate).
+ </para>
+
+ <para>As stored procedures s�o na maioria dos casos (leia: melhor n�o fazer) requeridas para
+ retornar o numero de linhas inseridas/atualizadas/deletadas. O hibernate tem algumas
+ verifica��es em tempo de execu��o para o sucesso da declara��o. Hibernate sempre registra
+ o primeiro par�metro da declara��o como uma sa�da num�rica para opera��es CRUD.
+ </para>
+
+ <programlisting><![CDATA[CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname IN VARCHAR2)
+ RETURN NUMBER IS
+BEGIN
+
+ update PERSON
+ set
+ NAME = uname,
+ where
+ ID = uid;
+
+ return SQL%ROWCOUNT;
+
+END updatePerson;]]>
+</programlisting>
+
+ </sect1>
+
+ <sect1 id="querysql-load">
+ <title>SQL customizado para carga</title>
+
+ <para>
+ Voc� pode declarar sua pr�pria query SQL (ou HQL) para iniciar entidades:
+ </para>
+
+ <programlisting><![CDATA[<sql-query name="person">
+ <return alias="pers" class="Person" lock-mode="upgrade"/>
+ SELECT NAME AS {pers.name}, ID AS {pers.id}
+ FROM PERSON
+ WHERE ID=?
+ FOR UPDATE
+</sql-query>]]></programlisting>
+
+ <para>
+ Este � apenas uma declara��o de query com nome, como discutido anteriormente.
+ Voc� pode referenciar esta query com nome em um mapeamento de classe:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <loader query-ref="person"/>
+</class>]]></programlisting>
+
+ <para>Isto tamb�m funciona com stored procedures.
+ </para>
+
+ <para>Voc� pode temb�m definir uma query para iniciar collection:
+ </para>
+
+ <programlisting><![CDATA[<set name="employments" inverse="true">
+ <key/>
+ <one-to-many class="Employment"/>
+ <loader query-ref="employments"/>
+</set>]]></programlisting>
+
+ <programlisting><![CDATA[<sql-query name="employments">
+ <load-collection alias="emp" role="Person.employments"/>
+ SELECT {emp.*}
+ FROM EMPLOYMENT emp
+ WHERE EMPLOYER = :id
+ ORDER BY STARTDATE ASC, EMPLOYEE ASC
+</sql-query>]]></programlisting>
+
+ <para>You could even define an entity loader that loads a collection by
+ join fetching:</para>
+
+ <programlisting><![CDATA[<sql-query name="person">
+ <return alias="pers" class="Person"/>
+ <return-join alias="emp" property="pers.employments"/>
+ SELECT NAME AS {pers.*}, {emp.*}
+ FROM PERSON pers
+ LEFT OUTER JOIN EMPLOYMENT emp
+ ON pers.ID = emp.PERSON_ID
+ WHERE ID=?
+</sql-query>]]></programlisting>
+ </sect1>
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/session_api.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/session_api.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/session_api.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/session_api.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,1245 @@
+<chapter id="objectstate">
+ <title>Trabalhando com objetos</title>
+
+ <para>
+ O Hibernate é uma solução completa de mapeamento objeto/relacional que não apenas
+ poupa o desenvolvedor dos detalhes de baixo nível do sistema de gerenciamento do
+ banco de dados, mas também oferece um <emphasis>gerenciamento de estado </emphasis>
+ para objetos. Isto é, ao contrário do gerenciamento de <literal>instruções </literal>
+ SQL em camadas de persistência JDBC/SQL comuns, uma visão natural da persistência
+ orientada a objetos em aplicações Java.
+ </para>
+
+ <para>
+ Em outras palavras, desenvolvedores de aplicações Hibernate podem sempre pensar em
+ relação ao <emphasis>estado</emphasis> de seus objetos, e não necessariamente em
+ relação a execução de instruções SQL. Este parte é responsabilidade do Hibernate e
+ é relevante aos desenvolvedores de aplicações apenas quando estão ajustando
+ a performance do sistema.
+ </para>
+
+ <sect1 id="objectstate-overview">
+ <title>Estado dos objetos no Hibernate</title>
+
+ <para>
+ O Hibernate define e suporta os seguintes estados de um objetos:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Transient</emphasis> - um objeto é transiente se ele foi instanciando
+ usando apenas o operador <literal>new</literal>, e não foi associado com uma
+ <literal>Session</literal> do Hibernate. Ele não terá uma representação
+ persistente no banco de dados e nenhum identificador será atribuído para ele.
+ Instâncias transientes serão destruídas pelo coletor de lixo se a aplicação
+ não manter sua referência. Use uma <literal>Session</literal> do Hibernate
+ para tornar o objeto persistente ( e deixe o Hibernate gerenciar as
+ instruções SQL que serão necessárias para executar esta transição).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Persistent</emphasis> -– uma instância persistente possui uma
+ representação no banco de dados e um identificador. Ele pode ter sido salvo
+ ou carregado, assim, ele está por definição no escopo de uma
+ <literal>Session</literal>. O Hibernate irá detectar qualquer mudança feita a
+ um objeto persistente e sincronizar o seu estado com o banco de dados quando
+ completar a unidade de trabalho. Desenvolvedores não executam instruções manuais
+ de <literal>UPDATE</literal>, ou instruções de <literal>DELETE</literal>
+ quando o objeto deve ser passado para transiente.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Detached</emphasis> – uma instância desaclopada é um objeto que
+ foi persistido, mas sua <literal>Session</literal> foi fechada. A referência
+ ao objeto continua válida, é claro, e a instância destacada desaclopada pode
+ ser acoplada a uma nova <literal>Session</literal> no futuro, fazendo-o
+ ( e todas as modificações sofridas) persistente novamente. Essa característica
+ possibilita um modelo de programação para unidades de trabalho que rodam
+ durante muito tempo que requer um pensamento por tempo do usuário. Podemos
+ chamar-las de <emphasis>transações da aplicação</emphasis>, i.e. uma unidade
+ de trabalho do ponto de vista do usuário.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Agora iremos discutir os estados e suas transições ( e os métodos do Hibernate que
+ disparam uma transição) em mais detalhes.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-makingpersistent" revision="1">
+ <title>Tornando os objetos persistentes</title>
+
+ <para>
+ Instâncias recentemente instanciadas de uma classe persistente são
+ consideradas <emphasis>transientes </emphasis> pelo Hibernate.
+ Podemos tornar uma instância transiente em <emphasis>persistente</emphasis>
+ associando-a a uma sessão:
+ </para>
+
+ <programlisting><![CDATA[DomesticCat fritz = new DomesticCat();
+fritz.setColor(Color.GINGER);
+fritz.setSex('M');
+fritz.setName("Fritz");
+Long generatedId = (Long) sess.save(fritz);]]></programlisting>
+
+ <para>
+ Se <literal>Cat</literal> possui um identificador gerado, o identificador
+ é gerado e atribuído a <literal>cat</literal> quando <literal>save()</literal>
+ for chamada. Se <literal>Cat</literal> possuir um identificador
+ <literal>Associado</literal>, ou uma chave composta, o identificador deve ser
+ atribuído à instância de <literal>cat</literal> antes que <literal>save()</literal>
+ seja chamado. Pode-se usar também <literal>persist()</literal> ao invés de
+ <literal>save()</literal>, com a semântica definada no novo esboço do EJB3.
+ </para>
+
+ <para>
+ Alternativamente, pode-se atribuir o identificador usando uma versão
+ sobrecarregada de <literal>save()</literal>.
+ </para>
+
+<programlisting><![CDATA[DomesticCat pk = new DomesticCat();
+pk.setColor(Color.TABBY);
+pk.setSex('F');
+pk.setName("PK");
+pk.setKittens( new HashSet() );
+pk.addKitten(fritz);
+sess.save( pk, new Long(1234) );]]></programlisting>
+
+ <para>
+ Se o objeto persistido possuir objetos associados (e.g. a coleção
+ <literal>kittens</literal> no exemplo anterior), esses objetos podem ser
+ tornar persistente em qualquer ordem que se queira ao menos que se tenha uma
+ restrição <literal>NOT NULL</literal> em uma coluna de chave estrangeira.
+ Nunca há risco de violação de restrições de chave estrangeira. Assim,
+ pode-se violar uma restrição <literal>NOT NULL</literal> se
+ <literal>save()</literal> for usada nos objetos em uma ordem errada.
+ </para>
+
+ <para>
+ Geralmente você não deve se importar com esses detalhes, muito provavelmente se
+ usará a característica de <emphasis>persistência transitiva </emphasis> do Hibernate
+ para salvar os objetos associados automaticamente. Então, enquanto uma restrição
+ <literal>NOT NULL</literal> não ocorrer – Hibernate tomará conta de tudo.
+ Persistência transitiva será discutida futuramente nesse capítulo.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-loading">
+ <title>Carregando o objetos</title>
+
+ <para>
+ O método <literal>load()</literal> de uma <literal> Session</literal> nos
+ fornece um meio para recuperar uma instância persistente se o identificador
+ for conhecido. <literal>load()</literal> recebe uma classe do objeto e carregará
+ o estado em uma instância mais recente dessa classe, no estado persistente.
+ </para>
+
+ <programlisting><![CDATA[Cat fritz = (Cat) sess.load(Cat.class, generatedId);]]></programlisting>
+
+<programlisting><![CDATA[// you need to wrap primitive identifiers
+long id = 1234;
+DomesticCat pk = (DomesticCat) sess.load( DomesticCat.class, new Long(id) );]]></programlisting>
+
+ <para>
+ Alternatively, you can load state into a given instance:
+Alternativamente, pode-se carregar um estado em uma instância dada:
+ </para>
+
+<programlisting><![CDATA[Cat cat = new DomesticCat();
+// load pk's state into cat
+sess.load( cat, new Long(pkId) );
+Set kittens = cat.getKittens();]]></programlisting>
+
+ <para>
+ Repare que <literal>load()</literal> irá lançar uma exceção irrecuperável
+ se não houver na tabela no banco de dados um registro que combine.
+ Se a classe for mapeada com um proxy, <literal>load()</literal>
+ simplesmente retorna um proxy não inicializado e realmente não chamará
+ o banco de dados até que um método do proxy seja invocado.
+ Esse comportamento é muito útil se deseja-se criar uma associação
+ com um objeto sem que realmente o carregue do bando de dados.
+ Isto também permite que sejam carregadas múltiplas instâncias como um
+ grupo se <literal>batch-size</literal> estiver para o mapeamento da
+ classe.
+ </para>
+
+ <para>
+ Se você não tiver certeza da existencia do registro no banco, você deve
+ usar o metodo <literal>get()</literal>, que consulta o banco
+ imediantamente e retorna um null se não existir o registro.
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) sess.get(Cat.class, id);
+if (cat==null) {
+ cat = new Cat();
+ sess.save(cat, id);
+}
+return cat;]]></programlisting>
+
+ <para>
+ Também pode-se carregar um objeto usando <literal>SELECT ... FOR UPDATE</literal>,
+ usando um <literal>LockMode</literal>. Veja a documentação da API para maiores
+ informações.
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) sess.get(Cat.class, id, LockMode.UPGRADE);]]></programlisting>
+
+ <para>
+ Note that any associated instances or contained collections are
+ <emphasis>not</emphasis> selected <literal>FOR UPDATE</literal>, unless you decide
+ to specify <literal>lock</literal> or <literal>all</literal> as a
+ cascade style for the association.
+ </para>
+
+ <para>
+ O recarregamento de um objeto e todas as suas coleções é possível a qualquer momento,
+ usando o método <literal>refresh()</literal>. Util quando as triggers do banco de
+ dados são usados para inicializar algumas propriedades do objeto.
+ </para>
+
+ <programlisting><![CDATA[sess.save(cat);
+sess.flush(); //force the SQL INSERT
+sess.refresh(cat); //re-read the state (after the trigger executes)]]></programlisting>
+
+ <para>
+ Uma importante questão geralmente aparece neste ponto: O quanto Hibernate carrega
+ do banco de dados e quantos SQL <literal>SELECT</literal> ele irá usar? Isto
+ depende da estratégia de <emphasis>recuperação</emphasis>usada e explicada na
+ <xref linkend="performance-fetching"/>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-querying" revision="1">
+ <title>Consultando</title>
+
+ <para>
+ Se o identificador do objeto que se está buscando não for conhecido,
+ uma consulta será necessária. O Hibernate suporta uma linguagem de consulta
+ (HQL) orientada a objetos fácil mas poderosa. Para criação via programação
+ de consultas, o Hibernate suporta características sofisticadas de consulta
+ por Critério e Exemplo (QBCe QBE). Pode-se também expressar a consulta
+ por meio de SQL nativa do banco de dados, com suporte opcional do Hibernate
+ para conversão do conjunto de reultados em objetos.
+ </para>
+
+ <sect2 id="objectstate-querying-executing" revision="1">
+ <title>Executando consultas</title>
+
+ <para>
+ Consultas HQL e SQL nativa são representadas por uma instância de <literal>org.hibernate.Query</literal>.
+ Esta interface oferece métodos para associação de parâmetros, tratamento de conjunto de resultados,
+ e para a execução de consultas reais. Você pode obter uma <literal>Query</literal> usando a
+ <literal>Session</literal> atual:
+ </para>
+
+ <programlisting><![CDATA[List cats = session.createQuery(
+ "from Cat as cat where cat.birthdate < ?")
+ .setDate(0, date)
+ .list();
+
+List mothers = session.createQuery(
+ "select mother from Cat as cat join cat.mother as mother where cat.name = ?")
+ .setString(0, name)
+ .list();
+
+List kittens = session.createQuery(
+ "from Cat as cat where cat.mother = ?")
+ .setEntity(0, pk)
+ .list();
+
+Cat mother = (Cat) session.createQuery(
+ "select cat.mother from Cat as cat where cat = ?")
+ .setEntity(0, izi)
+ .uniqueResult();]]
+
+Query mothersWithKittens = (Cat) session.createQuery(
+ "select mother from Cat as mother left join fetch mother.kittens");
+Set uniqueMothers = new HashSet(mothersWithKittens.list());]]></programlisting>
+
+ <para>
+ Geralmente uma consulta é executada ao invocar <literal>list()</literal>,
+ o resultado da consulta será carregado completamente em uma coleção na memória.
+ Instâncias de entidades recuperadas por uma consulta estão no estado persistente.
+ O <literal>uniqueResult()</literal> oferece um atalho se você souber de
+ previamente que a consulta retornará apenas um único objeto. Repare que consultas
+ que fazem uso de buscas de coleções de forma ansiosa (eager) geralmente retornam
+ duplicatas dos objetos raiz ( mas com suas coleções inicializadas ). Pode-se
+ filtrar estas duplicatas através de um simples <literal>Set</literal>.
+ </para>
+
+ <sect3 id="objectstate-querying-executing-iterate">
+ <title>Interagindo com resultados</title>
+
+ <para>
+ Ocasionalmente, deves-se ser capaz de atingir performances melhores com
+ a execução de consultas usando o método <literal>iterate()</literal>.
+ Geralmente isso será o caso esperado apenas se as instâncias dos entidades
+ reais retornadas pela consulta já estiverem na sessão ou no caché de segundo
+ nível. Caso elas ainda não tenham sido armazenadas, <literal>iterate()</literal>
+ será mais devagar do que <literal>list()</literal> e pode ser necessário vários
+ acessos ao banco de dados para um simples consulta, geralmente <emphasis>1</emphasis>
+ para a seleção inicial que retorna apenas identificadores, e <emphasis>n</emphasis>
+ consultas adicionais para inicializar as instâncias reais.
+ </para>
+
+ <programlisting><![CDATA[// fetch ids
+Iterator iter = sess.createQuery("from eg.Qux q order by q.likeliness").iterate();
+while ( iter.hasNext() ) {
+ Qux qux = (Qux) iter.next(); // fetch the object
+ // something we couldnt express in the query
+ if ( qux.calculateComplicatedAlgorithm() ) {
+ // delete the current instance
+ iter.remove();
+ // dont need to process the rest
+ break;
+ }
+}]]></programlisting>
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-tuples">
+ <title>Consultas que retornam tuplas</title>
+
+ <para>
+ Algumas vezes as consultas do Hibernate retornam tuplas de objetos, nesse caso
+ cada tupla é retornada como um array:
+ </para>
+
+ <programlisting><![CDATA[Iterator kittensAndMothers = sess.createQuery(
+ "select kitten, mother from Cat kitten join kitten.mother mother")
+ .list()
+ .iterator();
+
+while ( kittensAndMothers.hasNext() ) {
+ Object[] tuple = (Object[]) kittensAndMothers.next();
+ Cat kitten = (Cat) tuple[0];
+ Cat mother = (Cat) tuple[1];
+ ....
+}]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-scalar" revision="1">
+ <title>Resultados escalares</title>
+
+ <para>
+ Consultas devem especificar uma propriedade da classe na clausula
+ <literal>select</literal>. Elas também podem chamar funções SQL de agregaçãos.
+ Propriedades ou agregações são considerados resultados agregados
+ ( e não entidades no estado persistente).
+ </para>
+
+ <programlisting><![CDATA[Iterator results = sess.createQuery(
+ "select cat.color, min(cat.birthdate), count(cat) from Cat cat " +
+ "group by cat.color")
+ .list()
+ .iterator();
+
+while ( results.hasNext() ) {
+ Object[] row = (Object[]) results.next();
+ Color type = (Color) row[0];
+ Date oldest = (Date) row[1];
+ Integer count = (Integer) row[2];
+ .....
+}]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-parameters">
+ <title>Bind parameters</title>
+
+ <para>
+ Methods on <literal>Query</literal> are provided for binding values to
+ named parameters or JDBC-style <literal>?</literal> parameters.
+ <emphasis>Contrary to JDBC, Hibernate numbers parameters from zero.</emphasis>
+ Named parameters are identifiers of the form <literal>:name</literal> in
+ the query string. The advantages of named parameters are:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ named parameters are insensitive to the order they occur in the
+ query string
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ they may occur multiple times in the same query
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ they are self-documenting
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting><![CDATA[//named parameter (preferred)
+Query q = sess.createQuery("from DomesticCat cat where cat.name = :name");
+q.setString("name", "Fritz");
+Iterator cats = q.iterate();]]></programlisting>
+
+ <programlisting><![CDATA[//positional parameter
+Query q = sess.createQuery("from DomesticCat cat where cat.name = ?");
+q.setString(0, "Izi");
+Iterator cats = q.iterate();]]></programlisting>
+
+ <programlisting><![CDATA[//named parameter list
+List names = new ArrayList();
+names.add("Izi");
+names.add("Fritz");
+Query q = sess.createQuery("from DomesticCat cat where cat.name in (:namesList)");
+q.setParameterList("namesList", names);
+List cats = q.list();]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-pagination">
+ <title>Pagination</title>
+
+ <para>
+ If you need to specify bounds upon your result set (the maximum number of rows
+ you want to retrieve and / or the first row you want to retrieve) you should
+ use methods of the <literal>Query</literal> interface:
+ </para>
+
+ <programlisting><![CDATA[Query q = sess.createQuery("from DomesticCat cat");
+q.setFirstResult(20);
+q.setMaxResults(10);
+List cats = q.list();]]></programlisting>
+
+ <para>
+ Hibernate knows how to translate this limit query into the native
+ SQL of your DBMS.
+ </para>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-scrolling">
+ <title>Scrollable iteration</title>
+
+ <para>
+ If your JDBC driver supports scrollable <literal>ResultSet</literal>s, the
+ <literal>Query</literal> interface may be used to obtain a
+ <literal>ScrollableResults</literal> object, which allows flexible
+ navigation of the query results.
+ </para>
+
+ <programlisting><![CDATA[Query q = sess.createQuery("select cat.name, cat from DomesticCat cat " +
+ "order by cat.name");
+ScrollableResults cats = q.scroll();
+if ( cats.first() ) {
+
+ // find the first name on each page of an alphabetical list of cats by name
+ firstNamesOfPages = new ArrayList();
+ do {
+ String name = cats.getString(0);
+ firstNamesOfPages.add(name);
+ }
+ while ( cats.scroll(PAGE_SIZE) );
+
+ // Now get the first page of cats
+ pageOfCats = new ArrayList();
+ cats.beforeFirst();
+ int i=0;
+ while( ( PAGE_SIZE > i++ ) && cats.next() ) pageOfCats.add( cats.get(1) );
+
+}
+cats.close()]]></programlisting>
+
+ <para>
+ Note that an open database connection (and cursor) is required for this
+ functionality, use <literal>setMaxResult()</literal>/<literal>setFirstResult()</literal>
+ if you need offline pagination functionality.
+ </para>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-named" revision="1">
+ <title>Externalizing named queries</title>
+
+ <para>
+ You may also define named queries in the mapping document. (Remember to use a
+ <literal>CDATA</literal> section if your query contains characters that could
+ be interpreted as markup.)
+ </para>
+
+ <programlisting><![CDATA[<query name="ByNameAndMaximumWeight"><![CDATA[
+ from eg.DomesticCat as cat
+ where cat.name = ?
+ and cat.weight > ?
+] ]></query>]]></programlisting>
+
+ <para>
+ Parameter binding and executing is done programatically:
+ </para>
+
+ <programlisting><![CDATA[Query q = sess.getNamedQuery("ByNameAndMaximumWeight");
+q.setString(0, name);
+q.setInt(1, minWeight);
+List cats = q.list();]]></programlisting>
+
+ <para>
+ Note that the actual program code is independent of the query language that
+ is used, you may also define native SQL queries in metadata, or migrate
+ existing queries to Hibernate by placing them in mapping files.
+ </para>
+
+ <para>
+ Also note that a query declaration inside a <literal><hibernate-mapping></literal>
+ element requires a global unique name for the query, while a query declaration inside a
+ <literal><class></literal> element is made unique automatically by prepending the
+ fully qualified name of the class, for example
+ <literal>eg.Cat.ByNameAndMaximumWeight</literal>.
+ </para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="objectstate-filtering" revision="1">
+ <title>Filtering collections</title>
+ <para>
+ A collection <emphasis>filter</emphasis> is a special type of query that may be applied to
+ a persistent collection or array. The query string may refer to <literal>this</literal>,
+ meaning the current collection element.
+ </para>
+
+ <programlisting><![CDATA[Collection blackKittens = session.createFilter(
+ pk.getKittens(),
+ "where this.color = ?")
+ .setParameter( Color.BLACK, Hibernate.custom(ColorUserType.class) )
+ .list()
+);]]></programlisting>
+
+ <para>
+ The returned collection is considered a bag, and it's a copy of the given
+ collection. The original collection is not modified (this is contrary to
+ the implication of the name "filter", but consistent with expected behavior).
+ </para>
+
+ <para>
+ Observe that filters do not require a <literal>from</literal> clause (though they may have
+ one if required). Filters are not limited to returning the collection elements themselves.
+ </para>
+
+ <programlisting><![CDATA[Collection blackKittenMates = session.createFilter(
+ pk.getKittens(),
+ "select this.mate where this.color = eg.Color.BLACK.intValue")
+ .list();]]></programlisting>
+
+ <para>
+ Even an empty filter query is useful, e.g. to load a subset of elements in a
+ huge collection:
+ </para>
+
+ <programlisting><![CDATA[Collection tenKittens = session.createFilter(
+ mother.getKittens(), "")
+ .setFirstResult(0).setMaxResults(10)
+ .list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="objecstate-querying-criteria" revision="1">
+ <title>Criteria queries</title>
+
+ <para>
+ HQL is extremely powerful but some developers prefer to build queries dynamically,
+ using an object-oriented API, rather than building query strings. Hibernate provides
+ an intuitive <literal>Criteria</literal> query API for these cases:
+ </para>
+
+ <programlisting><![CDATA[Criteria crit = session.createCriteria(Cat.class);
+crit.add( Restrictions.eq( "color", eg.Color.BLACK ) );
+crit.setMaxResults(10);
+List cats = crit.list();]]></programlisting>
+
+ <para>
+ The <literal>Criteria</literal> and the associated <literal>Example</literal>
+ API are discussed in more detail in <xref linkend="querycriteria"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="objectstate-querying-nativesql" revision="2">
+ <title>Queries in native SQL</title>
+
+ <para>
+ You may express a query in SQL, using <literal>createSQLQuery()</literal> and
+ let Hibernate take care of the mapping from result sets to objects. Note
+ that you may at any time call <literal>session.connection()</literal> and
+ use the JDBC <literal>Connection</literal> directly. If you chose to use the
+ Hibernate API, you must enclose SQL aliases in braces:
+ </para>
+
+ <programlisting><![CDATA[List cats = session.createSQLQuery("SELECT {cat.*} FROM CAT {cat} WHERE ROWNUM<10")
+ .addEntity("cat", Cat.class)
+.list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = session.createSQLQuery(
+ "SELECT {cat}.ID AS {cat.id}, {cat}.SEX AS {cat.sex}, " +
+ "{cat}.MATE AS {cat.mate}, {cat}.SUBCLASS AS {cat.class}, ... " +
+ "FROM CAT {cat} WHERE ROWNUM<10")
+ .addEntity("cat", Cat.class)
+.list()]]></programlisting>
+
+ <para>
+ SQL queries may contain named and positional parameters, just like Hibernate queries.
+ More information about native SQL queries in Hibernate can be found in
+ <xref linkend="querysql"/>.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="objectstate-modifying" revision="1">
+ <title>Modifying persistent objects</title>
+
+ <para>
+ <emphasis>Transactional persistent instances</emphasis> (ie. objects loaded, saved, created or
+ queried by the <literal>Session</literal>) may be manipulated by the application
+ and any changes to persistent state will be persisted when the <literal>Session</literal>
+ is <emphasis>flushed</emphasis> (discussed later in this chapter). There is no need
+ to call a particular method (like <literal>update()</literal>, which has a different
+ purpose) to make your modifications persistent. So the most straightforward way to update
+ the state of an object is to <literal>load()</literal> it,
+ and then manipulate it directly, while the <literal>Session</literal> is open:
+ </para>
+
+ <programlisting><![CDATA[DomesticCat cat = (DomesticCat) sess.load( Cat.class, new Long(69) );
+cat.setName("PK");
+sess.flush(); // changes to cat are automatically detected and persisted]]></programlisting>
+
+ <para>
+ Sometimes this programming model is inefficient since it would require both an SQL
+ <literal>SELECT</literal> (to load an object) and an SQL <literal>UPDATE</literal>
+ (to persist its updated state) in the same session. Therefore Hibernate offers an
+ alternate approach, using detached instances.
+ </para>
+
+ <para>
+ <emphasis>Note that Hibernate does not offer its own API for direct execution of
+ <literal>UPDATE</literal> or <literal>DELETE</literal> statements. Hibernate is a
+ <emphasis>state management</emphasis> service, you don't have to think in
+ <emphasis>statements</emphasis> to use it. JDBC is a perfect API for executing
+ SQL statements, you can get a JDBC <literal>Connection</literal> at any time
+ by calling <literal>session.connection()</literal>. Furthermore, the notion
+ of mass operations conflicts with object/relational mapping for online
+ transaction processing-oriented applications. Future versions of Hibernate
+ may however provide special mass operation functions. See <xref linkend="batch"/>
+ for some possible batch operation tricks.</emphasis>
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-detached" revision="2">
+ <title>Modifying detached objects</title>
+
+ <para>
+ Many applications need to retrieve an object in one transaction, send it to the
+ UI layer for manipulation, then save the changes in a new transaction.
+ Applications that use this kind of approach in a high-concurrency environment
+ usually use versioned data to ensure isolation for the "long" unit of work.
+ </para>
+
+ <para>
+ Hibernate supports this model by providing for reattachment of detached instances
+ using the <literal>Session.update()</literal> or <literal>Session.merge()</literal>
+ methods:
+ </para>
+
+ <programlisting><![CDATA[// in the first session
+Cat cat = (Cat) firstSession.load(Cat.class, catId);
+Cat potentialMate = new Cat();
+firstSession.save(potentialMate);
+
+// in a higher layer of the application
+cat.setMate(potentialMate);
+
+// later, in a new session
+secondSession.update(cat); // update cat
+secondSession.update(mate); // update mate]]></programlisting>
+
+ <para>
+ If the <literal>Cat</literal> with identifier <literal>catId</literal> had already
+ been loaded by <literal>secondSession</literal> when the application tried to
+ reattach it, an exception would have been thrown.
+ </para>
+
+ <para>
+ Use <literal>update()</literal> if you are sure that the session does
+ not contain an already persistent instance with the same identifier, and
+ <literal>merge()</literal> if you want to merge your modifications at any time
+ without consideration of the state of the session. In other words, <literal>update()</literal>
+ is usually the first method you would call in a fresh session, ensuring that
+ reattachment of your detached instances is the first operation that is executed.
+ </para>
+
+ <para>
+ The application should individually <literal>update()</literal> detached instances
+ reachable from the given detached instance if and <emphasis>only</emphasis> if it wants
+ their state also updated. This can be automated of course, using <emphasis>transitive
+ persistence</emphasis>, see <xref linkend="objectstate-transitive"/>.
+ </para>
+
+ <para>
+ The <literal>lock()</literal> method also allows an application to reassociate
+ an object with a new session. However, the detached instance has to be unmodified!
+ </para>
+
+ <programlisting><![CDATA[//just reassociate:
+sess.lock(fritz, LockMode.NONE);
+//do a version check, then reassociate:
+sess.lock(izi, LockMode.READ);
+//do a version check, using SELECT ... FOR UPDATE, then reassociate:
+sess.lock(pk, LockMode.UPGRADE);]]></programlisting>
+
+ <para>
+ Note that <literal>lock()</literal> can be used with various
+ <literal>LockMode</literal>s, see the API documentation and the
+ chapter on transaction handling for more information. Reattachment is not
+ the only usecase for <literal>lock()</literal>.
+ </para>
+
+ <para>
+ Other models for long units of work are discussed in <xref linkend="transactions-optimistic"/>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-saveorupdate">
+ <title>Automatic state detection</title>
+
+ <para>
+ Hibernate users have requested a general purpose method that either saves a
+ transient instance by generating a new identifier or updates/reattaches
+ the detached instances associated with its current identifier.
+ The <literal>saveOrUpdate()</literal> method implements this functionality.
+ </para>
+
+ <programlisting><![CDATA[// in the first session
+Cat cat = (Cat) firstSession.load(Cat.class, catID);
+
+// in a higher tier of the application
+Cat mate = new Cat();
+cat.setMate(mate);
+
+// later, in a new session
+secondSession.saveOrUpdate(cat); // update existing state (cat has a non-null id)
+secondSession.saveOrUpdate(mate); // save the new instance (mate has a null id)]]></programlisting>
+
+ <para>
+ The usage and semantics of <literal>saveOrUpdate()</literal> seems to be confusing
+ for new users. Firstly, so long as you are not trying to use instances from one session
+ in another new session, you should not need to use <literal>update()</literal>,
+ <literal>saveOrUpdate()</literal>, or <literal>merge()</literal>. Some whole
+ applications will never use either of these methods.
+ </para>
+
+ <para>
+ Usually <literal>update()</literal> or <literal>saveOrUpdate()</literal> are used in
+ the following scenario:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ the application loads an object in the first session
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ the object is passed up to the UI tier
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ some modifications are made to the object
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ the object is passed back down to the business logic tier
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ the application persists these modifications by calling
+ <literal>update()</literal> in a second session
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>saveOrUpdate()</literal> does the following:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ if the object is already persistent in this session, do nothing
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ if another object associated with the session has the same identifier,
+ throw an exception
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ if the object has no identifier property, <literal>save()</literal> it
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ if the object's identifier has the value assigned to a newly instantiated
+ object, <literal>save()</literal> it
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ if the object is versioned (by a <literal><version></literal> or
+ <literal><timestamp></literal>), and the version property value
+ is the same value assigned to a newly instantiated object,
+ <literal>save()</literal> it
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ otherwise <literal>update()</literal> the object
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ and <literal>merge()</literal> is very different:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ if there is a persistent instance with the same identifier currently
+ associated with the session, copy the state of the given object onto
+ the persistent instance
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ if there is no persistent instance currently associated with the session,
+ try to load it from the database, or create a new persistent instance
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ the persistent instance is returned
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ the given instance does not become associated with the session, it
+ remains detached
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 id="objectstate-deleting" revision="1">
+ <title>Deleting persistent objects</title>
+
+ <para>
+ <literal>Session.delete()</literal> will remove an object's state from the database.
+ Of course, your application might still hold a reference to a deleted object.
+ It's best to think of <literal>delete()</literal> as making a persistent instance
+ transient.
+ </para>
+
+ <programlisting><![CDATA[sess.delete(cat);]]></programlisting>
+
+ <para>
+ You may delete objects in any order you like, without risk of foreign key
+ constraint violations. It is still possible to violate a <literal>NOT
+ NULL</literal> constraint on a foreign key column by deleting objects in
+ the wrong order, e.g. if you delete the parent, but forget to delete the
+ children.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-replicating" revision="1">
+ <title>Replicating object between two different datastores</title>
+
+ <para>
+ It is occasionally useful to be able to take a graph of persistent instances
+ and make them persistent in a different datastore, without regenerating identifier
+ values.
+ </para>
+
+ <programlisting><![CDATA[//retrieve a cat from one database
+Session session1 = factory1.openSession();
+Transaction tx1 = session1.beginTransaction();
+Cat cat = session1.get(Cat.class, catId);
+tx1.commit();
+session1.close();
+
+//reconcile with a second database
+Session session2 = factory2.openSession();
+Transaction tx2 = session2.beginTransaction();
+session2.replicate(cat, ReplicationMode.LATEST_VERSION);
+tx2.commit();
+session2.close();]]></programlisting>
+
+ <para>
+ The <literal>ReplicationMode</literal> determines how <literal>replicate()</literal>
+ will deal with conflicts with existing rows in the database.
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>ReplicationMode.IGNORE</literal> - ignore the object when there is
+ an existing database row with the same identifier
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.OVERWRITE</literal> - overwrite any existing database
+ row with the same identifier
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.EXCEPTION</literal> - throw an exception if there is
+ an existing database row with the same identifier
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.LATEST_VERSION</literal> - overwrite the row if its
+ version number is earlier than the version number of the object, or ignore
+ the object otherwise
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Usecases for this feature include reconciling data entered into different database
+ instances, upgrading system configuration information during product upgrades,
+ rolling back changes made during non-ACID transactions and more.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-flushing">
+ <title>Flushing the Session</title>
+
+ <para>
+ From time to time the <literal>Session</literal> will execute the SQL statements
+ needed to synchronize the JDBC connection's state with the state of objects held in
+ memory. This process, <emphasis>flush</emphasis>, occurs by default at the following
+ points
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ before some query executions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ from <literal>org.hibernate.Transaction.commit()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ from <literal>Session.flush()</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The SQL statements are issued in the following order
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ all entity insertions, in the same order the corresponding objects
+ were saved using <literal>Session.save()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ all entity updates
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ all collection deletions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ all collection element deletions, updates and insertions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ all collection insertions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ all entity deletions, in the same order the corresponding objects
+ were deleted using <literal>Session.delete()</literal>
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ (An exception is that objects using <literal>native</literal> ID generation are
+ inserted when they are saved.)
+ </para>
+
+ <para>
+ Except when you explicity <literal>flush()</literal>, there are absolutely no
+ guarantees about <emphasis>when</emphasis> the <literal>Session</literal> executes
+ the JDBC calls, only the <emphasis>order</emphasis> in which they are executed.
+ However, Hibernate does guarantee that the <literal>Query.list(..)</literal>
+ will never return stale data; nor will they return the wrong data.
+ </para>
+
+ <para>
+ It is possible to change the default behavior so that flush occurs less frequently.
+ The <literal>FlushMode</literal> class defines three different modes: only flush
+ at commit time (and only when the Hibernate <literal>Transaction</literal> API
+ is used), flush automatically using the explained routine, or never flush unless
+ <literal>flush()</literal> is called explicitly. The last mode is useful for long running
+ units of work, where a <literal>Session</literal> is kept open and disconnected for
+ a long time (see <xref linkend="transactions-optimistic-longsession"/>).
+ </para>
+
+ <programlisting><![CDATA[sess = sf.openSession();
+Transaction tx = sess.beginTransaction();
+sess.setFlushMode(FlushMode.COMMIT); // allow queries to return stale state
+
+Cat izi = (Cat) sess.load(Cat.class, id);
+izi.setName(iznizi);
+
+// might return stale data
+sess.find("from Cat as cat left outer join cat.kittens kitten");
+
+// change to izi is not flushed!
+...
+tx.commit(); // flush occurs
+sess.close();]]></programlisting>
+
+ <para>
+ During flush, an exception might occur (e.g. if a DML operation violates a constraint).
+ Since handling exceptions involves some understanding of Hibernate's transactional
+ behavior, we discuss it in <xref linkend="transactions"/>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-transitive" revision="1">
+ <title>Transitive persistence</title>
+
+ <para>
+ It is quite cumbersome to save, delete, or reattach individual objects,
+ especially if you deal with a graph of associated objects. A common case is
+ a parent/child relationship. Consider the following example:
+ </para>
+
+ <para>
+ If the children in a parent/child relationship would be value typed (e.g. a collection
+ of addresses or strings), their life cycle would depend on the parent and no
+ further action would be required for convenient "cascading" of state changes.
+ When the parent is saved, the value-typed child objects are saved as
+ well, when the parent is deleted, the children will be deleted, etc. This
+ even works for operations such as the removal of a child from the collection;
+ Hibernate will detect this and, since value-typed objects can't have shared
+ references, delete the child from the database.
+ </para>
+
+ <para>
+ Now consider the same scenario with parent and child objects being entities,
+ not value-types (e.g. categories and items, or parent and child cats). Entities
+ have their own life cycle, support shared references (so removing an entity from
+ the collection does not mean it can be deleted), and there is by default no
+ cascading of state from one entity to any other associated entities. Hibernate
+ does not implement <emphasis>persistence by reachability</emphasis> by default.
+ </para>
+
+ <para>
+ For each basic operation of the Hibernate session - including <literal>persist(), merge(),
+ saveOrUpdate(), delete(), lock(), refresh(), evict(), replicate()</literal> - there is a
+ corresponding cascade style. Respectively, the cascade styles are named <literal>create,
+ merge, save-update, delete, lock, refresh, evict, replicate</literal>. If you want an
+ operation to be cascaded along an association, you must indicate that in the mapping
+ document. For example:
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="person" cascade="persist"/>]]></programlisting>
+
+ <para>
+ Cascade styles my be combined:
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="person" cascade="persist,delete,lock"/>]]></programlisting>
+
+ <para>
+ You may even use <literal>cascade="all"</literal> to specify that <emphasis>all</emphasis>
+ operations should be cascaded along the association. The default <literal>cascade="none"</literal>
+ specifies that no operations are to be cascaded.
+ </para>
+
+ <para>
+ A special cascade style, <literal>delete-orphan</literal>, applies only to one-to-many
+ associations, and indicates that the <literal>delete()</literal> operation should
+ be applied to any child object that is removed from the association.
+ </para>
+
+
+ <para>
+ Recommendations:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ It doesn't usually make sense to enable cascade on a <literal><many-to-one></literal>
+ or <literal><many-to-many></literal> association. Cascade is often useful for
+ <literal><one-to-one></literal> and <literal><one-to-many></literal>
+ associations.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If the child object's lifespan is bounded by the lifespan of the parent
+ object, make it a <emphasis>life cycle object</emphasis> by specifying
+ <literal>cascade="all,delete-orphan"</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Otherwise, you might not need cascade at all. But if you think that you will often be
+ working with the parent and children together in the same transaction, and you want to save
+ yourself some typing, consider using <literal>cascade="persist,merge,save-update"</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Mapping an association (either a single valued association, or a collection) with
+ <literal>cascade="all"</literal> marks the association as a
+ <emphasis>parent/child</emphasis> style relationship where save/update/delete of the
+ parent results in save/update/delete of the child or children.
+ </para>
+ <para>
+ Futhermore, a mere reference to a child from a persistent parent will result in
+ save/update of the child. This metaphor is incomplete, however. A child which becomes
+ unreferenced by its parent is <emphasis>not</emphasis> automatically deleted, except
+ in the case of a <literal><one-to-many></literal> association mapped with
+ <literal>cascade="delete-orphan"</literal>. The precise semantics of cascading
+ operations for a parent/child relationship are as follows:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ If a parent is passed to <literal>persist()</literal>, all children are passed to
+ <literal>persist()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If a parent is passed to <literal>merge()</literal>, all children are passed to
+ <literal>merge()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If a parent is passed to <literal>save()</literal>, <literal>update()</literal> or
+ <literal>saveOrUpdate()</literal>, all children are passed to <literal>saveOrUpdate()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If a transient or detached child becomes referenced by a persistent parent,
+ it is passed to <literal>saveOrUpdate()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If a parent is deleted, all children are passed to <literal>delete()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If a child is dereferenced by a persistent parent, <emphasis>nothing
+ special happens</emphasis> - the application should explicitly delete
+ the child if necessary - unless <literal>cascade="delete-orphan"</literal>,
+ in which case the "orphaned" child is deleted.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Finally, note that cascading of operations can be applied to an object graph at
+ <emphasis>call time</emphasis> or at <emphasis>flush time</emphasis>. All operations,
+ if enabled, are cascaded to associated entities reachable when the operation is
+ executed. However, <literal>save-upate</literal> and <literal>delete-orphan</literal>
+ are transitive for all associated entities reachable during flush of the
+ <literal>Session</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-metadata">
+ <title>Usando metadados</title>
+
+ <para>
+ O Hibernate requer um modelo muito rico a nível de metadados de todas as entidades e tipos de
+ valores. De tempos em tempos, este modelo é muito útil à própria aplicação. Por exemplo, a
+ aplicação pode usar o metadados do Hibernate que executa um algoritmo "inteligente" que
+ compreende quais objetos podem ser copiados (por exemplo, tipos de valores mutáveis) ou
+ não (por exemplo, tipos de valores imutáveis e, possivelmente, entidades associadas).
+ </para>
+ <para>
+ O Hibernate expõe o metadados via interfaces <literal>ClassMetadata</literal>
+ e <literal>CollectionMetadata</literal> e pela hierarquia <literal>Type</literal>.
+ Instâncias das interfaces de metadados podem ser obtidas a partir do
+ <literal>SessionFactory</literal>.
+ </para>
+
+ <programlisting><![CDATA[Cat fritz = ......;
+ClassMetadata catMeta = sessionfactory.getClassMetadata(Cat.class);
+
+Object[] propertyValues = catMeta.getPropertyValues(fritz);
+String[] propertyNames = catMeta.getPropertyNames();
+Type[] propertyTypes = catMeta.getPropertyTypes();
+
+// get a Map of all properties which are not collections or associations
+Map namedValues = new HashMap();
+for ( int i=0; i<propertyNames.length; i++ ) {
+ if ( !propertyTypes[i].isEntityType() && !propertyTypes[i].isCollectionType() ) {
+ namedValues.put( propertyNames[i], propertyValues[i] );
+ }
+}]]></programlisting>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/toolset_guide.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/toolset_guide.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/toolset_guide.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/toolset_guide.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,604 @@
+<chapter id="toolsetguide" revision="2">
+ <title>Toolset Guide</title>
+
+ <para>
+ Roundtrip engineering with Hibernate is possible using a set of Eclipse plugins,
+ commandline tools, as well as Ant tasks.
+ </para>
+
+ <para>
+ The <emphasis>Hibernate Tools</emphasis> currently include plugins for the Eclipse
+ IDE as well as Ant tasks for reverse engineering of existing databases:
+ </para>
+
+ <itemizedlist>
+ <listitem><para>
+ <emphasis>Mapping Editor:</emphasis> An editor for Hibernate XML mapping files,
+ supporting auto-completion and syntax highlighting. It also supports semantic
+ auto-completion for class names and property/field names, making it much more versatile than a normal XML editor.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Console:</emphasis> The console is a new view in Eclipse. In addition to
+ a tree overview of your console configurations, you also get an interactive view
+ of your persistent classes and their relationships. The console allows you to
+ execute HQL queries against your database and browse the result directly in
+ Eclipse.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Development Wizards:</emphasis> Several wizards are provided with the
+ Hibernate Eclipse tools; you can use a wizard to quickly generate Hibernate configuration
+ (cfg.xml) files, or you may even completely reverse engineer an existing database schema
+ into POJO source files and Hibernate mapping files. The reverse engineering wizard
+ supports customizable templates.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Ant Tasks:</emphasis>
+ </para></listitem>
+
+ </itemizedlist>
+
+ <para>
+ Please refer to the <emphasis>Hibernate Tools</emphasis> package and it's documentation
+ for more information.
+ </para>
+
+ <para>
+ However, the Hibernate main package comes bundled with an integrated tool (it can even
+ be used from "inside" Hibernate on-the-fly): <emphasis>SchemaExport</emphasis> aka
+ <literal>hbm2ddl</literal>.
+ </para>
+
+ <sect1 id="toolsetguide-s1" revision="2">
+ <title>Automatic schema generation</title>
+
+ <para>
+ DDL may be generated from your mapping files by a Hibernate utility. The generated
+ schema includes referential integrity constraints (primary and foreign keys) for
+ entity and collection tables. Tables and sequences are also created for mapped
+ identifier generators.
+ </para>
+
+ <para>
+ You <emphasis>must</emphasis> specify a SQL <literal>Dialect</literal> via the
+ <literal>hibernate.dialect</literal> property when using this tool, as DDL
+ is highly vendor specific.
+ </para>
+
+ <para>
+ First, customize your mapping files to improve the generated schema.
+ </para>
+
+ <sect2 id="toolsetguide-s1-2" revision="3">
+ <title>Customizing the schema</title>
+
+ <para>
+ Many Hibernate mapping elements define optional attributes named <literal>length</literal>,
+ <literal>precision</literal> and <literal>scale</literal>. You may set the length, precision
+ and scale of a column with this attribute.
+
+ </para>
+
+ <programlisting><![CDATA[<property name="zip" length="5"/>]]></programlisting>
+ <programlisting><![CDATA[<property name="balance" precision="12" scale="2"/>]]></programlisting>
+
+ <para>
+ Some tags also accept a <literal>not-null</literal> attribute (for generating a
+ <literal>NOT NULL</literal> constraint on table columns) and a <literal>unique</literal>
+ attribute (for generating <literal>UNIQUE</literal> constraint on table columns).
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="bar" column="barId" not-null="true"/>]]></programlisting>
+
+ <programlisting><![CDATA[<element column="serialNumber" type="long" not-null="true" unique="true"/>]]></programlisting>
+
+ <para>
+ A <literal>unique-key</literal> attribute may be used to group columns in
+ a single unique key constraint. Currently, the specified value of the
+ <literal>unique-key</literal> attribute is <emphasis>not</emphasis> used
+ to name the constraint in the generated DDL, only to group the columns in
+ the mapping file.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="org" column="orgId" unique-key="OrgEmployeeId"/>
+<property name="employeeId" unique-key="OrgEmployee"/>]]></programlisting>
+
+ <para>
+ An <literal>index</literal> attribute specifies the name of an index that
+ will be created using the mapped column or columns. Multiple columns may be
+ grouped into the same index, simply by specifying the same index name.
+ </para>
+
+ <programlisting><![CDATA[<property name="lastName" index="CustName"/>
+<property name="firstName" index="CustName"/>]]></programlisting>
+
+ <para>
+ A <literal>foreign-key</literal> attribute may be used to override the name
+ of any generated foreign key constraint.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="bar" column="barId" foreign-key="FKFooBar"/>]]></programlisting>
+
+ <para>
+ Many mapping elements also accept a child <literal><column></literal> element.
+ This is particularly useful for mapping multi-column types:
+ </para>
+
+ <programlisting><![CDATA[<property name="name" type="my.customtypes.Name"/>
+ <column name="last" not-null="true" index="bar_idx" length="30"/>
+ <column name="first" not-null="true" index="bar_idx" length="20"/>
+ <column name="initial"/>
+</property>]]></programlisting>
+
+ <para>
+ The <literal>default</literal> attribute lets you specify a default value for
+ a column (you should assign the same value to the mapped property before
+ saving a new instance of the mapped class).
+ </para>
+
+ <programlisting><![CDATA[<property name="credits" type="integer" insert="false">
+ <column name="credits" default="10"/>
+</property>]]></programlisting>
+
+ <programlisting><![CDATA[<version name="version" type="integer" insert="false">
+ <column name="version" default="0"/>
+</property>]]></programlisting>
+
+ <para>
+ The <literal>sql-type</literal> attribute allows the user to override the default
+ mapping of a Hibernate type to SQL datatype.
+ </para>
+
+ <programlisting><![CDATA[<property name="balance" type="float">
+ <column name="balance" sql-type="decimal(13,3)"/>
+</property>]]></programlisting>
+
+ <para>
+ The <literal>check</literal> attribute allows you to specify a check constraint.
+ </para>
+
+ <programlisting><![CDATA[<property name="foo" type="integer">
+ <column name="foo" check="foo > 10"/>
+</property>]]></programlisting>
+
+ <programlisting><![CDATA[<class name="Foo" table="foos" check="bar < 100.0">
+ ...
+ <property name="bar" type="float"/>
+</class>]]></programlisting>
+
+
+ <table frame="topbot" id="schemattributes-summary" revision="2">
+ <title>Summary</title>
+ <tgroup cols="3">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>Attribute</entry>
+ <entry>Values</entry>
+ <entry>Interpretation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>length</literal></entry>
+ <entry>number</entry>
+ <entry>column length</entry>
+ </row>
+ <row>
+ <entry><literal>precision</literal></entry>
+ <entry>number</entry>
+ <entry>column decimal precision</entry>
+ </row>
+ <row>
+ <entry><literal>scale</literal></entry>
+ <entry>number</entry>
+ <entry>column decimal scale</entry>
+ </row>
+ <row>
+ <entry><literal>not-null</literal></entry>
+ <entry><literal>true|false</literal></entry>
+ <entry>specfies that the column should be non-nullable</entry>
+ </row>
+ <row>
+ <entry><literal>unique</literal></entry>
+ <entry><literal>true|false</literal></entry>
+ <entry>specifies that the column should have a unique constraint</entry>
+ </row>
+ <row>
+ <entry><literal>index</literal></entry>
+ <entry><literal>index_name</literal></entry>
+ <entry>specifies the name of a (multi-column) index</entry>
+ </row>
+ <row>
+ <entry><literal>unique-key</literal></entry>
+ <entry><literal>unique_key_name</literal></entry>
+ <entry>specifies the name of a multi-column unique constraint</entry>
+ </row>
+ <row>
+ <entry><literal>foreign-key</literal></entry>
+ <entry><literal>foreign_key_name</literal></entry>
+ <entry>
+ specifies the name of the foreign key constraint generated
+ for an association, for a <literal><one-to-one></literal>,
+ <literal><many-to-one></literal>, <literal><key></literal>,
+ or <literal><many-to-many></literal> mapping element. Note that
+ <literal>inverse="true"</literal> sides will not be considered
+ by <literal>SchemaExport</literal>.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>sql-type</literal></entry>
+ <entry><literal>SQL column type</literal></entry>
+ <entry>
+ overrides the default column type (attribute of
+ <literal><column></literal> element only)
+ </entry>
+ </row>
+ <row>
+ <entry><literal>default</literal></entry>
+ <entry>SQL expression</entry>
+ <entry>
+ specify a default value for the column
+ </entry>
+ </row>
+ <row>
+ <entry><literal>check</literal></entry>
+ <entry>SQL expression</entry>
+ <entry>
+ create an SQL check constraint on either column or table
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <literal><comment></literal> element allows you to specify comments
+ for the generated schema.
+ </para>
+
+ <programlisting><![CDATA[<class name="Customer" table="CurCust">
+ <comment>Current customers only</comment>
+ ...
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[<property name="balance">
+ <column name="bal">
+ <comment>Balance in USD</comment>
+ </column>
+</property>]]></programlisting>
+
+ <para>
+ This results in a <literal>comment on table</literal> or
+ <literal>comment on column</literal> statement in the generated
+ DDL (where supported).
+ </para>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-3" revision="2">
+ <title>Running the tool</title>
+
+ <para>
+ The <literal>SchemaExport</literal> tool writes a DDL script to standard out and/or
+ executes the DDL statements.
+ </para>
+
+ <para>
+ <literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaExport</literal> <emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title><literal>SchemaExport</literal> Command Line Options</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Option</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>--quiet</literal></entry>
+ <entry>don't output the script to stdout</entry>
+ </row>
+ <row>
+ <entry><literal>--drop</literal></entry>
+ <entry>only drop the tables</entry>
+ </row>
+ <row>
+ <entry><literal>--create</literal></entry>
+ <entry>only create the tables</entry>
+ </row>
+ <row>
+ <entry><literal>--text</literal></entry>
+ <entry>don't export to the database</entry>
+ </row>
+ <row>
+ <entry><literal>--output=my_schema.ddl</literal></entry>
+ <entry>output the ddl script to a file</entry>
+ </row>
+ <row>
+ <entry><literal>--naming=eg.MyNamingStrategy</literal></entry>
+ <entry>select a <literal>NamingStrategy</literal></entry>
+ </row>
+ <row>
+ <entry><literal>--config=hibernate.cfg.xml</literal></entry>
+ <entry>read Hibernate configuration from an XML file</entry>
+ </row>
+ <row>
+ <entry><literal>--properties=hibernate.properties</literal></entry>
+ <entry>read database properties from a file</entry>
+ </row>
+ <row>
+ <entry><literal>--format</literal></entry>
+ <entry>format the generated SQL nicely in the script</entry>
+ </row>
+ <row>
+ <entry><literal>--delimiter=;</literal></entry>
+ <entry>set an end of line delimiter for the script</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ You may even embed <literal>SchemaExport</literal> in your application:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaExport(cfg).create(false, true);]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-4">
+ <title>Properties</title>
+
+ <para>
+ Database properties may be specified
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>as system properties with <literal>-D</literal><emphasis><property></emphasis></para>
+ </listitem>
+ <listitem>
+ <para>in <literal>hibernate.properties</literal></para>
+ </listitem>
+ <listitem>
+ <para>in a named properties file with <literal>--properties</literal></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The needed properties are:
+ </para>
+
+ <table frame="topbot">
+ <title>SchemaExport Connection Properties</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>hibernate.connection.driver_class</literal></entry>
+ <entry>jdbc driver class</entry>
+ </row>
+ <row>
+ <entry><literal>hibernate.connection.url</literal></entry>
+ <entry>jdbc url</entry>
+ </row>
+ <row>
+ <entry><literal>hibernate.connection.username</literal></entry>
+ <entry>database user</entry>
+ </row>
+ <row>
+ <entry><literal>hibernate.connection.password</literal></entry>
+ <entry>user password</entry>
+ </row>
+ <row>
+ <entry><literal>hibernate.dialect</literal></entry>
+ <entry>dialect</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-5">
+ <title>Using Ant</title>
+
+ <para>
+ You can call <literal>SchemaExport</literal> from your Ant build script:
+ </para>
+
+ <programlisting><![CDATA[<target name="schemaexport">
+ <taskdef name="schemaexport"
+ classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
+ classpathref="class.path"/>
+
+ <schemaexport
+ properties="hibernate.properties"
+ quiet="no"
+ text="no"
+ drop="no"
+ delimiter=";"
+ output="schema-export.sql">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemaexport>
+</target>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-6" revision="2">
+ <title>Incremental schema updates</title>
+
+ <para>
+ The <literal>SchemaUpdate</literal> tool will update an existing schema with "incremental" changes.
+ Note that <literal>SchemaUpdate</literal> depends heavily upon the JDBC metadata API, so it will
+ not work with all JDBC drivers.
+ </para>
+
+ <para>
+ <literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaUpdate</literal> <emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title><literal>SchemaUpdate</literal> Command Line Options</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Option</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>--quiet</literal></entry>
+ <entry>don't output the script to stdout</entry>
+ </row>
+ <row>
+ <entry><literal>--text</literal></entry>
+ <entry>don't export the script to the database</entry>
+ </row>
+ <row>
+ <entry><literal>--naming=eg.MyNamingStrategy</literal></entry>
+ <entry>select a <literal>NamingStrategy</literal></entry>
+ </row>
+ <row>
+ <entry><literal>--properties=hibernate.properties</literal></entry>
+ <entry>read database properties from a file</entry>
+ </row>
+ <row>
+ <entry><literal>--config=hibernate.cfg.xml</literal></entry>
+ <entry>specify a <literal>.cfg.xml</literal> file</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ You may embed <literal>SchemaUpdate</literal> in your application:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaUpdate(cfg).execute(false);]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-7">
+ <title>Using Ant for incremental schema updates</title>
+
+ <para>
+ You can call <literal>SchemaUpdate</literal> from the Ant script:
+ </para>
+
+ <programlisting><![CDATA[<target name="schemaupdate">
+ <taskdef name="schemaupdate"
+ classname="org.hibernate.tool.hbm2ddl.SchemaUpdateTask"
+ classpathref="class.path"/>
+
+ <schemaupdate
+ properties="hibernate.properties"
+ quiet="no">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemaupdate>
+</target>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-8" revision="1">
+ <title>Schema validation</title>
+
+ <para>
+ The <literal>SchemaValidator</literal> tool will validate that the existing database schema "matches"
+ your mapping documents. Note that <literal>SchemaValidator</literal> depends heavily upon the JDBC
+ metadata API, so it will not work with all JDBC drivers. This tool is extremely useful for testing.
+ </para>
+
+ <para>
+ <literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaValidator</literal> <emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title><literal>SchemaValidator</literal> Command Line Options</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Option</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>--naming=eg.MyNamingStrategy</literal></entry>
+ <entry>select a <literal>NamingStrategy</literal></entry>
+ </row>
+ <row>
+ <entry><literal>--properties=hibernate.properties</literal></entry>
+ <entry>read database properties from a file</entry>
+ </row>
+ <row>
+ <entry><literal>--config=hibernate.cfg.xml</literal></entry>
+ <entry>specify a <literal>.cfg.xml</literal> file</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ You may embed <literal>SchemaValidator</literal> in your application:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaValidator(cfg).validate();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-9">
+ <title>Using Ant for schema validation</title>
+
+ <para>
+ You can call <literal>SchemaValidator</literal> from the Ant script:
+ </para>
+
+ <programlisting><![CDATA[<target name="schemavalidate">
+ <taskdef name="schemavalidator"
+ classname="org.hibernate.tool.hbm2ddl.SchemaValidatorTask"
+ classpathref="class.path"/>
+
+ <schemavalidator
+ properties="hibernate.properties">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemavalidator>
+</target>]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/transactions.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/transactions.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/transactions.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/transactions.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,1147 @@
+<chapter id="transactions" revision="2">
+ <title>Transações e Concorrência</title>
+
+ <para>
+ O ponto o mais importante sobre o Hibernate e o controle de concorrência é que é muito
+ fácil de ser compreendido. O Hibernate usa diretamente conexões de JDBC e recursos de
+ JTA sem adicionar nenhum comportamento de bloqueio a mais. Nós altamente recomendamos
+ que você gaste algum tempo com o JDBC, o ANSI e a especificação de isolamento de transação
+ de seu sistema de gerência da base de dados.
+ </para>
+
+ <para>
+ O Hibernate não bloqueia objetos na memória. Sua aplicação pode esperar o comportamento
+ tal qual definido pelo nível de isolamento de suas transações de banco de dados.
+ Note que graças ao <literal>Session</literal>, que também é um cache de escopo de
+ transação, o Hibernate fornece leituras repetíveis para procurar por identificadores
+ e consultas de entidade (não pesquisas de relatórios que retornam valores escalares).
+ </para>
+
+ <para>
+ Além do versionamento para o controle automático de concorrência otimista, o Hibernate
+ oferece também uma API (menor) para bloqueio pessimista de linhas usando a sintaxe
+ <literal>SELECT FOR UPDATE</literal>. O controle de concorrência otimista e esta
+ API são discutidos mais tarde neste capítulo.
+ </para>
+
+ <para>
+ Nós começamos a discussão do controle de concorrência no Hibernate com a granularidade
+ do <literal>Configuration</literal>, <literal>SessionFactory</literal>, e
+ <literal>Session</literal>, além de transações de base de dados e conversações longas.
+ </para>
+
+ <sect1 id="transactions-basics" revision="1">
+ <title>Session e escopos de transações</title>
+
+ <para>
+ Um <literal>SessionFactory</literal> é objeto threadsafe compartilhado por
+ todas as threads da aplicação que consome muitos recursos na sua criação.
+ É criado uma unica vez no inicio da execução da aplicação a partir da
+ instância de uma <literal>Configuration</literal>.
+ </para>
+
+ <para>
+ Uma <literal>Session</literal> é um objeto de baixo custo de criação, não é threadsafe,
+ deve ser usado uma vez, para uma única requisição, uma conversação, uma única unidade
+ do trabalho e então deve ser descartado. Um <literal>Session</literal> não obterá um
+ JDBC <literal>Connection</literal> (ou um <literal>Datasource</literal>) a menos que
+ necessite, conseqüentemente não consome nenhum recurso até ser usado.
+ </para>
+
+ <para>
+ Para completar, você também tem que pensar sobre as transações de base de dados.
+ Uma transação tem que ser tão curta quanto possível, para reduzir a disputa pelo
+ bloqueio na base de dados. Transações longas impedirão que sua aplicação escale a
+ carga altamente concorrente. Por isso, em um projeto raramente é para manter
+ uma transação de base de dados aberta durante o tempo que o usuário pensa,
+ até que a unidade do trabalho esteja completa.
+ </para>
+
+ <para>
+ Qual é o escopo de uma unidade de trabalho? Pode uma únicoa <literal>Session</literal>
+ do Hibernate gerenciar diversas transações ou é esta um o relacionamento um-para-um dos
+ escopos? Quando deve você abrir e fechar uma <literal>Session</literal> e como você
+ demarca os limites da transação?
+ </para>
+
+ <sect2 id="transactions-basics-uow" revision="1">
+ <title>Unidade de trabalho</title>
+
+ <para>
+ Primeiro, não use o antipattern <emphasis>sessão-por-operação</emphasis>,
+ isto é, não abra e não feche uma <literal>Session</literal> para cada simples chamada
+ ao banco de de dados em uma única thread! Naturalmente, o mesmo é verdadeiro para
+ transações. As chamadas a banco de dados em uma aplicação são feitas usando uma
+ seqüência planejada, elas são agrupadas em unidades de trabalho atômicas.
+ (Veja que isso também significa que um auto-commit depois de cada sentença SQL é
+ inútil em uma aplicação, esta modalidade é ideal para o trabalho ad hoc do console
+ do SQL. O Hibernate impede, ou espera que o servidor de aplicação impessa isso,
+ o uso da modalidade de auto-commit.) As transações nunca são opcionais, toda a
+ comunicação com um banco de dados tem que ocorrer dentro de uma transação, não
+ importa se você vai ler ou escrever dados. Como explicado, o comportamento auto-commit
+ para leitura de dados deve ser evitado, como muitas transações pequenas são
+ improváveis de executar melhor do que uma unidade claramente definida do trabalho. A
+ última opção também muito mais manutenível e extensível.
+ </para>
+
+ <para>
+ O pattern mais comum em uma aplicação multi-usuário cliente/servidor é
+ <emphasis>sessão-por-requisição</emphasis>. Neste modelo, uma requisição do cliente é
+ enviada ao servidor (onde a camada de persistência do Hibernate roda), uma
+ <literal>Session</literal> nova do Hibernate é aberta, e todas as operações da base de
+ dados são executadas nesta unidade do trabalho. Logo que o trabalho for completado
+ (e a resposta para o cliente for preparada), a sessão é descarregad e fechada.
+ Você usaria também uma única transação de base de dados para servir às requisições
+ dos clientes, começando e commitando-o quando você abre e fecha a <literal>Session</literal>.
+ O relacionamento entre os dois é um-para-um e este modelo é um ajuste perfeito para muitas
+ aplicações.
+ </para>
+
+ <para>
+ O desafio encontra-se na implementação. O Hibernate fornece gerência integrada da "sessão atual"
+ para simplificar este pattern. Tudo que você tem que fazer é iniciar uma transação quando uma
+ requisição tem que ser processada e termina a transação antes que a resposta seja enviada ao
+ cliente. Você pode fazer onde quiser, soluções comuns são <literal>ServletFilter</literal>,
+ interceptador AOP com um pointcut (ponto de corte) nos métodos de serviço ou em um
+ container de proxy/interceptação. Um container de EJB é uma maneira padronizada para
+ implementar aspectos cross-cutting tais como a demarcação da transação em EJB session beans,
+ declarativamente com CMT. Se você se decidir usar demarcação programática de transação,
+ de preferencia a API <literal>Transaction</literal> do Hibernate mostrada mais adiante neste
+ capítulo, para fácilidade no uso e portabilidade de código.
+ </para>
+
+ <para>
+ Seu código de aplicação pode acessar a "sessão atual" para processar a requisição
+ fazendo uma chamada simples a <literal>sessionFactory.getCurrentSession()</literal> em
+ qualquer lugar e com a frequencia necessária. Você sempre conseguirá uma
+ <literal>Session</literal> limitada a transação atual. Isto tem que ser configurado
+ para recurso local ou os ambientes JTA. Veja <xref linkend="architecture-current-session"/>.
+ </para>
+
+ <para>
+ Às vezes é conveniente estender o escopo de uma <literal>Session</literal> e de
+ uma transação do banco de dados até que a "visão esteja renderizada". É especialmente
+ útil em aplicações servlet que utilizam uma fase de rendenderização separada depois
+ que a requisição ter sido processada. Estendendo a transação até que renderização da
+ visão esteja completa é fácil de fazer se você implementar seu próprio interceptador.
+ Entretanto, não se pode fazer facilmente se você confiar em EJBs com transações
+ gerenciadas por contêiner, porque uma transação será terminada quando um método de
+ EJB retornar, antes da renderização de toda visão puder começar.
+ Veja o website e o fórum do Hibernate para dicas e exemplos em torno deste
+ pattern <emphasis>Open Session in View</emphasis>.
+
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-basics-apptx" revision="1">
+ <title>Longas conversações</title>
+
+ <para>
+ O pattern sessão-por-requisição não é o único conceito útil que você pode usar ao projetar
+ unidades de trabalho. Muitos processos de negócio requerem uma totalidade de séries de
+ interações com o usuário intercaladas com acessos a uma base de dados. Em aplicações web
+ e corporativas não é aceitável para uma transação atrapalhe uma interação do usuário.
+ Considere o seguinte exemplo:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ A primeira tela de um diálogo abre os dados carregado pelo usuário em através de
+ <literal>Session</literal> e transação particulares. O usuário está livre
+ modificar os objetos.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ O usuário clica em "Salvar" após 5 minutos e espera suas modificações serem persistidas;
+ espera também que ele era a única pessoa que edita esta informação e que nenhuma
+ modificação conflitante possa ocorrer.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Nós chamamos esta unidade de trabalho, do ponto da visão do usuário, executando uma
+ longa <emphasis>conversação</emphasis> (ou <emphasis>transação da aplicação</emphasis>).
+ Há muitas maneiras de você pode implementar em sua aplicação.
+
+ </para>
+
+ <para>
+ Uma primeira implementação simples pode manter a<literal>Session</literal> e a transação
+ aberta durante o tempo de interação do usuário, com bloqueios na base de dados para impedir
+ a modificação concorrente e para garantir o isolamento e a atomicidade. Esse é naturalmente
+ um anti-pattern, desde que a disputa do bloqueio não permitiria o escalonameneto da
+ aplicação com o número de usuários concorrentes.
+ </para>
+
+ <para>
+ Claramente, nós temos que usar diversas transações para implementar a conversação.
+ Neste caso, Manter o isolamento dos processos de negócio torna-se responsabilidade
+ parcial da camada da aplicação. Uma única conversação geralmente usa diversas transações.
+ Ela será atômica se somente uma destas transações (a última) armazenar os
+ dados atualizados, todas as outras simplesmente leram os dados (por exemplo em um
+ diálogo do estilo wizard que mede diversos ciclos de requisição/resposta). Isto é mais
+ fácil de implementar do que pode parecer, especialmente se você usar as
+ características do Hibernate:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Versionamento automático</emphasis> - O Hibernate pode fazer o
+ controle automático de concorrência otimista para você, ele pode
+ automaticamente detectar se uma modificação concorrente
+ ocorreu durante o tempo de interação do usuário. Geralmente nós verificamos
+ somente no fim da conversação.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Detached Objects</emphasis>- se você se decidir usar o já discutido
+ pattern <emphasis>session-per-request</emphasis>, todas as instâncias carregadas
+ estarão no estado destacado durante o tempo em que o usuário estiver pensando.
+ O Hibernate permite que você reatache os objetos e persita as modificações,
+ esse pattern é chamado
+ <emphasis>session-per-request-with-detached-objects</emphasis>.
+ É usado versionamento automatico para isolar as modificações concorrentes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Extended (or Long) Session</emphasis> A <literal>Session</literal>
+ do Hibernate pode ser desligada da conexão básica do JDBC depois que a
+ transação foi commitada e ser reconectado quando uma nova requisição do
+ cliente ocorrer. Este pattern é conhecido como
+ <emphasis>session-per-conversation</emphasis> e faz o reatamento uniforme
+ desnecessário. Versionamento automático é usado para isolar modificações
+ concorrentes e a <emphasis>session-per-conversation</emphasis> usualmente
+ não é permitido para ser nivelado automaticamente, e sim explicitamente.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Ambos <emphasis>session-per-request-with-detached-objects</emphasis> e
+ <emphasis>session-per-conversation</emphasis> possuem vantagens e desvantagens,
+ nos discutiremos mais tarde neste capítulo no contexto do controle de
+ concorrência otimista.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-basics-identity">
+ <title>Considerando a identidade do objeto</title>
+
+ <para>
+ Uma aplicação pode acessar concorrentemente o mesmo estado persistente em duas
+ <literal>Session</literal>s diferentes. Entretanto, uma instância de uma classe
+ persistente nunca é compartilhada entre duas instâncias <literal>Session</literal>.
+ Por tanto, há duas noções diferentes da identidade:
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>Identidade da base de dados</term>
+ <listitem>
+ <para>
+ <literal>foo.getId().equals( bar.getId() )</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Identidade da JVM</term>
+ <listitem>
+ <para>
+ <literal>foo==bar</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Então para os objetos acoplados a um <literal>Session</literal> em <literal>particular </literal>
+ (isto é no escopo de um <literal>Session</literal>), as duas noções são equivalentes e a
+ identidade da JVM para a identidade da base de dados é garantida pelo Hibernate. Entretanto,
+ quando a aplicação pode acessar concorrentemente o "mesmo" objeto do negócio (identidade
+ persistente) em duas sessões diferentes, as duas instâncias serão realmente "diferentes"
+ (identidade de JVM). Os conflitos são resolvidos usando (versionamento automático) no
+ flush/commit, usando abordagem otimista.
+
+ </para>
+
+ <para>
+ Este caminho deixa o Hibernate e o banco dedados se preocuparem com a concorrência; também
+ fornece uma escalabilidade melhor, garantindo que a identidade em unidades de trabalho
+ único-encadeadas não necessite de bloqueio dispendioso ou de outros meios de sincronização.
+ A aplicação nunca necessita sincronizar qualquer objeto de negócio tão longo que transpasse
+ uma única thread por <literal>Session</literal>. Dentro de uma <literal>Session</literal> a
+ aplicação pode usar com segurança o <literal>==</literal> para comparar objetos.
+ </para>
+
+ <para>
+ Com tudo, uma aplicação que usa <literal>==</literal> fora de uma <literal>Session</literal>,
+ pode ver resultados inesperados. Isto pode ocorrer mesmo em alguns lugares inesperados, por
+ exemplo, se você colocar duas instâncias desacopladas em um mesmo <literal>Set</literal>.
+ Ambos podem ter a mesma identidade na base de dados (isto é eles representam a mesma linha
+ em uma tabela), mas a identidade da JVM pela definição não garantida para instâncias em estado
+ desacoplado. O desenvolvedor tem que sobrescrever os métodos <literal>equals()</literal> e
+ <literal>hashCode()</literal> em classes persistentes e implementar sua própria noção da
+ igualdade do objeto. Advertência: nunca use o identificador da base de dados para implementar
+ a igualdade, use atributos de negócio, uma combinação única, geralmente imutável. O
+ identificador da base de dados mudará se um objeto transiente passar para o estado persistente.
+ Se a instância transiente (geralmente junto com instâncias desacopladas) for inserida em um
+ <literal>Set</literal>, mudar o hashcode quebra o contrato do <literal>Set</literal>.
+ Atributos para chaves de negócio não têm que ser tão estável quanto às chaves primárias
+ da base de dados, você somente tem que garantir a estabilidade durante o tempo que
+ os objetos estiverem no mesmo Set. Veja o website do Hibernate para uma discussão mais
+ completa sobre o assunto. Note também que esta não é uma caracteristica do Hibernate,
+ mas simplesmente como a identidade e a igualdade do objeto de Java têm que ser implementadas.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-basics-issues">
+ <title>Edições comuns</title>
+
+ <para>
+ Nunca use o anti-patterns <emphasis>session-per-user-session</emphasis> ou
+ <emphasis>session-per-application</emphasis> (naturalmente, há umas exceções raras a
+ essa regra). Note que algumas das seguintes edições podem também aparecer com patterns
+ recomendados, certifique-se que tenha compreendido as implicações antes de fazer
+ uma decisão de projeto:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Uma <literal>Session</literal> não é threadsafe. As coisas que são supostas para trabalhar
+ concorrentemente, como requisições HTTP, session beans, ou Swing, causarão condições de
+ disputa se uma instância <literal>Session</literal> for compartilhada. Se você mantiver
+ sua <literal>Session</literal> do Hibernate em seu <literal>HttpSession</literal>
+ (discutido mais tarde), você deve considerar sincronizar o acesso a sua sessão do HTTP.
+ Caso contrário, um usuário que clica em reload várias muito rapidamente pode usar o
+ mesmo <literal>Session</literal> em duas threads executando concorrentemente.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Uma exceção lançada pelo Hibernate significa que você tem que dar rollback na sua
+ transação no banco de dados e fechar a <literal>Session</literal> imediatamente
+ (discutido mais tarde em maiores detalhes). Se sua <literal>Session</literal> é
+ limitado pela aplicação, você tem que parar a aplicação. Dando rollback na
+ transação no banco de dados não põe seus objetos do negócio em um estado anterior
+ que estavam no início da transação. Isto significa que o estado da base de dados
+ e os objetos de negócio perdem a sincronização. Geralmente não é um problema
+ porque as exceções não são recuperáveis e você tem que iniciar após o
+ rollback de qualquer maneira.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ O <literal>Session</literal> guarda em cache cada objeto que está no estado persistente
+ (guardado e checado para estado "sujo" pelo Hibernate). Isto significa que ele cresce
+ infinitamente até que você obtenha uma OutOfMemoryException, se você o mantiver aberto
+ por muito tempo ou simplesmente carregar dados demais. Uma solução é chamar
+ <literal>clear()</literal> e <literal>evict()</literal> para controlar o cache
+ da <literal>Session</literal>, mas você deve considerar uma Store Procedure
+ se precisar de operações que envolvam grande volume de dados. Algumas soluções são
+ mostradas no <xref linkend="batch"/>. Manter uma <literal>Session</literal> aberta
+ durante uma sessão do usuário significa também uma probabilidade elevada de se acabar
+ com dados velhos.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="transactions-demarcation">
+ <title>Demarcação de transações de bancos de dados</title>
+
+ <para>
+ Os limites de uma transação de banco de dados (ou sistema) são sempre necessários. Nenhuma
+ comunicação com o banco de dados pode ocorrer fora de uma transação de banco de dados (isto
+ parece confundir muitos desenvolvedores que estão usados modo auto-commit). Sempre use os
+ limites desobstruídos da transação, até mesmo para operações somente leitura. Dependendo
+ de seu nível de isolamento e capacidade da base de dados isto pode não ser requerido,
+ mas não há nenhum aspecto negativo se você demarca sempre transações explicitamente.
+ Certamente, uma única transação será melhor executada do que muitas transações pequenas,
+ até mesmo para dados de leitura.
+ </para>
+
+ <para>
+ Uma aplicação do Hibernate pode funcionar em ambientes não gerenciados (isto é aplicações standalone, Web
+ simples ou Swing) e ambientes gerenciados J2EE. Em um ambiente não gerenciado, o Hibernate é geralmente
+ responsável pelo seu próprio pool de conexões. O desenvolvedor tem que manualmente ajustar limites das
+ transaçãos, ou seja, começar, commitar, ou dar rollback nas transações ele mesmo. Um ambiente gerenciado
+ fornece transações gerenciadas por contêiner (CMT - container-managed transactions), com um conjunto
+ da transações definido declarativamente em descritores de deployment de EJB session beans, por exemplo.
+ A demarcação programática é então já não é necessário.
+ </para>
+
+ <para>
+ Entretanto, é freqüentemente desejável manter sua camada de persistência portável entre ambientes
+ de recurso locais não gerenciados e sistemas que podem confiar em JTA, mas usar BMT em vez de CMT.
+ Em ambos os casos você usaria demarcação de transação programática. O Hibernate oferece uma API
+ chamada Transaction que traduz dentro do sistema de transação nativa de seu ambiente de deployment.
+ Esta API é realmente opcional, mas nós encorajamos fortemente seu uso a menos que você estiver
+ em um CMT session bean.
+ </para>
+
+ <para>
+ Geralmente, finalizar um <literal>Session</literal>envolve quatro fases distintas:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ flush da sessão
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ commitar a transação
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ fechar a sessão
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ tratar as exceções
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ A limpeza da sessão já foi bem discutida, agora nós daremos uma olhada na demarcação da
+ transação e na manipulação de exceção em ambientes controlados e não controlados.
+ </para>
+
+
+ <sect2 id="transactions-demarcation-nonmanaged" revision="2">
+ <title>Ambiente não gerenciado</title>
+
+ <para>
+ Se uma camada de persistência do Hibernate roda em um ambiente não gerenciado, as conexões
+ do banco de dados são geralmente tratadas pelos pools de conexões simples
+ (isto é, não baseados em DataSource) dos quais o Hibernate obtém as conexões assim
+ que necessita. A maneira de se manipular uma sessão/transação é mais ou menos assim:
+ </para>
+
+ <programlisting><![CDATA[// Non-managed environment idiom
+Session sess = factory.openSession();
+Transaction tx = null;
+try {
+ tx = sess.beginTransaction();
+
+ // do some work
+ ...
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ if (tx != null) tx.rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>
+ Você não pode chamar <literal>flush()</literal> do <literal>Session()</literal>
+ explicitamente - a chamada ao <literal>commit()</literal> dispara automaticamente
+ a sincronização para a sessão (dependendo do <xref linkend="objectstate-flushing">
+ FlushMode</xref>). Uma chamada ao <literal>close()</literal> marca o fim de uma sessão.
+ A principal implicação do <literal>close()</literal> é que a conexão JDBC será abandonada
+ pela sessão. Este código Java é portável e funciona em ambientes não gerenciado e de JTA.
+ </para>
+
+ <para>
+ Uma solução muito mais flexível é gerência integrada de contexto da "sessão atual"
+ do Hibernate, como descrito anteriormente:
+ </para>
+
+ <programlisting><![CDATA[// Non-managed environment idiom with getCurrentSession()
+try {
+ factory.getCurrentSession().beginTransaction();
+
+ // do some work
+ ...
+
+ factory.getCurrentSession().getTransaction().commit();
+}
+catch (RuntimeException e) {
+ factory.getCurrentSession().getTransaction().rollback();
+ throw e; // or display error message
+}]]></programlisting>
+
+ <para>
+ Você muito provavelmente nunca verá estes fragmentos de código em uma aplicação
+ regular; as exceções fatais (do sistema) devem sempre ser pegas no "alto".
+ Ou seja, o código que executa chamadas do Hibernate (na camada de persistência)
+ e o código que trata <literal>RuntimeException</literal> (e geralmente pode
+ somente limpar acima e na saída) estão em camadas diferentes. O gerenciamento do
+ contexto atual feito pelo Hibernate pode significativamente simplificar este
+ projeto, como tudo que você necessita é do acesso a um <literal>SessionFactory</literal>.
+ A manipulação de exceção é discutida mais tarde neste capítulo.
+ </para>
+
+ <para>
+ Note que você deve selecionar <literal>org.hibernate.transaction.JDBCTransactionFactory</literal>
+ (que é o padrão) e para o segundo exemplo <literal>"thread"</literal> como seu
+ <literal>hibernate.current_session_context_class</literal>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-jta" revision="3">
+ <title>Usando JTA</title>
+
+ <para>
+ Se sua camada de persistência funcionar em um servidor de aplicação (por exemplo,
+ dentro dos EJB session beans), cada conexão do datasource obtida pelo Hibernate
+ automaticamente fará parte da transação global de JTA. Você pode também instalar uma
+ implementação standalone de JTA e usá-la sem EJB. O Hibernate oferece duas estratégias
+ para a integração de JTA.
+ </para>
+
+ <para>
+ Se você usar bean-managed transactions (BMT - transações gerenciadas por bean) o Hibernate dirá
+ ao servidor de aplicação para começar e para terminar uma transação de BMT se você usar a API
+ Transaction. Assim, o código de gerência de transação é idêntico ao ambiente não gerenciado.
+ </para>
+
+ <programlisting><![CDATA[// BMT idiom
+Session sess = factory.openSession();
+Transaction tx = null;
+try {
+ tx = sess.beginTransaction();
+
+ // do some work
+ ...
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ if (tx != null) tx.rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>
+ Se você quiser usar um <literal>Session</literal> limitada por transação, isto é,
+ a funcionalidade do <literal>getCurrentSession()</literal> para a propagação fácil
+ do contexto, você terá que usar diretamente a API JTA <literal>UserTransaction</literal>:
+ </para>
+
+ <programlisting><![CDATA[// BMT idiom with getCurrentSession()
+try {
+ UserTransaction tx = (UserTransaction)new InitialContext()
+ .lookup("java:comp/UserTransaction");
+
+ tx.begin();
+
+ // Do some work on Session bound to transaction
+ factory.getCurrentSession().load(...);
+ factory.getCurrentSession().persist(...);
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ tx.rollback();
+ throw e; // or display error message
+}]]></programlisting>
+
+ <para>
+ Com CMT, a demarcação da transação é feita em descritores de deployment do session beans,
+ não programaticamente, conseqüentemente, o código é reduzido a:
+ </para>
+
+ <programlisting><![CDATA[// CMT idiom
+ Session sess = factory.getCurrentSession();
+
+ // do some work
+ ...
+]]></programlisting>
+
+ <para>
+ Em um CMT/EJB mesmo um rollback acontece automaticamente, desde que uma exeção <literal>RuntimeException</literal>
+ não tratável seja lançada por um método de um session bean que informa ao contêiner ajustar a
+ transação global ao rollback. <emphasis>Isto significa que você não necessita usar a API
+ <literal>Transaction</literal> do Hibernate em tudo com BMT ou CMT e você obtém a propagação
+ automática do Session "atual" limitada à transação.</emphasis>
+ </para>
+
+ <para>
+ Veja que você deverá escolher <literal>org.hibernate.transaction.JTATransactionFactory</literal>
+ se você usar o JTA diretamente (BMT) e <literal>org.hibernate.transaction.CMTTransactionFactory</literal>
+ em um CMT session bean, quando você configura a fábrica de transação do Hibernate. Lembre-se também de
+ configurar o <literal>hibernate.transaction.manager_lookup_class</literal>. Além disso, certifique-se
+ que seu <literal>hibernate.current_session_context_class</literal> ou não é configurado (compatibilidade
+ com o legado) ou é definido para <literal>"jta"</literal>.
+
+ </para>
+
+ <para>
+ A operação <literal>getCurrentSession()</literal> tem um aspecto negativo em um ambiente JTA.
+ Há uma advertência para o uso do método liberado de conexão <literal>after_statement</literal>,
+ o qual é usado então por padrão. Devido a uma limitação simples da especificação JTA, não é
+ possível para o Hibernate automaticamente limpar quaisquer instâncias <literal>ScrollableResults</literal>
+ ou <literal>Iterator</literal> abertas retornadas pelo <literal>scroll()</literal> ou
+ <literal>iterate()</literal>. Você <emphasis>deve</emphasis> liberar o cursor subjacente da
+ base de dados chamando <literal>ScrollableResults.close()</literal> ou
+ <literal>Hibernate.close(Iterator)</literal> explicitamente de um bloco <literal>finally</literal>.
+ (Claro que a maioria de aplicações podem facilmente evitar o uso do <literal>scroll()</literal> ou
+ do <literal>iterate()</literal> em todo código provindo do JTA ou do CMT.)
+
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-exceptions">
+ <title>Tratamento de Exceção</title>
+
+ <para>
+ Se a <literal>Session</literal> levantar uma exceção (incluindo qualquer
+ <literal>SQLException</literal>), você deve imediatamente dar um rollback
+ na transação do banco, chamando <literal>Session.close()</literal> e descartando
+ a instância da <literal>Session</literal>. Certos métodos da <literal>Session</literal>
+ <literal>não</literal> deixarão a sessão em um estado inconsistente. Nenhuma exceção
+ lançada pelo Hibernate pode ser recuperada. Certifique-se que a <literal>Session</literal>
+ será fechada chamando <literal>close()</literal> no bloco <literal>finally</literal>.
+ </para>
+
+ <para>
+ A exceção <literal>HibernateException</literal>, a qual envolve a maioria dos erros
+ que podem ocorrer em uma camada de persistência do Hibernate, é uma exceção unchecked (
+ não estava em umas versões mais antigas de Hibernate). Em nossa opinião, nós não devemos
+ forçar o desenvolvedor a tratar uma exceção irrecuperável em uma camada mais baixa.
+ Na maioria dos sistemas, as exceções unchecked e fatais são tratadas em um dos primeiros
+ frames da pilha da chamada do método (isto é, em umas camadas mais elevadas) e uma mensagem
+ de erro é apresentada ao usuário da aplicação (ou a alguma outra ação apropriada é feita).
+ Note que Hibernate pode também lançar outras exceções unchecked que não são um
+ <literal>HibernateException</literal>. Estas, também são, irrecuperáveis e uma ação
+ apropriada deve ser tomada.
+ </para>
+
+ <para>
+ O Hibernate envolve <literal>SQLException</literal>s lançadas ao interagir com a base de dados
+ em um <literal>JDBCException</literal>. Na realidade, o Hibernate tentará converter a exceção em
+ em uma sub classe mais significativa da <literal>JDBCException</literal>. A
+ <literal>SQLException</literal> subjacente está sempre disponível através de
+ <literal>JDBCException.getCause()</literal>.
+ </para>
+
+ <para>
+ O Hibernate converte a <literal>SQLException</literal> em uma sub classe
+ <literal>JDBCException</literal> apropriada usando <literal>SQLExceptionConverter</literal>
+ associado ao SessionFactory. Por padrão, o <literal>SQLExceptionConverter</literal> é definido
+ pelo dialeto configurado; entretanto, é também possível conectar em uma implementação customizada
+ (veja o javadoc para mais detalhes da classe <literal>SQLExceptionConverterFactory</literal>).
+ Os subtipos padrão de <literal>JDBCException</literal> são:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>JDBCConnectionException</literal> - indica um erro com a comunicação subjacente de JDBC.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>SQLGrammarException</literal> - indica um problema da gramática ou da sintaxe com o SQL emitido.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ConstraintViolationException</literal> - indica algum forma de violação de confinamento de integridade.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockAcquisitionException</literal> - indica um erro ao adquirir um nível de bloqueio necessário para realizar a operação de requisição.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>GenericJDBCException</literal> - uma exceção genérica que não cai em algumas das outras categorias.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-timeout">
+ <title>Timeout de Transação</title>
+
+ <para>
+ Uma característica extremamente importante fornecida por um ambiente
+ gerenciado como EJB e que nunca é fornecido pelo código não gerenciado é o timeout
+ de transação. Timeouts de transação asseguram que nenhuma transação possa
+ reter indefinidamente recursos enquanto não retorna nenhuma resposta ao usuário.
+ Fora de um ambiente controlado (JTA), o Hibernate não pode fornecer inteiramente
+ esta funcionalidade. Entretanto, o Hibernate pode afinal controlar as operações
+ do acesso a dados, assegurando que o nível de deadlocks e queries do banco de
+ dados com imensos resultados definidos sejam limitados pelo timeout. Em um ambiente
+ gerenciado, o Hibernate pode delegar o timeout da transação ao JTA. Esta funcionalidade
+ é abstraída pelo objeto <literal>Transaction</literal> do Hibernate.
+ </para>
+
+ <programlisting><![CDATA[
+Session sess = factory.openSession();
+try {
+ //set transaction timeout to 3 seconds
+ sess.getTransaction().setTimeout(3);
+ sess.getTransaction().begin();
+
+ // do some work
+ ...
+
+ sess.getTransaction().commit()
+}
+catch (RuntimeException e) {
+ sess.getTransaction().rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>
+ Veja que <literal>setTimeout()</literal> não pode ser chamado em um CMT bean,
+ onde os timeouts das transações devem ser definidos declarativamente.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="transactions-optimistic">
+ <title>Controle de concorrência otimista</title>
+
+ <para>
+ O único caminho que é consistente com a elevada concorrência e escalabilidade
+ é controle de concorrência otimista com versionamento. Checagem de versão usa
+ número de versão, ou timestamps, para detectar conflitos de atualizações (e para
+ impedir atualizações perdidas). O Hibernate fornece três caminhos possíveis para
+ escrever aplicações que usam concorrência otimista. Os casos de uso que nós mostramos
+ estão no contexto de conversações longas, mas a checagem de versão também tem o
+ benefício de impedir atualizações perdidas em únicas transações.
+ </para>
+
+ <sect2 id="transactions-optimistic-manual">
+ <title>Checagem de versão da aplicação</title>
+
+ <para>
+ Em uma implementação sem muita ajuda do Hibernate, cada interação com o banco de dados
+ ocorre em uma nova <literal>Session</literal> e o desenvolvedor é responsável para
+ recarregar todas as instâncias persistentes da base de dados antes de manipulá-las.
+ Este caminho força a aplicação a realizar sua própria checagem de versão para assegurar
+ a conversação do isolamento da transação. Este caminho é menos eficiente em termos de
+ acesso ao banco de dados. É a caminho mais similar a EJBs entity.
+ </para>
+
+ <programlisting><![CDATA[// foo is an instance loaded by a previous Session
+session = factory.openSession();
+Transaction t = session.beginTransaction();
+
+int oldVersion = foo.getVersion();
+session.load( foo, foo.getKey() ); // load the current state
+if ( oldVersion != foo.getVersion() ) throw new StaleObjectStateException();
+foo.setProperty("bar");
+
+t.commit();
+session.close();]]></programlisting>
+
+ <para>
+ A propriedade <literal>version</literal> é mapeada usando <literal><version></literal>,
+ e o Hibernate vai incrementá-lo-á automaticamente durante o flush se a entidade
+ estiver alterada.
+ </para>
+
+ <para>
+ Claro, se você se estiver operando em um ambiente de baixa concorrência de dados
+ e não requerer a checagem de versão, você pode usar este caminho e apenas saltar a
+ checagem de versão. Nesse caso, o <emphasis>ultimo commit realizdo </emphasis> é
+ a estratégia padrão para suas conversações longas. Mantenha em mente que isto pode
+ confundir os usuários da aplicação, assim como eles podem experimentar atualizações
+ perdidas sem mensagens de erro ou uma possibilidade ajustar mudanças de conflito.
+
+ </para>
+
+ <para>
+ Claro que, checagem manual da versão é somente praticável em circunstâncias triviais
+ e não para a maioria de aplicações. Freqüentemente, os grafos completos de objetos
+ modificados têm que ser verificados, não somente únicas instâncias. O Hibernate oferece
+ checagem de versão automática com uma <literal>Session</literal> estendida ou instâncias
+ desatachadas como o paradigma do projeto.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-longsession">
+ <title>Sessão estendida e versionamento automático</title>
+
+ <para>
+ Uma única instância de <literal>Session</literal> e suas instâncias persistentes
+ são usadas para a conversação inteira, isto é conhecido como
+ <emphasis>session-per-conversation</emphasis>. O Hibernate verifica versões da instância
+ no momento dio flush, lançando uma exceção se a modificação concorrente for detectada.
+ Até o desenvolvedor pegar e tratar essa exceção (as opções comuns são a oportunidade
+ para que o usuário intercale as mudanças ou reinicie a conversação do negócio com
+ dados não antigos).
+ </para>
+
+ <para>
+ The <literal>Session</literal> is disconnected from any underlying JDBC connection
+ when waiting for user interaction. This approach is the most efficient in terms
+ of database access. The application need not concern itself with version checking or
+ with reattaching detached instances, nor does it have to reload instances in every
+ database transaction.
+ A <literal>Session</literal> é desconectada de toda a conexão JDBC subjacente
+ enquanto espera a interação do usuário. Este caminho é a mais eficiente em termos
+ de acesso a bancos de dados. A aplicação não necessita concernir-se com a checagem
+ de versão ou com as instâncias destacadas reatadas, nem tem que recarregar instâncias
+ em cada transação.
+ </para>
+
+ <programlisting><![CDATA[// foo is an instance loaded earlier by the old session
+Transaction t = session.beginTransaction(); // Obtain a new JDBC connection, start transaction
+
+foo.setProperty("bar");
+
+session.flush(); // Only for last transaction in conversation
+t.commit(); // Also return JDBC connection
+session.close(); // Only for last transaction in conversation]]></programlisting>
+ <para>
+ O objeto <literal>foo</literal> sabe que <literal>Session</literal> já foi carregada. Começando
+ uma nova transação em uma sessão velha obtém uma conexão nova e recomeça a sessão. Commitando
+ uma transação desconecta uma sessão da conexão JDBC e retorna a conexão ao pool. Após a reconexão,
+ forçar uma checagem de versão em dados que você não está atualizando, você pode chamar
+ <literal>Session.lock()</literal> com o <literal>LockMode.READ</literal> em todos os objetos
+ que possam ter sido atualizados por uma outra transação. Você não necessita bloquear nenhum
+ dado para atualizar. Geralmente você configuraria <literal>FlushMode.MANUAL</literal> em uma
+ <literal>Session</literal> estendida, de modo que somente o último ciclo da transação tenha
+ permissão de persistir todas as modificações feitas nesta conversação. Disso, somente esta última
+ transação incluiria a operação <literal>flush()</literal> e então chamar também <literal>close()</literal>
+ da sessão para terminar a conversação.
+ </para>
+
+ <para>
+ Este pattern é problemático se a <literal>Session</literal> for demasiadamente grande para
+ ser armazenado durante o tempo que usuário pensar, por exemplo um <literal>HttpSession</literal>
+ estiver mantido tão pequeno quanto possível. Como o <literal>Session</literal> é também cache
+ de primeiro nível (imperativo) e contém todos os objetos carregados, nós podemos provavelmente
+ usar esta estratégia somente para alguns ciclos de requisição/resposta. Você deve usar a
+ <literal>Session</literal> somente para uma única conversação, porque ela logo também
+ estará com dados velhos.
+ </para>
+
+ <para>
+ (Note que versões mais atuais de Hibernate requerem a desconexão e o reconexão explícitas de
+ uma <literal>Session</literal>. Estes métodos são desatualizados, como o início e término de
+ uma transação tem o mesmo efeito.)
+ </para>
+
+ <para>
+ Note também que você deve manter a <literal>Session</literal> desconectada fechada
+ para a camada de persistência. Ou seja, use um EJB stateful session bean para
+ prender a <literal>Session</literal> em um ambiente do três camadas e não o
+ transferir à camada web (ou até serializá-lo para uma camada separada)
+ para armazená-lo no <literal>HttpSession</literal>.
+
+ </para>
+
+ <para>
+ O pattern sessão estendida, ou <emphasis>session-per-conversation</emphasis>, é mais
+ difícil de implementar com gerenciamento automático de sessão atual. Você precisa fornecer
+ sua própria implementação do <literal>CurrentSessionContext</literal> para isto
+ (veja o Hibernate Wiki para exemplos).
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-detached">
+ <title>Objetos destacados e versionamento automático</title>
+
+ <para>
+ Cada interação com o armazenamento persistente ocorre em uma <literal>Session</literal> nova.
+ Entretanto, as mesmas instâncias persistentes são reusadas para cada interação com o banco de dados.
+ A aplicação manipula o estado das instâncias desatachadas originalmente carregadas em um outro
+ <literal>Session</literal> e reata-os então usando <literal>Session.update()</literal>,
+ <literal>Session.saveOrUpdate()</literal> ou <literal>Session.merge()</literal>.
+ </para>
+
+ <programlisting><![CDATA[// foo is an instance loaded by a previous Session
+foo.setProperty("bar");
+session = factory.openSession();
+Transaction t = session.beginTransaction();
+session.saveOrUpdate(foo); // Use merge() if "foo" might have been loaded already
+t.commit();
+session.close();]]></programlisting>
+
+ <para>
+ Outra vez, o Hibernate verificará versões da instância durante o flush,
+ lançando uma exceção se ocorrer conflitos de atualizações.
+ </para>
+
+ <para>
+ Você pode também chamar o <literal>lock()</literal> em vez de <literal>update()</literal>
+ e usar <literal>LockMode.READ</literal> (executando uma checagem de versão, ignorando
+ todos os caches) se você estiver certo de que o objeto não foi modificado.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-customizing">
+ <title>Versionamento automático customizado</title>
+
+ <para>
+ Você pode desabilitar o incremento da versão automática de Hibernate para propriedades
+ e coleções particulares configurando o mapeamento do atributo <literal>optimistic-lock</literal>
+ para false. O Hibernate então não irá incrementa versões se a propriedade estiver
+ modificada.
+ </para>
+
+ <para>
+ Os esquemas da base de dados legada são freqüentemente estáticos e não podem ser modificados.
+ Ou outras aplicações puderam também acessar a mesma base de dados e não sabem tratar a
+ versão dos números ou timestamps. Em ambos os casos, o versionamento não pode confiar em uma
+ coluna particular em uma tabela. Para forçar uma checagem de versão sem uma versão ou mapeamento
+ da propriedade do timestamp com uma comparação do estado de todos os campos em uma linha,
+ configure <literal>optimistic-lock="all"</literal> no mapeamento <literal><class></literal>.
+ Note que isto conceitualmente é somente feito em trabalhos se Hibernate puder comparar o estado
+ velho e novo, isto é, se você usa um único <literal>Session</literal> longo e não
+ session-per-request-with-detached-objects.
+ </para>
+
+ <para>
+ Às vezes a modificação concorrente pode ser permitida tão longa quanto às mudanças que
+ tiveram sido feitas que não sobrepuseram. Se você configurar <literal>optimistic-lock="dirty"</literal>
+ ao mapear o <literal><class></literal>, o Hibernate comparará somente campos
+ modificados durante o flush.
+ </para>
+
+ <para>
+ Em ambos os casos, com as colunas dedicadas da versão/timestamp ou com comparação do
+ campo cheio/modificados, o Hibernate usa uma única declaração UPDATE (com uma cláusula
+ WHERE apropriada ) por entidade para executar a checagem da versão e atualizar a informação.
+ Se você usa a persistência transitiva para cascatear o reatamento das entidades associadas,
+ o Hibernate pode executar atualizações desnecessárias. Isso não é geralmente um problema,
+ mas triggers <emphasis>on update</emphasis> em um banco de dados podem ser executados
+ mesmo quando nenhuma mudança foi feita nas instâncias destacadas. Você pode customizar
+ este comportamento configurando <literal>select-before-update="true"</literal> no
+ mapeamento <literal><class></literal>, forçando o Hibernate a dá um SELECT nas
+ instâncias para assegurar-se esse as mudanças ocorreram realmente, antes de atualizar
+ a linha.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="transactions-locking">
+ <title>Locking pessimista</title>
+
+ <para>
+ Não se pretende que os usuários gastam muitas horas se preocupando com suas estratégias de
+ locking. Geralmente é o bastante para especificar um nível de isolamento para as conexões
+ JDBC e então deixar simplesmente o banco de dados fazer todo o trabalho. Entretanto, os
+ usuários avançados podem às vezes desejar obter locks pessimistas exclusivos, ou re-obter
+ locks no início de uma nova transação.
+ </para>
+
+ <para>
+ O Hibernate usará sempre o mecanismo de lock da base de dados, nunca trava objetos
+ na memória!
+ </para>
+
+ <para>
+ A classe <literal>LockMode</literal> define os diferentes níveis de lock que o Hibernate
+ pode adquirir. Um lock é obtido pelos seguintes mecanismos:
+
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>LockMode.WRITE</literal> é adquirido automaticamente quando o Hibernate atualiza
+ ou insere uma linha.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.UPGRADE</literal> pode ser adquirido explicitamente pelo usuário
+ usando <literal>SELECT ... FOR UPDATE</literal> em um banco de dados que suporte
+ esse sintaxe.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.UPGRADE_NOWAIT</literal> pode ser adquirido explicitamente pelo usuário
+ usando <literal>SELECT ... FOR UPDATE NOWAIT</literal> no Oracle.
+
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.READ</literal> é adquirido automaticamente quando o Hibernate lê
+ dados em um nível Repeatable Read ou Serializable isolation. Pode ser readquirido
+ explicitamente pelo usuário.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.NONE</literal> representa a ausência do lock. Todos os objetos mudam para
+ esse estado de lock no final da <literal>Transaction</literal>. Objetos associados com a sessão
+ através do método <literal>update()</literal> ou <literal>saveOrUpdate()</literal> também são
+ inicializados com esse lock mode.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ O lock obtido "explicitamente pelo usuário" se dá em uma das seguintes maneiras:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Uma chamada a <literal>Session.load()</literal>, especificando
+ o <literal>LockMode</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Uma chamada a <literal>Session.lock()</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Uma chamada a <literal>Query.setLockMode()</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Se uma <literal>Session.load()</literal> é invocada com <literal>UPGRADE</literal> ou
+ <literal>UPGRADE_NOWAIT</literal>, e o objeto requisitado ainda não foi carregado
+ pela sessão, o objeto é carregado usando <literal>SELECT ... FOR UPDATE</literal>.
+ Se <literal>load()</literal> for chamado para um objeto que já foi carregado
+ com um lock menos restritivo que o novo lock solicitado, o Hibernate invoca o
+ método <literal>lock()</literal> para aquele objeto.
+ </para>
+
+ <para>
+ O método <literal>Session.lock()</literal> executa uma verificação no número da versão
+ se o modo de lock especificado for <literal>READ</literal>, <literal>UPGRADE</literal> ou
+ <literal>UPGRADE_NOWAIT</literal>.. (No caso do <literal>UPGRADE</literal> ou
+ <literal>UPGRADE_NOWAIT</literal>, é usado <literal>SELECT ... FOR UPDATE</literal>.)
+ </para>
+
+ <para>
+ Se o banco de dados não suportar o lock mode solicitado, o Hibernate vai usar um modo
+ alternativo apropriado (ao invés de lançar uma exceção). Isso garante que a aplicação
+ vai ser portável.
+ </para>
+
+ </sect1>
+
+ <sect1 id="transactions-connection-release">
+ <title>Modos de liberar a Connection</title>
+
+ <para>
+ O comportamento legado do Hibernate (2.x) em consideração ao gerenciamento da conexão
+ via JDBC fez com que a <literal>Session</literal> precisasse obter uma conexão
+ quando ela precisasse pela primeira vez e depois manter a conexão enquanto
+ a sessão não fosse fechada. O Hibernate 3.x introduz a idéia de modos de liberar a
+ sessão, para informar a sessão a forma como deve manusear a sua conexão JDBC.
+ Veja que essa discussão só é pertinente para conexões fornecidas com um
+ <literal>ConnectionProvider</literal> configurado; conexões fornecidas pelo usuário
+ estão fora do escopo dessa discussão. Os diferentes modos de liberação estão definidos
+ pelos valores da enumeração
+ <literal>org.hibernate.ConnectionReleaseMode</literal>:
+
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>ON_CLOSE</literal> - essencialmente é o modo legado descrito acima. A sessão
+ do Hibernate obtêm a conexão quando precisar executar alguma operação JDBC pela
+ primeira vez e mantem enquanto a conexão não for fechada.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>AFTER_TRANSACTION</literal> – informa que a conexão deve ser
+ liberada após a conclusão de uma <literal>org.hibernate.Transaction</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>AFTER_STATEMENT</literal> (também conhecida com liberação agressiva) – informa
+ que a conexão deve ser liberada após a execução de cada statement. A liberação agressiva
+ não ocorre se o statement deixa pra trás algum recurso aberto associado com a sessão
+ obtida; atualmente, a única situação em que isso é possível é com o uso de
+ <literal>org.hibernate.ScrollableResults</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ O parâmetro de configuração <literal>hibernate.connection.release_mode</literal> é usado
+ para especificar qual modo de liberação deve ser usado. Opções disponíveis:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>auto</literal> (padrão) – essa opção delega ao modo de liberação retornado pelo
+ método <literal>org.hibernate.transaction.TransactionFactory.getDefaultReleaseMode()</literal>.
+ Para JTATransactionFactory, ele retorna ConnectionReleaseMode.AFTER_STATEMENT; para
+ JDBCTransactionFactory, ele retorna ConnectionReleaseMode.AFTER_TRANSACTION.
+ Raramente é uma boa idéia alterar padrão, como frequencia ao se fazer isso temos falhas
+ que parecem bugs e/ou suposições inválidas no código do usuário.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>on_close</literal> - indica o uso da ConnectionReleaseMode.ON_CLOSE. Essa opção
+ foi deixada para manter a compatibilidade, mas seu uso é fortemente desencorajado.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>after_transaction</literal> – indica o uso da ConnectionReleaseMode.AFTER_TRANSACTION.
+ Essa opção nada deve ser usada com ambientes JTA. Também note que no caso da
+ ConnectionReleaseMode.AFTER_TRANSACTION, se a sessão foi colocada no modo auto-commit a
+ conexão vai ser liberada de forma similar ao modo AFTER_STATEMENT.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>after_statement</literal> – indica o uso ConnectionReleaseMode.AFTER_STATEMENT.
+ Adicionalmente, o <literal>ConnectionProvider</literal> configurado é consultado para
+ verificar se suporta essa configuração ((<literal>supportsAggressiveRelease()</literal>).
+ Se não suportar, o modo de liberação é redefinido como ConnectionRelease-Mode.AFTER_TRANSACTION.
+ Essa configuração só é segura em ambientes onde podemos readquirir a mesma conexão JDBC
+ toda vez que o método <literal>ConnectionProvider.getConnection()</literal> for chamado ou
+ em um ambiente auto-commit onde não importa se nós recuperamos a mesma conexão.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tutorial.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/tutorial.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tutorial.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tutorial.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,1530 @@
+<chapter id="tutorial">
+ <title>Introdução ao Hibernate</title>
+
+ <sect1 id="tutorial-intro" revision="1">
+ <title>Prefácio</title>
+
+ <para>
+ Este capítulo é um tutorial introdutório para novos usuários do Hibernate. Nós iniciaremos com uma simples linha de comando em uma aplicação usando uma base de dados em memória tornando isto um passo de fácil de compreender.
+ </para>
+
+ <para>
+ Este tutorial é voltado para novos usuários do Hibernate, mas requer um conhecimento de Java e SQL. Este tutorial é baseado no tutorial de Michael Gloegl, as bibliotecas Third Party foram nomeadas para JDK 1.4 e 5.0. Você pode precisar de outras bibliotecas para JDK 1.3.
+ </para>
+
+ <para>
+ O código fonte para o tutorial está incluído no diretório da distribuição
+ <literal>doc/reference/tutorial/</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="tutorial-firstapp" revision="2">
+ <title>Parte 1 – A primeira aplicação Hibernate</title>
+
+ <para>
+ Primeiro, iremos criar uma simples aplicação Hibernate baseada em console. Usaremos uma base de dados Java (HSQL DB), então não teremos que instalar nenhum servidor de base de dados.
+ </para>
+
+ <para>
+ Vamos supor que precisemos de uma aplicação com um banco de dados pequeno que possa armazenar e atender os eventos que queremos, e as informaççes sobre os hosts destes eventos.
+ </para>
+
+ <para>
+ A primeira coisa que devemos fazer é configurar nosso diretório de desenvolvimento,
+ e colocar todas as bibliotecas Java que precisamos dentro dele. Faça o download da
+ distribuição do Hibernate no site do Hibernate. Descompacte o pacote e coloque todas
+ as bibliotecas necessárias encontradas no diretório <literal>/lib</literal>, dentro do
+ diretório <literal>/lib</literal> do seu novo projeto. Você deverá ter algo parecido
+ com isso:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ antlr.jar
+ cglib.jar
+ asm.jar
+ asm-attrs.jars
+ commons-collections.jar
+ commons-logging.jar
+ hibernate3.jar
+ jta.jar
+ dom4j.jar
+ log4j.jar ]]></programlisting>
+
+ <para>
+ Esta é a configuração mínima requerida das bibliotecas (observe que também foi copiado
+ o hibernate3.jar da pasta principal do Hibernate) para o Hibernate <emphasis>na hora do desenvolvimento</emphasis>. O Hibernate permite que você utilize mais ou menos bibliotecas.
+ Veja o arquivo <literal>README.txt</literal> no diretório <literal>lib/</literal> da distribuição
+ do Hibernate para maiores informaççes sobre bibliotecas requeridas e opcionais.
+ (Atualmente, a biblioteca Log4j não é requerida, mas é preferida por muitos desenvolvedores.)
+ </para>
+
+ <para>
+ Agora, iremos criar uma classe que representa o evento que queremos armazenar na base de dados..
+ </para>
+
+ <sect2 id="tutorial-firstapp-firstclass" revision="1">
+ <title>A primeira Classe</title>
+
+ <para>
+ Nossa primeira classe de persistência é uma simples classe JavaBean com algumas propriedades:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+import java.util.Date;
+
+public class Event {
+ private Long id;
+
+ private String title;
+ private Date date;
+
+ public Event() {}
+
+ public Long getId() {
+ return id;
+ }
+
+ private void setId(Long id) {
+ this.id = id;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}]]></programlisting>
+
+ <para>
+ Você pode ver que esta classe usa o padrão JavaBean para o nomeamento convencional da propriedade getter e dos métodos setter, como também a visibilidade private dos campos. Este é um padrão de projeto recomendado, mas não requerido. O Hibernate pode também acessar campos diretamente, o benefício para os métodos de acesso é a robustez para o Refactoring. O construtor sem argumento é requerido para instanciar um objeto desta classe com a reflexão.
+ </para>
+
+ <para>
+ A propriedade <literal>id</literal> mantém um único valor de identificação para um evento
+ particular. Todas as classes persistentes da entidade (bem como aquelas classes dependentes
+ de menos importância) precisam de uma propriedade de identificação, caso nós queiramos usar o
+ conjunto completo de características do Hibernate. De fato, a maioria das aplicações
+ (esp. aplicações web) precisam destinguir os objetos pelo identificador, então você deverá
+ considerar esta, uma característica em lugar de uma limitação. Porém, nós normalmente não
+ manipulamos a identidade de um objeto, consequentemente o método setter deverá ser privado.
+ O Hibernate somente nomeará os identificadores quando um objeto for salvo. Você pode ver como
+ o Hibernate pode acessar métodos públicos, privados, e protegidos, como também campos
+ (públicos, privados, protegidos) diretamente. A escolha está até você, e você pode combinar
+ isso para adaptar seu projeto de aplicação
+ </para>
+
+ <para>
+ O construtor sem argumentos é um requerimento para todas as classes persistentes;
+ O Hibernate tem que criar para você os objetos usando Java Reflection. O construtor
+ pode ser privado, porém, a visibilidade do pacote é requerida para a procuração da
+ geração em tempo de execução e recuperação eficiente dos dados sem a instrumentação
+ de bytecode
+ </para>
+
+ <para>
+ Coloque este fonte Java no diretório chamado <literal>src</literal> na pasta de desenvolvimento,
+ e em seu pacote correto. O diretório deverá ser parecido como este:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java]]></programlisting>
+
+ <para>
+ No próximo passo, iremos falar sobre as classes de persistência do Hibernate..
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-mapping" revision="1">
+ <title>O mapeamento do arquivo</title>
+
+ <para>
+ O Hibernate precisa saber como carregar e armazenar objetos da classe de
+ persistência. Isto será onde o mapeamento do arquivo do Hibernate entrará em
+ jogo. O arquivo mapeado informa ao Hibernate, qual tabela no banco de dados
+ ele deverá acessar, e quais as colunas na tabela ele deverá usar.
+ </para>
+
+ <para>
+ A estrutura básica de um arquivo de mapeamento é parecida com:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping>
+[...]
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Note que o Hibernate DTD é muito sofisticado. Você pode usar isso para auto-conclusão
+ no mapeamento XML dos elementos e atributos no seu editor ou IDE. Você também pode
+ abrir o arquivo DTD no seu editor – é a maneira mais fácil de ter uma visão geral
+ de todos os elementos e atributos e dos padrões, como também alguns comentários.
+ Note que o Hibernate não irá carregar o arquivo DTD da web, e sim do diretório
+ da aplicação (classpath). O arquivo DTD está incluído no <literal>hibernate3.jar</literal> como
+ também no diretório <literal>src/</literal> da distribuição do Hibernate.
+ </para>
+
+ <para>
+ Nós omitiremos a declaração do DTD nos exemplos futuros para encurtar o código. Isto, é claro, não é opcional.
+ </para>
+
+ <para>
+ Entre os dois tags <literal>hibernate-mapping</literal>, inclua um elemento <literal>class</literal>.
+ Todas as classes persistentes da entidade (novamente, poderá haver
+ mais tarde, dependências sobre as classes que não são classes-primárias
+ de entidades) necessitam do tal mapeamento, para uma tabela na base
+ de dados SQL
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Mais adiante iremos dizer ao Hibernate como fazer para persistir e carregar objetos da classe
+ <literal>Event</literal> da tabela <literal>EVENTS</literal>, cada instancia representada por
+ uma coluna na tabela. Agora, continuaremos com o mapeamento de uma única propriedade identificadora
+ para as chaves primárias da tabela. Além disso, nós não iremos se importar com esta propriedade
+ identificadora, nós iremos configurar uma estratégia de geração de id’s para uma chave primária
+ de uma surrogate key:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+ <id name="id" column="EVENT_ID">
+ <generator class="native"/>
+ </id>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ O elemento <literal>id</literal> é a declaração da propriedade identificadora,
+ o <literal>name="id"</literal> declara o nome da propriedade Java –
+ o Hibernate irá usar os métodos getter e setter para acessar a propriedade.
+ O atributo da coluna informa ao Hibernate qual coluna da tabela <literal>EVENTS</literal> nós
+ iremos usar como chave primária. O elemento <literal>generator</literal> especifica
+ a estratégia de geração do identificador, neste caso usaremos <literal>native</literal>, que
+ escolhe a melhor estratégia dependendo da base de dados (dialeto) configurada.
+ O Hibernate suporta a base de dados gerada, globalmente única, bem como a atribuição
+ aos identificadores da aplicação (ou toda estratégia escrita para uma extensão).
+ </para>
+
+ <para>
+ Finalmente incluiremos as declarações para as propriedades persistentes da classe
+ no arquivo mapeado. Por default, nenhuma das propriedades da classe é considerada persistente:
+ </para>
+
+ <programlisting><![CDATA[
+<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+ <id name="id" column="EVENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="date" type="timestamp" column="EVENT_DATE"/>
+ <property name="title"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Da mesma maneira que com o elemento <literal>id</literal>, o atributo <literal>name</literal> do elemento
+ <literal>property</literal> informa ao Hibernate qual método getter e setter deverá usar.
+ Assim, neste caso, o Hibernate irá procurar pelo <literal>getDate()/setDate()</literal>,
+ como também pelo <literal>getTitle()/setTitle()</literal>.
+ </para>
+
+ <para>
+ Porque fazer o mapeamento da propriedade <literal>date</literal> incluído no
+ atributo <literal>column</literal>, e no title não fazer?
+ Sem o atributo <literal>column</literal> o Hibernate por padrão usa o nome
+ da propriedade como o nome da coluna. Isto trabalha muito
+ bem para o <literal>title</literal>. Entretanto o <literal>date</literal> é uma palavra-chave reservada
+ na maioria dos bancos de dados, assim nós melhoramos o mapeamentos
+ disto com um nome diferente.
+ </para>
+
+ <para>
+ A próxima coisa interessante é que mapemanto do <literal>title</literal>
+ também falta o atributo <literal>type</literal>. O tipo que declaramos e o uso nos
+ arquivos mapeados, não são como você pôde esperar, atributos de dados Java.
+ Eles não são como os tipos de base de dados SQL.
+ Esses tipos podem ser chamados de <emphasis>Tipos de mapeamento Hibernate</emphasis>, que são conversores
+ que podem traduzir tipos de dados do Java para os tipos de dados SQL e vice-versa.
+ Novamente, o Hibernate irá tentar determinar a conversão correta e mapeará o <literal>type</literal>
+ próprio, caso o tipo do atributo não estiver presente no mapeamento.
+ Em alguns casos, esta detecção automática (que usa Reflection sobre as classes Java)
+ poderá não ter padrão que você espera ou necessita.
+ Este é o caso com a propriedade <literal>date</literal>. O Hibernate não pode saber se a propriedade
+ (que é do <literal>java.util.Date</literal>) pode mapear para uma coluna do tipo <literal>date</literal>
+ do SQL, <literal>timestamp</literal>, ou <literal>time</literal> .
+ Nós preservamos a informação cheia de datas e horas pelo mapeamento da propriedade com um conversor
+ <literal>timestamp</literal>.
+ </para>
+
+ <para>
+ Este arquivo de mapeamento deve ser salvo como <literal>Event.hbm.xml</literal>,
+ corretamente no diretório próximo ao arquivo fonte da Classe Java <literal>Event</literal>.
+ O nomeamento dos arquivos de mapeamento podem ser arbitrários, porém o sufixo
+ <literal>hbm.xml</literal> é uma convenção da comunidade dos desenvolvedores do Hibernate.
+ Esta estrutura do diretório deve agora se parecer com isso:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java
+ Event.hbm.xml]]></programlisting>
+
+ <para>
+ Nós iremos continuar com a configuração principal do Hibernate.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-configuration" revision="2">
+ <title>Configuração do Hibernate</title>
+
+ <para>
+ Agora nós temos uma classe persistente e este arquivo de mapeamento no lugar.
+ Está na hora de configurar o Hibernate. Antes de fazermos isso, iremos precisar de uma base de dados.
+ O HSQL DB, um SQL DBMS feito em java, pode ser baixado através do site do HSQL DB(http://hsqldb.org/).
+ Atualmente, você só precisa baixar o <literal>hsqldb.jar</literal>.
+ Coloque este arquivo no diretório da pasta de desenvolvimento <literal>lib/</literal>.
+ </para>
+
+ <para>
+ Crie um diretório chamado <literal>data</literal> no diretório root de desenvolvimento –
+ Isto será onde o HSQL DB irá armazenar arquivos de dados. Agora iremos iniciar o banco de dados
+ executando <literal>java -classpath ../lib/hsqldb.jar org.hsqldb.Server</literal> neste diretório de dados.
+ Você pode ver ele iniciando e conectando ao socket TCP/IP, isto será onde nossa aplicação irá se
+ conectar depois. Se você deseja iniciar uma nova base de dados durante este tutorial,
+ finalize o HSQL DB(pressionando o <literal>CTRL + C</literal> na janela), delete todos os
+ arquivos no diretório <literal>data/</literal>, e inicie o HSQL BD novamente.
+ </para>
+
+ <para>
+ O Hibernate é uma camada na sua aplicação na qual se conecta com a base de dados, para isso
+ necessita de informação da conexão. As conexões são feitas através de um pool de conexão JDBC,
+ na qual teremos que configurar. A distribuição do Hibernate contém diversas ferramentas de pooling
+ da conexão JDBC de fonte aberta, mas iremos usar o pool de conexão interna para este tutorial.
+ Note que você tem que copiar a biblioteca necessária em seu classpath e use configurações
+ diferentes para pooling de conexão caso você deseje utilizar um software de pooling JDBC terceirizado
+ para qualidade de produção.
+ </para>
+
+ <para>
+ Para as configurações do Hibernate, nós podemos usar um arquivo simples <literal>hibernate.properties</literal>,
+ um arquivo mais ligeiramente sofisticado <literal>hibernate.cfg.xml</literal> ou até mesmo uma
+ instalação programática completa. A maioria dos usuários preferem utilizar o arquivo de configuração XML
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <session-factory>
+
+ <!-- Database connection settings -->
+ <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
+ <property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
+ <property name="connection.username">sa</property>
+ <property name="connection.password"></property>
+
+ <!-- JDBC connection pool (use the built-in) -->
+ <property name="connection.pool_size">1</property>
+
+ <!-- SQL dialect -->
+ <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
+
+ <!-- Enable Hibernate's automatic session context management -->
+ <property name="current_session_context_class">thread</property>
+
+ <!-- Disable the second-level cache -->
+ <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
+
+ <!-- Echo all executed SQL to stdout -->
+ <property name="show_sql">true</property>
+
+ <!-- Drop and re-create the database schema on startup -->
+ <property name="hbm2ddl.auto">create</property>
+
+ <mapping resource="events/Event.hbm.xml"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ Note que esta configuração XML usa um diferente DTD. Nós configuraremos
+ as <literal>SessionFactory</literal> do Hibernate – uma factory global responsável
+ por uma base de dedados particular. Se você tiver diversas bases de dados,
+ use diversas configurações <literal><session-factory></literal>, geralmente
+ em diversos arquivos de configuração (para uma partida mais fácil).
+ </para>
+
+ <para>
+ As primeiras quatro <literal>propriedades</literal> do elemento contém a configuração
+ necessária para a conexão ao JDBC. A propriedade <literal>propriedade</literal> dialect
+ do elemento especifica a variante particular do SQL que o Hibernate gera.
+ O gerenciamento automático de sessão do Hibernate para contextos de persistência
+ estará disponível em breve. A opção <literal>hbm2ddl.auto</literal> habilita a geração
+ automática de schemas da base de dados – diretamente na base de dados.
+ Isto também pode ser naturalmente desligado (removendo a opção de configuração) ou redirecionando
+ para um arquivo com ajuda do <literal>SchemaExport</literal> nas tarefas do Ant.
+ Finalmente, iremos adicionar os arquivos das classes de persistência mapeadas na configuração.
+ </para>
+
+ <para>
+ Copie este arquivo no diretório fonte, assim isto irá terminar na raiz (root) do
+ classpath. O Hibernate automaticamente procura por um arquivo chamado
+ <literal>hibernate.cfg.xml</literal> na raiz do classpath, no startup.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-ant" revision="1">
+ <title>Construindo com o Ant</title>
+
+ <para>
+ Nos iremos, agora, construir o tutorial com Ant. Você ira precisar o Ant instalado –
+ se encontra disponível <ulink url="http://ant.apache.org/bindownload.cgi">na página de download do Ant</ulink>.
+ Como instalar o Ant, não será abordado aqui. Caso tenha alguma dúvida, por favor,
+ vá ao <ulink url="http://ant.apache.org/manual/index.html">Ant manual</ulink>.
+ Depois que tiver instalado o Ant, podemos começar a criar o arquivo de construção <literal>build.xml</literal>.
+ Este arquivo será chamado de <literal>build.xml</literal> e posto diretamente no diretório de desenvolvimento.
+ </para>
+
+ <para>
+ Um arquivo básico de build, se parece com isto:
+ </para>
+
+ <programlisting><![CDATA[<project name="hibernate-tutorial" default="compile">
+
+ <property name="sourcedir" value="${basedir}/src"/>
+ <property name="targetdir" value="${basedir}/bin"/>
+ <property name="librarydir" value="${basedir}/lib"/>
+
+ <path id="libraries">
+ <fileset dir="${librarydir}">
+ <include name="*.jar"/>
+ </fileset>
+ </path>
+
+ <target name="clean">
+ <delete dir="${targetdir}"/>
+ <mkdir dir="${targetdir}"/>
+ </target>
+
+ <target name="compile" depends="clean, copy-resources">
+ <javac srcdir="${sourcedir}"
+ destdir="${targetdir}"
+ classpathref="libraries"/>
+ </target>
+
+ <target name="copy-resources">
+ <copy todir="${targetdir}">
+ <fileset dir="${sourcedir}">
+ <exclude name="**/*.java"/>
+ </fileset>
+ </copy>
+ </target>
+
+</project>]]></programlisting>
+
+ <para>
+ Isto irá avisar ao Ant para adicionar todos os arquivos no diretório lib terminando com
+ <literal>.jar</literal>, para o classpath usado para compilação. Irá também copiar todos os
+ arquivos não-java para o diretório alvo (arquivos de configuração, mapeamento). Se você rodar
+ o ant agora, deverá ter esta saída.
+ </para>
+
+ <programlisting><![CDATA[C:\hibernateTutorial\>ant
+Buildfile: build.xml
+
+copy-resources:
+ [copy] Copying 2 files to C:\hibernateTutorial\bin
+
+compile:
+ [javac] Compiling 1 source file to C:\hibernateTutorial\bin
+
+BUILD SUCCESSFUL
+Total time: 1 second ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-helpers" revision="3">
+ <title>Startup and helpers</title>
+
+ <para>
+ É hora de carregar e arquivar alguns objetos <literal>Event</literal>, mas primeiro
+ nós temos de completar o setup com algum código de infraestrutura. Este startup
+ inclui a construção de um objeto <literal>SessionFactory</literal> global e armazenar
+ isto em algum lugar de fácil acesso para o código da aplicação.
+ Uma <literal>SessionFactory</literal> pode abrir novas <literal>Session</literal>'s.
+ Uma <literal>Session</literal> representa uma unidade single-theaded do trabalho, a
+ <literal>SessionFactory</literal> é um objeto global thread-safe, instanciado uma vez.
+ </para>
+
+ <para>
+ Nos iremos criar uma classe de ajuda <literal>HibernateUtil</literal>, que toma
+ conta do startup e faz acesso a uma <literal>SessionFactory</literal> conveniente.
+ Vamos dar uma olhada na implementação:
+ </para>
+
+ <programlisting><![CDATA[package util;
+
+import org.hibernate.*;
+import org.hibernate.cfg.*;
+
+public class HibernateUtil {
+
+ private static final SessionFactory sessionFactory;
+
+ static {
+ try {
+ // Create the SessionFactory from hibernate.cfg.xml
+ sessionFactory = new Configuration().configure().buildSessionFactory();
+ } catch (Throwable ex) {
+ // Make sure you log the exception, as it might be swallowed
+ System.err.println("Initial SessionFactory creation failed." + ex);
+ throw new ExceptionInInitializerError(ex);
+ }
+ }
+
+ public static SessionFactory getSessionFactory() {
+ return sessionFactory;
+ }
+
+}]]></programlisting>
+
+ <para>
+ Esta classe não só produz a global <literal>SessionFactory</literal> no seu static initializer
+ (chamado uma vez pela JVM quando a classe é carregada), mas também esconde o fato
+ de que isto usa um static singleton. Ela pode muito bem, enxergar a
+ <literal>SessionFactory</literal> do JNDI em um application server.
+ </para>
+
+ <para>
+ Se você der à <literal>SessionFactory</literal> um nome, no seu arquivo de configuração.
+ O Hibernate irá, de fato, tentar uni-lo ao JNDI depois que estiver construído.
+ Para evitar este completamente este código, você também poderia usar JMX deployment
+ e deixar o contêiner JMX capaz, instanciar e unir um <literal>HibernateService</literal>
+ no JNDI. Essas opções avançadas são discutidas no documento de referência do Hibernate.
+ </para>
+
+ <para>
+ Coloque o <literal>HibernateUtil.java</literal> no diretório de arquivos
+ de desenvolvimento(source), em um pacote após o <literal>events</literal>:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java
+ Event.hbm.xml
+ +util
+ HibernateUtil.java
+ hibernate.cfg.xml
++data
+build.xml]]></programlisting>
+
+ <para>
+ Novamente, isto deve compilar sem problemas. Finalmente, nós precisamos configurar
+ um sistema de logging – o Hibernate usa commons logging e deixa você escolher entre o
+ Log4j e o logging do JDK 1.4 . A maioria dos desenvolvedores preferem o Log4j: copie
+ <literal>log4j.properties</literal> da distribuição do Hibernate (está no diretório
+ <literal>etc/</literal>), para seu diretório <literal>src</literal>,
+ depois vá em hibernate.cfg.xml. Dê uma olhada no exemplo de configuração e mude as
+ configurações se você quizer ter uma saída mais detalhada. Por default, apenas as
+ mensagems de startup e shwwn do Hibernate é mostrada no stdout.
+ </para>
+
+ <para>
+ O tutorial de infra-estrutura está completo - e nós já estamos preparados para algum
+ trabalho de verdade com o Hibernate.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-workingpersistence" revision="4">
+ <title>Carregando e salvando objetos</title>
+
+ <para>
+ Finalmente, nós podemos usar o Hibernate para carregar e armazenar objetos.
+ Nós escrevemos uma classe <literal>EventManager</literal> com um método main():
+ </para>
+
+ <programlisting><![CDATA[package events;
+import org.hibernate.Session;
+
+import java.util.Date;
+
+import util.HibernateUtil;
+
+public class EventManager {
+
+ public static void main(String[] args) {
+ EventManager mgr = new EventManager();
+
+ if (args[0].equals("store")) {
+ mgr.createAndStoreEvent("My Event", new Date());
+ }
+
+ HibernateUtil.getSessionFactory().close();
+ }
+
+ private void createAndStoreEvent(String title, Date theDate) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+ session.beginTransaction();
+
+ Event theEvent = new Event();
+ theEvent.setTitle(title);
+ theEvent.setDate(theDate);
+
+ session.save(theEvent);
+
+ session.getTransaction().commit();
+ }
+
+}]]></programlisting>
+
+ <para>
+ Nós criamos um novo objeto <literal>Event</literal>, e passamos para o Hibernate.
+ O Hibernate sabe como tomar conta do SQL e executa <literal>INSERT</literal>s
+ no banco de dados. Vamos dar uma olhada na <literal>Session</literal> e no
+ código <literal>Transaction</literal>-handling antes de executarmos.
+ </para>
+
+ <para>
+ Um <literal>Session</literal> é uma unidade simples de trabalho. Por agora nós
+ iremos pegar coisas simples e assumir uma granularidade de um-pra-um entre uma
+ <literal>Session</literal> do Hibernate e uma transação de banco de dados.
+ Para proteger nosso código de um atual sistema subjacente de transação (nesse
+ caso puro JDBC, mas também poderia rodar com JTA), nos usamos a API
+ <literal>Transaction</literal>, que está disponível na <literal>Session</literal> do Hibernate.
+ </para>
+
+ <para>
+ O que a <literal>sessionFactory.getCurrentSession()</literal> faz? Primeiro, você pode
+ chamar quantas vezes e de onde quiser, uma vez você recebe sua <literal>SessionFactory</literal>
+ (fácil graças ao <literal>HibernateUtil</literal>). O método <literal>getCurrentSession()</literal>
+ sempre retorna a unidade de trabalho "corrente". Lembra de que nós mudamos a opção
+ de configuração desse mecanismo para thread no <literal>hibernate.cfg.xml</literal>? Daqui em
+ diante, o escopo da unidade de trabalho corrente é a thread Java
+ corrente que executa nossa aplicação. Entretanto, esta não é toda a verdade. Uma
+ <literal>Session</literal> começa quando é primeiramente necessária, quando é feita a
+ primeira chamada à <literal>getCurrentSession()</literal>. É então limitado pelo Hibernate
+ para thread corrente. Quando a transação termina, tanto com commit quanto rollback,
+ o Hibernate também desune a <literal>Session</literal> da thread e fecha isso pra você.
+ Se você chamar <literal>getCurrentSession()</literal> novamente, você receberá uma nova
+ <literal>Session</literal> e pode começar uma nova unidade de trabalho. Esse modelo de
+ programação de limite de thread <emphasis>thread-bound</emphasis>, é o modo mais popular
+ de se usar o Hibernate.
+ </para>
+
+ <para>
+ Dê uma olhada no <xref linkend="transactions"/> para mais informações a
+ respeito de manipulação de transação e demarcação. Nós também pulamos qualquer
+ manipulação de erro e rollback no exemplo anterior.
+ </para>
+
+ <para>
+ Para executar esta primeira rotina, nos teremos que adicionar um ponto de chamada
+ para o arquivo de build do Ant:
+ </para>
+
+ <programlisting><![CDATA[<target name="run" depends="compile">
+ <java fork="true" classname="events.EventManager" classpathref="libraries">
+ <classpath path="${targetdir}"/>
+ <arg value="${action}"/>
+ </java>
+</target>]]></programlisting>
+
+ <para>
+ O valor do argumento <literal>action</literal>, é setado na linha de comando quando chamando esse ponto:
+ </para>
+
+ <programlisting><![CDATA[C:\hibernateTutorial\>ant run -Daction=store]]></programlisting>
+
+ <para>
+ Você deverá ver, após a compilação, o startup do Hibernate e, dependendo da sua
+ configuração, muito log de saída. No final você verá a seguinte linha:
+ </para>
+
+ <programlisting><![CDATA[[java] Hibernate: insert into EVENTS (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)]]></programlisting>
+
+ <para>
+ Este é o <literal>INSERT</literal> executado pelo Hibernate, os pontos de interrogação
+ representam parêmetros de união do JDBC. Para ver os valores substituídos, ou para diminuir a
+ verbalidade do log, check seu l<literal>log4j.properties</literal>.
+ </para>
+
+ <para>
+ Agora nós gostaríamos de listar os eventos arquivados, então nós adicionamos uma
+ opção para o método main:
+ </para>
+
+ <programlisting><![CDATA[if (args[0].equals("store")) {
+ mgr.createAndStoreEvent("My Event", new Date());
+}
+else if (args[0].equals("list")) {
+ List events = mgr.listEvents();
+ for (int i = 0; i < events.size(); i++) {
+ Event theEvent = (Event) events.get(i);
+ System.out.println("Event: " + theEvent.getTitle() +
+ " Time: " + theEvent.getDate());
+ }
+}]]></programlisting>
+
+ <para>
+ Nos também adicionamos um novo <literal>método listEvents()</literal>:
+ </para>
+
+ <programlisting><![CDATA[private List listEvents() {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+ session.beginTransaction();
+
+ List result = session.createQuery("from Event").list();
+
+ session.getTransaction().commit();
+
+ return result;
+}]]></programlisting>
+
+ <para>
+ O que nós fazemos aqui, é usar uma query HQL (Hibernate Query Language),
+ para carregar todos os objetos <literal>Event</literal> exitentes no banco de dados.
+ O Hibernate irá gerar o SQL apropriado, enviar para o banco de dados e popular objetos
+ <literal>Event</literal> com os dados. Você pode criar queries mais complexas com
+ HQL, claro.
+ </para>
+
+ <para>
+ Agora, para executar e testar tudo isso, siga os passos a seguir:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Execute <literal>ant run -Daction=store</literal> para armazenar algo no banco de dados
+ e, claro, gerar o esquema do banco de dados antes pelo hbm2ddl.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Agora desabilite hbm2ddl comentando a propriedade no seu arquivo <literal>hibernate.cfg.xml</literal>.
+ Normalmente só se deixa habilitado em teste unitários contínuos, mas outra carga de hbm2ddl
+ pode <emphasis>remover</emphasis> tudo que você já tenha arquivado. Sa configuração
+ <literal>create</literal>, atualmente são traduzidas para "apague todas as tabelas do esquema,
+ então recrie todas quando a SessionFactory estiver pronta".
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Se você agora chamar o Ant com <literal>-Daction=list</literal>, você deverá ver os
+ eventos que você acabou de criar. Você pode também chamar a ação <literal>store</literal>
+ mais algumas vezes.
+ </para>
+
+ <para>
+ Nota: A maioria dos novos usuários do Hibernate falha nesse ponto e nós regularmente, vemos
+ questões sobre mensagens de erro de <emphasis>tabela não encontrada </emphasis> .
+ Entretanto, se você seguir os passos marcados acima, você não terá esse problema,
+ com o hbm2ddl criando o esquema do banco de dados na primeira execução, e restarts
+ subsequentes da aplicação irão usar este esquema. Se você mudar o mapeamento e/ou
+ o esquema do banco de dados, terá de re-habilitar o hbm2ddl mais uma vez.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="tutorial-associations">
+ <title>Part 2 - Mapeando associações</title>
+
+ <para>
+ Nós mapeamos uma classe de entidade de persistência para uma tabela. Agora vamos continuar
+ e adicionar algumas associações de classe. Primeiro nos iremos adicionar pessoas a nossa aplicação,
+ e armazenar os eventos de que elas participam.
+ </para>
+
+ <sect2 id="tutorial-associations-mappinguser" revision="1">
+ <title>Mapeando a classe Person</title>
+
+ <para>
+ O primeiro código da classe <literal>Person</literal> é simples:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+public class Person {
+
+ private Long id;
+ private int age;
+ private String firstname;
+ private String lastname;
+
+ public Person() {}
+
+ // Accessor methods for all properties, private setter for 'id'
+
+}]]></programlisting>
+
+ <para>
+ Crie um novo arquivo de mapeamento, chamado <literal>Person.hbm.xml</literal> (não
+ esqueça a referencia ao DTD no topo)
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="native"/>
+ </id>
+ <property name="age"/>
+ <property name="firstname"/>
+ <property name="lastname"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Finalmente, adicione o novo mapeamento a configuração do Hibernate:
+ </para>
+
+ <programlisting><![CDATA[<mapping resource="events/Event.hbm.xml"/>
+<mapping resource="events/Person.hbm.xml"/>]]></programlisting>
+
+ <para>
+ Nos iremos agora criar uma associação entre estas duas entidades. Obviamente,
+ pessoas (Person) podem participar de eventos, e eventos possuem participantes.
+ As questões de design com que teremos de lidar são: direcionalidade, multiplicidade e
+ comportamento de coleção.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-unidirset" revision="3">
+ <title>Uma associação Set-based unidirectional</title>
+
+ <para>
+ Nos iremos adicionar uma coleção de eventos na classe <literal>Person</literal>. Desse jeito
+ poderemos navegar pelos eventos de uma pessoa em particular, sem executar uma query explicitamente –
+ apenas chamando <literal>aPerson.getEvents()</literal>. Nos usaremos uma coleção Java, um
+ <literal>Set</literal>, porquê a coleção não conterá elementos duplicados e a ordem não é
+ relevante para nós.
+ </para>
+
+ <para>
+ Vamos escrever o código para isto nas classes Java e então mapear:
+ </para>
+
+ <programlisting><![CDATA[public class Person {
+
+ private Set events = new HashSet();
+
+ public Set getEvents() {
+ return events;
+ }
+
+ public void setEvents(Set events) {
+ this.events = events;
+ }
+}]]></programlisting>
+
+ <para>
+ Antes de mapearmos esta associação, pense no outro lado. Claramente, poderíamos apenas fazer isto de
+ forma unidirecional. Ou poderíamos criar outra coleção no <literal>Event</literal>, se quisermos
+ ser capaz de navegar bidirecionalmente, i.e. um - <literal>anEvent.getParticipants()</literal>.
+ Isto não é necessário, de perspectiva funcional. Você poderia sempre executar uma query explicita
+ que retornasse os participantes de um evento em particular. Esta é uma escolha de design que cabe
+ a você, mas o que é claro nessa discussão é a multiplicidade da associação: "muitos" valores em ambos
+ os lados, nós chamamos isto uma associação <emphasis>muitos-para-muitos</emphasis>. Daqui pra frente,
+ nos usaremos o mapeamento muitos-para-muitos do Hibernate:
+ </para>
+
+ <programlisting><![CDATA[<class name="events.Person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="native"/>
+ </id>
+ <property name="age"/>
+ <property name="firstname"/>
+ <property name="lastname"/>
+
+ <set name="events" table="PERSON_EVENT">
+ <key column="PERSON_ID"/>
+ <many-to-many column="EVENT_ID" class="events.Event"/>
+ </set>
+
+</class>]]></programlisting>
+
+ <para>
+ O Hibernate suporta todo tipo de mapeamento de coleção , sendo um <literal><set></literal> mais comum.
+ Para uma associação muitos-para-muitos (ou relacionamento de entidade <emphasis>n:m</emphasis> ),
+ uma tabela de associação é necessária. Cada linha nessa tabela representa um link entre uma pessoa e um
+ evento. O nome da tabela é configurado com o atributo <literal>table</literal> do elemento
+ <literal>set</literal>. O nome da coluna identificadora na associção, peloo lado da pessoa,
+ é definido com o elemento <literal><key></literal> , o nome da coluna pelo lado dos eventos,
+ e definido com o atributo <literal>column</literal> do <literal><many-to-many></literal>.
+ Você também precisa dizer para o Hibernate a classe dos objetos na sua coleção (a classe do outro
+ lado das coleções de referência).
+ </para>
+
+ <para>
+ O esquema de mapeamento para o banco de dados está a seguir:
+ </para>
+
+ <programlisting><![CDATA[
+ _____________ __________________
+ | | | | _____________
+ | EVENTS | | PERSON_EVENT | | |
+ |_____________| |__________________| | PERSON |
+ | | | | |_____________|
+ | *EVENT_ID | <--> | *EVENT_ID | | |
+ | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID |
+ | TITLE | |__________________| | AGE |
+ |_____________| | FIRSTNAME |
+ | LASTNAME |
+ |_____________|
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-working" revision="1">
+ <title>Trabalhando a associação</title>
+
+ <para>
+ Vamos trazer juntos algumas pessoas e eventos em um novo método na classe <literal>EventManager</literal>::
+ </para>
+
+ <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session.load(Person.class, personId);
+ Event anEvent = (Event) session.load(Event.class, eventId);
+
+ aPerson.getEvents().add(anEvent);
+
+ session.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ Após carregar um <literal>Person</literal> e um <literal>Event</literal>, simplesmente
+ modifique a coleção usando os métodos normais de uma coleção. Como você pode ver, não há chamada explícita
+ para <literal>update()</literal> ou <literal>save()</literal>, o Hibernate detecta automaticamente
+ que a coleção foi modificada e necessita ser atualizada. Isso é chamado de <emphasis>checagem
+ suja automática</emphasis>, e você também pode usá-la modificando o nome ou a data de qualquer um dos
+ seus objetos. Assim que eles estiverem no estado <emphasis>persistent</emphasis>, ou seja,
+ limitado por uma <literal>Session</literal> do Hibernate em particular (i.e. eles foram carregados ou
+ salvos dentro de uma unidade de trabalho), o Hibernate monitora qualquer alteração e executa o SQL
+ em modo de escrita em segundo plano. O processo de sincronização do estado da memória com o banco de
+ dados, geralmente apenas no final de uma unidade de trabalho, é chamado de <emphasis>flushing</emphasis>.
+ No nosso código, a unidade de trabalho termina com o commit da transação do banco de dados –
+ como definido pela opção de configuração da <literal>thread</literal> da classe <literal>CurrentSessionContext</literal>.
+ </para>
+
+ <para>
+ Você pode também querer carregar pessoas e eventos em diferentes unidades de trabalho.
+ Ou você modifica um objeto fora de uma <literal>Session</literal>, quando não se encontra no
+ estado persistent (se já esteve neste estado anteriormente, chamamos esse estado de
+ <emphasis>detached</emphasis>). Você pode até mesmo modificar uma coleção quando esta
+ se encontrar no estado detached.
+ </para>
+
+ <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session
+ .createQuery("select p from Person p left join fetch p.events where p.id = :pid")
+ .setParameter("pid", personId)
+ .uniqueResult(); // Eager fetch the collection so we can use it detached
+
+ Event anEvent = (Event) session.load(Event.class, eventId);
+
+ session.getTransaction().commit();
+
+ // End of first unit of work
+
+ aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached
+
+ // Begin second unit of work
+
+ Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
+ session2.beginTransaction();
+
+ session2.update(aPerson); // Reattachment of aPerson
+
+ session2.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ A chamada <literal>update</literal> cria um objeto persistent novamente, você poderia
+ dizer que ele liga o objeto a uma nova unidade de trabalho, assim qualquer modificação
+ que você faça neste objeto enquanto estiver no estado detached pode ser salvo no banco de dados.
+ Isso inclui qualquer modificação (adição/exclusão) que você faça em uma coleção da entidade deste objeto.
+ </para>
+
+ <para>
+ Bom, isso não foi muito usado na nossa situação, porém, é um importante conceito que você
+ pode aplicar em seus aplicativos. Agora, complete este exercício adicionando uma nova ação
+ ao método main( ) da classe <literal>EventManager</literal> e chame-o pela linha de comando.
+ Se você precisar dos identificadores de uma pessoa ou evento – o método <literal>save()</literal>
+ retorna estes identificadores (você poderá modificar alguns dos métodos anteriores para retornar aquele
+ identificador):
+ </para>
+
+ <programlisting><![CDATA[else if (args[0].equals("addpersontoevent")) {
+ Long eventId = mgr.createAndStoreEvent("My Event", new Date());
+ Long personId = mgr.createAndStorePerson("Foo", "Bar");
+ mgr.addPersonToEvent(personId, eventId);
+ System.out.println("Added person " + personId + " to event " + eventId);]]></programlisting>
+
+ <para>
+ Este foi um exemplo de uma associação entre duas classes igualmente importantes, duas entidades.
+ Como mencionado anteriormente, há outras classes e tipos dentro de um modelo típico,
+ geralmente "menos importante". Alguns você já viu, como um <literal>int</literal> ou uma <literal>String</literal>.
+ Nós chamamos essas classes de <emphasis>value types</emphasis>, e suas instâncias <emphasis>depend</emphasis>
+ de uma entidade particular. As instâncias desses tipos não possuem sua própria identidade, nem são
+ compartilhados entre entidades (duas pessoas não referenciam o mesmo objeto <literal>firstname</literal>
+ mesmo se elas tiverem o mesmo objeto firstname). Naturalmente, os value types não são apenas encontrados
+ dentro da JDK (de fato, em um aplicativo Hibernate todas as classes JDK são consideradas como value types),
+ mas você pode também criar suas classes como, por exemplo, <literal>Address</literal> ou <literal>MonetaryAmount</literal>.
+
+ </para>
+
+ <para>
+ Você também pode criar uma coleção de value types. Isso é conceitualmente muito diferente
+ de uma coleção de referências para outras entidades, mas em Java parece ser quase a mesma coisa.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-valuecollections">
+ <title>Coleção de valores</title>
+
+ <para>
+ Nós adicionamos uma coleção de objetos de tipo de valores à entidade <literal>Person</literal>.
+ Nós querermos armazenar endereços de e-mail, para isso utilizamos o tipo <literal>String</literal>,
+ e a coleção novamente será um <literal>Set</literal>:
+ </para>
+ <programlisting><![CDATA[private Set emailAddresses = new HashSet();
+
+public Set getEmailAddresses() {
+ return emailAddresses;
+}
+
+public void setEmailAddresses(Set emailAddresses) {
+ this.emailAddresses = emailAddresses;
+}]]></programlisting>
+
+ <para>
+ O mapeamento deste <literal>Set</literal>:
+ </para>
+
+ <programlisting><![CDATA[<set name="emailAddresses" table="PERSON_EMAIL_ADDR">
+ <key column="PERSON_ID"/>
+ <element type="string" column="EMAIL_ADDR"/>
+</set>]]></programlisting>
+
+ <para>
+ A diferença comparada com o mapeamento anterior se encontra na parte <literal>element</literal>,
+ que indica ao Hibernate que a coleção não contém referências à outra entidade, mas uma coleção de
+ elementos do tipo <literal>String</literal> (a tag name em miniscula indica que se trata de um
+ mapeamento do Hibernate para conversão de tipos). Mais uma vez, o atributo <literal>table</literal>
+ do elemento <literal>set</literal> determina o nome da tabela para a coleção. O elemento
+ <literal>key</literal> define o nome da coluna de chave estrangeira na tabela de coleção.
+ O atributo <literal>column</literal> dentro do elemento <literal>element</literal> define o
+ nome da coluna onde os valores da <literal>String</literal> serão armazenados.
+ </para>
+
+ <para>
+ Dê uma olhada no esquema atualizado:
+ </para>
+
+ <programlisting><![CDATA[
+ _____________ __________________
+ | | | | _____________
+ | EVENTS | | PERSON_EVENT | | | ___________________
+ |_____________| |__________________| | PERSON | | |
+ | | | | |_____________| | PERSON_EMAIL_ADDR |
+ | *EVENT_ID | <--> | *EVENT_ID | | | |___________________|
+ | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID | <--> | *PERSON_ID |
+ | TITLE | |__________________| | AGE | | *EMAIL_ADDR |
+ |_____________| | FIRSTNAME | |___________________|
+ | LASTNAME |
+ |_____________|
+ ]]></programlisting>
+
+ <para>
+ Você pode observar que a chave primária da tabela da coleção é de na verdade uma chave composta,
+ usando ambas colunas. Isso também implica que cada pessoa não pode ter endereços de e-mail
+ duplicados, o que é exatamente a semântica que precisamos para um set em Java.
+ </para>
+
+ <para>
+ Você pode agora tentar adicionar elementos a essa coleção, do mesmo modo que fizemos
+ anteriormente ligando pessoas e eventos. È o mesmo código em Java:
+ </para>
+
+ <programlisting><![CDATA[private void addEmailToPerson(Long personId, String emailAddress) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session.load(Person.class, personId);
+
+ // The getEmailAddresses() might trigger a lazy load of the collection
+ aPerson.getEmailAddresses().add(emailAddress);
+
+ session.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ This time we didnt' use a <emphasis>fetch</emphasis> query to initialize the collection.
+ Hence, the call to its getter method will trigger an additional select to initialize
+ it, so we can add an element to it. Monitor the SQL log and try to optimize this with
+ an eager fetch.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-bidirectional" revision="1">
+ <title>Associações bidirecionais</title>
+
+ <para>
+ Agora iremos mapear uma associação bidirecional – fazendo a associação entre pessoas e
+ eventos, de ambos os lados, em Java. Logicamente, o esquema do banco de dados não muda,
+ nós continuamos tendo multiplicidades muitos-para-muitos. Um banco de dados é mais flexível do que
+ uma linguagem de programação para redes, ele não precisa de nenhuma direção de navegação – os
+ dados podem ser acessados em qualquer caminho possível.
+ </para>
+
+ <para>
+ Primeiramente, adicione uma coleção de participantes à classe <literal>Event</literal>:
+ </para>
+
+ <programlisting><![CDATA[private Set participants = new HashSet();
+
+public Set getParticipants() {
+ return participants;
+}
+
+public void setParticipants(Set participants) {
+ this.participants = participants;
+}]]></programlisting>
+
+ <para>
+ Agora mapeie este lado da associação em <literal>Event.hbm.xml</literal>.
+ </para>
+
+ <programlisting><![CDATA[<set name="participants" table="PERSON_EVENT" inverse="true">
+ <key column="EVENT_ID"/>
+ <many-to-many column="PERSON_ID" class="events.Person"/>
+</set>]]></programlisting>
+
+ <para>
+ Como você pode ver, esses é uma mapeamento normal usando <literal>set</literal> em ambos documenentos
+ de mapeamento. Observe que o nome das colunas em <literal>key</literal> e <literal>many-to-many</literal>
+ estão trocados em ambos os documentos de mapeamento. A adição mais importante feita está no atributo
+ <literal>inverse="true"</literal> no elemento set do mapeamento da coleção da classe <literal>Event</literal>.
+ </para>
+
+ <para>
+ Isso significa que o Hibernate deve pegar o outro lado – a classe <literal>Person</literal> –
+ quando necessitar encontrar informação sobre a relação entre as duas entidades. Isso será muito
+ mais facilmente compreendido quando você analisar como a relação bidirecional entre as entidades é criada.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-usingbidir">
+ <title>Trabalhando com links bidirecionais</title>
+
+ <para>
+ Primeiro tenha em mente que o Hibernate não afeta a semântica normal do Java. Como nós criamos
+ um link entre uma <literal>Person</literal> e um <literal>Event</literal> no exemplo unidirecional?
+ Nós adicionamos uma instância de <literal>Event</literal>, da coleção de referências de eventos,
+ a uma instância de <literal>Person</literal>. Então, obviamente, se nós queremos que este link funcione
+ bidirecionalmente, nós devemos fazer a mesma coisa para o outro lado – adicionando uma referência de
+ <literal>Person</literal> na coleção de um <literal>Event</literal>. Esse acerto de link de ambos
+ os lados é absolutamente necessário e você nunca deve esquecer de faze-lo.
+ </para>
+
+ <para>
+ Muitos desenvolvedores programam de maneira defensiva e criam métodos
+ gerenciador de associações que ajusta corretamente ambos os lados:
+ </para>
+
+ <programlisting><![CDATA[protected Set getEvents() {
+ return events;
+}
+
+protected void setEvents(Set events) {
+ this.events = events;
+}
+
+public void addToEvent(Event event) {
+ this.getEvents().add(event);
+ event.getParticipants().add(this);
+}
+
+public void removeFromEvent(Event event) {
+ this.getEvents().remove(event);
+ event.getParticipants().remove(this);
+}]]></programlisting>
+
+ <para>
+ Observe que os métodos set e get da a coleção estão protegidos – isso permite que classes e
+ subclasses do mesmo pacote continuem acessando os métodos, mas previne que qualquer outra classe,
+ que não esteja no mesmo pacote, acesse a coleção diretamente. Você provavelmente deve fazer a mesma
+ coisa para a coleção do outro lado.
+ </para>
+
+ <para>
+ E sobre o mapeamento do atributo <literal>inverse</literal>? Pra você, e para o Java, um link bidirecional
+ é simplesmente o fato de ajustar corretamente as referências de ambos os lados. O Hibernate, entretanto
+ não possui informação necessária para corretamente adaptar os estados <literal>INSERT</literal> e
+ <literal>UPDATE</literal> do SQL, e precisa de ajuda para manipular as propriedades das associações
+ bidirecionais. Fazer um lado da associação com o atributo <literal>inverse</literal> instrui o Hibernate
+ para basicamente ignora-lo, considerando-o uma <emphasis>cópia</emphasis> do outro lado. Isso é todo o
+ necessário para o Hibernate trabalhar com todas as possibilidades quando transformando um modelo de
+ navegação bidirecional em esquema de banco de dados do SQL. As regras que você possui para lembrar são
+ diretas: Todas associações bidirecionais necessitam que um lado possua o atributo inverse. Em uma
+ associação de um-para-muitos, o lado de "muitos" deve conter o atributo <literal>inverse</literal>,
+ já em uma associação de muitos-para-muitos você pode pegar qualquer lado, não há diferença.
+ </para>
+
+ </sect2>
+
+ <para>
+ Agora, vamos portar este exemplo para um pequeno aplicativo para internet.
+
+ </para>
+
+ </sect1>
+
+ <sect1 id="tutorial-webapp">
+ <title>EventManager um aplicativo para internet</title>
+
+ <para>
+ Um aplicativo para internet do Hibernate usa uma <literal>Session</literal> e uma <literal>Transaction</literal>
+ quase do mesmo modo que um aplicativo standalone. Entretanto, alguns patterns comuns são úteis.
+ Nós agora criaremos um <literal>EventManagerServlet</literal>. Esse servlet lista todos os eventos
+ salvos no banco de dados, e cria um formulário HTML para entrada de novos eventos.
+ </para>
+
+ <sect2 id="tutorial-webapp-servlet" revision="1">
+ <title>Criando um servlet básico</title>
+
+ <para>
+ Crie uma nova classe no seu diretório fonte, no pacote <literal>events</literal>:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+// Imports
+
+public class EventManagerServlet extends HttpServlet {
+
+ // Servlet code
+}]]></programlisting>
+
+ <para>
+ O servlet manuseia somente requisições <literal>GET</literal> do HTTP,
+ portanto o método que iremos implementar é <literal>doGet()</literal>:
+ </para>
+
+ <programlisting><![CDATA[protected void doGet(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+
+ SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");
+
+ try {
+ // Begin unit of work
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().beginTransaction();
+
+ // Process request and render page...
+
+ // End unit of work
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().getTransaction().commit();
+
+ } catch (Exception ex) {
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().getTransaction().rollback();
+ throw new ServletException(ex);
+ }
+
+}]]></programlisting>
+
+ <para>
+ O pattern que estamos aplicando neste código é chamado <emphasis>session-per-request</emphasis>.
+ Quando uma requisição chega ao servlet, uma nova <literal>Session</literal> do Hibernate é
+ aberta através da primeira chamada para <literal>getCurrentSession()</literal> em
+ <literal>SessionFactory</literal>. Então uma transação do banco de dados é inicializada -
+ todo acesso a dados deve ocorrer dentro de uma transação, não importando se o dado é de leitura ou escrita.
+ (nós não devemos usar o modo auto-commit em aplicações).
+
+ </para>
+
+ <para>
+ Agora, as possibilidades de ações de uma requisição serão processadas e uma resposta HTML será renderizada.
+ Nós já iremos chegar nesta parte.
+ </para>
+
+ <para>
+ Finalmente, a unidade de trabalho termina quando o processamento e a restituição são completados.
+ Se ocorrer algum erro durante o processamento ou a restituição, uma exceção será lançada e a
+ transação do banco de dados encerrada. Isso completa o pattern <literal>session-per-request</literal>.
+ Em vez de usar código de demarcação de transação em todo servlet você pode também criar um filtro servlet.
+ Dê uma olhada no site do Hibernate e do Wiki para maiores informações sobre esse pattern,
+ chamado <emphasis>Open Session in View</emphasis>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-webapp-processing" revision="1">
+ <title>Processando e renderizando</title>
+
+ <para>
+ Vamos implementar o processamento da requisição e a restituição da página HTML.
+ </para>
+
+<programlisting><![CDATA[// Write HTML header
+PrintWriter out = response.getWriter();
+out.println("<html><head><title>Event Manager</title></head><body>");
+
+// Handle actions
+if ( "store".equals(request.getParameter("action")) ) {
+
+ String eventTitle = request.getParameter("eventTitle");
+ String eventDate = request.getParameter("eventDate");
+
+ if ( "".equals(eventTitle) || "".equals(eventDate) ) {
+ out.println("<b><i>Please enter event title and date.</i></b>");
+ } else {
+ createAndStoreEvent(eventTitle, dateFormatter.parse(eventDate));
+ out.println("<b><i>Added event.</i></b>");
+ }
+}
+
+// Print page
+printEventForm(out);
+listEvents(out, dateFormatter);
+
+// Write HTML footer
+out.println("</body></html>");
+out.flush();
+out.close();]]></programlisting>
+
+ <para>
+ O estilo de código acima, misturando linguagem HTML e Java não será funcional em um aplicativo
+ mais complexo—tenha em mente que neste manual nós estamos apenas ilustrando conceitos
+ básicos do Hibernate. O código imprime um cabeçalho HTML e um rodapé. Dentro desta página,
+ é mostrado um formulário em HTML, para entrada de novos eventos, e uma lista de todos
+ os eventos contidos no banco de dados. O primeiro método é trivial e apenas imprime
+ uma página HTML:
+ </para>
+
+ <programlisting><![CDATA[private void printEventForm(PrintWriter out) {
+ out.println("<h2>Add new event:</h2>");
+ out.println("<form>");
+ out.println("Title: <input name='eventTitle' length='50'/><br/>");
+ out.println("Date (e.g. 24.12.2009): <input name='eventDate' length='10'/><br/>");
+ out.println("<input type='submit' name='action' value='store'/>");
+ out.println("</form>");
+}]]></programlisting>
+
+ <para>
+ O método <literal>listEvents()</literal> usa a <literal>Session</literal> do Hibernate
+ associada a thread atual para executar um query:
+ </para>
+
+ <programlisting><![CDATA[private void listEvents(PrintWriter out, SimpleDateFormat dateFormatter) {
+
+ List result = HibernateUtil.getSessionFactory()
+ .getCurrentSession().createCriteria(Event.class).list();
+ if (result.size() > 0) {
+ out.println("<h2>Events in database:</h2>");
+ out.println("<table border='1'>");
+ out.println("<tr>");
+ out.println("<th>Event title</th>");
+ out.println("<th>Event date</th>");
+ out.println("</tr>");
+ for (Iterator it = result.iterator(); it.hasNext();) {
+ Event event = (Event) it.next();
+ out.println("<tr>");
+ out.println("<td>" + event.getTitle() + "</td>");
+ out.println("<td>" + dateFormatter.format(event.getDate()) + "</td>");
+ out.println("</tr>");
+ }
+ out.println("</table>");
+ }
+}]]></programlisting>
+
+ <para>
+ Finalmente, a action <literal>store</literal> é passada pra o método
+ <literal>createAndStoreEvent()</literal>, que também usa a
+ <literal>Session</literal> da thread atual:
+ </para>
+
+ <programlisting><![CDATA[protected void createAndStoreEvent(String title, Date theDate) {
+ Event theEvent = new Event();
+ theEvent.setTitle(title);
+ theEvent.setDate(theDate);
+
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().save(theEvent);
+}]]></programlisting>
+
+ <para>
+ Pronto, o servlet está completo. Uma requisição para o servlet será processada
+ em uma <literal>Session</literal> e uma <literal>Transaction</literal> simples.
+ Como anteriormente, no aplicativo standalone, o Hibernate pode automaticamente
+ associar esses objetos a thread atual em execução. Isso possibilita a liberdade
+ de você modelar seu código e acessar o método <literal>SessionFactory</literal>
+ do jeito que achar melhor. Geralmente você irá usar um design mais sofisticado
+ e mover o código de acesso a dados para dentro de objetos de acesso a dados
+ (o patter DAO). Leia o Hibernate Wiki para maiores exemplos.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-webapp-deploy">
+ <title>Instalando e testando</title>
+
+ <para>
+ Para fazer o deploy desta aplicação você tem que criar um arquivo para web, um WAR.
+ Adicione o alvo Ant abaixo em seu <literal>build.xml</literal>:
+ </para>
+
+<programlisting><![CDATA[<target name="war" depends="compile">
+ <war destfile="hibernate-tutorial.war" webxml="web.xml">
+ <lib dir="${librarydir}">
+ <exclude name="jsdk*.jar"/>
+ </lib>
+
+ <classes dir="${targetdir}"/>
+ </war>
+</target>]]></programlisting>
+
+ <para>
+ Esta target cria um arquivo chamado <literal>hibernate-tutorial.war</literal>
+ no diretório do seu projeto. Ele empacota todas as bibliotecas e o arquivo de
+ descrição <literal>web.xml</literal>, o qual é esperado no diretório base do seu projeto:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4"
+ xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+ <servlet>
+ <servlet-name>Event Manager</servlet-name>
+ <servlet-class>events.EventManagerServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Event Manager</servlet-name>
+ <url-pattern>/eventmanager</url-pattern>
+ </servlet-mapping>
+</web-app>]]></programlisting>
+
+ <para>
+ Antes de você compilar e fazer o deploy desta aplicação web, note que uma biblioteca
+ adicional é requerida: <literal>jsdk.jar</literal>. Esse é o Java servlet development kit,
+ se você não possui esta biblioteca, faça seu download na página da Sun e copie-a
+ para seu diretório de bibliotecas. Entretanto, será usado somente para a compilação e
+ excluído do pacote WAR.
+ </para>
+
+ <para>
+ Para compilar e instalar execute <literal>ant war</literal> no seu diretório do projeto
+ e copie o arquivo <literal>hibernate-tutorial.war</literal> para o diretório
+ <literal>webapp</literal> do Tomcat. Se você não possui o Tomcat instalado faça
+ o download e siga as instruções de instalação. Você não precisa modificar
+ nenhuma configuração do Tomcat para rodar este aplicativo.
+ </para>
+
+ <para>
+ Uma vez feito o deploy e com Tomcat rodando, acesse o aplicativo em
+ <literal>http://localhost:8080/hibernate-tutorial/eventmanager</literal>.
+ Veja o log do Tomcat para observar a inicialização do Hibernate quando a
+ primeira requisição chega ao servlet (o inicializador estático dentro de
+ <literal>HibernateUtil</literal> é chamado) e para ter uma depuração
+ detalhada se ocorrer alguma exceção.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="tutorial-summary" revision="1">
+ <title>Sumário</title>
+
+ <para>
+ Este manual cobriu os princípios básicos para criação de uma aplicação simples do Hibernate
+ e uma pequena aplicação web.
+ </para>
+
+ <para>
+ Se você já se sente seguro com o Hibernate, continue navegando na documentação de referência
+ por tópicos que você acha interessante – os tópicos mais questionados são:
+ processo de transação (<xref linkend="transactions"/>), uso da API (<xref linkend="objectstate"/>)
+ e características de consulta (<xref linkend="objectstate-querying"/>).
+ </para>
+
+ <para>
+ Não esqueça de visitar o site do Hibernate para obter mais tutoriais especializados.
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tutorial1.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/tutorial1.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tutorial1.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tutorial1.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,1544 @@
+<chapter id="tutorial">
+ <title>Introdução ao Hibernate</title>
+
+ <sect1 id="tutorial-intro" revision="1">
+ <title>Prefácio</title>
+
+ <para>
+ Este capítulo é um tutorial introdutório para novos usuários do Hibernate. Nós iniciaremos com uma simples linha de comando em uma aplicação usando uma base de dados em memória tornando isto um passo de fácil de compreender.
+ </para>
+
+ <para>
+ Este tutorial é voltado para novos usuários do Hibernate, mas requer um conhecimento de Java e SQL. Este tutorial é baseado no tutorial de Michael Gloegl, as bibliotecas Third Party foram nomeadas para JDK 1.4 e 5.0. Você pode precisar de outras bibliotecas para JDK 1.3.
+ </para>
+
+ <para>
+ O código fonte para o tutorial está incluído no diretório da distribuição
+ <literal>doc/reference/tutorial/</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="tutorial-firstapp" revision="2">
+ <title>Parte 1 – A primeira aplicação Hibernate</title>
+
+ <para>
+ Primeiro, iremos criar uma simples aplicação Hibernate baseada em console. Usaremos uma base de dados Java (HSQL DB), então não teremos que instalar nenhum servidor de base de dados.
+ </para>
+
+ <para>
+ Vamos supor que precisemos de uma aplicação com um banco de dados pequeno que possa armazenar e atender os eventos que queremos, e as informaççes sobre os hosts destes eventos.
+ </para>
+
+ <para>
+ A primeira coisa que devemos fazer é configurar nosso diretório de desenvolvimento,
+ e colocar todas as bibliotecas Java que precisamos dentro dele. Faça o download da
+ distribuição do Hibernate no site do Hibernate. Descompacte o pacote e coloque todas
+ as bibliotecas necessárias encontradas no diretório <literal>/lib</literal>, dentro do
+ diretório <literal>/lib</literal> do seu novo projeto. Você deverá ter algo parecido
+ com isso:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ antlr.jar
+ cglib.jar
+ asm.jar
+ asm-attrs.jars
+ commons-collections.jar
+ commons-logging.jar
+ hibernate3.jar
+ jta.jar
+ dom4j.jar
+ log4j.jar ]]></programlisting>
+
+ <para>
+ Esta é a configuração mínima requerida das bibliotecas (observe que também foi copiado
+ o hibernate3.jar da pasta principal do Hibernate) para o Hibernate <emphasis>na hora do desenvolvimento</emphasis>. O Hibernate permite que você utilize mais ou menos bibliotecas.
+ Veja o arquivo <literal>README.txt</literal> no diretório <literal>lib/</literal> da distribuição
+ do Hibernate para maiores informaççes sobre bibliotecas requeridas e opcionais.
+ (Atualmente, a biblioteca Log4j não é requerida, mas é preferida por muitos desenvolvedores.)
+ </para>
+
+ <para>
+ Agora, iremos criar uma classe que representa o evento que queremos armazenar na base de dados..
+ </para>
+
+ <sect2 id="tutorial-firstapp-firstclass" revision="1">
+ <title>A primeira Classe</title>
+
+ <para>
+ Nossa primeira classe de persistência é uma simples classe JavaBean com algumas propriedades:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+import java.util.Date;
+
+public class Event {
+ private Long id;
+
+ private String title;
+ private Date date;
+
+ public Event() {}
+
+ public Long getId() {
+ return id;
+ }
+
+ private void setId(Long id) {
+ this.id = id;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}]]></programlisting>
+
+ <para>
+ Você pode ver que esta classe usa o padrão JavaBean para o nomeamento convencional da propriedade getter e dos métodos setter, como também a visibilidade private dos campos. Este é um padrão de projeto recomendado, mas não requerido. O Hibernate pode também acessar campos diretamente, o benefício para os métodos de acesso é a robustez para o Refactoring. O construtor sem argumento é requerido para instanciar um objeto desta classe com a reflexão.
+ </para>
+
+ <para>
+ A propriedade <literal>id</literal> mantém um único valor de identificação para um evento
+ particular. Todas as classes persistentes da entidade (bem como aquelas classes dependentes
+ de menos importância) precisam de uma propriedade de identificação, caso nós queiramos usar o
+ conjunto completo de características do Hibernate. De fato, a maioria das aplicações
+ (esp. aplicações web) precisam destinguir os objetos pelo identificador, então você deverá
+ considerar esta, uma característica em lugar de uma limitação. Porém, nós normalmente não
+ manipulamos a identidade de um objeto, consequentemente o método setter deverá ser privado.
+ O Hibernate somente nomeará os identificadores quando um objeto for salvo. Você pode ver como
+ o Hibernate pode acessar métodos públicos, privados, e protegidos, como também campos
+ (públicos, privados, protegidos) diretamente. A escolha está até você, e você pode combinar
+ isso para adaptar seu projeto de aplicação
+ </para>
+
+ <para>
+ O construtor sem argumentos é um requerimento para todas as classes persistentes;
+ O Hibernate tem que criar para você os objetos usando Java Reflection. O construtor
+ pode ser privado, porém, a visibilidade do pacote é requerida para a procuração da
+ geração em tempo de execução e recuperação eficiente dos dados sem a instrumentação
+ de bytecode
+ </para>
+
+ <para>
+ Coloque este fonte Java no diretório chamado <literal>src</literal> na pasta de desenvolvimento,
+ e em seu pacote correto. O diretório deverá ser parecido como este:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java]]></programlisting>
+
+ <para>
+ No próximo passo, iremos falar sobre as classes de persistência do Hibernate..
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-mapping" revision="1">
+ <title>O mapeamento do arquivo</title>
+
+ <para>
+ O Hibernate precisa saber como carregar e armazenar objetos da classe de
+ persistência. Isto será onde o mapeamento do arquivo do Hibernate entrará em
+ jogo. O arquivo mapeado informa ao Hibernate, qual tabela no banco de dados
+ ele deverá acessar, e quais as colunas na tabela ele deverá usar.
+ </para>
+
+ <para>
+ A estrutura básica de um arquivo de mapeamento é parecida com:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping>
+[...]
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Note que o Hibernate DTD é muito sofisticado. Você pode usar isso para auto-conclusão
+ no mapeamento XML dos elementos e atributos no seu editor ou IDE. Você também pode
+ abrir o arquivo DTD no seu editor – é a maneira mais fácil de ter uma visão geral
+ de todos os elementos e atributos e dos padrões, como também alguns comentários.
+ Note que o Hibernate não irá carregar o arquivo DTD da web, e sim do diretório
+ da aplicação (classpath). O arquivo DTD está incluído no <literal>hibernate3.jar</literal> como
+ também no diretório <literal>src/</literal> da distribuição do Hibernate.
+ </para>
+
+ <para>
+ Nós omitiremos a declaração do DTD nos exemplos futuros para encurtar o código. Isto, é claro, não é opcional.
+ </para>
+
+ <para>
+ Entre os dois tags <literal>hibernate-mapping</literal>, inclua um elemento <literal>class</literal>.
+ Todas as classes persistentes da entidade (novamente, poderá haver
+ mais tarde, dependências sobre as classes que não são classes-primárias
+ de entidades) necessitam do tal mapeamento, para uma tabela na base
+ de dados SQL
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Mais adiante iremos dizer ao Hibernate como fazer para persistir e carregar objetos da classe
+ <literal>Event</literal> da tabela <literal>EVENTS</literal>, cada instancia representada por
+ uma coluna na tabela. Agora, continuaremos com o mapeamento de uma única propriedade identificadora
+ para as chaves primárias da tabela. Além disso, nós não iremos se importar com esta propriedade
+ identificadora, nós iremos configurar uma estratégia de geração de id’s para uma chave primária
+ de coluna surrogate:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+ <id name="id" column="EVENT_ID">
+ <generator class="native"/>
+ </id>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ O elemento <literal>id</literal> é a declaração da propriedade identificadora,
+ o <literal>name="id"</literal> declara o nome da propriedade Java –
+ o Hibernate irá usar os métodos getter e setter para acessar a propriedade.
+ O atributo da coluna informa ao Hibernate qual coluna da tabela <literal>EVENTS</literal> nós
+ iremos usar como chave primária. O elemento <literal>generator</literal> especifica
+ a estratégia de geração do identificador, neste caso usaremos <literal>native</literal>, que
+ escolhe a melhor estratégia dependendo da base de dados (dialeto) configurada.
+ O Hibernate suporta a base de dados gerada, globalmente única, bem como a atribuição
+ aos identificadores da aplicação (ou toda estratégia escrita para uma extensão).
+ </para>
+
+ <para>
+ Finalmente incluiremos as declarações para as propriedades persistentes da classe
+ no arquivo mapeado. Por default, nenhuma das propriedades da classe é considerada persistente:
+ </para>
+
+ <programlisting><![CDATA[
+<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+ <id name="id" column="EVENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="date" type="timestamp" column="EVENT_DATE"/>
+ <property name="title"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Da mesma maneira que com o elemento <literal>id</literal>, o atributo <literal>name</literal> do elemento
+ <literal>property</literal> informa ao Hibernate qual método getter e setter deverá usar.
+ Assim, neste caso, o Hibernate irá procurar pelo <literal>getDate()/setDate()</literal>,
+ como também pelo <literal>getTitle()/setTitle()</literal>.
+ </para>
+
+ <para>
+ Porque fazer o mapeamento da propriedade <literal>date</literal> incluído no
+ atributo <literal>column</literal>, e no title não fazer?
+ Sem o atributo <literal>column</literal> o Hibernate por padrão usa o nome
+ da propriedade como o nome da coluna. Isto trabalha muito
+ bem para o <literal>title</literal>. Entretanto o <literal>date</literal> é uma palavra-chave reservada
+ na maioria dos bancos de dados, assim nós melhoramos o mapeamentos
+ disto com um nome diferente.
+ </para>
+
+ <para>
+ A próxima coisa interessante é que mapemanto do <literal>title</literal>
+ também falta o atributo <literal>type</literal>. O tipo que declaramos e o uso nos
+ arquivos mapeados, não são como você pôde esperar, atributos de dados Java.
+ Eles não são como os tipos de base de dados SQL.
+ Esses tipos podem ser chamados de <emphasis>Tipos de mapeamento Hibernate</emphasis>, que são conversores
+ que podem traduzir tipos de dados do Java para os tipos de dados SQL e vice-versa.
+ Novamente, o Hibernate irá tentar determinar a conversão correta e mapeará o <literal>type</literal>
+ próprio, caso o tipo do atributo não estiver presente no mapeamento.
+ Em alguns casos, esta detecção automática (que usa Reflection sobre as classes Java)
+ poderá não ter padrão que você espera ou necessita.
+ Este é o caso com a propriedade <literal>date</literal>. O Hibernate não pode saber se a propriedade
+ (que é do <literal>java.util.Date</literal>) pode mapear para uma coluna do tipo <literal>date</literal>
+ do SQL, <literal>timestamp</literal>, ou <literal>time</literal> .
+ Nós preservamos a informação cheia de datas e horas pelo mapeamento da propriedade com um conversor
+ <literal>timestamp</literal>.
+ </para>
+
+ <para>
+ Este arquivo de mapeamento deve ser salvo como <literal>Event.hbm.xml</literal>,
+ corretamente no diretório próximo ao arquivo fonte da Classe Java <literal>Event</literal>.
+ O nomeamento dos arquivos de mapeamento podem ser arbitrários, porém o sufixo
+ <literal>hbm.xml</literal> é uma convenção da comunidade dos desenvolvedores do Hibernate.
+ Esta estrutura do diretório deve agora se parecer com isso:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java
+ Event.hbm.xml]]></programlisting>
+
+ <para>
+ Nós iremos continuar com a configuração principal do Hibernate.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-configuration" revision="2">
+ <title>Configuração do Hibernate</title>
+
+ <para>
+ Agora nós temos uma classe persistente e este arquivo de mapeamento no lugar.
+ Está na hora de configurar o Hibernate. Antes de fazermos isso, iremos precisar de uma base de dados.
+ O HSQL DB, um SQL DBMS feito em java, pode ser baixado através do site do HSQL DB(http://hsqldb.org/).
+ Atualmente, você só precisa baixar o <literal>hsqldb.jar</literal>.
+ Coloque este arquivo no diretório da pasta de desenvolvimento <literal>lib/</literal>.
+ </para>
+
+ <para>
+ Crie um diretório chamado <literal>data</literal> no diretório root de desenvolvimento –
+ Isto será onde o HSQL DB irá armazenar arquivos de dados. Agora iremos iniciar o banco de dados
+ executando <literal>java -classpath ../lib/hsqldb.jar org.hsqldb.Server</literal> neste diretório de dados.
+ Você pode ver ele iniciando e conectando ao socket TCP/IP, isto será onde nossa aplicação irá se
+ conectar depois. Se você deseja iniciar uma nova base de dados durante este tutorial,
+ finalize o HSQL DB(pressionando o <literal>CTRL + C</literal> na janela), delete todos os
+ arquivos no diretório <literal>data/</literal>, e inicie o HSQL BD novamente.
+ </para>
+
+ <para>
+ O Hibernate é uma camada na sua aplicação na qual se conecta com a base de dados, para isso
+ necessita de informação da conexão. As conexões são feitas através de um pool de conexão JDBC,
+ na qual teremos que configurar. A distribuição do Hibernate contém diversas ferramentas de pooling
+ da conexão JDBC de fonte aberta, mas iremos usar o pool de conexão interna para este tutorial.
+ Note que você tem que copiar a biblioteca necessária em seu classpath e use configurações
+ diferentes para pooling de conexão caso você deseje utilizar um software de pooling JDBC terceirizado
+ para qualidade de produção.
+ </para>
+
+ <para>
+ Para as configurações do Hibernate, nós podemos usar um arquivo simples <literal>hibernate.properties</literal>,
+ um arquivo mais ligeiramente sofisticado <literal>hibernate.cfg.xml</literal> ou até mesmo uma
+ instalação programática completa. A maioria dos usuários preferem utilizar o arquivo de configuração XML
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <session-factory>
+
+ <!-- Database connection settings -->
+ <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
+ <property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
+ <property name="connection.username">sa</property>
+ <property name="connection.password"></property>
+
+ <!-- JDBC connection pool (use the built-in) -->
+ <property name="connection.pool_size">1</property>
+
+ <!-- SQL dialect -->
+ <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
+
+ <!-- Enable Hibernate's automatic session context management -->
+ <property name="current_session_context_class">thread</property>
+
+ <!-- Disable the second-level cache -->
+ <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
+
+ <!-- Echo all executed SQL to stdout -->
+ <property name="show_sql">true</property>
+
+ <!-- Drop and re-create the database schema on startup -->
+ <property name="hbm2ddl.auto">create</property>
+
+ <mapping resource="events/Event.hbm.xml"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ Note que esta configuração XML usa um diferente DTD. Nós configuraremos
+ as <literal>SessionFactory</literal> do Hibernate – uma factory global responsável
+ por uma base de dedados particular. Se você tiver diversas bases de dados,
+ use diversas configurações <literal><session-factory></literal>, geralmente
+ em diversos arquivos de configuração (para uma partida mais fácil).
+ </para>
+
+ <para>
+ As primeiras quatro <literal>propriedades</literal> do elemento contém a configuração
+ necessária para a conexão ao JDBC. A propriedade <literal>propriedade</literal> dialect
+ do elemento especifica a variante particular do SQL que o Hibernate gera.
+ O gerenciamento automático de sessão do Hibernate para contextos de persistência
+ estará disponível em breve. A opção <literal>hbm2ddl.auto</literal> habilita a geração
+ automática de schemas da base de dados – diretamente na base de dados.
+ Isto também pode ser naturalmente desligado (removendo a opção de configuração) ou redirecionando
+ para um arquivo com ajuda do <literal>SchemaExport</literal> nas tarefas do Ant.
+ Finalmente, iremos adicionar os arquivos das classes de persistência mapeadas na configuração.
+ </para>
+
+ <para>
+ Copie este arquivo no diretório fonte, assim isto irá terminar na raiz (root) do
+ classpath. O Hibernate automaticamente procura por um arquivo chamado
+ <literal>hibernate.cfg.xml</literal> na raiz do classpath, no startup.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-ant" revision="1">
+ <title>Construindo com o Ant</title>
+
+ <para>
+ Nos iremos, agora, construir o tutorial com Ant. Você ira precisar o Ant instalado –
+ se encontra disponível <ulink url="http://ant.apache.org/bindownload.cgi">na página de download do Ant</ulink>.
+ Como instalar o Ant, não será abordado aqui. Caso tenha alguma dúvida, por favor,
+ vá ao <ulink url="http://ant.apache.org/manual/index.html">Ant manual</ulink>.
+ Depois que tiver instalado o Ant, podemos começar a criar o arquivo de construção <literal>build.xml</literal>.
+ Este arquivo será chamado de <literal>build.xml</literal> e posto diretamente no diretório de desenvolvimento.
+ </para>
+
+ <para>
+ Um arquivo básico de build, se parece com isto:
+ </para>
+
+ <programlisting><![CDATA[<project name="hibernate-tutorial" default="compile">
+
+ <property name="sourcedir" value="${basedir}/src"/>
+ <property name="targetdir" value="${basedir}/bin"/>
+ <property name="librarydir" value="${basedir}/lib"/>
+
+ <path id="libraries">
+ <fileset dir="${librarydir}">
+ <include name="*.jar"/>
+ </fileset>
+ </path>
+
+ <target name="clean">
+ <delete dir="${targetdir}"/>
+ <mkdir dir="${targetdir}"/>
+ </target>
+
+ <target name="compile" depends="clean, copy-resources">
+ <javac srcdir="${sourcedir}"
+ destdir="${targetdir}"
+ classpathref="libraries"/>
+ </target>
+
+ <target name="copy-resources">
+ <copy todir="${targetdir}">
+ <fileset dir="${sourcedir}">
+ <exclude name="**/*.java"/>
+ </fileset>
+ </copy>
+ </target>
+
+</project>]]></programlisting>
+
+ <para>
+ Isto irá avisar ao Ant para adicionar todos os arquivos no diretório lib terminando com
+ <literal>.jar</literal>, para o classpath usado para compilação. Irá também copiar todos os
+ arquivos não-java para o diretório alvo (arquivos de configuração, mapeamento). Se você rodar
+ o ant agora, deverá ter esta saída.
+ </para>
+
+ <programlisting><![CDATA[C:\hibernateTutorial\>ant
+Buildfile: build.xml
+
+copy-resources:
+ [copy] Copying 2 files to C:\hibernateTutorial\bin
+
+compile:
+ [javac] Compiling 1 source file to C:\hibernateTutorial\bin
+
+BUILD SUCCESSFUL
+Total time: 1 second ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-helpers" revision="3">
+ <title>Startup and helpers</title>
+
+ <para>
+ É hora de carregar e arquivar alguns objetos <literal>Event</literal>, mas primeiro
+ nós temos de completar o setup com algum código de infraestrutura. Este startup
+ inclui a construção de um objeto <literal>SessionFactory</literal> global e armazenar
+ isto em algum lugar de fácil acesso para o código da aplicação.
+ Uma <literal>SessionFactory</literal> pode abrir novas <literal>Session</literal>'s.
+ Uma <literal>Session</literal> representa uma unidade single-theaded do trabalho, a
+ <literal>SessionFactory</literal> é um objeto global thread-safe, instanciado uma vez.
+ </para>
+
+ <para>
+ Nos iremos criar uma classe de ajuda <literal>HibernateUtil</literal>, que toma
+ conta do startup e faz acesso a uma <literal>SessionFactory</literal> conveniente.
+ Vamos dar uma olhada na implementação:
+ </para>
+
+ <programlisting><![CDATA[package util;
+
+import org.hibernate.*;
+import org.hibernate.cfg.*;
+
+public class HibernateUtil {
+
+ private static final SessionFactory sessionFactory;
+
+ static {
+ try {
+ // Create the SessionFactory from hibernate.cfg.xml
+ sessionFactory = new Configuration().configure().buildSessionFactory();
+ } catch (Throwable ex) {
+ // Make sure you log the exception, as it might be swallowed
+ System.err.println("Initial SessionFactory creation failed." + ex);
+ throw new ExceptionInInitializerError(ex);
+ }
+ }
+
+ public static SessionFactory getSessionFactory() {
+ return sessionFactory;
+ }
+
+}]]></programlisting>
+
+ <para>
+ Esta classe não só produz a global <literal>SessionFactory</literal> no seu static initializer
+ (chamado uma vez pela JVM quando a classe é carregada), mas também esconde o fato
+ de que isto usa um static singleton. Ela pode muito bem, enxergar a
+ <literal>SessionFactory</literal> do JNDI em um application server.
+ </para>
+
+ <para>
+ Se você der à <literal>SessionFactory</literal> um nome, no seu arquivo de configuração.
+ O Hibernate irá, de fato, tentar uni-lo ao JNDI depois que estiver construído.
+ Para evitar este completamente este código, você também poderia usar JMX deployment
+ e deixar o contêiner JMX capaz, instanciar e unir um <literal>HibernateService</literal>
+ no JNDI. Essas opções avançadas são discutidas no documento de referência do Hibernate.
+ </para>
+
+ <para>
+ Coloque o Place <literal>HibernateUtil.java</literal> no diretório de arquivos
+ de desenvolvimento(source), em um pacote após o <literal>events</literal>:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java
+ Event.hbm.xml
+ +util
+ HibernateUtil.java
+ hibernate.cfg.xml
++data
+build.xml]]></programlisting>
+
+ <para>
+ Novamente, isto deve compilar sem problemas. Finalmente, nós precisamos configurar
+ um sistema de logging – o Hibernate usa commons logging e deixa você escolher entre o
+ Log4j e o logging do JDK 1.4 . A maioria dos desenvolvedores preferem o Log4j: copie
+ <literal>log4j.properties</literal> da distribuição do Hibernate (está no diretório
+ <literal>etc/</literal>), para seu diretório <literal>src</literal>,
+ depois vá em hibernate.cfg.xml. Dê uma olhada no exemplo de configuração e mude as
+ configurações se você quizer ter uma saída mais detalhada. Por default, apenas as
+ mensagems de startup e shwwn do Hibernate é mostrada no stdout.
+ </para>
+
+ <para>
+ O tutorial de infra-estrutura está completo - e nós já estamos preparados para algum
+ trabalho de verdade com o Hibernate.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-workingpersistence" revision="4">
+ <title>Carregando e salvando objetos</title>
+
+ <para>
+ Finalmente, nós podemos usar o Hibernate para carregar e armazenar objetos.
+ Nós escrevemos uma classe <literal>EventManager</literal> com um método main():
+ </para>
+
+ <programlisting><![CDATA[package events;
+import org.hibernate.Session;
+
+import java.util.Date;
+
+import util.HibernateUtil;
+
+public class EventManager {
+
+ public static void main(String[] args) {
+ EventManager mgr = new EventManager();
+
+ if (args[0].equals("store")) {
+ mgr.createAndStoreEvent("My Event", new Date());
+ }
+
+ HibernateUtil.getSessionFactory().close();
+ }
+
+ private void createAndStoreEvent(String title, Date theDate) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+ session.beginTransaction();
+
+ Event theEvent = new Event();
+ theEvent.setTitle(title);
+ theEvent.setDate(theDate);
+
+ session.save(theEvent);
+
+ session.getTransaction().commit();
+ }
+
+}]]></programlisting>
+
+ <para>
+ We create a new <literal>Event</literal> object, and hand it over to Hibernate.
+ Hibernate now takes care of the SQL and executes <literal>INSERT</literal>s
+ on the database. Let's have a look at the <literal>Session</literal> and
+ <literal>Transaction</literal>-handling code before we run this.
+
+ Nós criamos um novo objeto <literal>Event</literal>, e passamos para o Hibernate.
+ O Hibernate sabe como tomar conta do SQL e executa <literal>INSERT</literal>s
+ no banco de dados. Vamos dar uma olhada na <literal>Session</literal> e no
+ código <literal>Transaction</literal>-handling antes de executarmos.
+ </para>
+
+ <para>
+ Um <literal>Session</literal> é uma unidade simples de trabalho. Por agora nós
+ iremos pegar coisas simples e assumir uma granularidade de um-pra-um entre uma
+ <literal>Session</literal> do Hibernate e uma transação de banco de dados.
+ Para proteger nosso código de um atual sistema subjacente de transação (nesse
+ caso puro JDBC, mas também poderia rodar com JTA), nos usamos a API
+ <literal>Transaction</literal>, que está disponível na <literal>Session</literal> do Hibernate.
+ </para>
+
+ <para>
+ O que a <literal>sessionFactory.getCurrentSession()</literal> faz? Primeiro, você pode
+ chamar quantas vezes e de onde quiser, uma vez você recebe sua <literal>SessionFactory</literal>
+ (fácil graças ao <literal>HibernateUtil</literal>). O método <literal>getCurrentSession()</literal>
+ sempre retorna a unidade de trabalho "corrente". Lembra de que nós mudamos a opção
+ de configuração desse mecanismo para thread no <literal>hibernate.cfg.xml</literal>? Daqui em
+ diante, o escopo da unidade de trabalho corrente é a thread Java
+ corrente que executa nossa aplicação. Entretanto, esta não é toda a verdade. Uma
+ <literal>Session</literal> começa quando é primeiramente necessária, quando é feita a
+ primeira chamada à <literal>getCurrentSession()</literal>. É então limitado pelo Hibernate
+ para thread corrente. Quando a transação termina, tanto com commit quanto rollback,
+ o Hibernate também desune a <literal>Session</literal> da thread e fecha isso pra você.
+ Se você chamar <literal>getCurrentSession()</literal> novamente, você receberá uma nova
+ <literal>Session</literal> e pode começar uma nova unidade de trabalho. Esse modelo de
+ programação de limite de thread <emphasis>thread-bound</emphasis>, é o modo mais popular
+ de se usar o Hibernate.
+ </para>
+
+ <para>
+ Dê uma olhada no <xref linkend="transactions"/> para mais informações a
+ respeito de manipulação de transação e demarcação. Nós também pulamos qualquer
+ manipulação de erro e rollback no exemplo anterior.
+ </para>
+
+ <para>
+ Para executar esta primeira rotina, nos teremos que adicionar um ponto de chamada
+ para o arquivo de build do Ant:
+ </para>
+
+ <programlisting><![CDATA[<target name="run" depends="compile">
+ <java fork="true" classname="events.EventManager" classpathref="libraries">
+ <classpath path="${targetdir}"/>
+ <arg value="${action}"/>
+ </java>
+</target>]]></programlisting>
+
+ <para>
+ O valor do argumento <literal>action</literal>, é setado na linha de comando quando chamando esse ponto:
+ </para>
+
+ <programlisting><![CDATA[C:\hibernateTutorial\>ant run -Daction=store]]></programlisting>
+
+ <para>
+ Você deverá ver, após a compilação, o startup do Hibernate e, dependendo da sua
+ configuração, muito log de saída. No final você verá a seguinte linha:
+ </para>
+
+ <programlisting><![CDATA[[java] Hibernate: insert into EVENTS (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)]]></programlisting>
+
+ <para>
+ Este é o <literal>INSERT</literal> executado pelo Hibernate, os pontos de interrogação
+ representam parêmetros de união do JDBC. Para ver os valores substituídos, ou para diminuir a
+ verbalidade do log, check seu l<literal>log4j.properties</literal>.
+ </para>
+
+ <para>
+ Agora nós gostaríamos de listar os eventos arquivados, então nós adicionamos uma
+ opção para o método main:
+ </para>
+
+ <programlisting><![CDATA[if (args[0].equals("store")) {
+ mgr.createAndStoreEvent("My Event", new Date());
+}
+else if (args[0].equals("list")) {
+ List events = mgr.listEvents();
+ for (int i = 0; i < events.size(); i++) {
+ Event theEvent = (Event) events.get(i);
+ System.out.println("Event: " + theEvent.getTitle() +
+ " Time: " + theEvent.getDate());
+ }
+}]]></programlisting>
+
+ <para>
+ Nos também adicionamos um novo <literal>método listEvents()</literal>:
+ </para>
+
+ <programlisting><![CDATA[private List listEvents() {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+ session.beginTransaction();
+
+ List result = session.createQuery("from Event").list();
+
+ session.getTransaction().commit();
+
+ return result;
+}]]></programlisting>
+
+ <para>
+ O que nós fazemos aqui, é usar uma query HQL (Hibernate Query Language),
+ para carregar todos os objetos <literal>Event</literal> exitentes no banco de dados.
+ O Hibernate irá gerar o SQL apropriado, enviar para o banco de dados e popular objetos
+ <literal>Event</literal> com os dados. Você pode criar queries mais complexas com
+ HQL, claro.
+ </para>
+
+ <para>
+ Agora, para executar e testar tudo isso, siga os passos a seguir:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Execute <literal>ant run -Daction=store</literal> para armazenar algo no banco de dados
+ e, claro, gerar o esquema do banco de dados antes pelo hbm2ddl.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Agora desabilite hbm2ddl comentando a propriedade no seu arquivo <literal>hibernate.cfg.xml</literal>.
+ Normalmente só se deixa habilitado em teste unitários contínuos, mas outra carga de hbm2ddl
+ pode <emphasis>remover</emphasis> tudo que você já tenha arquivado. Sa configuração
+ <literal>create</literal>, atualmente são traduzidas para "apague todas as tabelas do esquema,
+ então recrie todas quando a SessionFactory estiver pronta".
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Se você agora chamar o Ant com <literal>-Daction=list</literal>, você deverá ver os
+ eventos que você acabou de criar. Você pode também chamar a ação <literal>store</literal>
+ mais algumas vezes.
+ </para>
+
+ <para>
+ Nota: A maioria dos novos usuários do Hibernate falha nesse ponto e nós regularmente, vemos
+ questões sobre mensagens de erro de <emphasis>tabela não encontrada </emphasis> .
+ Entretanto, se você seguir os passos marcados acima, você não terá esse problema,
+ com o hbm2ddl criando o esquema do banco de dados na primeira execução, e restarts
+ subsequentes da aplicação irão usar este esquema. Se você mudar o mapeamento e/ou
+ o esquema do banco de dados, terá de re-habilitar o hbm2ddl mais uma vez.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="tutorial-associations">
+ <title>Part 2 - Mapeando associações</title>
+
+ <para>
+ Nós mapeamos uma classe de entidade de persistência para uma tabela. Agora vamos continuar
+ e adicionar algumas associações de classe. Primeiro nos iremos adicionar pessoas a nossa aplicação,
+ e armazenar os eventos de que elas participam.
+ </para>
+
+ <sect2 id="tutorial-associations-mappinguser" revision="1">
+ <title>Mapeando a classe Person</title>
+
+ <para>
+ O primeiro código da classe <literal>Person</literal> é simples:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+public class Person {
+
+ private Long id;
+ private int age;
+ private String firstname;
+ private String lastname;
+
+ public Person() {}
+
+ // Accessor methods for all properties, private setter for 'id'
+
+}]]></programlisting>
+
+ <para>
+ Crie um novo arquivo de mapeamento, chamado <literal>Person.hbm.xml</literal> (não
+ esqueça a referencia ao DTD no topo)
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="native"/>
+ </id>
+ <property name="age"/>
+ <property name="firstname"/>
+ <property name="lastname"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Finalmente, adicione o novo mapeamento a configuração do Hibernate:
+ </para>
+
+ <programlisting><![CDATA[<mapping resource="events/Event.hbm.xml"/>
+<mapping resource="events/Person.hbm.xml"/>]]></programlisting>
+
+ <para>
+ Nos iremos agora criar uma associação entre estas duas entidades. Obviamente,
+ pessoas (Person) podem participar de eventos, e eventos possuem participantes.
+ As questões de design com que teremos de lidar são: direcionalidade, multiplicidade e
+ comportamento de coleção.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-unidirset" revision="3">
+ <title>Uma associação Set-based unidirectional</title>
+
+ <para>
+ Nos iremos adicionar uma coleção de eventos na classe <literal>Person</literal>. Desse jeito
+ poderemos navegar pelos eventos de uma pessoa em particular, sem executar uma query explicitamente –
+ apenas chamando <literal>aPerson.getEvents()</literal>. Nos usaremos uma coleção Java, um
+ <literal>Set</literal>, porquê a coleção não conterá elementos duplicados e a ordem não é
+ relevante para nós.
+ </para>
+
+ <para>
+ Vamos escrever o código para isto nas classes Java e então mapear:
+ </para>
+
+ <programlisting><![CDATA[public class Person {
+
+ private Set events = new HashSet();
+
+ public Set getEvents() {
+ return events;
+ }
+
+ public void setEvents(Set events) {
+ this.events = events;
+ }
+}]]></programlisting>
+
+ <para>
+ Antes de mapearmos esta associação, pense no outro lado. Claramente, poderíamos apenas fazer isto de
+ forma unidirecional. Ou poderíamos criar outra coleção no <literal>Event</literal>, se quisermos
+ ser capaz de navegar bidirecionalmente, i.e. um - <literal>anEvent.getParticipants()</literal>.
+ Isto não é necessário, de perspectiva funcional. Você poderia sempre executar uma query explicita
+ que retornasse os participantes de um evento em particular. Esta é uma escolha de design que cabe
+ a você, mas o que é claro nessa discussão é a multiplicidade da associação: "muitos" valores em ambos
+ os lados, nós chamamos isto uma associação <emphasis>muitos-para-muitos</emphasis>. Daqui pra frente,
+ nos usaremos o mapeamento muitos-para-muitos do Hibernate:
+ </para>
+
+ <programlisting><![CDATA[<class name="events.Person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="native"/>
+ </id>
+ <property name="age"/>
+ <property name="firstname"/>
+ <property name="lastname"/>
+
+ <set name="events" table="PERSON_EVENT">
+ <key column="PERSON_ID"/>
+ <many-to-many column="EVENT_ID" class="events.Event"/>
+ </set>
+
+</class>]]></programlisting>
+
+ <para>
+ O Hibernate suporta todo tipo de mapeamento de coleção , sendo um <literal><set></literal> mais comum.
+ Para uma associação muitos-para-muitos (ou relacionamento de entidade <emphasis>n:m</emphasis> ),
+ uma tabela de associação é necessária. Cada linha nessa tabela representa um link entre uma pessoa e um
+ evento. O nome da tabela é configurado com o atributo <literal>table</literal> do elemento
+ <literal>set</literal>. O nome da coluna identificadora na associção, peloo lado da pessoa,
+ é definido com o elemento <literal><key></literal> , o nome da coluna pelo lado dos eventos,
+ e definido com o atributo <literal>column</literal> do <literal><many-to-many></literal>.
+ Você também precisa dizer para o Hibernate a classe dos objetos na sua coleção (a classe do outro
+ lado das coleções de referência).
+ </para>
+
+ <para>
+ O esquema de mapeamento para o banco de dados está a seguir:
+ </para>
+
+ <programlisting><![CDATA[
+ _____________ __________________
+ | | | | _____________
+ | EVENTS | | PERSON_EVENT | | |
+ |_____________| |__________________| | PERSON |
+ | | | | |_____________|
+ | *EVENT_ID | <--> | *EVENT_ID | | |
+ | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID |
+ | TITLE | |__________________| | AGE |
+ |_____________| | FIRSTNAME |
+ | LASTNAME |
+ |_____________|
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-working" revision="1">
+ <title>Trabalhando a associação</title>
+
+ <para>
+ Vamos trazer juntos algumas pessoas e eventos em um novo método na classe <literal>EventManager</literal>::
+ </para>
+
+ <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session.load(Person.class, personId);
+ Event anEvent = (Event) session.load(Event.class, eventId);
+
+ aPerson.getEvents().add(anEvent);
+
+ session.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ Após carregar um <literal>Person</literal> e um <literal>Event</literal>, simplesmente
+ modifique a coleção usando os métodos normais de uma coleção. Como você pode ver, não há chamada explícita
+ para <literal>update()</literal> ou <literal>save()</literal>, o Hibernate detecta automaticamente
+ que a coleção foi modificada e necessita ser atualizada. Isso é chamado de <emphasis>checagem
+ suja automática</emphasis>, e você também pode usá-la modificando o nome ou a data de qualquer um dos
+ seus objetos. Assim que eles estiverem no estado <emphasis>persistent</emphasis>, ou seja,
+ limitado por uma <literal>Session</literal> do Hibernate em particular (i.e. eles foram carregados ou
+ salvos dentro de uma unidade de trabalho), o Hibernate monitora qualquer alteração e executa o SQL
+ em modo de escrita em segundo plano. O processo de sincronização do estado da memória com o banco de
+ dados, geralmente apenas no final de uma unidade de trabalho, é chamado de <emphasis>flushing</emphasis>.
+ No nosso código, a unidade de trabalho termina com o commit da transação do banco de dados –
+ como definido pela opção de configuração da <literal>thread</literal> da classe <literal>CurrentSessionContext</literal>.
+ </para>
+
+ <para>
+ Você pode também querer carregar pessoas e eventos em diferentes unidades de trabalho.
+ Ou você modifica um objeto fora de uma <literal>Session</literal>, quando não se encontra no
+ estado persistent (se já esteve neste estado anteriormente, chamamos esse estado de
+ <emphasis>detached</emphasis>). Você pode até mesmo modificar uma coleção quando esta
+ se encontrar no estado detached.
+ </para>
+
+ <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session
+ .createQuery("select p from Person p left join fetch p.events where p.id = :pid")
+ .setParameter("pid", personId)
+ .uniqueResult(); // Eager fetch the collection so we can use it detached
+
+ Event anEvent = (Event) session.load(Event.class, eventId);
+
+ session.getTransaction().commit();
+
+ // End of first unit of work
+
+ aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached
+
+ // Begin second unit of work
+
+ Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
+ session2.beginTransaction();
+
+ session2.update(aPerson); // Reattachment of aPerson
+
+ session2.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ A chamada <literal>update</literal> cria um objeto persistent novamente, você poderia
+ dizer que ele liga o objeto a uma nova unidade de trabalho, assim qualquer modificação
+ que você faça neste objeto enquanto estiver no estado detached pode ser salvo no banco de dados.
+ Isso inclui qualquer modificação (adição/exclusão) que você faça em uma coleção da entidade deste objeto.
+ </para>
+
+ <para>
+ Bom, isso não foi muito usado na nossa situação, porém, é um importante conceito que você
+ pode aplicar em seus aplicativos. Agora, complete este exercício adicionando uma nova ação
+ ao método main( ) da classe <literal>EventManager</literal> e chame-o pela linha de comando.
+ Se você precisar dos identificadores de uma pessoa ou evento – o método <literal>save()</literal>
+ retorna estes identificadores (você poderá modificar alguns dos métodos anteriores para retornar aquele
+ identificador):
+ </para>
+
+ <programlisting><![CDATA[else if (args[0].equals("addpersontoevent")) {
+ Long eventId = mgr.createAndStoreEvent("My Event", new Date());
+ Long personId = mgr.createAndStorePerson("Foo", "Bar");
+ mgr.addPersonToEvent(personId, eventId);
+ System.out.println("Added person " + personId + " to event " + eventId);]]></programlisting>
+
+ <para>
+ Este foi um exemplo de uma associação entre duas classes igualmente importantes, duas entidades.
+ Como mencionado anteriormente, há outras classes e tipos dentro de um modelo típico,
+ geralmente "menos importante". Alguns você já viu, como um <literal>int</literal> ou uma <literal>String</literal>.
+ Nós chamamos essas classes de <emphasis>value types</emphasis>, e suas instâncias <emphasis>depend</emphasis>
+ de uma entidade particular. As instâncias desses tipos não possuem sua própria identidade, nem são
+ compartilhados entre entidades (duas pessoas não referenciam o mesmo objeto <literal>firstname</literal>
+ mesmo se elas tiverem o mesmo objeto firstname). Naturalmente, os value types não são apenas encontrados
+ dentro da JDK (de fato, em um aplicativo Hibernate todas as classes JDK são consideradas como value types),
+ mas você pode também criar suas classes como, por exemplo, <literal>Address</literal> ou <literal>MonetaryAmount</literal>.
+
+ </para>
+
+ <para>
+ Você também pode criar uma coleção de value types. Isso é conceitualmente muito diferente
+ de uma coleção de referências para outras entidades, mas em Java parece ser quase a mesma coisa.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-valuecollections">
+ <title>Coleção de valores</title>
+
+ <para>
+ Nós adicionamos uma coleção de objetos de tipo de valores à entidade <literal>Person</literal.
+ Nós querermos armazenar endereços de e-mail, para isso utilizamos o tipo <literal>String</literal>,
+ e a coleção novamente será um <literal>Set</literal>:
+ </para>
+ <programlisting><![CDATA[private Set emailAddresses = new HashSet();
+
+public Set getEmailAddresses() {
+ return emailAddresses;
+}
+
+public void setEmailAddresses(Set emailAddresses) {
+ this.emailAddresses = emailAddresses;
+}]]></programlisting>
+
+ <para>
+ O mapeamento deste <literal>Set</literal>:
+ </para>
+
+ <programlisting><![CDATA[<set name="emailAddresses" table="PERSON_EMAIL_ADDR">
+ <key column="PERSON_ID"/>
+ <element type="string" column="EMAIL_ADDR"/>
+</set>]]></programlisting>
+
+ <para>
+ The difference compared with the earlier mapping is the <literal>element</literal> part, which tells Hibernate that the collection
+ does not contain references to another entity, but a collection of elements of type
+ <literal>String</literal> (the lowercase name tells you it's a Hibernate mapping type/converter).
+ Once again, the <literal>table</literal> attribute of the <literal>set</literal> element determines
+ the table name for the collection. The <literal>key</literal> element defines the foreign-key column
+ name in the collection table. The <literal>column</literal> attribute in the <literal>element</literal>
+ element defines the column name where the <literal>String</literal> values will actually be stored.
+
+ A diferença comparada com o mapeamento anterior se encontra na parte <literal>element</literal>,
+ que indica ao Hibernate que a coleção não contém referências à outra entidade, mas uma coleção de
+ elementos do tipo <literal>String</literal> (a tag name em miniscula indica que se trata de um
+ mapeamento do Hibernate para conversão de tipos). Mais uma vez, o atributo <literal>table</literal>
+ do elemento <literal>set</literal> determina o nome da tabela para a coleção. O elemento
+ <literal>key</literal> define o nome da coluna de chave estrangeira na tabela de coleção.
+ O atributo <literal>column</literal> dentro do elemento <literal>element</literal> define o
+ nome da coluna onde os valores da <literal>String</literal> serão armazenados.
+ </para>
+
+ <para>
+ Dê uma olhada no esquema atualizado:
+ </para>
+
+ <programlisting><![CDATA[
+ _____________ __________________
+ | | | | _____________
+ | EVENTS | | PERSON_EVENT | | | ___________________
+ |_____________| |__________________| | PERSON | | |
+ | | | | |_____________| | PERSON_EMAIL_ADDR |
+ | *EVENT_ID | <--> | *EVENT_ID | | | |___________________|
+ | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID | <--> | *PERSON_ID |
+ | TITLE | |__________________| | AGE | | *EMAIL_ADDR |
+ |_____________| | FIRSTNAME | |___________________|
+ | LASTNAME |
+ |_____________|
+ ]]></programlisting>
+
+ <para>
+ Você pode observar que a chave primária da tabela da coleção é de na verdade uma chave composta,
+ usando ambas colunas. Isso também implica que cada pessoa não pode ter endereços de e-mail
+ duplicados, o que é exatamente a semântica que precisamos para um set em Java.
+ </para>
+
+ <para>
+ Você pode agora tentar adicionar elementos a essa coleção, do mesmo modo que fizemos
+ anteriormente ligando pessoas e eventos. È o mesmo código em Java:
+ </para>
+
+ <programlisting><![CDATA[private void addEmailToPerson(Long personId, String emailAddress) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session.load(Person.class, personId);
+
+ // The getEmailAddresses() might trigger a lazy load of the collection
+ aPerson.getEmailAddresses().add(emailAddress);
+
+ session.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ This time we didnt' use a <emphasis>fetch</emphasis> query to initialize the collection.
+ Hence, the call to its getter method will trigger an additional select to initialize
+ it, so we can add an element to it. Monitor the SQL log and try to optimize this with
+ an eager fetch.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-bidirectional" revision="1">
+ <title>Associações bidirecionais</title>
+
+ <para>
+ Agora iremos mapear uma associação bidirecional – fazendo a associação entre pessoas e
+ eventos, de ambos os lados, em Java. Logicamente, o esquema do banco de dados não muda,
+ nós continuamos tendo multiplicidades muitos-para-muitos. Um banco de dados é mais flexível do que
+ uma linguagem de programação para redes, ele não precisa de nenhuma direção de navegação – os
+ dados podem ser acessados em qualquer caminho possível.
+ </para>
+
+ <para>
+ Primeiramente, adicione uma coleção de participantes à classe <literal>Event</literal>:
+ </para>
+
+ <programlisting><![CDATA[private Set participants = new HashSet();
+
+public Set getParticipants() {
+ return participants;
+}
+
+public void setParticipants(Set participants) {
+ this.participants = participants;
+}]]></programlisting>
+
+ <para>
+ Agora mapeie este lado da associação em <literal>Event.hbm.xml</literal>.
+ </para>
+
+ <programlisting><![CDATA[<set name="participants" table="PERSON_EVENT" inverse="true">
+ <key column="EVENT_ID"/>
+ <many-to-many column="PERSON_ID" class="events.Person"/>
+</set>]]></programlisting>
+
+ <para>
+ Como você pode ver, esses é uma mapeamento normal usando <literal>set</literal> em ambos documenentos
+ de mapeamento. Observe que o nome das colunas em <literal>key</literal> e <literal>many-to-many</literal>
+ estão trocados em ambos os documentos de mapeamento. A adição mais importante feita está no atributo
+ <literal>inverse="true"</literal> no elemento set do mapeamento da coleção da classe <literal>Event</literal>.
+ </para>
+
+ <para>
+ Isso significa que o Hibernate deve pegar o outro lado – a classe <literal>Person</literal> –
+ quando necessitar encontrar informação sobre a relação entre as duas entidades. Isso será muito
+ mais facilmente compreendido quando você analisar como a relação bidirecional entre as entidades é criada.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-usingbidir">
+ <title>Trabalhando com links bidirecionais</title>
+
+ <para>
+ Primeiro tenha em mente que o Hibernate não afeta a semântica normal do Java. Como nós criamos
+ um link entre uma <literal>Person</literal> e um <literal>Event</literal> no exemplo unidirecional?
+ Nós adicionamos uma instância de <literal>Event</literal>, da coleção de referências de eventos,
+ a uma instância de <literal>Person</literal>. Então, obviamente, se nós queremos que este link funcione
+ bidirecionalmente, nós devemos fazer a mesma coisa para o outro lado – adicionando uma referência de
+ <literal>Person</literal> na coleção de um <literal>Event</literal>. Esse acerto de link de ambos
+ os lados é absolutamente necessário e você nunca deve esquecer de faze-lo.
+ </para>
+
+ <para>
+ Muitos desenvolvedores programam de maneira defensiva e criam métodos
+ gerenciador de links que ajusta corretamente ambos os lados:
+ </para>
+
+ <programlisting><![CDATA[protected Set getEvents() {
+ return events;
+}
+
+protected void setEvents(Set events) {
+ this.events = events;
+}
+
+public void addToEvent(Event event) {
+ this.getEvents().add(event);
+ event.getParticipants().add(this);
+}
+
+public void removeFromEvent(Event event) {
+ this.getEvents().remove(event);
+ event.getParticipants().remove(this);
+}]]></programlisting>
+
+ <para>
+ Notice that the get and set methods for the collection are now protected - this allows classes in the
+ same package and subclasses to still access the methods, but prevents everybody else from messing
+ with the collections directly (well, almost). You should probably do the same with the collection
+ on the other side.
+ </para>
+
+ <para>
+ What about the <literal>inverse</literal> mapping attribute? For you, and for Java, a bi-directional
+ link is simply a matter of setting the references on both sides correctly. Hibernate however doesn't
+ have enough information to correctly arrange SQL <literal>INSERT</literal> and <literal>UPDATE</literal>
+ statements (to avoid constraint violations), and needs some help to handle bi-directional associations
+ properly. Making one side of the association <literal>inverse</literal> tells Hibernate to basically
+ ignore it, to consider it a <emphasis>mirror</emphasis> of the other side. That's all that is necessary
+ for Hibernate to work out all of the issues when transformation a directional navigation model to
+ a SQL database schema. The rules you have to remember are straightforward: All bi-directional associations
+ need one side as <literal>inverse</literal>. In a one-to-many association it has to be the many-side,
+ in many-to-many association you can pick either side, there is no difference.
+ </para>
+
+ </sect2>
+
+ <para>
+ Let's turn this into a small web application.
+ </para>
+
+ </sect1>
+
+ <sect1 id="tutorial-webapp">
+ <title>Part 3 - The EventManager web application</title>
+
+ <para>
+ A Hibernate web application uses <literal>Session</literal> and <literal>Transaction</literal>
+ almost like a standalone application. However, some common patterns are useful. We now write
+ an <literal>EventManagerServlet</literal>. This servlet can list all events stored in the
+ database, and it provides an HTML form to enter new events.
+ </para>
+
+ <sect2 id="tutorial-webapp-servlet" revision="1">
+ <title>Writing the basic servlet</title>
+
+ <para>
+ Create a new class in your source directory, in the <literal>events</literal>
+ package:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+// Imports
+
+public class EventManagerServlet extends HttpServlet {
+
+ // Servlet code
+}]]></programlisting>
+
+ <para>
+ The servlet handles HTTP <literal>GET</literal> requests only, hence, the method
+ we implement is <literal>doGet()</literal>:
+ </para>
+
+ <programlisting><![CDATA[protected void doGet(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+
+ SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");
+
+ try {
+ // Begin unit of work
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().beginTransaction();
+
+ // Process request and render page...
+
+ // End unit of work
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().getTransaction().commit();
+
+ } catch (Exception ex) {
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().getTransaction().rollback();
+ throw new ServletException(ex);
+ }
+
+}]]></programlisting>
+
+ <para>
+ The pattern we are applying here is called <emphasis>session-per-request</emphasis>.
+ When a request hits the servlet, a new Hibernate <literal>Session</literal> is
+ opened through the first call to <literal>getCurrentSession()</literal> on the
+ <literal>SessionFactory</literal>. Then a database transaction is started—all
+ data access as to occur inside a transaction, no matter if data is read or written
+ (we don't use the auto-commit mode in applications).
+ </para>
+
+ <para>
+ Next, the possible actions of the request are processed and the response HTML
+ is rendered. We'll get to that part soon.
+ </para>
+
+ <para>
+ Finally, the unit of work ends when processing and rendering is complete. If any
+ problem occured during processing or rendering, an exception will be thrown
+ and the database transaction rolled back. This completes the
+ <literal>session-per-request</literal> pattern. Instead of the transaction
+ demarcation code in every servlet you could also write a servlet filter.
+ See the Hibernate website and Wiki for more information about this pattern,
+ called <emphasis>Open Session in View</emphasis>—you'll need it as soon
+ as you consider rendering your view in JSP, not in a servlet.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-webapp-processing" revision="1">
+ <title>Processing and rendering</title>
+
+ <para>
+ Let's implement the processing of the request and rendering of the page.
+ </para>
+
+<programlisting><![CDATA[// Write HTML header
+PrintWriter out = response.getWriter();
+out.println("<html><head><title>Event Manager</title></head><body>");
+
+// Handle actions
+if ( "store".equals(request.getParameter("action")) ) {
+
+ String eventTitle = request.getParameter("eventTitle");
+ String eventDate = request.getParameter("eventDate");
+
+ if ( "".equals(eventTitle) || "".equals(eventDate) ) {
+ out.println("<b><i>Please enter event title and date.</i></b>");
+ } else {
+ createAndStoreEvent(eventTitle, dateFormatter.parse(eventDate));
+ out.println("<b><i>Added event.</i></b>");
+ }
+}
+
+// Print page
+printEventForm(out);
+listEvents(out, dateFormatter);
+
+// Write HTML footer
+out.println("</body></html>");
+out.flush();
+out.close();]]></programlisting>
+
+ <para>
+ Granted, this coding style with a mix of Java and HTML would not scale
+ in a more complex application—keep in mind that we are only illustrating
+ basic Hibernate concepts in this tutorial. The code prints an HTML
+ header and a footer. Inside this page, an HTML form for event entry and
+ a list of all events in the database are printed. The first method is
+ trivial and only outputs HTML:
+ </para>
+
+ <programlisting><![CDATA[private void printEventForm(PrintWriter out) {
+ out.println("<h2>Add new event:</h2>");
+ out.println("<form>");
+ out.println("Title: <input name='eventTitle' length='50'/><br/>");
+ out.println("Date (e.g. 24.12.2009): <input name='eventDate' length='10'/><br/>");
+ out.println("<input type='submit' name='action' value='store'/>");
+ out.println("</form>");
+}]]></programlisting>
+
+ <para>
+ The <literal>listEvents()</literal> method uses the Hibernate
+ <literal>Session</literal> bound to the current thread to execute
+ a query:
+ </para>
+
+ <programlisting><![CDATA[private void listEvents(PrintWriter out, SimpleDateFormat dateFormatter) {
+
+ List result = HibernateUtil.getSessionFactory()
+ .getCurrentSession().createCriteria(Event.class).list();
+ if (result.size() > 0) {
+ out.println("<h2>Events in database:</h2>");
+ out.println("<table border='1'>");
+ out.println("<tr>");
+ out.println("<th>Event title</th>");
+ out.println("<th>Event date</th>");
+ out.println("</tr>");
+ for (Iterator it = result.iterator(); it.hasNext();) {
+ Event event = (Event) it.next();
+ out.println("<tr>");
+ out.println("<td>" + event.getTitle() + "</td>");
+ out.println("<td>" + dateFormatter.format(event.getDate()) + "</td>");
+ out.println("</tr>");
+ }
+ out.println("</table>");
+ }
+}]]></programlisting>
+
+ <para>
+ Finally, the <literal>store</literal> action is dispatched to the
+ <literal>createAndStoreEvent()</literal> method, which also uses
+ the <literal>Session</literal> of the current thread:
+ </para>
+
+ <programlisting><![CDATA[protected void createAndStoreEvent(String title, Date theDate) {
+ Event theEvent = new Event();
+ theEvent.setTitle(title);
+ theEvent.setDate(theDate);
+
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().save(theEvent);
+}]]></programlisting>
+
+ <para>
+ That's it, the servlet is complete. A request to the servlet will be processed
+ in a single <literal>Session</literal> and <literal>Transaction</literal>. As
+ earlier in the standalone application, Hibernate can automatically bind these
+ ojects to the current thread of execution. This gives you the freedom to layer
+ your code and access the <literal>SessionFactory</literal> in any way you like.
+ Usually you'd use a more sophisticated design and move the data access code
+ into data access objects (the DAO pattern). See the Hibernate Wiki for more
+ examples.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-webapp-deploy">
+ <title>Deploying and testing</title>
+
+ <para>
+ To deploy this application you have to create a web archive, a WAR. Add the
+ following Ant target to your <literal>build.xml</literal>:
+ </para>
+
+<programlisting><![CDATA[<target name="war" depends="compile">
+ <war destfile="hibernate-tutorial.war" webxml="web.xml">
+ <lib dir="${librarydir}">
+ <exclude name="jsdk*.jar"/>
+ </lib>
+
+ <classes dir="${targetdir}"/>
+ </war>
+</target>]]></programlisting>
+
+ <para>
+ This target creates a file called <literal>hibernate-tutorial.war</literal>
+ in your project directory. It packages all libraries and the <literal>web.xml</literal>
+ descriptor, which is expected in the base directory of your project:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4"
+ xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+ <servlet>
+ <servlet-name>Event Manager</servlet-name>
+ <servlet-class>events.EventManagerServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Event Manager</servlet-name>
+ <url-pattern>/eventmanager</url-pattern>
+ </servlet-mapping>
+</web-app>]]></programlisting>
+
+ <para>
+ Before you compile and deploy the web application, note that an additional library
+ is required: <literal>jsdk.jar</literal>. This is the Java servlet development kit,
+ if you don't have this library already, get it from the Sun website and copy it to
+ your library directory. However, it will be only used for compliation and excluded
+ from the WAR package.
+ </para>
+
+ <para>
+ To build and deploy call <literal>ant war</literal> in your project directory
+ and copy the <literal>hibernate-tutorial.war</literal> file into your Tomcat
+ <literal>webapp</literal> directory. If you don't have Tomcat installed, download
+ it and follow the installation instructions. You don't have to change any Tomcat
+ configuration to deploy this application though.
+ </para>
+
+ <para>
+ Once deployed and Tomcat is running, access the application at
+ <literal>http://localhost:8080/hibernate-tutorial/eventmanager</literal>. Make
+ sure you watch the Tomcat log to see Hibernate initialize when the first
+ request hits your servlet (the static initializer in <literal>HibernateUtil</literal>
+ is called) and to get the detailed output if any exceptions occurs.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="tutorial-summary" revision="1">
+ <title>Summary</title>
+
+ <para>
+ This tutorial covered the basics of writing a simple standalone Hibernate application
+ and a small web application.
+ </para>
+
+ <para>
+ If you already feel confident with Hibernate, continue browsing through the reference
+ documentation table of contents for topics you find interesting - most asked are
+ transactional processing (<xref linkend="transactions"/>), fetch
+ performance (<xref linkend="performance"/>), or the usage of the API (<xref linkend="objectstate"/>)
+ and the query features (<xref linkend="objectstate-querying"/>).
+ </para>
+
+ <para>
+ Don't forget to check the Hibernate website for more (specialized) tutorials.
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/xml.xml (from rev 12794, core/trunk/documentation/manual/pt-BR/src/main/docbook/modules/xml.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/xml.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/xml.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,289 @@
+<chapter id="xml">
+ <title>Mapeamento XML</title>
+
+ <para><emphasis>
+ Note that this is an experimental feature in Hibernate 3.0 and is under
+ extremely active development.
+ Veja que essa é uma feature experimental no Hibernate 3.0 e o
+ desenvolvimento esta bastante ativo.
+
+ </emphasis></para>
+
+ <sect1 id="xml-intro" revision="1">
+ <title>Trabalhando com dados em XML</title>
+
+ <para>
+ O Hibernate permite que se trabalhe com dados persistentes em XML quase
+ da mesma maneira como você trabalhar com POJOs persistentes. Uma árvore XML
+ parseada, pode ser imaginada como apenas uma maneira de representar os
+ dados relacionais como objetos, ao invés dos POJOs.
+ </para>
+
+ <para>
+ O Hibernate suporta a API dom4j para manipular árvores XML. Você pode escrever
+ queries que retornem árvores dom4j do banco de dados e automaticamente
+ sincronizar com o banco de dados qualquer modificação feita nessas árvores.
+ Você pode até mesmo pegar um documento XML, parsear usando o dom4j, e escrever
+ as alterações no banco de dados usando quaisquer operações básicas do Hibernate:
+ <literal>persist(), saveOrUpdate(),merge(), delete(), replicate()</literal>
+ (merging ainda não é suportado)
+ </para>
+
+ <para>
+ Essa funcionalidade tem várias aplicações incluindo importação/exportação de dados,
+ externalização de dados de entidade via JMS or SOAP e relatórios usando XSLT.
+ </para>
+
+ <para>
+ Um mapeamento simples pode ser usado para simultaneamente mapear propriedades
+ da classe e nós de um documento XML para um banco de dados ou, se não houver
+ classe para mapear, pode ser usado simplesmente para mapear o XML.
+ </para>
+
+ <sect2 id="xml-intro-mapping">
+ <title>Especificando o mapeamento de uma classe e de um arquivo XML simultaneamente</title>
+
+ <para>
+ Segue um exemplo de como mapear um POJO e um XML ao mesmo tempo:
+ </para>
+
+ <programlisting><![CDATA[<class name="Account"
+ table="ACCOUNTS"
+ node="account">
+
+ <id name="accountId"
+ column="ACCOUNT_ID"
+ node="@id"/>
+
+ <many-to-one name="customer"
+ column="CUSTOMER_ID"
+ node="customer/@id"
+ embed-xml="false"/>
+
+ <property name="balance"
+ column="BALANCE"
+ node="balance"/>
+
+ ...
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="xml-onlyxml">
+ <title>Especificando somente um mapeamento XML</title>
+
+ <para>
+ Segue um exemplo que não contém uma classe POJO:
+ </para>
+
+ <programlisting><![CDATA[<class entity-name="Account"
+ table="ACCOUNTS"
+ node="account">
+
+ <id name="id"
+ column="ACCOUNT_ID"
+ node="@id"
+ type="string"/>
+
+ <many-to-one name="customerId"
+ column="CUSTOMER_ID"
+ node="customer/@id"
+ embed-xml="false"
+ entity-name="Customer"/>
+
+ <property name="balance"
+ column="BALANCE"
+ node="balance"
+ type="big_decimal"/>
+
+ ...
+
+</class>]]></programlisting>
+
+ <para>
+ Esse mapeamento permite que você acesse os dados como uma árvore dom4j ou um
+ grafo de de pares nome de propriedade/valor (<literal>Map</literal>s do Java).
+ Os nomes de propriedades são somente construções lógicas que podem ser
+ referenciadas em consultas HQL.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="xml-mapping" revision="1">
+ <title>Mapeando metadados com XML</title>
+
+ <para>
+ Muitos elementos do mapeamento do Hibernate aceitam o atributo <literal>node</literal>.
+ Por meio dele, você pode especificar o nome de um atributo ou elemento XML que contém
+ a propriedade ou os dados da entidade. O formato do atributo <literal>node</literal>
+ deve ser o seguinte:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>"element-name"</literal> - mapeia para o elemento XML com determinado nome</para>
+ </listitem>
+ <listitem>
+ <para><literal>"@attribute-name"</literal> - mapeia para o atributo XML com determinado nome</para>
+ </listitem>
+ <listitem>
+ <para><literal>"."</literal> - mapeia para o elemento pai</para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>"element-name/@attribute-name"</literal> -
+ mapeia para para o atributo com determinado nome do elemento com determinado nome
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Para coleções e associações simples, existe o atributo adicional <literal>embed-xml</literal>.
+ Se o atributo <literal>embed-xml="true"</literal>, que é o valor padrão, a árvore XML para a
+ entidade associada (ou coleção de determinado tipo de valor) será embutida diretamente na
+ árvore XML que contém a associação. Por outro lado, se <literal>embed-xml="false"</literal>,
+ então apenas o valor do identificador referenciado irá aparecer no XML para associações
+ simples e coleções simplesmentenão irão aparecer.
+ </para>
+
+ <para>
+ Você precisa tomar cuidado em não deixar o<literal>embed-xml="true"</literal>
+ para muitas associações, pois o XML não suporta bem referências circulares.
+ </para>
+
+ <programlisting><![CDATA[<class name="Customer"
+ table="CUSTOMER"
+ node="customer">
+
+ <id name="id"
+ column="CUST_ID"
+ node="@id"/>
+
+ <map name="accounts"
+ node="."
+ embed-xml="true">
+ <key column="CUSTOMER_ID"
+ not-null="true"/>
+ <map-key column="SHORT_DESC"
+ node="@short-desc"
+ type="string"/>
+ <one-to-many entity-name="Account"
+ embed-xml="false"
+ node="account"/>
+ </map>
+
+ <component name="name"
+ node="name">
+ <property name="firstName"
+ node="first-name"/>
+ <property name="initial"
+ node="initial"/>
+ <property name="lastName"
+ node="last-name"/>
+ </component>
+
+ ...
+
+</class>]]></programlisting>
+
+ <para>
+ Nesse caso, decidimos embutir a colenção de account ids, e não os dados de accounts.
+ A query HQL a seguir:
+ </para>
+
+ <programlisting><![CDATA[from Customer c left join fetch c.accounts where c.lastName like :lastName]]></programlisting>
+
+ <para>
+ Retornaria um conjunto de dados como esse:
+ </para>
+
+ <programlisting><![CDATA[<customer id="123456789">
+ <account short-desc="Savings">987632567</account>
+ <account short-desc="Credit Card">985612323</account>
+ <name>
+ <first-name>Gavin</first-name>
+ <initial>A</initial>
+ <last-name>King</last-name>
+ </name>
+ ...
+</customer>]]></programlisting>
+
+ <para>
+ Se você setar <literal>embed-xml="true"</literal> em um mapeamento
+ <literal><one-to-many></literal>, os dados se pareceriam com o seguinte:
+ </para>
+
+ <programlisting><![CDATA[<customer id="123456789">
+ <account id="987632567" short-desc="Savings">
+ <customer id="123456789"/>
+ <balance>100.29</balance>
+ </account>
+ <account id="985612323" short-desc="Credit Card">
+ <customer id="123456789"/>
+ <balance>-2370.34</balance>
+ </account>
+ <name>
+ <first-name>Gavin</first-name>
+ <initial>A</initial>
+ <last-name>King</last-name>
+ </name>
+ ...
+</customer>]]></programlisting>
+
+ </sect1>
+
+
+ <sect1 id="xml-manipulation" revision="1">
+ <title>Manipulando dados em XML</title>
+
+ <para>
+ Vamos reler e atualizar documentos em XML em nossa aplicação. Nós fazemos isso
+ obtendo uma session do dom4j:
+ </para>
+
+ <programlisting><![CDATA[Document doc = ....;
+
+Session session = factory.openSession();
+Session dom4jSession = session.getSession(EntityMode.DOM4J);
+Transaction tx = session.beginTransaction();
+
+List results = dom4jSession
+ .createQuery("from Customer c left join fetch c.accounts where c.lastName like :lastName")
+ .list();
+for ( int i=0; i<results.size(); i++ ) {
+ //add the customer data to the XML document
+ Element customer = (Element) results.get(i);
+ doc.add(customer);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <programlisting><![CDATA[Session session = factory.openSession();
+Session dom4jSession = session.getSession(EntityMode.DOM4J);
+Transaction tx = session.beginTransaction();
+
+Element cust = (Element) dom4jSession.get("Customer", customerId);
+for ( int i=0; i<results.size(); i++ ) {
+ Element customer = (Element) results.get(i);
+ //change the customer name in the XML and database
+ Element name = customer.element("name");
+ name.element("first-name").setText(firstName);
+ name.element("initial").setText(initial);
+ name.element("last-name").setText(lastName);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ É extremamente útil combinar essa funcionalidade com a operação <literal>replicate()</literal>
+ do Hibernate para implementar importação/exportação baseadas em XML.
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/AuthorWork.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/AuthorWork.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/AuthorWork.zargo (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/AuthorWork.zargo)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/CustomerOrderProduct.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/CustomerOrderProduct.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/CustomerOrderProduct.zargo (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/CustomerOrderProduct.zargo)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/EmployerEmployee.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/EmployerEmployee.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/EmployerEmployee.zargo (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/EmployerEmployee.zargo)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/full_cream.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/full_cream.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/full_cream.svg (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/full_cream.svg)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/images/full_cream.svg (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/images/full_cream.svg 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,429 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="354.331"
+ height="336.614"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,5.25349)"
+ style="font-size:12;"
+ id="g659">
+ <rect
+ width="212.257"
+ height="57.2441"
+ x="17.9576"
+ y="100.132"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ transform="matrix(0.743454,0,0,0.482981,6.46949,52.2178)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <rect
+ width="325.86"
+ height="63.6537"
+ x="17.4083"
+ y="15.194"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="325.86"
+ height="63.6537"
+ x="13.6713"
+ y="12.4966"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ <g
+ transform="matrix(1.14345,0,0,0.729078,-1.67818,105.325)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <text
+ x="170.824753"
+ y="58.402939"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="170.824997"
+ y="58.402901"
+ id="tspan360">
+Application</tspan>
+ </text>
+ <text
+ x="178.076340"
+ y="364.281433"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="178.076004"
+ y="364.281006"
+ id="tspan421">
+Database</tspan>
+ </text>
+ <text
+ x="68.605331"
+ y="138.524582"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="68.605301"
+ y="138.524994"
+ id="tspan384">
+SessionFactory</tspan>
+ </text>
+ <rect
+ width="67.0014"
+ height="101.35"
+ x="196.927"
+ y="89.2389"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect387" />
+ <rect
+ width="67.0014"
+ height="101.35"
+ x="194.633"
+ y="86.4389"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect388" />
+ <text
+ x="249.108841"
+ y="173.885559"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text389">
+ <tspan
+ x="249.108994"
+ y="173.886002"
+ id="tspan392">
+Session</tspan>
+ </text>
+ <rect
+ width="73.0355"
+ height="101.35"
+ x="270.995"
+ y="90.0018"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect395" />
+ <rect
+ width="73.0355"
+ height="101.35"
+ x="267.869"
+ y="87.2018"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect396" />
+ <text
+ x="328.593658"
+ y="174.715622"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text397">
+ <tspan
+ x="328.593994"
+ y="174.716003"
+ id="tspan563">
+Transaction</tspan>
+ </text>
+ <g
+ transform="matrix(0.29544,0,0,0.397877,9.70533,103.96)"
+ style="font-size:12;"
+ id="g565">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect566" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect567" />
+ </g>
+ <text
+ x="25.592752"
+ y="204.497803"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:10;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text568">
+ <tspan
+ x="25.592800"
+ y="204.498001"
+ id="tspan662">
+TransactionFactory</tspan>
+ </text>
+ <g
+ transform="matrix(0.298082,0,0,0.397877,99.6898,103.96)"
+ style="font-size:12;"
+ id="g573">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect574" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect575" />
+ </g>
+ <text
+ x="134.030670"
+ y="205.532791"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:10;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text576">
+ <tspan
+ x="134.031006"
+ y="205.533005"
+ id="tspan664">
+ConnectionProvider</tspan>
+ </text>
+ <g
+ transform="matrix(1.14345,0,0,0.729078,-1.67818,38.9539)"
+ style="font-size:12;"
+ id="g587">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect588" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect589" />
+ </g>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="25.6196"
+ y="206.028"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect594" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="24.4229"
+ y="204.135"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect595" />
+ <text
+ x="85.575645"
+ y="282.300354"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text596">
+ <tspan
+ x="85.575600"
+ y="282.299988"
+ id="tspan607">
+JNDI</tspan>
+ </text>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="236.937"
+ y="206.791"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect610" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="235.741"
+ y="204.898"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect611" />
+ <text
+ x="342.093201"
+ y="283.226410"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text612">
+ <tspan
+ x="342.092987"
+ y="283.226013"
+ id="tspan621">
+JTA</tspan>
+ </text>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="130.134"
+ y="206.791"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect616" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="128.937"
+ y="204.898"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect617" />
+ <text
+ x="212.445343"
+ y="283.226410"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text618">
+ <tspan
+ x="212.445007"
+ y="283.226013"
+ id="tspan623">
+JDBC</tspan>
+ </text>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,6.19341)"
+ style="font-size:12;"
+ id="g637">
+ <g
+ transform="matrix(0.499515,0,0,0.415467,-0.237339,5.61339)"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="33.749969"
+ y="50.589706"
+ style="font-size:11;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="33.750000"
+ y="50.589699"
+ id="tspan635">
+Transient Objects</tspan>
+ </text>
+ </g>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,5.25349)"
+ style="font-size:12;"
+ id="g644">
+ <g
+ transform="matrix(0.297486,0,0,0.516482,230.251,36.9178)"
+ id="g364">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect365" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect366" />
+ </g>
+ <text
+ x="277.123230"
+ y="85.155571"
+ style="font-size:11;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text367">
+ <tspan
+ x="277.122986"
+ y="85.155602"
+ id="tspan631">
+Persistent</tspan>
+ <tspan
+ x="277.122986"
+ y="96.155602"
+ id="tspan633">
+Objects</tspan>
+ </text>
+ </g>
+</svg>
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/hibernate_logo_a.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/hibernate_logo_a.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/lite.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/lite.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/lite.svg (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/lite.svg)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/images/lite.svg (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/images/lite.svg 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,334 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="318.898"
+ height="248.031"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <rect
+ width="291.837"
+ height="57.0074"
+ x="17.3169"
+ y="18.646"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="291.837"
+ height="57.0074"
+ x="13.9703"
+ y="16.2302"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ <g
+ transform="matrix(0.326107,0,0,0.765831,9.59261,8.98517)"
+ style="font-size:12;"
+ id="g161">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <g
+ transform="matrix(1.02406,0,0,0.652953,0.223384,39.9254)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <g
+ transform="matrix(0.449834,0,0,0.338463,-3.15909,9.73319)"
+ style="font-size:12;"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="302.277679"
+ y="65.943230"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="302.277954"
+ y="65.943184"
+ id="tspan360">
+Application</tspan>
+ </text>
+ <text
+ x="36.235924"
+ y="63.796055"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:14;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="36.235950"
+ y="63.796051"
+ id="tspan427">
+Transient Objects</tspan>
+ </text>
+ <text
+ x="180.416245"
+ y="290.543701"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="180.415939"
+ y="290.543549"
+ id="tspan421">
+Database</tspan>
+ </text>
+ <text
+ x="25.037701"
+ y="179.154755"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="25.037655"
+ y="179.154648"
+ id="tspan384">
+SessionFactory</tspan>
+ </text>
+ <g
+ transform="matrix(0.252763,0,0,0.765831,109.104,8.98517)"
+ style="font-size:12;"
+ id="g386">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect387" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect388" />
+ </g>
+ <g
+ transform="matrix(0.297394,0,0,0.572692,101.502,21.6359)"
+ style="font-size:12;"
+ id="g364">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect365" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect366" />
+ </g>
+ <text
+ x="202.746506"
+ y="102.992203"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:14;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text367">
+ <tspan
+ x="202.746948"
+ y="102.992249"
+ id="tspan423">
+Persistent</tspan>
+ <tspan
+ x="202.746948"
+ y="116.992355"
+ id="tspan425">
+Objects</tspan>
+ </text>
+ <text
+ x="174.458496"
+ y="180.080795"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text389">
+ <tspan
+ x="174.458618"
+ y="180.080338"
+ id="tspan392">
+Session</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,188.675,8.98517)"
+ style="font-size:12;"
+ id="g394">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect395" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect396" />
+ </g>
+ <text
+ x="260.413269"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text397">
+ <tspan
+ x="260.412964"
+ y="179.154343"
+ id="tspan400">
+JDBC</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,229.156,8.98517)"
+ style="font-size:12;"
+ id="g405">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect406" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect407" />
+ </g>
+ <text
+ x="320.606903"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text408">
+ <tspan
+ x="320.606964"
+ y="179.154343"
+ id="tspan417">
+JNDI</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,269.281,8.98517)"
+ style="font-size:12;"
+ id="g411">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect412" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect413" />
+ </g>
+ <text
+ x="377.096313"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text414">
+ <tspan
+ x="377.096008"
+ y="179.154999"
+ id="tspan145">
+JTA</tspan>
+ </text>
+</svg>
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/overview.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/overview.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/images/overview.svg (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/overview.svg)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/images/overview.svg (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/images/overview.svg 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,250 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="248.031"
+ height="248.031"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,-3.02123)"
+ style="font-size:12;"
+ id="g158">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="17.3527"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="15.3883"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,3.04452)"
+ style="font-size:12;"
+ id="g161">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,8.0993)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.543505,2.59104,21.1103)"
+ style="font-size:12;"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="105.392174"
+ y="56.568123"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="105.392273"
+ y="56.568146"
+ id="tspan186">
+Application</tspan>
+ </text>
+ <text
+ x="81.820183"
+ y="103.149330"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:20;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="81.820213"
+ y="103.149727"
+ id="tspan206">
+Persistent Objects</tspan>
+ </text>
+ <text
+ x="111.548180"
+ y="278.927887"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="111.547874"
+ y="278.927551"
+ id="tspan200">
+Database</tspan>
+ </text>
+ <text
+ x="94.436180"
+ y="153.805740"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="94.436180"
+ y="153.805740"
+ id="tspan221">
+HIBERNATE</tspan>
+ </text>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,2.59083,1.02261)"
+ style="font-size:12;"
+ id="g254">
+ <g
+ transform="translate(4.58374,2.61928)"
+ id="g176">
+ <g
+ transform="matrix(0.571429,0,0,0.67347,-10.6174,117.093)"
+ id="g170">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect171" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect172" />
+ </g>
+ <g
+ transform="matrix(0.571429,0,0,0.67347,138.682,117.093)"
+ id="g173">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect174" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect175" />
+ </g>
+ </g>
+ <text
+ x="47.259438"
+ y="182.367538"
+ style="font-weight:bold;stroke-width:1pt;font-family:Courier;"
+ id="text191">
+ <tspan
+ x="47.259399"
+ y="182.367996"
+ id="tspan212">
+hibernate.</tspan>
+ <tspan
+ x="47.259399"
+ y="194.367996"
+ id="tspan214">
+properties</tspan>
+ </text>
+ <text
+ x="198.523010"
+ y="188.260941"
+ style="font-weight:normal;stroke-width:1pt;font-family:helvetica;"
+ id="text194">
+ <tspan
+ id="tspan195">
+XML Mapping</tspan>
+ </text>
+ </g>
+</svg>
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/legal_notice.xml (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/legal_notice.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/legal_notice.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/legal_notice.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,52 @@
+<?xml version='1.0'?>
+<!DOCTYPE legalnotice PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<legalnotice id="Legal_Notice">
+ <title>Legal Notice</title>
+ <para>
+ <address>
+ <street>1801 Varsity Drive</street>
+ <city>Raleigh</city>, <state>NC</state><postcode>27606-2072</postcode><country>USA</country>
+ <phone>Phone: +1 919 754 3700</phone>
+ <phone>Phone: 888 733 4281</phone>
+ <fax>Fax: +1 919 754 3701</fax>
+ <pob>PO Box 13588</pob><city>Research Triangle Park</city>, <state>NC</state><postcode>27709</postcode><country>USA</country>
+ </address>
+ </para>
+ <para>
+ Copyright <trademark class="copyright"></trademark> 2007 by Red Hat, Inc. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, V1.0 or later (the latest version is presently available at <ulink url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).
+ </para>
+ <para>
+ Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder.
+ </para>
+ <para>
+ Distribution of the work or derivative of the work in any standard (paper) book form for commercial purposes is prohibited unless prior permission is obtained from the copyright holder.
+ </para>
+ <para>
+ Red Hat and the Red Hat "Shadow Man" logo are registered trademarks of Red Hat, Inc. in the United States and other countries.
+ </para>
+ <para>
+ All other trademarks referenced herein are the property of their respective owners.
+ </para>
+ <para>
+ The GPG fingerprint of the security(a)redhat.com key is:
+ </para>
+ <para>
+ CA 20 86 86 2B D6 9D FC 65 F6 EC C4 21 91 80 CD DB 42 A6 0E
+ </para>
+</legalnotice>
\ No newline at end of file
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/legal_notice2.xml (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/legal_notice.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/legal_notice2.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/legal_notice2.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,15 @@
+<?xml version='1.0'?>
+<!DOCTYPE legalnotice PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<legalnotice id="Legal_Notice">
+ <title>Translation-specific Legal Notice</title>
+ <para>
+ <emphasis>Advertencia! Esta é uma versão traduzida do inglês da
+ documentação de referencia do Hibernate. A versão traduziada pode estar
+ desatualizada. Sem dúvida, as diferenças devem ser pequenas e serão corrigidas o
+ mais breve possivel. Consulte a documentação de referencia em inglês, se estiver
+ faltando alguma informação ou você encotrar erros de tradução. Se quiser
+ colaborar com ama tradução em particular, entre em contato com um dos tradutores
+ abaixo:</emphasis>. Gamarra
+ </para>
+</legalnotice>
\ No newline at end of file
Deleted: core/trunk/documentation/manual/pt-BR/src/main/docbook/master.xml
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/master.xml 2007-10-09 19:14:22 UTC (rev 14079)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/master.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -1,261 +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 tutorial SYSTEM "modules/tutorial.xml">
-<!ENTITY architecture SYSTEM "modules/architecture.xml">
-<!ENTITY configuration SYSTEM "modules/configuration.xml">
-<!ENTITY persistent-classes SYSTEM "modules/persistent_classes.xml">
-<!ENTITY basic-mapping SYSTEM "modules/basic_mapping.xml">
-<!ENTITY collection-mapping SYSTEM "modules/collection_mapping.xml">
-<!ENTITY association-mapping SYSTEM "modules/association_mapping.xml">
-<!ENTITY component-mapping SYSTEM "modules/component_mapping.xml">
-<!ENTITY inheritance-mapping SYSTEM "modules/inheritance_mapping.xml">
-<!ENTITY session-api SYSTEM "modules/session_api.xml">
-<!ENTITY transactions SYSTEM "modules/transactions.xml">
-<!ENTITY events SYSTEM "modules/events.xml">
-<!ENTITY batch SYSTEM "modules/batch.xml">
-<!ENTITY query-hql SYSTEM "modules/query_hql.xml">
-<!ENTITY query-criteria SYSTEM "modules/query_criteria.xml">
-<!ENTITY query-sql SYSTEM "modules/query_sql.xml">
-<!ENTITY filters SYSTEM "modules/filters.xml">
-<!ENTITY xml SYSTEM "modules/xml.xml">
-<!ENTITY performance SYSTEM "modules/performance.xml">
-<!ENTITY toolset-guide SYSTEM "modules/toolset_guide.xml">
-<!ENTITY example-parentchild SYSTEM "modules/example_parentchild.xml">
-<!ENTITY example-weblog SYSTEM "modules/example_weblog.xml">
-<!ENTITY example-mappings SYSTEM "modules/example_mappings.xml">
-<!ENTITY best-practices SYSTEM "modules/best_practices.xml">
-]>
-
-<book lang="en">
-
- <bookinfo>
- <title>HIBERNATE - Relational Persistence for Idiomatic Java</title>
- <subtitle>Documenta��o da Refer�ncia do Hibernate</subtitle>
- <releaseinfo>3.2 cr2</releaseinfo>
- </bookinfo>
-
- <toc/>
-
- <preface id="preface" revision="2">
- <title>Pref�cio</title>
-
- <para>
- <emphasis>Advertencia! Esta � uma vers�o traduzida do ingl�s da
- documenta��o de referencia do Hibernate. A vers�o traduziada pode estar
- desatualizada. Sem d�vida, as diferen�as devem ser pequenas e ser�o corrigidas o
- mais breve possivel. Consulte a documenta��o de referencia em ingl�s, se estiver
- faltando alguma informa��o ou voc� encotrar erros de tradu��o. Se quiser
- colaborar com ama tradu��o em particular, entre em contato com um dos tradutores
- abaixo:</emphasis>. Gamarra
-
- </para>
-
- <para>
- Tradutor(es) em ordem alfab�tica:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>Alvaro Netto</emphasis> alvaronetto(a)cetip.com.br
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Anderson Braulio</emphasis> andersonbraulio(a)gmail.com
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Daniel Vieira Costa</emphasis> danielvc(a)gmail.com
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Francisco gamarra</emphasis> francisco.gamarra(a)gmail.com
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Gamarra</emphasis> mauricio.gamarra(a)gmail.com
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Luiz Carlos Rodrigues</emphasis> luizcarlos_rodrigues(a)yahoo.com.br
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Marcel Castelo</emphasis> marcel.castelo(a)gmail.com
- </para>
- </listitem>
-
- <listitem>
- <para>
- <emphasis>Paulo C�sar</emphasis> paulocol(a)gmail.com
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Pablo L. de Miranda</emphasis> pablolmiranda(a)gmail.com
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Renato Deggau</emphasis> rdeggau(a)gmail.com
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Rog�rio Ara�jo</emphasis> rgildoaraujo(a)yahoo.com.br
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Wanderson Siqueira</emphasis> wandersonxs(a)gmail.com
- </para>
- </listitem>
-
-
- </itemizedlist>
-
- <para>
- Trabalhando com software orientado a objetos e banco de dados relacional, podemos
- ter alguns inc�modos hoje em dia em ambientes empresariais. Hibernate � uma ferramenta
- que mapeia o objeto/relacional para o ambiente Java. O termo de mapeamento de
- objeto/relacional (ou ORM � Object/Relational Mapping) se refere a t�cnica de mapear
- uma representa��o de dados de um modelo de objeto para dados de modelo
- relacional com o esquema baseado em SQL
- </para>
-
- <para>
- O Hibernate n�o somente cuida do mapeamento de classes em Java
- para tabelas de banco de dados (e de tipos de dados em Java para tipos de dados em SQL), como tamb�m
- fornece facilidade de consultas e recupera��o de dados, podendo tamb�m reduzir significantemente o
- tempo de desenvolvimento gasto com a manipula��o manual de dados no SQL e JDBC.
- </para>
-
- <para>
- O objetivo do Hibernate � de aliviar o desenvolvedor de 95 por cento das tarefas de programa��o
- relacionadas aos dados comuns de persist�ncia. O Hibernate talvez n�o seja a melhor solu��o para
- aplica��es de dados-data-centric que somente usa stored-procedures para implementar a l�gica
- de neg�cio no banco de dados, isto � muito utilizado com o dom�nio de modelos orientado a objetos e
- l�gicas de neg�cio em camadas do meio (middle-tier) baseadas em Java. Por�m, o Hibernate
- poder� certamente ajuda-lo a remover ou encapsular o c�digo SQL de um vendedor espec�fico,
- ajudando tamb�m com a tarefa comum da tradu��o do resultado ajustado de uma representa��o
- para um gr�fico de objetos.
- </para>
-
- <para>
- Se voc� for novo no Hibernate e no mapeamento Objeto/Relacional, ou at� mesmo em Java,
- por favor, siga os seguintes passos.
- </para>
-
- <orderedlist>
- <listitem>
- <para>
- Leia <xref linkend="tutorial"/> para um tutorial com instru��es passo-a-passo.
- O c�digo fonte para do tutorial est� inclu�do na distribui��o no diret�rio
- <literal>doc/reference/tutorial/</literal>.
- </para>
- </listitem>
- <listitem>
- <para>
- Leia o <xref linkend="architecture"/> para entender o ambiente onde o Hibernate pode ser utilizado.
- </para>
- </listitem>
- <listitem>
- <para>
- D� uma olhada no diret�rio de exemplo <literal>eg/</literal> da distribui��o
- do Hibernate, ele cont�m uma simples aplica��o standalone.
- Copie seu driver JDBC para o diret�rio <literal>lib/</literal> e edite o arquivo
- <literal>etc/hibernate.properties</literal>, especificando corretamente os valores
- para seu banco de dados. Usando o prompt de commando no diretorio de distribuicao,
- digite <literal>ant eg</literal> (usando Ant), ou no Windows, digite
- <literal>build eg</literal>.
- </para>
- </listitem>
- <listitem>
- <para>
- Use esta documenta��o de referencia como sua fonte primaria de informa��o.
- Considere ler tamb�m o livro <emphasis>Java Persistence with Hibernate</emphasis>
- (http://www.manning.com/bauer2) caso voc� precise de mais ajuda com o
- desenvolvimento de aplica��es ou caso prefira um tutorial passo-a-passo.
- Tamb�m visite o site http://caveatemptor.hibernate.org e fa�a o download
- da aplica��o de exemplo do Java Persistence with Hibernate.
- </para>
- </listitem>
- <listitem>
- <para>
- FAQs (perguntas feitas com mais freq��ncia) est�o respondidas no site do Hibernate
- </para>
- </listitem>
- <listitem>
- <para>
- Demonstra��es, exemplos e tutorials est�o dispon�veis no site do Hibernate.
- </para>
- </listitem>
- <listitem>
- <para>
- A �rea da comunidade no site do Hibernate � uma boa fonte de recursos
- para padr�es de projeto e v�rias solu��es de integra��o (Tomcat, JBoss AS, Struts, EJB, etc.).
- </para>
- </listitem>
- </orderedlist>
-
- <para>
- Caso voc� tenha d�vidas, use o f�rum dos usu�rios encontrado no site do Hibernate.
- N�s tamb�m fornecemos um sistema para controle de bug�s (JIRA) para relat�rios de erros
- e requisi��es de features. Se voc� est� interessado no desenvolvimento do Hibernate,
- junte-se a lista de e-mail dos desenvolvedores.
- </para>
-
- <para>
- Suporte comercial de desenvolvimento, suporte de produ��o e treinamento para o Hibernate
- est� dispon�vel atrav�s do JBoss Inc. (veja http://www.hibernate.org/SupportTraining).
- O Hibernate � um Projeto Profissional de C�digo Aberto e um componente cr�tico da su�te
- de produtos JBoss Enterprise Middleware System (JEMS).
- </para>
-
- </preface>
-
- &tutorial;
-
- &architecture;
-
- &configuration;
-
- &persistent-classes;
-
- &basic-mapping;
- &collection-mapping;
- &association-mapping;
- &component-mapping;
- &inheritance-mapping;
-
- &session-api;
- &transactions;
- &events;
- &batch;
-
- &query-hql;
- &query-criteria;
- &query-sql;
- &filters;
- &xml;
-
- &performance;
-
- &toolset-guide;
-
- &example-parentchild;
- &example-weblog;
- &example-mappings;
-
- &best-practices;
-
-</book>
-
Copied: core/trunk/documentation/manual/pt-BR/src/main/docbook/translators.xml (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/translators.xml)
===================================================================
--- core/trunk/documentation/manual/pt-BR/src/main/docbook/translators.xml (rev 0)
+++ core/trunk/documentation/manual/pt-BR/src/main/docbook/translators.xml 2007-10-09 19:32:35 UTC (rev 14080)
@@ -0,0 +1,93 @@
+<?xml version='1.0'?>
+
+<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<authorgroup id="AuthorGroup">
+
+ <othercredit class="translator">
+ <firstname>Alvaro</firstname>
+ <surname>Netto</surname>
+ <email>alvaronetto(a)cetip.com.br</email>
+ </othercredit>
+
+ <othercredit class="translator">
+ <firstname>Anderson</firstname>
+ <surname>Braulio</surname>
+ <email>andersonbraulio(a)gmail.com</email>
+ </othercredit>
+
+ <othercredit class="translator">
+ <firstname>Daniel Vieira</firstname>
+ <surname>Costa</surname>
+ <email>danielvc(a)gmail.com</email>
+ </othercredit>
+
+ <othercredit class="translator">
+ <firstname>Francisco</firstname>
+ <surname>gamarra</surname>
+ <email>francisco.gamarra(a)gmail.com</email>
+ </othercredit>
+
+ <othercredit class="translator">
+ <firstname>Gamarra</firstname>
+ <email>mauricio.gamarra(a)gmail.com</email>
+ </othercredit>
+
+ <othercredit class="translator">
+ <firstname>Luiz Carlos</firstname>
+ <surname>Rodrigues</surname>
+ <email>luizcarlos_rodrigues(a)yahoo.com.br</email>
+ </othercredit>
+
+ <othercredit class="translator">
+ <firstname>Marcel</firstname>
+ <surname>Castelo</surname>
+ <email>marcel.castelo(a)gmail.com</email>
+ </othercredit>
+
+ <othercredit class="translator">
+ <firstname>Paulo</firstname>
+ <surname>César</surname>
+ <email>paulocol(a)gmail.com</email>
+ </othercredit>
+
+ <othercredit class="translator">
+ <firstname>Pablo L.</firstname>
+ <surname>de Miranda</surname>
+ <email>pablolmiranda(a)gmail.com</email>
+ </othercredit>
+
+ <othercredit class="translator">
+ <firstname>Renato</firstname>
+ <surname>Deggau</surname>
+ <email>rdeggau(a)gmail.com</email>
+ </othercredit>
+
+ <othercredit class="translator">
+ <firstname>Rogério</firstname>
+ <surname>Araújo</surname>
+ <email>rgildoaraujo(a)yahoo.com.br</email>
+ </othercredit>
+
+ <othercredit class="translator">
+ <firstname>Wanderson</firstname>
+ <surname>Siqueira</surname>
+ <email>wandersonxs(a)gmail.com</email>
+ </othercredit>
+
+</authorgroup>
\ No newline at end of file
18 years, 6 months
Hibernate SVN: r14079 - in core/trunk/documentation/manual/ko-KR/src/main: docbook and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2007-10-09 15:14:22 -0400 (Tue, 09 Oct 2007)
New Revision: 14079
Added:
core/trunk/documentation/manual/ko-KR/src/main/docbook/Hibernate_Reference.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/architecture.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/association_mapping.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/basic_mapping.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/batch.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/best_practices.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/collection_mapping.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/component_mapping.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/configuration.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/events.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/example_mappings.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/example_parentchild.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/example_weblog.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/filters.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/inheritance_mapping.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/performance.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/persistent_classes.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/preface.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/query_criteria.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/query_hql.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/query_sql.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/quickstart.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/session_api.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/toolset_guide.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/transactions.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/tutorial.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/content/xml.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/AuthorWork.png
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/AuthorWork.zargo
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/CustomerOrderProduct.png
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/CustomerOrderProduct.zargo
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/EmployerEmployee.png
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/EmployerEmployee.zargo
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/full_cream.png
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/full_cream.svg
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/hibernate_logo_a.png
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/lite.png
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/lite.svg
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/overview.png
core/trunk/documentation/manual/ko-KR/src/main/docbook/images/overview.svg
core/trunk/documentation/manual/ko-KR/src/main/docbook/legal_notice.xml
Removed:
core/trunk/documentation/manual/ko-KR/src/main/docbook/master.xml
core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/
core/trunk/documentation/manual/ko-KR/src/main/resources/
Log:
new docbook layout (prep for translations migration to PO)
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/Hibernate_Reference.xml (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/Hibernate_Reference.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/Hibernate_Reference.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/Hibernate_Reference.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,72 @@
+<?xml version='1.0' encoding="UTF-8"?>
+
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+ <!ENTITY versionNumber "3.3.0.alpha1">
+ <!ENTITY copyrightYear "2004">
+ <!ENTITY copyrightHolder "Red Hat Middleware, LLC.">
+]>
+
+<book>
+
+ <bookinfo>
+ <title>HIBERNATE - 개성있는 자바를 위한 관계 영속</title>
+ <subtitle>하이버네이트 참조 문서</subtitle>
+ <releaseinfo>&versionNumber;</releaseinfo>
+ <productnumber>&versionNumber;</productnumber>
+ <issuenum>1</issuenum>
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/hibernate_logo_a.png" align="center" />
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="images/hibernate_logo_a.png" depth="3cm" />
+ </imageobject>
+ </mediaobject>
+ <copyright>
+ <year>©rightYear;</year>
+ <holder>©rightHolder;</holder>
+ </copyright>
+ <xi:include href="legal_notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </bookinfo>
+
+ <toc/>
+
+ <xi:include href="content/preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/tutorial.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/configuration.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/persistent_classes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/basic_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/collection_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/association_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/component_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/inheritance_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/session_api.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/transactions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/events.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/batch.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/query_hql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/query_criteria.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/query_sql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/filters.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/xml.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/performance.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/toolset_guide.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/example_parentchild.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/example_weblog.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/example_mappings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/best_practices.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+</book>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/architecture.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/architecture.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/architecture.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/architecture.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,323 @@
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<chapter id="architecture">
+
+ <title>아키텍처</title>
+
+ <sect1 id="architecture-overview" revision="1">
+ <title>개요</title>
+
+ <para>
+ Hibernate 아키텍처에 대한 (매우) 높은 수준의 개요::
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/overview.svg" format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/overview.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ 이 다이어그램은 어플리케이션에 영속화 서비스들(과 영속 객체들)을 제공하기 위해 데이터베이스와
+ 컨피그레이션을 사용하는 Hibernate를 보여준다.
+ </para>
+
+ <para>
+ 우리는 런타임 아키텍처에 대한 보다 상세한 뷰를 보여주고 싶다. 불행하게도, Hibernate는 유연하며
+ 몇 가지 접근법들을 제공한다. 우리는 두 가지 극단을 보여줄 것이다. "경량급" 아키텍처는 그것 자신의
+ JDBC 커넥션들을 제공하고 그것 자신의 트랜잭션들을 관리하는 어플리케이션을 갖는다. 이 접근법은
+ Hibernate의 API의 최소 부분집합을 사용한다:
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/lite.svg" format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/lite.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ "전체 정수" 아키텍처는 기본 JDBC/JTA로부터 어플리케이션을 추상화 시키고 Hibernate로 하여금
+ 상세한 것을 처리하게 한다.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/full_cream.svg" format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/full_cream.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ 다음은 다이어그램들 내에 있는 객체들에 대한 몇가지 정의들이다:
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>SessionFactory (<literal>org.hibernate.SessionFactory</literal>)</term>
+ <listitem>
+ <para>
+ 단일 데이터베이스에 대한 컴파일된 매핑들의 threadsafe (불변의) 캐시. Session과 ConnectionProvider의
+ 클라이언트를 위한 팩토리. 프로세스 레벨 또는 클러스터 레벨에서 트랜잭션들 사이에 재사용 가능한 데이터의 선택적인
+ (second-level) 캐시를 보관할 수도 있다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Session (<literal>org.hibernate.Session</literal>)</term>
+ <listitem>
+ <para>
+ 어플리케이션과 영속 저장소 사이의 대화를 표현하는 단일 쓰레드이고, 수명이 짧은 객체. JDBC 커넥션을 포장한다.
+ <literal>Transaction</literal> 용 팩토리. 객체 그래프를 네비게이트 하거나 식별자로 객체들을 룩업할 때
+ 사용되는 영속 객체들에 대한 필수적인(첫 번째 레벨의) 캐시를 보관한다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>영속 객체들과 콜렉션들</term>
+ <listitem>
+ <para>
+ persistent 상태와 비지니스 기능을 포함하는 수명이 짧고, 단일 쓰레드인 객체들. 이것들은 통상의 JavaBeans/POJO들일
+ 수 있고, 오직 그것들에 대한 오직 특별한 것은 그것들이 현재 (정확하게 한 개의) <literal>Session</literal>과 연관되어
+ 있다는 점이다. <literal>Session</literal>이 닫히자마자, 그것들은 분리될(detached 상태가 될) 것이고 어플리케이션
+ 레이어에서 사용하는 것이 자유로와진다(예를 들면. 직접적으로 프리젠테이션 계층으로
+ 데이터 전송 객체들로서 그리고 직접적으로 프리젠테이션 계층으로부터 데이터 전송 객체들로서).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>전이(Transient, 필자 주-과도) 객체들과 콜렉션들</term>
+ <listitem>
+ <para>
+ <literal>Session</literal>과 현재 연관되어 있지 않은 영속 클래스들의 인스턴스들. 그것들은 어플리케이션에 의해 초기화
+ 되었고 (아직) 영속화 되지 않았거나 그것들은 닫혀진<literal>Session</literal>에 의해 초기화 되었을 수도 있다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Transaction (<literal>org.hibernate.Transaction</literal>)</term>
+ <listitem>
+ <para>
+ (옵션) 작업의 원자 단위를 지정하기 위해 어플리케이션에 의해 사용되는 단일 쓰레드이고, 수명이 짧은 객체. 기본 JDBC, JTA
+ 또는 CORBA 트랜잭션으로부터 어플리케이션을 추상화 시킨다. 몇몇 경우들에서 하나의 <literal>Session</literal>은
+ 여러 개의 <literal>Transaction</literal>들에 걸칠 수 있다. 하지만 기본 API 또는 <literal>Transaction</literal>을
+ 사용하는 트랜잭션 경계 설정은 결코 옵션이 아니다!
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ConnectionProvider (<literal>org.hibernate.connection.ConnectionProvider</literal>)</term>
+ <listitem>
+ <para>
+ (옵션) JDBC 커넥션들에 대한 팩토리(그리고 그것들의 pool). 기본 <literal>Datasource</literal> 또는
+ <literal>DriverManager</literal>로부터 어플리케이션을 추상화 시킨다. 어플리케이션에 노출되지는 않지만
+ 개발자에 의해 확장/구현 된다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>TransactionFactory (<literal>org.hibernate.TransactionFactory</literal>)</term>
+ <listitem>
+ <para>
+ (옵션) <literal>Transaction</literal> 인스턴스들에 대한 팩토리. 어플리케이션에 노출되지는 않지만 개발자에 의해
+ 확장/구현 된다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis>Extension Interfaces</emphasis></term>
+ <listitem>
+ <para>
+ Hibernate는 당신의 영속 계층의 특성을 맞춤화 시키기 위해 당신이 구현할 수 있는 선택적인 확장 인터페이스들을 제공한다.
+ 상세한 것은 API 문서를 보라.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ 주어진 "경량급" 아키텍처의 경우, 어플리케이션은 JTA 또는 JDBC와 직접 대화하기 위해서 <literal>Transaction</literal>/<literal>TransactionFactory</literal>
+ 그리고/또는 <literal>ConnectionProvider</literal> API들을 무시한다.
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-states" revision="1">
+ <title>인스턴스 상태들</title>
+ <para>
+ 영속 클래스들의 인스턴스는 세개의 상태들 중 하나 일 수 있다. 그것들(상태들)은 영속 컨텍스트(<emphasis>persistence context</emphasis>)에
+ 대해 정의된다. Hibernate <literal>Session</literal> 객체는 영속 컨텍스트이다:
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>transient</term>
+ <listitem>
+ <para>
+ 인스턴스는 임의의 컨텍스트와 연관되어 있지 않고, 결코 연관된 적이 없었다. 그것은 영속 식별자(프라이머리 키 값)을 갖지 않는다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>persistent</term>
+ <listitem>
+ <para>
+ 인스턴스는 현재 영속 컨텍스트와 연관되어 있다. 그것은 영속 식별자(프라이머리 키 값) 그리고 아마 데이터베이스 내에 있는 대응하는
+ 행을 갖는다. 특별한 영속 컨텍스트의 경우, Hibernate는 영속 identity가 Java identity(객체의 메모리 내 위치)와 같다는 점을
+ <emphasis>보증한다</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>detached</term>
+ <listitem>
+ <para>
+ 인스턴스는 영속 컨텍스트와 한번 연관되었지만, 그 컨텍스트가 닫혔거나, 그 인스턴스가 또 다른 프로세스로 직렬화 되었다. 그것은 영속
+ identity 그리고, 아마 데이터베이스 내에 대응하는 행을 갖는다. detached 인스턴스들의 경우, Hibernate는 영속 identity과
+ Java identity 사이의 관계를 보증하지 않는다.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 id="architecture-jmx" revision="1">
+ <title>JMX 통합</title>
+
+ <para>
+ JMX는 자바 컴포넌트 관리를 위한 J2EE 표준이다. Hibernate는 JMX 표준 서비스를 통해 관리될 수도 있다. 우리는 배포본 내에 MBean 구현,
+ <literal>org.hibernate.jmx.HibernateService</literal>를 제공한다.
+ </para>
+
+ <para>
+ JBoss 어플리케이션 서버 상에 Hibernae를 JMX 서비스로서 배치하는 방법에 대한 예제는 JBoss 사용자 가이드를 보길 바란다. JBoss
+ 어플리케이션 서버 상에서, 만일 당신이 JMX를 사용하여 배치할 경우 당신은 또한 다음 이점들을 얻는다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Session 관리:</emphasis> Hibernate <literal>Session</literal>의 생명주기가 JTA 트랜잭션의
+ 영역 내에 자동적으로 바인드 될 수 있다. 이것은 당신이 더이상 <literal>Session</literal>을 수작업으로 열고 닫지 않아도
+ 됨을 의미하고, 이것은 JBoss EJB 인터셉터의 업무가 된다. 당신은 또한 더 이상 당신의 코드 어느 곳에서든 트랜잭션 경계설정에
+ 대해 걱정하지 않아도 된다(당신이 물론 이식성 있는 영속 계층을 작성하고자 원하지 않는한, 이를 위해 옵션 Hibernate <literal>Transaction</literal>
+ API를 사용하라). 당신은 <literal>Session</literal>에 접근하기 위해 <literal>HibernateContext</literal>를 호출한다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>HAR 배치:</emphasis> 대개 당신은 JBoss 서비스 배치 디스크립터를 사용하여 Hibernate JMX 서비스를
+ (EAR 과/또는 SAR 파일로) 배치하고, 그것은 Hibernate <literal>SessionFactory</literal>의 통상적인 구성
+ 옵션들 모두를 지원한다. 하지만 당신은 여전히 모든 당신의 매핑 파일들을 배치 디스크립터 속에 명명해야 한다. 만일 당신이
+ 옵션 HAR 배치를 사용하고자 결정하는 경우, JBoss는 당신의 HAR 파일 내에 있는 모든 매핑 파일들을 자동적으로 검출해낼 것이다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 이들 옵션들에 대한 추가 정보는 JBoss 어플리케이션 서버 사용자 가이드를 참조하라.
+ </para>
+
+ <para>
+ JMX 서비스로서 이용 가능한 또다른 특징은 런타임 Hibernate 통계이다.
+ <xref linkend="configuration-optional-statistics"/>를 보라.
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-jca" revision="1">
+ <title>JCA 지원</title>
+ <para>
+ Hibernate는 JCA 커넥터로서 구성될 수도 있다. 상세한 것은 웹 사이트를 보길 바란다. Hibernate JCA 지원은 여전히 실험적으로
+ 검토 중에 있음을 노트하길 바란다.
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-current-session" revision="2">
+ <title>컨텍스트 상의 세션들</title>
+ <para>
+ Hibernate를 사용하는 대부분의 어플리케이션들은 어떤 양식의 "컨텍스트상의(contextual)" 세션들을 필요로 한다. 여기서
+ 주어진 세션은 주어진 컨텍스트의 영역에 걸쳐 활동을 한다. 하지만 어플리케이션들을 가로질러 컨텍스트를 구성하는 것에 대한 정의는
+ 일반적으로 다르다; 그리고 다른 컨텍스트들은 현재라고 하는 개념에 대해 다른 영역들을 정의한다. 버전 3.0 전의 Hibernate를
+ 사용하는 어플리케이션들은 자가생산된 <literal>ThreadLocal</literal>-기반의 컨텍스상의 세션들,
+ <literal>HibernateUtil</literal>과 같은 helper 클래스들을 활용했거나
+ 프락시/인터셉션 기반의 컨텍스트상의 세션들을 제공해주었던 (Spring 또는 Pico와 같은 )제 3의 프레임웍들을 활용하는 경향이 있었다.
+ </para>
+ <para>
+ 버전 3.0.1에서부터 시작하여, Hibernate는 <literal>SessionFactory.getCurrentSession()</literal> 메소드를
+ 추가했다. 초기에 이것은 <literal>JTA</literal> 트랜잭션들을 사용하는 것을 전제했다. 여기서 <literal>JTA</literal>
+ 트랜잭션은 현재 세션의 영역과 컨텍스트를 정의했다. Hibernate 팀은 성숙된 다수의 스탠드얼론 <literal>JTA TransactionManager</literal>
+ 구현들이 발표되면, (전부는 아니겠지만) 대부분의 어플리케이션들이 그것들이 <literal>J2EE</literal> 컨테이너 내로 배치되든
+ 그렇지 않든 간에 <literal>JTA</literal> 트랜잭션 관리를 사용하게 될 것이라고 주장한다. 그것에 기초하여, <literal>JTA</literal>에 기반한
+ 컨텍스트상의 세션들은 언젠가 당신이 사용을 필요로 하게 될 전부다.
+ </para>
+ <para>
+ 하지만 버전 3.1 이후로 <literal>SessionFactory.getCurrentSession()</literal> 이면의 처리과정은
+ 이제 플러그 가능하다. 그것을 끝내기 위해, 하나의 새로운 확장 인터페이스
+ (<literal>org.hibernate.context.CurrentSessionContext</literal>)와
+ 하나의 새로운 구성 파라미터(<literal>hibernate.current_session_context_class</literal>)가 현재 세션들을
+ 정의하는 영역과 컨텍스트의 플러그 가능성을 허용하기 위해 추가되었다.
+ </para>
+ <para>
+ 그것의 계약에 대한 상세한 논의는 <literal>org.hibernate.context.CurrentSessionContext</literal> 인터페이스에
+ 관한 javadocs를 보라. 그것은 하나의 메소드, <literal>currentSession()</literal>를 정의하며, 그 구현은
+ 현재의 컨텍스트 상의 세션을 추적할 책임이 있다. 비공식적으로, Hibernate는 이 인터페이스에 대한 세 개의 구현들을 부수적으로
+ 포함하고 있다.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>org.hibernate.context.JTASessionContext</literal> - 현재의 세션들은 하나의
+ <literal>JTA</literal>에 의해 추적되고 영역화 된다. 여기서 처리과정은 이전의 JTA-전용 접근과 정확하게
+ 동일하다. 상세한 것은 javadocs를 보라.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>org.hibernate.context.ThreadLocalSessionContext</literal> - 현재의 세션들은
+ 실행 쓰레드에 의해 추적된다. 상세한 것은 다시 javadocs를 보라.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ 처음의 두 구현들은 <emphasis>session-per-request</emphasis>로 알려지고 사용되고 있는
+ "하나의 세션 - 하나의 데이터베이스 트랜잭션" 프로그래밍 모형을 제공한다. 하나의 Hibernate 세션의 시작과 끝은
+ 데이터베이스 트랜잭션의 존속 기간에 의해 정의된다. 만일 (예를 들면 순수 J2SE에서 또는 JTA/UserTransaction/BMT의 경우에)
+ 당신이 프로그램 상의 트랜잭션 경계구분을 사용할 경우, 당신은 당신의 코드로부터 기본 트랜잭션 시스템을 은폐시키는데
+ Hibernate <literal>Transaction</literal> API를 사용하는 것이 권장된다. 만일 당신이 CMT를 지원하는
+ 하나의 EJB 컨테이너에서 실행할 경우, 트랜잭션 경계들이 선언적으로 정의되고 당신은 당신의 코드 내에 어떤 트랜잭션도
+ 세션 경계구분 오퍼레이션들을 필요로 하지 않는다. 추가 정보와 코드 예제들은 <xref linkend="transactions"/>를 참조하라.
+ </para>
+
+ <para>
+ <literal>hibernate.current_session_context_class</literal> 구성 파라미터는
+ <literal>org.hibernate.context.CurrentSessionContext</literal> 구현이 사용될 것임을 정의한다. 역호환을 위해.
+ 만일 이 구성 파라미터가 설정되지 않았지만 하나의 <literal>org.hibernate.transaction.TransactionManagerLookup</literal>이
+ 구성되어 있을 경우, Hibernate는 <literal>org.hibernate.context.JTASessionContext</literal>를 사용할 것임을
+ 노트하라. 일반적으로, 이 파라미터의 값은 단지 사용할 구현 클래스를 명명할 것이다; 하지만 두 가지 비공식적인 구현들로서 두 개의
+ 대응하는 짧은 이름들 "jta"와 "thread"이 존재한다.
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/association_mapping.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/association_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/association_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/association_mapping.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,603 @@
+<chapter id="associations">
+
+ <title>연관 매핑들</title>
+
+ <sect1 id="assoc-intro" revision="1">
+ <title>개요</title>
+
+ <para>
+ 연관 매핑들은 올바른 것을 얻기가 종종 가장 어려운 것이다. 이 절에서 우리는 단방향 매핑들에서 시작하고, 그런 다음 양방향 경우들을
+ 검토함으로써, 하나씩 표준적인 경우들을 상세히 논의할 것이다. 우리는 모든 예제들에서 <literal>Person</literal>과
+ <literal>Address</literal>를 사용할 것이다.
+ </para>
+
+ <para>
+ 우리는 연관들을 중재하는 join 테이블로 매핑시킬 것인지 여부에 따라, 그리고 multiplicity(다중성)에 따라 연관들을 분류할 것이다.
+ </para>
+
+ <para>
+ null 허용 가능한 foreign 키들은 전통적인 데이터 모델링에서 좋은 실례로 간주되지 않아서, 모든 우리의 예제들은 not null
+ foreign 키들을 사용한다. 이것은 Hibernate에서 필수가 아니고, 당신이 null 허용 가능 컨스트레인트들을 드롭시킬 경우 매핑들은
+ 모두 동작할 것이다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="assoc-unidirectional" revision="1">
+ <title>단방향 연관들</title>
+
+ <sect2 id="assoc-unidirectional-m21">
+ <title>many to one</title>
+
+ <para>
+ <emphasis>단방향 many-to-one 연관</emphasis>은 가장 공통적인 종류의 단방향 연관이다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-121">
+ <title>one to one</title>
+
+ <para>
+ <emphasis>foreign 키에 대한 단방향 one-to-one 연관은 대개 아주 동일하다.</emphasis> 유일한 차이점은
+ 컬럼 유일(unique) 컨스트레인트이다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ unique="true"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ <emphasis>하나의 프라이머리 키에 대한 단방향 one-to-one 연관</emphasis>은 대개 특별한 id 생성기를 사용한다.
+ (이 예제에서 연관의 방향이 역전되었음을 주목하라.)
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+</class>
+
+<class name="Address">
+ <id name="id" column="personId">
+ <generator class="foreign">
+ <param name="property">person</param>
+ </generator>
+ </id>
+ <one-to-one name="person" constrained="true"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( personId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-12m">
+ <title>one to many</title>
+
+ <para>
+ <emphasis>하나의 foreign 키에 대한 단방향 one-to-many 연관</emphasis>은 매우 색다른 경우이고, 실제로 권장되지 않는다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses">
+ <key column="personId"
+ not-null="true"/>
+ <one-to-many class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( addressId bigint not null primary key, personId bigint not null )
+ ]]></programlisting>
+
+ <para>
+ 우리는 이런 종류의 연관에 대해 하나의 join 테이블을 사용하는 것이 더 좋다고 생각한다.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-unidirectional-join" revision="1">
+ <title>join 테이블들에 대한 단방향 연관들</title>
+
+ <sect2 id="assoc-unidirectional-join-12m">
+ <title>one to many</title>
+
+ <para>
+ <emphasis>하나의 join 테이블에 대한 단방향 one-to-many 연관</emphasis>이 보다 더 선호된다. <literal>unique="true"</literal>를
+ 지정함으로써 우리는 many-to-many에서 one-to-many로 아중성(multiplicity)를 변경시켰음을 주목하라.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ unique="true"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId not null, addressId bigint not null primary key )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-m21">
+ <title>many to one</title>
+
+ <para>
+ <emphasis>하나의 join 테이블에 대한 단방향 many-to-one 연관</emphasis>은 그 연관이 선택적일 때 매우 공통적이다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId" unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-121">
+ <title>one to one</title>
+
+ <para>
+ <emphasis>하나의 join 테이블에 대한 단방향 one-to-one 연관</emphasis>은 극히 통상적이지 않지만 가능하다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId"
+ unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-m2m">
+ <title>many to many</title>
+
+ <para>
+ 마지막으로, 우리는 <emphasis>단방향 many-to-many 연관</emphasis>을 갖는다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-bidirectional" revision="1">
+ <title>양방향 연관들</title>
+
+ <sect2 id="assoc-bidirectional-m21" revision="2">
+ <title>one to many / many to one</title>
+
+ <para>
+ <emphasis>양방향 many-to-one 연관</emphasis>은 가장 공통된 종류의 연관이다.(이것은 표준 부모/자식 관계이다. )
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <set name="people" inverse="true">
+ <key column="addressId"/>
+ <one-to-many class="Person"/>
+ </set>
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ 만일 당신이 <literal>List</literal>(또는 다른 인덱싱 된 콜렉션)을 사용할 경우 당신은 foreign key의
+ <literal>key</literal> 컬럼을 <literal>not null</literal>로 설정하고, Hibernate로 하여금
+ 각각의 요소의 인덱스를 유지관리하기 위해 (<literal>update="false"</literal>와
+ <literal>insert="false"</literal>를 설정함으로써 다른 측을 가상적으로 inverse로 만들어)
+ 그 콜렉션들 측으로부터 연관을 관리하도록 할 필요가 있다:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id"/>
+ ...
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ insert="false"
+ update="false"/>
+</class>
+
+<class name="Address">
+ <id name="id"/>
+ ...
+ <list name="people">
+ <key column="addressId" not-null="true"/>
+ <list-index column="peopleIdx"/>
+ <one-to-many class="Person"/>
+ </list>
+</class>]]></programlisting>
+
+ <para>
+ 만일 기본 외래 키 컬럼이 <literal>NOT NULL</literal>일 경우 콜렉션 매핑의 <literal><key></literal>
+ 요소 상에 <literal>not-null="true"</literal>를 정의하는 것이 중요하다. 내포된
+ <literal><column></literal> 요소 상에 <literal>not-null="true"</literal>를
+ 선언하지 말고, <literal><key></literal> 요소 상에 선언하라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-121">
+ <title>one to one</title>
+
+ <para>
+ <emphasis>foreign에 대한 양방향 one-to-one 연관</emphasis>은 꽤 공통적이다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ unique="true"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <one-to-one name="person"
+ property-ref="address"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ <emphasis>하나의 프라이머리 키에 대한 양방향 one-to-one 연관</emphasis>은 특별한 id 생성기를 사용한다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <one-to-one name="address"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="personId">
+ <generator class="foreign">
+ <param name="property">person</param>
+ </generator>
+ </id>
+ <one-to-one name="person"
+ constrained="true"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( personId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-bidirectional-join" revision="1">
+ <title>join 테이블들에 대한 양방향 연관들</title>
+
+ <sect2 id="assoc-bidirectional-join-12m">
+ <title>one to many / many to one</title>
+
+ <para>
+ <emphasis>하나의 join 테이블에 대한 양방향 one-to-many 연관</emphasis>. <literal>inverse="true"</literal>는
+ 연관의 어느 쪽 끝이든 콜렉션 측으로 또는 join 측으로 갈 수 있다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses"
+ table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ unique="true"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ inverse="true"
+ optional="true">
+ <key column="addressId"/>
+ <many-to-one name="person"
+ column="personId"
+ not-null="true"/>
+ </join>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null primary key )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-join-121">
+ <title>one to one</title>
+
+ <para>
+ <emphasis>하나의 join 테이블에 대한 양방향 one-to-one 연관</emphasis>은 극히 통상적이지 않지만, 가능하다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId"
+ unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true"
+ inverse="true">
+ <key column="addressId"
+ unique="true"/>
+ <many-to-one name="person"
+ column="personId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-join-m2m" revision="1">
+ <title>many to many</title>
+
+ <para>
+ 마지막으로, 우리는 하나의 <emphasis>양방향 many-to-many 연관</emphasis>을 갖는다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <set name="people" inverse="true" table="PersonAddress">
+ <key column="addressId"/>
+ <many-to-many column="personId"
+ class="Person"/>
+ </set>
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-complex">
+ <title>보다 복잡한 연관 매핑들</title>
+
+ <para>
+ 보다 복잡한 연관 조인들은 <emphasis>극기</emphasis> 드물다.
+ Hibernate는 매핑 문서들 내에 삽입된 SQL 조각들을 사용하여 보다 복잡한 상황을 처리하는 것을
+ 가능하도록 해준다. 예를 들어, 만일 계좌 내역 정보 데이터를 가진 하나이 테이블이
+ <literal>accountNumber</literal>, <literal>effectiveEndDate</literal>
+ 그리고 <literal>effectiveStartDate</literal> 컬럼들을 정의할 경우, 다음과 같이 매핑된다:
+ </para>
+
+ <programlisting><![CDATA[<properties name="currentAccountKey">
+ <property name="accountNumber" type="string" not-null="true"/>
+ <property name="currentAccount" type="boolean">
+ <formula>case when effectiveEndDate is null then 1 else 0 end</formula>
+ </property>
+</properties>
+<property name="effectiveEndDate" type="date"/>
+<property name="effectiveStateDate" type="date" not-null="true"/>]]></programlisting>
+
+ <para>
+ 그때 우리는 다음을 사용하여 하나의 연관을 <emphasis>현재</emphasis> 인스턴스
+ (null <literal>effectiveEndDate</literal>을 가진 인스턴스)로 매핑시킬 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="currentAccountInfo"
+ property-ref="currentAccountKey"
+ class="AccountInfo">
+ <column name="accountNumber"/>
+ <formula>'1'</formula>
+</many-to-one>]]></programlisting>
+
+ <para>
+ 보다 복잡한 예제에서, <literal>Employee</literal>와 <literal>Organization</literal> 사이의
+ 연관이 전체 고용 내역 데이터를 가진 <literal>Employment</literal> 테이블 내에 유지된다고 가정하자.
+ 그때 종업원의 <emphasis>가장 최근의</emphasis> 고용주에 대한 하나의 연관(가장 최근의
+ <literal>startDate</literal>를 갖고 있는 것)이 다음 방법으로 매핑될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<join>
+ <key column="employeeId"/>
+ <subselect>
+ select employeeId, orgId
+ from Employments
+ group by orgId
+ having startDate = max(startDate)
+ </subselect>
+ <many-to-one name="mostRecentEmployer"
+ class="Organization"
+ column="orgId"/>
+</join>]]></programlisting>
+
+ <para>
+ 당신은 이 기능으로 아주 생산성을 얻을 수 있지만, 그것은 대개 HQL 또는 criteria 질의를 사용하여 이들 종류의 경우들을
+ 처리하는 것이 보다 실용적이다.
+ </para>
+
+ </sect1>
+
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/basic_mapping.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/basic_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/basic_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/basic_mapping.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,3202 @@
+<chapter id="mapping">
+ <title>기본 O/R 매핑</title>
+
+ <sect1 id="mapping-declaration" revision="1">
+ <title>매핑 선언</title>
+
+ <para>
+ 객체/관계형 매핑들은 대개 XML 문서 내에 정의된다. 매핑 문서는 가독성이 있고 수작업 편집이 가능하도록
+ 설계되어 있다. 매핑 언어는 매핑들이 테이블 선언들이 아닌, 영속 클래스 선언들로 생성된다는 의미에서
+ 자바 중심적이다.
+ </para>
+
+ <para>
+ 심지어 많은 Hibernate 사용자들이 수작업으로 XML을 작성하고자 선택할지라도, XDoclet, Middlegen,
+ 그리고 AndroMDA를 포함하는, 매핑 문서를 생성시키는 많은 도구들이 존재한다는 점을 노트하라.
+ </para>
+
+ <para>
+ 예제 매핑으로 시작하자:
+ </para>
+
+ <programlisting id="mapping-declaration-ex1" revision="1"><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class name="Cat"
+ table="cats"
+ discriminator-value="C">
+
+ <id name="id">
+ <generator class="native"/>
+ </id>
+
+ <discriminator column="subclass"
+ type="character"/>
+
+ <property name="weight"/>
+
+ <property name="birthdate"
+ type="date"
+ not-null="true"
+ update="false"/>
+
+ <property name="color"
+ type="eg.types.ColorUserType"
+ not-null="true"
+ update="false"/>
+
+ <property name="sex"
+ not-null="true"
+ update="false"/>
+
+ <property name="litterId"
+ column="litterId"
+ update="false"/>
+
+ <many-to-one name="mother"
+ column="mother_id"
+ update="false"/>
+
+ <set name="kittens"
+ inverse="true"
+ order-by="litter_id">
+ <key column="mother_id"/>
+ <one-to-many class="Cat"/>
+ </set>
+
+ <subclass name="DomesticCat"
+ discriminator-value="D">
+
+ <property name="name"
+ type="string"/>
+
+ </subclass>
+
+ </class>
+
+ <class name="Dog">
+ <!-- mapping for Dog could go here -->
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 우리는 이제 매핑 문서의 내용을 논의할 것이다. 우리는 Hibernate에 의해 실행 시에 사용되는 문서 요소들과
+ 속성들 만을 설명할 것이다. 매핑 문서는 또한 스키마 내보내기 도구에 의해 내보내진 데이터베이스 스키마에
+ 영향을 주는 어떤 특별한 옵션 속성들과 요소들을 포함한다. (예를 들어 <literal>not-null</literal> 속성.)
+ </para>
+
+
+
+ <sect2 id="mapping-declaration-doctype" revision="3">
+ <title>Doctype</title>
+
+ <para>
+ 모든 XML 매핑들은 doctype이 보이게 선언해야 한다. 실제 DTD는 위의 URL에서,
+ <literal>hibernate-x.x.x/src/org/hibernate</literal> 디렉토리 내에서 또는 <literal>hibernate3.jar</literal>
+ 내에서 찾을 수 있다. Hibernate는 항상 첫 번째로 그것의 classpath 속에서 DTD를 찾게 될 것이다. 만일
+ 당신이 인터넷 연결을 사용하는 DTD에 대한 룩업들을 겪게 될 경우, 당신의 classpath의 컨텐츠에 대해 당신의 DTD 선언을
+ 체크하라.
+ </para>
+
+ <sect3 id="mapping-declaration-entity-resolution">
+ <title>EntityResolver</title>
+ <para>
+ 앞서 언급했듯이, Hibernate는 먼저 그것의 classpath에서 DTD들을 해석하려고 시도할 것이다.
+ Hibernate가 이것을 행하는 방법은 그것이 xml 파일들을 읽어들이는데 사용하는 SAXReader에 맞춤형
+ <literal>org.xml.sax.EntityResolver</literal> 구현을 등록하는 것이다. 이 맞춤형
+ <literal>EntityResolver</literal>는 두 개의 다른 systemId namespace들을 인지해낸다.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>hibernate namespace</literal>는 resolver가
+ <literal>http://hibernate.sourceforge.net/</literal>로 시작하는 하나의
+ systemId와 만날때마다 인지된다; resolver는 Hibernate 클래스들을 로드시켰던 클래스로더를 통해
+ 이들 엔티티들을 해석하려고 시도한다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>user namespace</literal>는 resolver가 <literal>classpath://</literal>
+ URL 프로토콜을 사용하는 systemId를 만날때마다 인지된다; resolver는 (1)현재 쓰레드 컨텍스트
+ 클래스로더와 (2)Hibernate 클래스들을 로드시켰던 클래스로더를 통해 이들 엔티티들을 해석하려고
+ 시도할 것이다.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ user namespacing을 활용하는 예제:
+ </para>
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" [
+ <!ENTITY types SYSTEM "classpath://your/domain/types.xml">
+]>
+
+<hibernate-mapping package="your.domain">
+ <class name="MyEntity">
+ <id name="id" type="my-custom-id-type">
+ ...
+ </id>
+ <class>
+ &types;
+</hibernate-mapping>]]></programlisting>
+ <para>
+ 여기서 <literal>types.xml</literal>은 <literal>your.domain</literal> 패키지 내에 있는 리소스이고
+ 맞춤형 <xref linkend="mapping-types-custom">typedef</xref>를 포함한다.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="mapping-declaration-mapping" revision="3">
+ <title>hibernate-mapping</title>
+
+ <para>
+ 이 요소는 몇 개의 선택적인 속성들을 갖는다. <literal>schema</literal> 속성과 <literal>catalog</literal>
+ 속성은 이 매핑 내에서 참조된 테이블들이 명명된 schema 와/또는 catalog에 속한다는 점을 지정한다. 만일 지정될 경우,
+ 테이블 이름들은 주어진 schema 이름과 catalog 이름에 의해 한정(수식)될 것이다. 누락될 경우, 테이블 이름들은
+ 한정되지((수식어가 붙지) 않을 것이다. <literal>default-cascade</literal> 속성은 <literal>cascade</literal>
+ 속성을 지정하지 않은 프로퍼티들과 콜렉션들에 대해 전제될 <literal>cascade</literal> 스타일이 무엇인지를 지정한다.
+ <literal>auto-import</literal> 속성은 디폴트로 우리가 질의 언어 속에서 수식어가 붙지 않은(unqualified)
+ 클래스 이름들을 사용하게 할 것이다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="hm1" coords="2 55"/>
+ <area id="hm2" coords="3 55"/>
+ <area id="hm3" coords="4 55"/>
+ <area id="hm4" coords="5 55"/>
+ <area id="hm5" coords="6 55"/>
+ <area id="hm6" coords="7 55"/>
+ <area id="hm7" coords="8 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<hibernate-mapping
+ schema="schemaName"
+ catalog="catalogName"
+ default-cascade="cascade_style"
+ default-access="field|property|ClassName"
+ default-lazy="true|false"
+ auto-import="true|false"
+ package="package.name"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="hm1">
+ <para>
+ <literal>schema</literal> (옵션): 데이터베이스 스키마의 이름.
+ </para>
+ </callout>
+ <callout arearefs="hm2">
+ <para>
+ <literal>catalog</literal> (옵션): 데이터베이스 카다록의 이름.
+ </para>
+ </callout>
+ <callout arearefs="hm3">
+ <para>
+ <literal>default-cascade</literal> (옵션 - 디폴트는 <literal>none</literal>):
+ 디폴트 cascade 스타일.
+ </para>
+ </callout>
+ <callout arearefs="hm4">
+ <para>
+ <literal>default-access</literal> (옵션 - 디폴트는 <literal>property</literal>):
+ Hibernate가 모든 프로퍼티들에 액세스하는데 사용하게 될 방도. <literal>PropertyAccessor</literal>에
+ 대한 맞춤형 구현일 수 있다.
+ </para>
+ </callout>
+ <callout arearefs="hm5">
+ <para>
+ <literal>default-lazy</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ class 및 collection 매핑들의 지정되지 않은 <literal>lazy</literal> 속성들에 대한 디폴트 값.
+ </para>
+ </callout>
+ <callout arearefs="hm6">
+ <para>
+ <literal>auto-import</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ 우리가 질의 언어 내에 (이 매핑에서 클래스들에 대해) 수식어가 붙지 않은 클래스 이름들을 사용할 수 있는지를
+ 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="hm7">
+ <para>
+ <literal>package</literal> (옵션): 매핑 문서 내에서 수식어가 붙지 않은 클래스 이름들에 대해
+ 가정할 패키지 접두어를 지정한다.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 만일 당신이 동일한 (수식어가 붙지 않은) 이름을 가진 두 개의 영속 클래스들을 갖고 있다면, 당신은 <literal>auto-import="false"</literal>를
+ 설정해야 한다. 만일 당신이 두 개의 클래스들에 동일한 "imported" 이름을 할당하려고 시도할 경우에 Hibernate는 예외상황을 던질 것이다.
+ </para>
+
+ <para>
+ 위에 보여진 것처럼 <literal>hibernate-mapping</literal> 요소는 몇몇 영속 <literal><class></literal> 매핑들을 내부에 포함하는
+ 것을 허용해준다는 점을 노트하라. 하지만 한 개의 매핑 파일 속에 한 개의 영속 클래스(또는 한 개의 클래스 계층구조) 만을 매핑하고 영속 서브 클래스 뒤에
+ 그것을 명명하는 것이 좋은 연습이다 (그리고 몇몇 도구들에 의해 기대된다). 예를 들면 <literal>Cat.hbm.xml</literal>,
+ <literal>Dog.hbm.xml</literal> 또는 상속을 사용할 경우에는 <literal>Animal.hbm.xml</literal>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-class" revision="3">
+ <title>class</title>
+
+ <para>
+ 당신은 <literal>class</literal> 요소를 사용하여 영속 클래스를 선언할 수도 있다:
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="class1" coords="2 55"/>
+ <area id="class2" coords="3 55" />
+ <area id="class3" coords="4 55"/>
+ <area id="class4" coords="5 55" />
+ <area id="class5" coords="6 55"/>
+ <area id="class6" coords="7 55" />
+ <area id="class7" coords="8 55"/>
+ <area id="class8" coords="9 55" />
+ <area id="class9" coords="10 55" />
+ <area id="class10" coords="11 55"/>
+ <area id="class11" coords="12 55"/>
+ <area id="class12" coords="13 55"/>
+ <area id="class13" coords="14 55"/>
+ <area id="class14" coords="15 55"/>
+ <area id="class15" coords="16 55"/>
+ <area id="class16" coords="17 55"/>
+ <area id="class17" coords="18 55"/>
+ <area id="class18" coords="19 55"/>
+ <area id="class19" coords="20 55"/>
+ <area id="class20" coords="21 55"/>
+ <area id="class21" coords="22 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<class
+ name="ClassName"
+ table="tableName"
+ discriminator-value="discriminator_value"
+ mutable="true|false"
+ schema="owner"
+ catalog="catalog"
+ proxy="ProxyInterface"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ select-before-update="true|false"
+ polymorphism="implicit|explicit"
+ where="arbitrary sql where condition"
+ persister="PersisterClass"
+ batch-size="N"
+ optimistic-lock="none|version|dirty|all"
+ lazy="true|false"
+ entity-name="EntityName"
+ check="arbitrary sql check condition"
+ rowid="rowid"
+ subselect="SQL expression"
+ abstract="true|false"
+ node="element-name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="class1">
+ <para>
+ <literal>name</literal> (옵션): 영속 클래스(또는 인터페이스)의 전체 수식어가 붙은 Java 클래스 이름.
+ 만일 이 속성이 누락될 경우, 매핑이 non-POJO 엔티티라고 가정된다.
+ </para>
+ </callout>
+ <callout arearefs="class2">
+ <para>
+ <literal>table</literal> (옵션 - 디폴트는 수식어가 붙지 않은 클래스명): 그것의 데이터베이스 테이블의 이름.
+ </para>
+ </callout>
+ <callout arearefs="class3">
+ <para>
+ <literal>discriminator-value</literal> (옵션 - 디폴트는 클래스 이름): 다형성(polymorphic) 특징에 사용되는,
+ 개별 서브 클래스들를 구별짓는 값. 허용가능한 값들은<literal>null</literal>과 <literal>not null</literal>을 포함한다.
+ </para>
+ </callout>
+ <callout arearefs="class4">
+ <para>
+ <literal>mutable</literal> (옵션 - 디폴트는 <literal>true</literal>): 클래스들의 인스턴스들이 가변적인지를
+ (가변적이지 않은지를) 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="class5">
+ <para>
+ <literal>schema</literal> (옵션): 루트 <literal><hibernate-mapping></literal> 요소에 의해 지정된
+ 스키마 이름을 오버라이드 시킨다.
+ </para>
+ </callout>
+ <callout arearefs="class6">
+ <para>
+ <literal>catalog</literal> (옵션): 루트 <literal><hibernate-mapping></literal> 요소에 의해 지정된
+ 카다록 이름을 오버라이드 시킨다.
+ </para>
+ </callout>
+ <callout arearefs="class7">
+ <para>
+ <literal>proxy</literal> (옵션): lazy initializing proxy들에 사용할 인터페이스를 지정한다. 당신은 클래스
+ 그 자체의 이름을 지정할 수 도 있다.
+ </para>
+ </callout>
+ <callout arearefs="class8">
+ <para>
+ <literal>dynamic-update</literal> (옵션 - 디폴트는 <literal>false</literal>):
+ <literal>UPDATE</literal> SQL이 실행 시에 생성되고 그들 컬럼들의 값들이 변경된 그들 컬럼들 만을
+ 포함할 것인지를 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="class9">
+ <para>
+ <literal>dynamic-insert</literal> (옵션 - 디폴트는 <literal>false</literal>):
+ 생성될 <literal>INSERT</literal>이 실행 시에 생성되고 그들 컬럼들의 값이 null이 아닌 컬럼들 만을
+ 포함할 것인지를 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="class10">
+ <para>
+ <literal>select-before-update</literal> (옵션 - 디폴트는 <literal>false</literal>):
+ 객체가 실제로 변경되는 것이 확실하지 않는 한, Hibernate가 SQL <literal>UPDATE</literal>를
+ <emphasis>결코</emphasis> 실행하지 않을 것임을 지정한다. 어떤 경우들에서(실제로 transient
+ 객체가 <literal>update()</literal>를 사용하여 새로운 session에 연관되었을 때에만), 이것은
+ 하나의 <literal>UPDATE</literal>가 실제로 필요한 경우인지 여부를 결정하기 위해 Hibernate는
+ 특별한 SQL <literal>SELECT</literal>를 실행할 것임을 의미한다.
+ </para>
+ </callout>
+ <callout arearefs="class11">
+ <para>
+ <literal>polymorphism</literal> (옵션 - 디폴트는 <literal>implicit</literal>):
+ implicit 질의 다형성이나 explicit 질의 다형성 중 어느 것이 사용될 것인지를 결정한다.
+ </para>
+ </callout>
+ <callout arearefs="class12">
+ <para>
+ <literal>where</literal> (옵션) 이 클래스의 객체들을 검색할 때 사용될 임의적인 SQL
+ <literal>WHERE</literal> 조건을 지정한다
+ </para>
+ </callout>
+ <callout arearefs="class13">
+ <para>
+ <literal>persister</literal> (옵션): 맞춤형 <literal>ClassPersister</literal>를 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="class14">
+ <para>
+ <literal>batch-size</literal> (옵션 - 디폴트는 <literal>1</literal>) 식별자에 의해 이 클래스의
+ 인스턴스들을 페치시키는 "배치 사이즈"를 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="class15">
+ <para>
+ <literal>optimistic-lock</literal> (옵션 - 디폴트는 <literal>version</literal>):
+ optimistic 잠금 방도를 결정한다.
+ </para>
+ </callout>
+ <callout arearefs="class16">
+ <para>
+ <literal>lazy</literal> (옵션): <literal>lazy="false"</literal>를 설정함으로써
+ Lazy fetching이 전체적으로 사용불가능하게 될 수 있다.
+ </para>
+ </callout>
+ <callout arearefs="class17">
+ <para>
+ <literal>entity-name</literal>(옵션, 디폴트는 클래스 이름): Hibernate3는 하나의 클래스가
+ (잠정적으로 다른 테이블들로) 여러번 매핑되는 것을 허용해주고, Java 레벨에서 Map 또는 XML에 의해 표현
+ 되는 엔티티 매핑들을 허용한다. 이들 경우들에서, 당신은 그 엔티티에 대한 명시적인 임의의 이름을 제공해야 한다.
+ <literal>entity-name</literal> (옵션): Hibernate3는 하나의 클래스가 (잠정적으로 다른 테이블들로)
+ 여러 번 매핑되는 것을 허용하며, 자바 레벨에서 Map들 또는 XML에 의해 표현되는 엔티티 매핑들을 허용한다.
+ 이들 경우들에서, 당신은 그 엔티티들에 대한 명시적인 임의의 이름을 제공해야 한다. 추가 정보는
+ <xref linkend="persistent-classes-dynamicmodels"/>과 <xref linkend="xml"/>을 보라.
+ </para>
+ </callout>
+ <callout arearefs="class18">
+ <para>
+ <literal>check</literal> (옵션): 자동적인 스키마 생성을 위한 다중-행 <emphasis>check</emphasis>
+ constraint를 생성시키는데 사용되는 SQL 표현식.
+ </para>
+ </callout>
+ <callout arearefs="class19">
+ <para>
+ <literal>rowid</literal> (옵션): Hibernate는 지원되는 데이터베이스들, 예를 들어 Oracle 상에서 이른바
+ ROWID들을 사용할 수 있고, Hibernate는 당신이 이 옵션을 <literal>rowid</literal>로 설정하는 경우에 빠른
+ 업데이트를 위한 특별한 <literal>rowid</literal> 컬럼을 사용할 수 있다. ROWID는 구현 상세이고 저장된
+ 튜플(tuple)의 물리적이니 위치를 표현한다.
+ </para>
+ </callout>
+ <callout arearefs="class20">
+ <para>
+ <literal>subselect</literal> (옵션): 불변의 읽기 전용 엔티티를 데이터베이스 subselect로 매핑시킨다.
+ 당신이 기본 테이블 대신에 뷰를 갖고자 원할 경우에 유용하지만, 사용을 자제하라. 추가 정보는 아래를 보라.
+ </para>
+ </callout>
+ <callout arearefs="class21">
+ <para>
+ <literal>abstract</literal> (옵션): <literal><union-subclass></literal> 계층 구조들 내에서
+ abstract 슈퍼클래스들을 마크하는데 사용된다.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 명명된 영속 클래스가 인터페이스가 되는 것은 완전히 수용가능하다. 그런 다음 당신은 <literal><subclass></literal>
+ 요소를 사용하여 그 인터페이스에 대한 구현 클래스들을 선언할 것이다. 당신은 임의의 <emphasis>static</emphasis> inner
+ 클래스를 영속화 시킬 수 있다. 당신은 표준 형식, 예를 들어 <literal>eg.Foo$Bar</literal>를 사용하여 클래스 이름을
+ 지정해야 한다.
+ </para>
+
+ <para>
+ 불변의 클래스, <literal>mutable="false"</literal>는 어플리케이션에 의해 업데이트되지 않을 것이거나 삭제되지 않을 것이다.
+ 이것은 Hibernate로 하여금 어떤 마이너 퍼포먼스 최적화를 행하게끔 허용해준다.
+ </para>
+
+ <para>
+ 선택적인 <literal>proxy</literal> 속성은 그 클래스의 영속 인스턴스들에 대한 lazy 초기화를 가능하게 해준다. Hibernate는
+ 명명된 인터페이스를 구현하는 CGLIB 프락시들을 초기에 반환할 것이다. 실제 영속 객체는 프락시의 메소드가 호출될 때 로드될 것이다.
+ 아래 "Lazy 초기화를 위한 프락시들"을 보라.
+ </para>
+
+ <para><emphasis>Implicit</emphasis> 다형성은 클래스의 인스턴스들이 어떤 서브클래스나 구현된 인터페이스 또는 클래스를 명명하는
+ 질의에 의해 반환될 것임을 의미하고 그 클래스의 어떤 서브클래스에 대한 인스턴스들이 그 클래스 자체를 명명하는 질의에 의해 반환될 것임을
+ 의미한다. <emphasis>Explicit</emphasis> 다형성은 클래스 인스턴스들이 그 클래스를 명시적으로 명명하는 질의들에 의해서만
+ 반환될 것임을 의미고 그 클래스를 명명하는 질의들이 이 <literal><class></literal> 선언 내부에서 <literal><subclass></literal>
+ 또는 <literal><joined-subclass></literal>로 매핑된 서브 클래스들의 인스턴스들 만을 반환하게 될 것임을 의미한다.
+ 대부분의 용도로, 디폴트인 <literal>polymorphism="implicit"</literal>가 적절하다.두 개의 다른 클래스들이 동일한 테이블로
+ 매핑될 때 Explicit 다형성이 유용하다(이것은 테이블 컬럼들의 서브셋을 포함하는 "경량급" 클래스를 허용한다).
+ </para>
+
+ <para>
+ <literal>persister</literal> 속성은 클래스에 사용되는 영속화 방도를 당신이 커스트마이징 할 수 있도록 해준다. 예를 들어
+ 당신은 <literal>org.hibernate.persister.EntityPersister</literal>에 대한 당신 자신의 서브클래스를 지정할 수도
+ 있거나 당신은 심지어 예를 들어 플랫 파일들이나 LDAP로의 직렬화,내장 프로시저 호출들을 통해 영속화를 구현하는 인터페이스
+ <literal>org.hibernate.persister.ClassPersister</literal>에 대한 완전히 새로운 구현을 제공할 수도 있다.
+ (<literal>Hashtable</literal>로의 "영속성"에 관한) 간단한 예제는
+ <literal>org.hibernate.test.CustomPersister</literal>를 보라.
+ </para>
+
+ <para>
+ <literal>dynamic-update</literal> 설정과 <literal>dynamic-insert</literal> 설정은 서브클래스들에 의해
+ 상속되지 않고 따라서 또한 <literal><subclass></literal> 또는 <literal><joined-subclass></literal>
+ 요소들 상에 지정될 수도 있음을 노트하라. 이들 설정들은 몇몇 경우들에서 퍼포먼스를 증가시키지만 다른 경우들에서는 퍼포먼스를
+ 실제로 감소시킬 수도 있다. 적절하게 사용하라.
+ </para>
+
+ <para>
+ <literal>select-before-update</literal> 사용은 대개 퍼포먼스를 감소시킬 것이다. 당신이 detached 인스턴스들의
+ 그래프를 <literal>Session</literal>에 다시 첨부할 경우에 그것은 데이터베이스 업데이트 트리거가 불필요하게 호출되는
+ 것을 방지하는데 매우 유용하다.
+ </para>
+
+ <para>
+ <literal>dynamic-update</literal>를 사용가능하게 할 경우, 당신은 다음 optimistic 잠금 전략들을 선택하게 될 것이다:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>version</literal>은 version/timestamp 컬럼들을 체크한다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>all</literal>은 모든 컬럼들을 체크한다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>dirty</literal>는 몇몇 동시성 업데이트들을 허용하여, 변경된 컬럼들을 체크한다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>none</literal>은 optimistic 잠금을 사용하지 않는다
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ 우리는 당신이 Hibernate에서 optimistic 잠금을 위해 version/timestamp 컬럼들을 사용할 것을 <emphasis>매우</emphasis> 강력하게
+ 권장한다. 이것은 퍼포먼스에 대해 최적의 방도이고 detached 인스턴스들에 대해 행해진 변경들을 정확하게 핸들링하는 유일한 방도이다(예를 들어
+ <literal>Session.merge()</literal>가 사용될 때).
+ </para>
+
+ <para>
+ Hibernate 매핑의 경우에 베이스 테이블과 뷰 사이에 차이점이 존재하지 않는다. 왜냐하면 이것이 데이터베이스 레벨에서는 투명하다고 기대되기
+ 때문이다(몇몇 DBMS는 뷰를 고유하게 지원하지 않고 특히 뷰 업데이트를 지원하지 않음을 노트하라). 때때로 당신이 뷰를 사용하고자 원하지만,
+ (예를 들어 리거시 스키마로) 데이터베이스 속에 뷰를 생성시킬 수 없다. 이 경우에, 당신은 불변의 읽기 전용 엔티티를 주어진 SQL subselect
+ 표현식으로 매핑시킬 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<class name="Summary">
+ <subselect>
+ select item.name, max(bid.amount), count(*)
+ from item
+ join bid on bid.item_id = item.id
+ group by item.name
+ </subselect>
+ <synchronize table="item"/>
+ <synchronize table="bid"/>
+ <id name="name"/>
+ ...
+</class>]]></programlisting>
+
+ <para>
+ auto-flush가 정확하게 발생하도록 하고, 그리고 파생된 엔티티에 대한 질의들이 쓸효성 없는 데이터를 반환하지 않도록 함으로써, 이 엔티티와 동기화 될
+ 테이블을 선언하라. <literal><subselect></literal>는 속성과 내포된 매핑 요소 양자로서 이용 가능하다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-id" revision="4">
+ <title>id</title>
+
+ <para>
+ 매핑된 클래스들은 데이터베이스 테이블의 프라이머리 키 컬럼을 선언<emphasis>해야 한다</emphasis>. 대부분의 클래스들은 또한 인스턴스의 유일 식별자를 소유하는
+ 자바빈즈-스타일 프로퍼티를 가질 것이다. <literal><id></literal> 요소는 그 프로퍼티로부터 프라이머리 키 컬럼으로의 매핑을 정의한다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="id1" coords="2 70"/>
+ <area id="id2" coords="3 70" />
+ <area id="id3" coords="4 70"/>
+ <area id="id4" coords="5 70" />
+ <area id="id5" coords="6 70" />
+ </areaspec>
+ <programlisting><![CDATA[<id
+ name="propertyName"
+ type="typename"
+ column="column_name"
+ unsaved-value="null|any|none|undefined|id_value"
+ access="field|property|ClassName">
+ node="element-name|@attribute-name|element/@attribute|."
+
+ <generator class="generatorClass"/>
+</id>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="id1">
+ <para>
+ <literal>name</literal> (옵션): 식별자 프로퍼티의 이름.
+ </para>
+ </callout>
+ <callout arearefs="id2">
+ <para>
+ <literal>type</literal> (옵션): Hibernate 타입을 나타내는 이름.
+ </para>
+ </callout>
+ <callout arearefs="id3">
+ <para>
+ <literal>column</literal> (옵션 - 디폴트는 프로퍼티 이름): 프라이머리 키 컬럼의 이름.
+ </para>
+ </callout>
+ <callout arearefs="id4">
+ <para>
+ <literal>unsaved-value</literal> (옵션 - 디폴트는 "sensible" 값):
+ 이전 세션에서 저장되었거나 로드되었던 detached(분리된) 인스턴스들로부터 그것을 구분지우도록, 인스턴스가 새로이 초기화되어 있음(저장되어
+ 있지 않음)을 나타내는 식별자 프로퍼티 값.
+ </para>
+ </callout>
+ <callout arearefs="id5">
+ <para>
+ <literal>access</literal> (옵션 - 디폴트는 <literal>property</literal>):
+ Hibernate가 프로퍼티 값에 액세스하는데 사용할 방도.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <literal>name</literal> 속성이 누락되면, 클래스는 식별자 프로퍼티를 갖지 않는다고 가정된다.
+ </para>
+
+ <para>
+ <literal>unsaved-value</literal> 속성은 Hibernate3에서는 거의 필요하지 않다.
+ </para>
+
+ <para>
+ composite 키들로서 리거시 데이터에 액세스하는 것을 허용해주는 대체적인 <literal><composite-id></literal>
+ 선언이 존재한다. 우리는 그 밖의 어떤것에 대한 그것의 사용에 대해 강력하게 반대한다.
+ </para>
+
+ <sect3 id="mapping-declaration-id-generator" revision="2">
+ <title>Generator</title>
+
+ <para>
+ 선택적인 <literal><generator></literal> 자식 요소는 영속 클래스의 인스턴스들에 대한 유일 식별자들을 생성시키는데 사용되는
+ 자바 클래스를 명명한다. 만일 임의의 파라미터들이 생성기 인스턴스를 구성하거나 초기화 시키는데 필요할 경우, 그것들은 <literal><param></literal>
+ 요소 를 사용하여 전달된다.
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+ <generator class="org.hibernate.id.TableHiLoGenerator">
+ <param name="table">uid_table</param>
+ <param name="column">next_hi_value_column</param>
+ </generator>
+</id>]]></programlisting>
+
+ <para>
+ 모든 생성기들은 <literal>org.hibernate.id.IdentifierGenerator</literal> 인터페이스를 구현한다. 이것은 매우 간단한 인터페이스이다;
+ 몇몇 어플리케이션들은 그것들 자신의 특화된 구현들을 제공하도록 선택할 수 있다. 하지만 Hibernate는 미리 빈드된 구현들의 영역들을 제공한다.
+ 빌드-인 생성기(generator)들에 대한 단축 이름들이 존재한다:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>increment</literal></term>
+ <listitem>
+ <para>
+ 동일한 테이블 속으로 데이터를 입력하는 다른 프로세스가 없을 때에만 유일한 <literal>long</literal>, <literal>short</literal> 또는 <literal>int</literal>
+ 타입의 식별자들을 생성시킨다. <emphasis>클러스터 내에서는 사용하지 말라.</emphasis>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>identity</literal></term>
+ <listitem>
+ <para>
+ DB2, MySQL, MS SQL Server, Sybase, HypersonicSQL에서 식별 컬럼들을 지원한다. 반환되는 식별자는 <literal>long</literal>,
+ <literal>short</literal> 또는 <literal>int</literal> 타입이다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>sequence</literal></term>
+ <listitem>
+ <para>
+ DB2, PostgreSQL, Oracle, SAP DB, McKoi에서 시퀀스를 사용하거나 Interbase에서 생성기(generator)를 사용한다. 반환되는 식별자는
+ <literal>long</literal>, <literal>short</literal> 또는 <literal>int</literal> 타입이다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>hilo</literal></term>
+ <listitem>
+ <para id="mapping-declaration-id-hilodescription" revision="1">
+ 테이블과 컬럼(디폴트로 각각 <literal>hibernate_unique_key</literal>와 <literal>next_hi</literal>)이 hi 값들의
+ 소스로서 주어지면, <literal>long</literal>, <literal>short</literal> 또는 <literal>int</literal> 타입의
+ 식별자들을 효과적으로 생성시키는데 hi/lo 알고리즘을 사용한다. hi/lo 알고리즘은 특정 데이터베이스에 대해서만 유일한 식별자들을
+ 생성시킨다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>seqhilo</literal></term>
+ <listitem>
+ <para>
+ 명명된 데이터베이스 시퀀스가 주어지면, <literal>long</literal>, <literal>short</literal> 또는 <literal>int</literal>
+ 타입의 식별자들을 효과적으로 생성시키는데 hi/lo 알고리즘을 사용한다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>uuid</literal></term>
+ <listitem>
+ <para>
+ 네트웍 내에서 유일한(IP 주소가 사용된다) string 타입의 식별자들을 생성시키기 위해 128 비트 UUID 알고리즘을 사용한다.
+ UUID는 길이가 32인 16진수들의 문자열로서 인코딩 된다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>guid</literal></term>
+ <listitem>
+ <para>
+ MS SQL Server와 MySQL 상에서 데이터베이스 생성 GUID 문자열을 사용한다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>native</literal></term>
+ <listitem>
+ <para>
+ 기본 데이터베이스의 가용성들에 의존하여 <literal>identity</literal>, <literal>sequence</literal>
+ 또는 <literal>hilo</literal>를 찾아낸다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>assigned</literal></term>
+ <listitem>
+ <para>
+ 어플리케이션으로 하여금 <literal>save()</literal>가 호출되기 전에 식별자를 객체에 할당하도록 한다.
+ <literal><generator></literal> 요소가 지정되지 않을 경우 이것이 디폴트 방도이다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>select</literal></term>
+ <listitem>
+ <para>
+ 어떤 유일 키에 의해 행을 select하고 프라이머리 키 값을 검색함으로써 데이터베이스 트리거에 의해 할당된
+ 프라이머리 키를 검색한다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>foreign</literal></term>
+ <listitem>
+ <para>
+ 또 다른 연관된 객체의 식별자를 사용한다. 대개 <literal><one-to-one></literal> 프라이머리 키
+ 연관관계와 함께 사용된다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>sequence-identity</literal></term>
+ <listitem>
+ <para>
+ 실제 값 생성을 위해 데이터베이스 시퀀스를 활용하지만, 생성된 식별자 값을 insert 문장 실행의 부분으로서
+ 실제로 반환시키기 위해 이것을 JDBC3 getGeneratedKeys와 결합시킨 특화된 시퀀스 생성 방도. 이 방도는
+ JDK 1.4에 대상화된 Oracle 10g 드라이버들 상에서만 지원되는 거승로 알려져 있다. 이들 insert 문장들에
+ 대한 주석들은 Oracle 드라이버들 내에 있는 버그 때문에 사용불가능하게 되어 있음을 노트하라.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-hilo" revision="1">
+ <title>Hi/lo algorithm</title>
+ <para>
+ <literal>hilo</literal>와 <literal>seqhilo</literal> 생성기들은 식별자 생성에 대한 마음에 드는 접근법인,
+ hi/lo 알고리즘에 대한 두 개의 대체 구현들은 제공한다. 첫 번째 구현은 다음에 이용 가능한 "hi" 값을 수용하기 위한 "특별한"
+ 데이터베이스 테이블을 필요로 한다. 두 번째는 (지원되는) Oracle 스타일의 시퀀스를 사용한다.
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+ <generator class="hilo">
+ <param name="table">hi_value</param>
+ <param name="column">next_value</param>
+ <param name="max_lo">100</param>
+ </generator>
+</id>]]></programlisting>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+ <generator class="seqhilo">
+ <param name="sequence">hi_value</param>
+ <param name="max_lo">100</param>
+ </generator>
+</id>]]></programlisting>
+
+ <para>
+ 불행히도 당신은 Hibernate에 당신 자신의 <literal>Connection</literal>을 제공할 때 <literal>hilo</literal>를
+ 사용할 수 없다. Hibernate가 JTA의 도움을 받는 커넥션들을 얻기 위해 어플리케이션 서버 데이터소스를 사용할 때 당신은
+ <literal>hibernate.transaction.manager_lookup_class</literal>를 적절하게 구성해야 한다.
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-uuid">
+ <title>UUID 알고리즘</title>
+ <para>
+ UUID 는 다음을 포함한다: IP 주소, JVM의 시작 시간(정확히 1/4 초), 시스템 시간과 (JVM 내에서 유일한) counter 값.
+ Java 코드로부터 MAC 주소 또는 메모리 주소를 얻는 것은 불가능하여서, 이것은 우리가 JNI를 사용하지 않고서 행할 수 있는
+ 최상의 것이다.
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-sequences">
+ <title>식별 컬럼들과 시퀀스들</title>
+ <para>
+ 식별 컬럼들을 지원하는 데이터베이스들(DB2, MySQL, Sybase, MS SQL)의 경우, 당신은 <literal>identity</literal> 키
+ 생성을 사용할 수 있다. 시퀀스들을 지원하는 데이터베이스들(DB2, Oracle, PostgreSQL, Interbase, McKoi, SAP DB)의
+ 경우, 당신은 <literal>sequence</literal> 스타일 키 생성을 사용할 수도 있다. 이들 방도들 모두 새로운 객체를 insert하기
+ 위해 두 개의 SQL 질의들을 필요로 한다.
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="person_id">
+ <generator class="sequence">
+ <param name="sequence">person_id_sequence</param>
+ </generator>
+</id>]]></programlisting>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="person_id" unsaved-value="0">
+ <generator class="identity"/>
+</id>]]></programlisting>
+
+ <para>
+ 크로스 플랫폼 개발을 위해서, <literal>native</literal> 방도가 기준 데이터베이스들의 가용성들에 따라 <literal>identity</literal>,
+ <literal>sequence</literal>, <literal>hilo</literal> 방도 중에서 선택될 것이다.
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-assigned">
+ <title>할당된 식별자들</title>
+ <para>
+ (Hibernate로 하여금 식별자들을 생성시키도록 하는 것과는 반대로) 당신이 어플리케이션으로 하여금 식별자들을 할당하도록 원할 경우,
+ 당신은 <literal>assigned</literal> 생성기를 사용할 수 있다. 이 특별한 생성기는 객체의 identifier 프로퍼티에 이미 할당된
+ 식별자 값을 사용할 것이다. 이 생성기(generator)는 프라이머리 키가 대용(surrogate ) 키 대신에 natural 키일 때 사용된다.
+ 당신이 <literal><generator></literal> 요소를 지정하지 않을 경우에 이것이 디폴트 특징이다
+ </para>
+
+ <para>
+ <literal>assigned</literal> 생성기(generator)를 선택하는 것은 , version 또는 timestamp 프로퍼티가 존재하지 않는 한
+ 또는 당신이 <literal>Interceptor.isUnsaved()</literal>를 정의하지 않는 한, 하나의 인스턴스가 transient 또는 detached인지를
+ 결정하기 위해 Hibernae로 하여금 데이터베이스에 접촉하도록 강제하는, <literal>unsaved-value="undefined"</literal>를
+ Hibernate에게 사용하도록 한다.
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-select">
+ <title>트리거들에 의해 할당된 프라이머리 키들</title>
+ <para>
+ 리거시 스키마에 대해서만(Hibernate는 트리거들을 가진 DDL을 생성시키지 않는다).
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="person_id">
+ <generator class="select">
+ <param name="key">socialSecurityNumber</param>
+ </generator>
+</id>]]></programlisting>
+
+ <para>
+ 위의 예제에서, natural 키로서 클래스에 의해 <literal>socialSecurityNumber</literal>로 명명된 유일 값을 가진 프로퍼티가 존재하고,
+ 트리거에 의해 그 값이 생성되는 <literal>person_id</literal>로 명명된 대용키가 존재한다.
+ </para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-compositeid" revision="3">
+ <title>composite-id</title>
+
+ <programlisting><![CDATA[<composite-id
+ name="propertyName"
+ class="ClassName"
+ mapped="true|false"
+ access="field|property|ClassName">
+ node="element-name|."
+
+ <key-property name="propertyName" type="typename" column="column_name"/>
+ <key-many-to-one name="propertyName class="ClassName" column="column_name"/>
+ ......
+</composite-id>]]></programlisting>
+
+ <para>
+ composite 키를 가진 테이블의 경우, 당신은 클래스의 여러 프로퍼티들을 식별자 프로퍼티들로서 매핑할 수 있다.
+ <literal><composite-id></literal> 요소는 자식 요소들로서 <literal><key-property></literal>
+ 프로퍼티 매핑과 <literal><key-many-to-one></literal> 매핑들을 허용한다.
+ </para>
+
+ <programlisting><![CDATA[<composite-id>
+ <key-property name="medicareNumber"/>
+ <key-property name="dependent"/>
+</composite-id>]]></programlisting>
+
+ <para>
+ 당신의 영속 클래스는 composite 식별자 동등성을 구현하기 위해서 <literal>equals()</literal>와
+ <literal>hashCode()</literal>를 오버라이드 <emphasis>시켜야 한다</emphasis>. 그것은 또한
+ <literal>Serializable</literal>을 구현해야 한다.
+ </para>
+
+ <para>
+ 불행히도, composite 식별자들에 대한 이 접근법은 영속 객체가 그것 자신의 식별자라는 점을 의미한다. 객체
+ 자신 외의 다른 "핸들"이 존재하지 않는다. 당신은 당신이 composite key로 연관된 영속 상태를 <literal>load()</literal>
+ 할 수 있기 이전에 영속 클래스 그 자체의 인스턴스를 초기화 하고 그것의 식별자 프로퍼티들을 군집화 시켜야 한다. 우리는
+ 이 접근법을 <emphasis>embedded</emphasis> composite 식별자로 부르고, 중대한 어플리케이션들에 대해 그것을 억제시킨다.
+ </para>
+
+ <para>
+ 두 번째 접근법은 우리가 <emphasis>mapped</emphasis> composite 식별자라고 부르는 것인데, 여기서
+ <literal><composite-id></literal> 요소 내에 명명된 여기서 식별자 프로퍼티들은 영속 클래스와 별도의 식별자 클래스
+ 양자 상에 중복된다.
+ </para>
+
+ <programlisting><![CDATA[<composite-id class="MedicareId" mapped="true">
+ <key-property name="medicareNumber"/>
+ <key-property name="dependent"/>
+</composite-id>]]></programlisting>
+
+ <para>
+ 이 예제에서, composite 식별자 클래스인 <literal>MedicareId</literal>와 엔티티 크래스 그 자체 양자는
+ <literal>medicareNumber</literal>와 <literal>dependent</literal>로 명명된 프로퍼티들을 갖는다. 식별자 클래스는
+ <literal>equals()</literal>와 <literal>hashCode()</literal>를 오버라이드 시켜고 <literal>Serializable</literal>을
+ 구현해야 한다. 이 접근법의 단점은 아주 명백한—코드 중복이다.
+ </para>
+
+ <para>
+ 다음 속성들은 매핑된 composite 식별자를 지정하는데 사용된다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>mapped</literal> (옵션, 디폴트는 <literal>false</literal>):
+ 하나의 매핑된 composite 식별자가 사용됨을, 그리고 포함된 프로퍼티 매핑들이 엔티티 클래스와
+ composite 식별자 클래스 양자를 참조함을 나타낸다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>class</literal> (옵션, 하지만 하나의 매핑된 commposite 식별자에 대해서는 필수적임):
+ 하나의 composite 식별자로서 사용되는 클래스.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 우리는 <xref linkend="components-compositeid"/>에서 composite 식별자가 하나의 component 클래스로서 구현되는
+ 보다 편리한 접근법인 세번째 방도를 설명할 것이다. 아래에 설명되어 있는 속성들은 이 대체적인 접근법에만 적용된다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>name</literal> (옵션, 이 접근법의 경우에는 필수임): 하나의 component
+ 식별자를 소유하는 컴포넌트 타입의 프로퍼티(9장을 보라).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>access</literal> (옵션 - 디폴트는 <literal>property</literal>):
+ Hibernate가 프로퍼티 값에 접근하는데 사용할 방도.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>class</literal> (옵션 - 디폴트는 reflection에 의해 결정된 프로퍼티 타입):
+ 하나의 composite 식별자로서 사용되는 컴포넌트 클래스(다음 절을 보라).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 이 세번째 접근법, <emphasis>identifier component</emphasis>은 거의 모든 어플리케이션들에 대해 우리가 권장하는 것이다.
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-declaration-discriminator" revision="3">
+ <title>discriminator</title>
+
+ <para>
+ <literal><discriminator></literal> 요소는 table-per-class-hierarchy(테이블 당 클래스 계층구조)
+ 매핑 방도를 사용하는 다형성 영속화에 필요하고 테이블의 discriminator(판별자) 컬럼을 선언한다. discriminator 컬럼은
+ 특정 행에 대해 초기화 시킬 서브 클래스가 무엇인지를 영속 계층에 알려주는 표시자 값들을 포함한다. 타입들의 제한적인 집합이
+ 사용될 수 있다: <literal>string</literal>, <literal>character</literal>, <literal>integer</literal>,
+ <literal>byte</literal>, <literal>short</literal>, <literal>boolean</literal>,
+ <literal>yes_no</literal>, <literal>true_false</literal>.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="discriminator1" coords="2 60"/>
+ <area id="discriminator2" coords="3 60" />
+ <area id="discriminator3" coords="4 60" />
+ <area id="discriminator4" coords="5 60" />
+ <area id="discriminator5" coords="6 60" />
+ </areaspec>
+ <programlisting><![CDATA[<discriminator
+ column="discriminator_column"
+ type="discriminator_type"
+ force="true|false"
+ insert="true|false"
+ formula="arbitrary sql expression"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="discriminator1">
+ <para>
+ <literal>column</literal> (옵션 - 디폴트는 <literal>class</literal>)
+ discriminator 컬럼명.
+ </para>
+ </callout>
+ <callout arearefs="discriminator2">
+ <para>
+ <literal>type</literal> (옵션 - 디폴트는 <literal>string</literal>)
+ Hibernate 타입을 나타내는 이름
+ </para>
+ </callout>
+ <callout arearefs="discriminator3">
+ <para>
+ <literal>force</literal> (옵션 - 디폴트는 <literal>false</literal>)
+ 이것은 Hibernate로 하여금 루트 클래스의 모든 인스턴스들을 검색할 때조차도 허용된 discriminator
+ 값들을 지정하도록 "강제한다".
+ </para>
+ </callout>
+ <callout arearefs="discriminator4">
+ <para>
+ <literal>insert</literal> (옵션 - 디폴트는 <literal>true</literal>)
+ 당신의 discriminator 컬럼이 또한 매핑된 composite 식별자의 부분일 경우에 이것을 <literal>false</literal>로 설정하라.
+ (Hibernate에게 SQL <literal>INSERT</literal>들 속에 그 컬럼을 포함하지 않도록 통보한다.)
+ </para>
+ </callout>
+ <callout arearefs="discriminator5">
+ <para>
+ <literal>formula</literal> (옵션)
+ 타입이 평가 되어야 할 때 실행되는 임의의 SQL 표현식. 컨텐츠 기반의 판별을 허용해준다.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ discriminator 컬럼의 실제 값들은 <literal><class></literal> 요소와
+ <literal><subclass></literal> 요소의 <literal>discriminator-value</literal> 속성에 의해 지정된다.
+ </para>
+
+ <para>
+ <literal>force</literal> 속성은 테이블이 영속 클래스로 매핑되지 않는 "특별한" discriminator 값들을 가진 행들을
+ 포함할 경우에(만) 유용하다. 이것은 대개 그 경우가 아닐 것이다.
+ </para>
+
+ <para>
+ <literal>formula</literal> 속성을 사용하여 당신은 행의 타입을 판단하는데 사용될 임의의 SQL 표현식을 선언할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<discriminator
+ formula="case when CLASS_TYPE in ('a', 'b', 'c') then 0 else 1 end"
+ type="integer"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-version" revision="4">
+ <title>version (옵션)</title>
+
+ <para>
+ <literal><version></literal> 요소는 옵션이고 테이블이 버전화된 데이터를 포함한다는 것을 나타낸다.
+ 이것은 당신이 <emphasis>긴 트랜잭션(long transaction)들</emphasis>을 사용할 계획이라면 특히 유용하다
+ (아래를 보라).
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="version1" coords="2 70"/>
+ <area id="version2" coords="3 70"/>
+ <area id="version3" coords="4 70"/>
+ <area id="version4" coords="5 70"/>
+ <area id="version5" coords="6 70"/>
+ <area id="version6" coords="7 70"/>
+ <area id="version7" coords="8 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<version
+ column="version_column"
+ name="propertyName"
+ type="typename"
+ access="field|property|ClassName"
+ unsaved-value="null|negative|undefined"
+ generated="never|always"
+ insert="true|false"
+ node="element-name|@attribute-name|element/@attribute|."
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="version1">
+ <para>
+ <literal>column</literal> (옵션 - 디폴트는 프로퍼티 명):
+ 버전 번호를 가진 컬럼의 이름.
+ </para>
+ </callout>
+ <callout arearefs="version2">
+ <para>
+ <literal>name</literal>: 영속 클래스의 프로퍼티 명.
+ </para>
+ </callout>
+ <callout arearefs="version3">
+ <para>
+ <literal>type</literal> (옵션 - 디폴트는 <literal>integer</literal>):
+ 버전 번호의 타입.
+ </para>
+ </callout>
+ <callout arearefs="version4">
+ <para>
+ <literal>access</literal> (옵션 - 디폴트는 <literal>property</literal>):
+ Hibernate가 프로퍼티 값에 액세스하는데 사용할 방도.
+ </para>
+ </callout>
+ <callout arearefs="version5">
+ <para>
+ <literal>unsaved-value</literal> (옵션 - 디폴트는 <literal>undefined</literal>):
+ 이전 세션에서 저장되었거나 로드되었던 detached 인스턴스로부터 구별지어서, 인스턴스가 새로이 초기화됨(unsaved)을
+ 나타내는 version 프로퍼티 값.(<literal>undefined</literal>는 식별자 프로퍼티 값이 사용될 것임을 지정한다.)
+ </para>
+ </callout>
+ <callout arearefs="version6">
+ <para>
+ <literal>generated</literal> (옵션 - 디폴트는 <literal>never</literal>):
+ 이 version 프로퍼티 값이 데이터베이스에 의해 실제로 산출되는지를 지정한다.
+ <xref linkend="mapping-generated">산출되는 프로퍼티들</xref>에 관한 논의를 보라.
+ </para>
+ </callout>
+ <callout arearefs="version7">
+ <para>
+ <literal>insert</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ version 컬럼이 SQL insert 문장들 속에 포함될 것인지 여부를 지정한다.
+ 데이터베이스 컬럼이 디폴트 값 <literal>0</literal>으로 정의되는 경우에만 <literal>false</literal>로
+ 설정될 수 있다.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 버전 번호들은 <literal>long</literal>, <literal>integer</literal>, <literal>short</literal>,
+ <literal>timestamp</literal> 또는 <literal>calendar</literal> 타입일 수 있다.
+ </para>
+
+ <para>
+ version 또는 timestamp 프로퍼티는 detached 인스턴스에 대해 결코 null일 수가 없어서, Hibernate는
+ 다른 <literal>unsaved-value</literal> 방도들이 지정되는 것에 상관없이, null version이나 timestamp를
+ 가진 임의의 인스턴스를 transient로서 검출할 것이다. <emphasis>null 허용되는 version 이나 property를
+ 선언하는 것은 Hibernate에서 transitive reattachment에 대한 임의의 문제들을 피하는 쉬운 방법이고,
+ assigned 식별자들이나 composite key들을 사용하는 사람들에게 특히 유용하다!</emphasis>
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-declaration-timestamp" revision="4" >
+ <title>timestamp (옵션)</title>
+
+ <para>
+ 옵션 <literal><timestamp></literal> 요소는 테이블이 타임스탬프화 된 데이터를 포함함을 나타낸다. 이것은
+ 버전화에 대한 대체물로서 고안되었다. Timestamp은 고유하게 optimistic 잠금에 대한 다소 안전한 구현이다. 하지만 때때로
+ 어플리케이션은 다른 방법들로 timestamp들을 사용할 수도 있다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="timestamp1" coords="2 70"/>
+ <area id="timestamp2" coords="3 70" />
+ <area id="timestamp3" coords="4 70" />
+ <area id="timestamp4" coords="5 70" />
+ <area id="timestamp5" coords="6 70" />
+ <area id="timestamp6" coords="7 70" />
+ </areaspec>
+ <programlisting><![CDATA[<timestamp
+ column="timestamp_column"
+ name="propertyName"
+ access="field|property|ClassName"
+ unsaved-value="null|undefined"
+ source="vm|db"
+ generated="never|always"
+ node="element-name|@attribute-name|element/@attribute|."
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="timestamp1">
+ <para>
+ <literal>column</literal> (옵션 - 디폴트는 프로퍼티 명):
+ 타임스탬프를 포함하는 컬럼 명.
+ </para>
+ </callout>
+ <callout arearefs="timestamp2">
+ <para>
+ <literal>name</literal>:
+ 영속 클래스에 대해 자바 <literal>Date</literal> 또는 <literal>Timestamp</literal> 타입을
+ 가진 자바빈즈 스타일의 프로퍼티 이름.
+ </para>
+ </callout>
+ <callout arearefs="timestamp3">
+ <para>
+ <literal>access</literal> (옵션 - 디폴트는 <literal>property</literal>):
+ Hibernate가 프로퍼티 값에 접근하는데 사용할 방도.
+ </para>
+ </callout>
+ <callout arearefs="timestamp4">
+ <para>
+ <literal>unsaved-value</literal> (옵션 - 디폴트는 <literal>null</literal>):
+ 이전 세션에서 저장되었거나 로드되었던 detached 인스턴스로부터 인스턴스를 구별지우는, 인스턴스가 새로이
+ 초기화됨(unsaved)을 나타내는 version 프로퍼티 값.(<literal>undefined</literal>는 식별자
+ 프로퍼티 값이 사용될 것임을 지정한다.)
+ </para>
+ </callout>
+ <callout arearefs="timestamp5">
+ <para>
+ <literal>source</literal> (옵션 - 디폴트는 <literal>vm</literal>):
+ Hibernate는 어디서 timestamp 값을 검색할 것인가? 데이터베이스로부터인가 현재의 JVM으로부터인가?
+ 데이터베이스 기반의 timestamp들은 Hibernate가 "다음 값"을 결정하기 위해 데이터베이스에 접속해야
+ 하기 때문에 오버헤드를 초래하지만, 클러스터링된 환경들에서의 용도로 보다 더 안전할 것이다. 또한 모든
+ <literal>Dialect</literal>들이 데이터베이스의 현재의 timestamp에 대한 검색을 지원하는 것으로 알려져
+ 있지 않지만, 다른 <literal>Dialect</literal>들은 정밀도 결핍 때문에 잠금에 있어 사용이 안전하지 않을
+ 수 있음을 노트하라(예를 들면 오라클 8).
+ </para>
+ </callout>
+ <callout arearefs="timestamp6">
+ <para>
+ <literal>generated</literal> (옵션 - 디폴트는 <literal>never</literal>):
+ 이 timestamp 프로퍼티 값이 데이터베이스에 의해 실제로 생성됨을 지정한다.
+ <xref linkend="mapping-generated">산출되는 프로퍼티들</xref>에 대한 논의들 보라.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <literal><timestamp></literal>는 <literal><version type="timestamp"></literal>과
+ 같음을 노트하라. 그리고 <literal><timestamp use-db="true"></literal>는
+ <literal><version type="dbtimestamp"></literal>과 같다
+ </para>
+ </sect2>
+
+
+ <sect2 id="mapping-declaration-property" revision="4">
+ <title>프로퍼티</title>
+
+ <para>
+ <literal><property></literal> 요소는 클래스의 자바빈즈 스타일의 영속 프로퍼티를 선언한다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="property1" coords="2 70"/>
+ <area id="property2" coords="3 70"/>
+ <area id="property3" coords="4 70"/>
+ <areaset id="property4-5" coords="">
+ <area id="property4" coords='5 70'/>
+ <area id="property5" coords='6 70'/>
+ </areaset>
+ <area id="property6" coords="7 70"/>
+ <area id="property7" coords="8 70"/>
+ <area id="property8" coords="9 70"/>
+ <area id="property9" coords="10 70"/>
+ <area id="property10" coords="11 70"/>
+ <area id="property11" coords="12 70"/>
+ <area id="property12" coords="13 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<property
+ name="propertyName"
+ column="column_name"
+ type="typename"
+ update="true|false"
+ insert="true|false"
+ formula="arbitrary SQL expression"
+ access="field|property|ClassName"
+ lazy="true|false"
+ unique="true|false"
+ not-null="true|false"
+ optimistic-lock="true|false"
+ generated="never|insert|always"
+ node="element-name|@attribute-name|element/@attribute|."
+ index="index_name"
+ unique_key="unique_key_id"
+ length="L"
+ precision="P"
+ scale="S"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="property1">
+ <para>
+ <literal>name</literal>: 첫 소문자로 시작하는 프로퍼티 이름.
+ </para>
+ </callout>
+ <callout arearefs="property2">
+ <para>
+ <literal>column</literal> (옵션 - 디폴트는 프로퍼티 이름):
+ 매핑된 데이터베이스 테이블 컬럼의 이름. 이것은 또한 내부에 포함되는 <literal><column></literal> 요소(들)에
+ 의해 지정될 수도 있다.
+ </para>
+ </callout>
+ <callout arearefs="property3">
+ <para>
+ <literal>type</literal> (옵션): Hibernate 타입을 나타내는 이름.
+ </para>
+ </callout>
+ <callout arearefs="property4-5">
+ <para>
+ <literal>update, insert</literal> (옵션 - 디폴트는 <literal>true</literal>) :
+ 매핑된 컬럼들이 <literal>UPDATE</literal>와/또는 <literal>INSERT</literal> 문장들속에 포함될 것임을 지정한다.
+ 둘다 <literal>false</literal>로 설정하는 것은 그 값이 동일한 컬럼(들)로 매핑되는 어떤 다른 프로퍼티로부터 또는 트리거에
+ 의해 또는 다른 어플리케이션으로부터 초기화 되는 순수하게 "파생된(derived)" 프로퍼티를 허용해준다.
+ </para>
+ </callout>
+ <callout arearefs="property6">
+ <para>
+ <literal>formula</literal> (옵션):
+ <emphasis>계산되는</emphasis> 프로퍼티에 대해 값을 정의하는 SQL 표현식. 계산되는 프로퍼티들은
+ 그것들 자신에 대한 컬럼 매핑을 갖지 않는다.
+ </para>
+ </callout>
+ <callout arearefs="property7">
+ <para>
+ <literal>access</literal> (옵션 - 디폴트는 <literal>property</literal>):
+ Hibernate가 프로퍼티 값에 접근하는데 사용할 방도.
+ </para>
+ </callout>
+ <callout arearefs="property8">
+ <para>
+ <literal>lazy</literal> (옵션 - 디폴트는 <literal>false</literal>):
+ 인스턴스 변수가 처음으로 액세스 될 때 이 프로퍼티가 lazily하게 페치될 것임을 지정한다(빌드-시 바이트코드
+ 수단을 필요로 한다).
+ </para>
+ </callout>
+ <callout arearefs="property9">
+ <para>
+ <literal>unique</literal> (옵션):
+ 컬럼들에 대한 유일 컨스트레인트의 DDL 생성을 가능하게 만든다. 또한 이것이 <literal>property-ref</literal>의
+ 타켓이 되는 것을 허용해준다.
+ </para>
+ </callout>
+ <callout arearefs="property10">
+ <para>
+ <literal>not-null</literal> (옵션):
+ 컬럼들에 대해 null 가능 컨스트레인트의 DDL 생성을 가능하게 만든다.
+ </para>
+ </callout>
+ <callout arearefs="property11">
+ <para>
+ <literal>optimistic-lock</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ 이 프로퍼티에 대한 업데이트들이 optimistic 잠금을 획득하는 것을 필요로 하거나 필요로 하지 않음을 지정한다.
+ 달리말해, 이 프로퍼티가 dirty일 때 버전 증가가 발생할 경우인지를 결정한다.
+ </para>
+ </callout>
+ <callout arearefs="property12">
+ <para>
+ <literal>generated</literal> (옵션 - 디폴트는 <literal>never</literal>):
+ 이 프로퍼티 값이 데이터베이스에 의해 실제로 산출되는지를 지정한다.
+ <xref linkend="mapping-generated">산출되는 프로퍼티들</xref>에 대한 논의를 보라.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <emphasis>typename</emphasis>은 다음일 수 있다:
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ Hibernate 기본 타입의 이름 (예를 들어. <literal>integer, string, character, date, timestamp,
+ float, binary, serializable, object, blob</literal>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 디폴트 기본 타입을 가진 Java 클래스의 이름(예를 들어. <literal>int, float,
+ char, java.lang.String, java.util.Date, java.lang.Integer, java.sql.Clob</literal>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ serializable Java 클래스의 이름.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 맞춤 타입의 클래스 이름(예를 들어. <literal>com.illflow.type.MyCustomType</literal>).
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ 만일 당신이 타입을 지정하지 않을 경우, Hibernate는 정확한 Hibernate 타입을 추정하기 위해 명명된 프로퍼티에 대해
+ reflection을 사용할 것이다. Hibernate는 그 순서에서 2,3,4 규칙들을 사용하여 프로퍼티 getter의 반환 클래스의
+ 이름을 해석하려고 시도할 것이다. 하지만 이것은 항상 충분하지는 않다. 어떤 경우들에서, 당신은 여전히 <literal>type</literal>
+ 속성을 필요로 할 것이다.(예를 들어, <literal>Hibernate.DATE</literal>와 <literal>Hibernate.TIMESTAMP</literal>
+ 사이를 구별하기 위해, 또는 맞춤 타입을 지정하기 위해.)
+ </para>
+
+ <para>
+ <literal>access</literal> 속성은 당신으로 하여금 Hibernate가 런타임 시에 프로퍼티에 액세스하는 방법을 제어하도록 해준다.
+ 디폴트로 Hibernate는 프로퍼티 get/set 쌍을 호출할 것이다. 만일 당신이 <literal>access="field"</literal>를 지정할
+ 경우, Hibernate는 get/set 쌍을 피하고 reflection을 사용하여 직접 필드에 액세스 할 것이다. 당신은
+ <literal>org.hibernate.property.PropertyAccessor</literal> 인터페이스를 구현하는 클래스를 명명함으로써
+ 프로퍼티 접근을 위한 당신 자신의 방도를 지정할 수도 있다.
+ </para>
+
+ <para>
+ 특별히 강력한 특징은 파생된 플로퍼티들이다. 이들 프로퍼티들은 정의상 읽기 전용이고, 그 프로퍼티 값은 로드 시에 계산된다. 당신은
+ 그 계산을 SQL 표현식으로 선언하고, 이것은 인스턴스를 로드시키는 SQL 질의 내의 <literal>SELECT</literal> 절 서브질의로
+ 번역된다:
+ </para>
+
+ <programlisting><![CDATA[
+<property name="totalPrice"
+ formula="( SELECT SUM (li.quantity*p.price) FROM LineItem li, Product p
+ WHERE li.productId = p.productId
+ AND li.customerId = customerId
+ AND li.orderNumber = orderNumber )"/>]]></programlisting>
+
+ <para>
+ 당신은 특정 컬럼(주어진 예제에서는 <literal>customerId</literal>)에 대해 alias를 선언하지 않음으로써 엔티티들 자신의
+ 테이블을 참조할 수 있음을 노트하라. 또한 당신은 만일 당신이 그 속성을 사용하고 싶지 않을 경우에 내포된 <literal><formula></literal>
+ 매핑 요소를 사용할 수 있음을 노트하라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-manytoone" revision="5">
+ <title>many-to-one</title>
+
+ <para>
+ 또 다른 영속 클래스에 대한 정규 연관관계는 <literal>many-to-one</literal> 요소를 사용하여 선언된다. 관계형 모형은
+ many-to-one 연관관계이다.: 하나의 테이블 내에 있는 foreign 키는 대상 테이블의 프라이머리 키 컬럼(들)을 참조하고 있다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="manytoone1" coords="2 70"/>
+ <area id="manytoone2" coords="3 70"/>
+ <area id="manytoone3" coords="4 70"/>
+ <area id="manytoone4" coords="5 70"/>
+ <area id="manytoone5" coords="6 70"/>
+ <areaset id="manytoone6-7" coords="">
+ <area id="manytoone6" coords='7 70'/>
+ <area id="manytoone7" coords='8 70'/>
+ </areaset>
+ <area id="manytoone8" coords="9 70"/>
+ <area id="manytoone9" coords="10 70"/>
+ <area id="manytoone10" coords="11 70"/>
+ <area id="manytoone11" coords="12 70"/>
+ <area id="manytoone12" coords="13 70"/>
+ <area id="manytoone13" coords="14 70"/>
+ <area id="manytoone14" coords="15 70"/>
+ <area id="manytoone15" coords="16 70"/>
+ <area id="manytoone16" coords="17 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<many-to-one
+ name="propertyName"
+ column="column_name"
+ class="ClassName"
+ cascade="cascade_style"
+ fetch="join|select"
+ update="true|false"
+ insert="true|false"
+ property-ref="propertyNameFromAssociatedClass"
+ access="field|property|ClassName"
+ unique="true|false"
+ not-null="true|false"
+ optimistic-lock="true|false"
+ lazy="proxy|no-proxy|false"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ formula="arbitrary SQL expression"
+ node="element-name|@attribute-name|element/@attribute|."
+ embed-xml="true|false"
+ index="index_name"
+ unique_key="unique_key_id"
+ foreign-key="foreign_key_name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="manytoone1">
+ <para>
+ <literal>name</literal>: 프로퍼티의 이름.
+ </para>
+ </callout>
+ <callout arearefs="manytoone2">
+ <para>
+ <literal>column</literal> (옵션):
+ foreign key 컬럼의 이름. 이것은 또한 내포된 <literal><column></literal> 요소(들)에 의해
+ 지정된다.
+ </para>
+ </callout>
+ <callout arearefs="manytoone3">
+ <para>
+ <literal>class</literal> (옵션 - 디폴트는 reflection에 의해 결정된 프로퍼티 타입):
+ 연관된 클래스의 이름.
+ </para>
+ </callout>
+ <callout arearefs="manytoone4">
+ <para>
+ <literal>cascade</literal> (옵션):
+ 어느 오퍼레이션들이 부모 객체로부터 연관된 객체로 케스케이드 될 것인지를 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="manytoone5">
+ <para>
+ <literal>fetch</literal> (옵션 - 디폴트는 <literal>select</literal>):
+ outer-join 페칭 또는 sequential select 페칭 사이에서 선택하라.
+ </para>
+ </callout>
+ <callout arearefs="manytoone6-7">
+ <para>
+ <literal>update, insert</literal> (옵션 - 디폴트는 <literal>true</literal>)
+ 매핑된 컬럼들이 SQL <literal>UPDATE</literal>와/또는 <literal>INSERT</literal> 문장들 속에 포함될 것인지를 지정한다.
+ 둘다 <literal>false</literal>로 설정하는 것은 그 값이 동일한 컬럼(들)로 매핑시키는 어떤 다른 컬럼들로부터 초기화 되거나 트리거나
+ 다른 어플리케이션에 의해 초기화되는 단순한 "파생된" 연관관계 값을 허용한다.
+ </para>
+ </callout>
+ <callout arearefs="manytoone8">
+ <para>
+ <literal>property-ref</literal>: (옵션) 이 foreign key에 조인되는 연관된 클래스의 프로퍼티 이름. 지정되지 않을 경우,
+ 연관 클래스의 프라이머리 키가 사용된다.
+ </para>
+ </callout>
+ <callout arearefs="manytoone9">
+ <para>
+ <literal>access</literal> (옵션 - 디폴트는 <literal>property</literal>):
+ Hibernate가 프로퍼티 값에 접근하는데 사용할 방도.
+ </para>
+ </callout>
+ <callout arearefs="manytoone10">
+ <para>
+ <literal>unique</literal> (옵션):
+ foreign-key 컬럼을 위한 유일 컨스트레인트의 DDL 생성을 가능하도록 해준다. 또한 이것이 property-ref의 대상이 되는 것을 허용해준다.
+ 이것은 연관 다중성(association multiplicity)을 효율적으로 일 대 일로 만든다.
+ </para>
+ </callout>
+ <callout arearefs="manytoone11">
+ <para>
+ <literal>not-null</literal> (옵션):
+ foreign key 컬럼들을 위한 null 가능한 컨스트레인트의 DDL 생성을 가능하도록 해준다.
+ </para>
+ </callout>
+ <callout arearefs="manytoone12">
+ <para>
+ <literal>optimistic-lock</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ 이 프로퍼티에 대한 업데이트들이 optimistic lock의 획득을 필요로 하는지 아닌지 여부를 지정한다.
+ 달리 말해 이 프로퍼티가 dirty일 때 version 증가가 발생해야 할 경우인지를 결정한다.
+ </para>
+ </callout>
+ <callout arearefs="manytoone13">
+ <para>
+ <literal>lazy</literal> (옵션 - 디폴트는 <literal>proxy</literal>):
+ 디폴트로, 단일 포인트 연관들이 프락시된다. <literal>lazy="no-proxy"</literal>는 인스턴스 변수가 처음으로 접근될 때
+ 그 프로퍼티가 lazily 페치될 것임을 지정한다(빌드-시 바이트코드 수단을 필요로 한다). <literal>lazy="false"</literal>는
+ 그 연관이 항상 eagerly 페치될 것임을 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="manytoone14">
+ <para>
+ <literal>not-found</literal> (옵션 - 디폴트는 <literal>exception</literal>):
+ 누락된 행들을 참조하는 foreign key들이 어떻게 처리될 것인지를 지정한다: <literal>ignore</literal>는 한 개의 누락된 행을
+ 한 개의 null 연관으로 취급할 것이다.
+ </para>
+ </callout>
+ <callout arearefs="manytoone15">
+ <para>
+ <literal>entity-name</literal> (옵션): 연관된 클래스의 엔티티 이름.
+ </para>
+ </callout>
+ </calloutlist>
+ <callout arearefs="manytoone16">
+ <para>
+ <literal>formula</literal> (옵션): <emphasis>계산된</emphasis> foreign key에 대한 값을 정의하는 SQL 표현식.
+ </para>
+ </callout>
+ </programlistingco>
+
+ <para>
+ <literal>cascade</literal> 속성 값을 <literal>none</literal> 아닌 어떤 의미있는 다른 값으로 설정하는 것은
+ 어떤 오퍼레이션들을 연관된 객체에게 보급할 것이다. 유의미한 값들은 Hibernate의 기본 오퍼레이션들의 이름들,
+ 즉 <literal>persist, merge, delete, save-update, evict, replicate, lock, refresh</literal>
+ 뿐만 아니라 특별한 값들, 즉 <literal>delete-orphan</literal>과 <literal>all</literal> 그리고 오퍼레이션 이름들의
+ 쉼표 분리된 조합들, 예를 들면 <literal>cascade="persist,merge,evict"</literal> 또는
+ <literal>cascade="all,delete-orphan"</literal>이다. 전체 설명은
+ <xref linkend="objectstate-transitive"/>를 보라. 단일값 연관들(many-to-one 연관과
+ one-to-one 연관)은 orphan delete를 지원하지 않음을 노트하라.
+ </para>
+
+ <para>
+ 일반적인 <literal>many-to-one</literal> 선언은 다음과 같이 간단하게 보여진다:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="product" class="Product" column="PRODUCT_ID"/>]]></programlisting>
+
+ <para>
+ <literal>property-ref</literal> 속성은 오직 foreign key가 프라이머리 키가 아닌 연관된 테이블의 유일 키를 참조하는
+ 리거시 데이터를 매핑하는데만 사용된다. 이것은 꼴사나운 관계형 모형이다. 예를 들어, <literal>Product</literal>
+ 클래스가 프라이머리 키를 아닌, 유일한 시리얼 번호를 갖는다고 가정하자.(<literal>unique</literal> 속성은
+ SchemaExport 도구로 Hibernate의 DDL 생성을 제어한다.)
+ </para>
+
+ <programlisting><![CDATA[<property name="serialNumber" unique="true" type="string" column="SERIAL_NUMBER"/>]]></programlisting>
+
+ <para>
+ 그런 다음 <literal>OrderItem</literal>에 대한 매핑은 다음을 사용할 것이다:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="product" property-ref="serialNumber" column="PRODUCT_SERIAL_NUMBER"/>]]></programlisting>
+
+ <para>
+ 하지만 이것은 확실히 권장되지 않는다.
+ </para>
+
+ <para>
+ 만일 참조된 유일 키가 연관된 엔티티의 여러 프로퍼티들을 포함할 경우, 당신은 명명된 <literal><properties></literal>
+ 요소 내부에 참조된 프로퍼티들을 매핑할 것이다.
+ </para>
+
+ <para>
+ 만일 참조된 유일키가 컴포넌트의 프로퍼티일 경우, 당신은 하나의 프로퍼티 경로를 지정할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="owner" property-ref="identity.ssn" column="OWNER_SSN"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-onetoone" revision="3">
+ <title>one-to-one</title>
+
+ <para>
+ 또 다른 영속 클래스에 대한 one-to-one 연관관계는 <literal>one-to-one</literal> 요소를 사용하여 선언된다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="onetoone1" coords="2 70"/>
+ <area id="onetoone2" coords="3 70"/>
+ <area id="onetoone3" coords="4 70"/>
+ <area id="onetoone4" coords="5 70"/>
+ <area id="onetoone5" coords="6 70"/>
+ <area id="onetoone6" coords="7 70"/>
+ <area id="onetoone7" coords="8 70"/>
+ <area id="onetoone8" coords="9 70"/>
+ <area id="onetoone9" coords="10 70"/>
+ <area id="onetoone10" coords="11 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<one-to-one
+ name="propertyName"
+ class="ClassName"
+ cascade="cascade_style"
+ constrained="true|false"
+ fetch="join|select"
+ property-ref="propertyNameFromAssociatedClass"
+ access="field|property|ClassName"
+ formula="any SQL expression"
+ lazy="proxy|no-proxy|false"
+ entity-name="EntityName"
+ node="element-name|@attribute-name|element/@attribute|."
+ embed-xml="true|false"
+ foreign-key="foreign_key_name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="onetoone1">
+ <para>
+ <literal>name</literal>: 프로퍼티의 이름.
+ </para>
+ </callout>
+ <callout arearefs="onetoone2">
+ <para>
+ <literal>class</literal> (옵션 - 디폴트는 reflection에 의해 결정된 프로퍼티 타입):
+ 연관된 클래스의 이름.
+ </para>
+ </callout>
+ <callout arearefs="onetoone3">
+ <para>
+ <literal>cascade</literal> (옵션) 어느 오퍼레이션들이 부모 객체로부터 연관된 객체로
+ 케스케이드 될 것인지를 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="onetoone4">
+ <para>
+ <literal>constrained</literal> (옵션) 매핑된 테이블의 프라이머리 키에 대한 foreign 키
+ 컨스트레인트가 연관된 클래스의 테이블을 참조하는지 여부를 지정한다. 이 옵션은 <literal>save()</literal>와
+ <literal>delete()</literal>가 케스케이드 되는 순서에 영향을 주고, 그 연관이 프락시 될 것인지 여부를 결정한다
+ (또한 스키마 내보내기 도구에 의해 사용된다).
+ </para>
+ </callout>
+ <callout arearefs="onetoone5">
+ <para>
+ <literal>fetch</literal> (옵션 - 디폴트는 <literal>select</literal>):
+ outer-join 페칭 또는 순차적인 select 페칭 중에서 선택하라.
+ </para>
+ </callout>
+ <callout arearefs="onetoone6">
+ <para>
+ <literal>property-ref</literal>: (옵션) 이 클래스의 프라이머리 키에 연결된 연관 클래스의 프로퍼티의 이름.
+ 만일 지정되지 않을 경우, 연관 클래스의 프라이머리 키가 사용된다.
+ </para>
+ </callout>
+ <callout arearefs="onetoone7">
+ <para>
+ <literal>access</literal> (옵션 - 디폴트는 <literal>property</literal>):
+ Hibernate가 프로퍼티 값에 접근 하는데 사용할 방도.
+ </para>
+ </callout>
+ <callout arearefs="onetoone8">
+ <para>
+ <literal>formula</literal> (옵션):
+ 거의 모든 one to one 연관관계들은 소유하는 엔티티의 프라이머리 키로 매핑된다. 이것이 그 경우가 아닌 드문 경우들에서,
+ 당신은 SQL formula 사용에 결합시킬 몇몇 다른 컬럼, 컬럼들, 또는 표현식을 지정할 수 있다.(예제는
+ <literal>org.hibernate.test.onetooneformula</literal>를 보라.)
+ </para>
+ </callout>
+ <callout arearefs="onetoone9">
+ <para>
+ <literal>lazy</literal> (옵션 - 디폴트는 <literal>proxy</literal>):
+ 디폴트로 한쪽 끝 연관들이 프락시 된다. <literal>lazy="no-proxy"</literal>는 인스턴스 변수가 처음 접근될 때
+ 그 프로퍼티가 lazily 페치될 것임을 지정한다(빌드-시 바이트코드 수단을 필요로 한다).
+ <literal>lazy="false"</literal>는 그 연관들이 항상 eagerly 페치될 것임을 지정한다. <emphasis>만일
+ <literal>constrained="false"</literal>인 경우에, 프락싱은 불가능하고 Hibernate는 그 연관을 eager 페치시킬 것이다!</emphasis>
+ </para>
+ </callout>
+ <callout arearefs="onetoone10">
+ <para>
+ <literal>entity-name</literal> (옵션): 연관된 클래스의 엔티티 이름.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ one-to-one 연관관계에는 두 가지 변종이 존재한다:
+ </para>
+ <itemizedlist>
+ <listitem><para>
+ 프라이머리 키 연관관계들
+ </para></listitem>
+ <listitem><para>
+ 유일 foreign 키 연관관계들
+ </para></listitem>
+ </itemizedlist>
+
+ <para>
+ 프라이머리 키 연관들은 특별한 테이블 컬럼을 필요로 하지 않는다; 만일 두 개의 행들이 그 연관에 의해 관계지워지면,
+ 두 개의 테이블 행들은 동일한 프라이머리 키 값을 공유한다. 따라서 만일 두 개의 객체들이 프라이머리 키 연관에 의해
+ 관계지워지도록 당신이 원할 경우, 당신은 그것들에 동일한 식별자 값이 할당되도록 해야 한다!
+ </para>
+
+ <para>
+ 프라이머리 키 연관에 대해, 다음 매핑들을 <literal>Employee</literal>와 <literal>Person</literal> 각각에 추가하라.
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="person" class="Person"/>]]></programlisting>
+ <programlisting><![CDATA[<one-to-one name="employee" class="Employee" constrained="true"/>]]></programlisting>
+
+ <para>
+ 이제 우리는 PERSON 과 EMPLOYEE 테이블들에서 관계지워진 행들의 프라이머리 키들이 동일함을 확실히 해야 한다! 우리는
+ <literal>foreign</literal>로 명명되는 특별한 Hibernate 식별자 생성 방도를 사용한다:
+ </para>
+
+ <programlisting><![CDATA[<class name="person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="foreign">
+ <param name="property">employee</param>
+ </generator>
+ </id>
+ ...
+ <one-to-one name="employee"
+ class="Employee"
+ constrained="true"/>
+</class>]]></programlisting>
+
+ <para>
+ 그때 <literal>Person</literal>의 새로이 저장된 인스턴스는 그 <literal>Person</literal>의
+ <literal>employee</literal> 프로퍼티에 대해 참조된 <literal>Employee</literal> 인스턴스와 동일한
+ 프라이머리 키를 할당받는다.
+ </para>
+
+ <para>
+ 달리, <literal>Employee</literal>로부터 <literal>Person</literal>으로의 유일 컨스트레인트를 가진
+ 하나의 foreign key는 다음과 같이 표현될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="person" class="Person" column="PERSON_ID" unique="true"/>]]></programlisting>
+
+ <para>
+ 그리고 이 연관은 다음을 <literal>Person</literal> 매핑에 추가함으로써 양방향이 될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="employee" class="Employee" property-ref="person"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-naturalid">
+ <title>natural-id</title>
+
+ <programlisting><![CDATA[<natural-id mutable="true|false"/>
+ <property ... />
+ <many-to-one ... />
+ ......
+</natural-id>]]></programlisting>
+
+ <para>
+ 비록 우리가 프라이머리 키들로서 대용키들을 사용하는 것을 권장했을지라도, 당신은 여전히 모든 엔티티들에 대한 natural
+ 키들을 식별하고자 원할 것이다. narutal 키는 유일(unique)하고 null이 아닌 프로퍼티 또는 프로퍼티들의 조합이다.
+ 그것이 또한 불변하는 것일 경우가 더 좋다. <literal><natural-id></literal> 요소 내부에 있는 natural 키의
+ 프로퍼티들을 매핑하라. Hibernate는 필수적인 유일 키와 null 허용가능한 컨스트레인트들을 생성시킬 것이고, 당신의
+ 매핑은 보다 자가 설명적이게 될 것이다.
+ </para>
+
+ <para>
+ 우리는 당신이 엔티티에 대한 narutal 키 프로퍼티들을 비교하는데 <literal>equals()</literal>와
+ <literal>hashCode()</literal>를 구현할 것을 강력하게 권장한다.
+ </para>
+
+ <para>
+ 이 매핑은 natural 프라이머리 키들을 가진 엔티티들을 위한 용도로 고안된 것은 아니다.
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>mutable</literal> (옵션, 디폴트는 <literal>false</literal>):
+ 디폴트로, narutal 식별자 프로퍼티들은 변경될 수 없는 것(상수)으로 가정된다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-component" revision="2">
+ <title>component, dynamic-component</title>
+
+ <para>
+ <literal><component></literal> 요소는 자식 객체의 프로퍼티들을 부모 클래스에 대한 테이블의 컬럼들로 매핑시킨다.
+ 컴포넌트들은 그것들 자신의 프로퍼티들, 컴포넌트들, 또는 콜렉션들을 선언한다. 이래 "컴포넌트들"을 보라.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="component1" coords="2 45"/>
+ <area id="component2" coords="3 45"/>
+ <area id="component3" coords="4 45"/>
+ <area id="component4" coords="5 45"/>
+ <area id="component5" coords="6 45"/>
+ <area id="component6" coords="7 45"/>
+ <area id="component7" coords="8 45"/>
+ <area id="component8" coords="9 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<component
+ name="propertyName"
+ class="className"
+ insert="true|false"
+ update="true|false"
+ access="field|property|ClassName"
+ lazy="true|false"
+ optimistic-lock="true|false"
+ unique="true|false"
+ node="element-name|."
+>
+
+ <property ...../>
+ <many-to-one .... />
+ ........
+</component>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="component1">
+ <para>
+ <literal>name</literal>: 프로퍼티의 이름.
+ </para>
+ </callout>
+ <callout arearefs="component2">
+ <para>
+ <literal>class</literal> (옵션 - 디폴트는 reflection에 의해 결정된 프로퍼티 타입):
+ 컴포넌트(자식) 클래스의 이름.
+ </para>
+ </callout>
+ <callout arearefs="component3">
+ <para>
+ <literal>insert</literal>: 매핑된 컬럼들이 SQL <literal>INSERT</literal>들 속에
+ 나타나야 하는가?
+ </para>
+ </callout>
+ <callout arearefs="component4">
+ <para>
+ <literal>update</literal>: 매핑된 컬럼들이 SQL <literal>UPDATE</literal>들 속에
+ 나타나야 하는가?
+ </para>
+ </callout>
+ <callout arearefs="component5">
+ <para>
+ <literal>access</literal> (옵션 - 디폴트는 <literal>property</literal>):
+ Hibernate가 프로퍼티 값에 액세스하는데 사용할 방도.
+ </para>
+ </callout>
+ <callout arearefs="component6">
+ <para>
+ <literal>lazy</literal> (옵션 - 디폴트는 <literal>false</literal>):
+ 인스턴스 변수가 처음으로 액세스될 때 이 컴포넌트가 lazily(느리게) 페치되어야 하는지 여부를 지정한다
+ (빌드 시 바이트코드 수단을 필요로 한다).
+ </para>
+ </callout>
+ <callout arearefs="component7">
+ <para>
+ <literal>optimistic-lock</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ 이 컴포넌트에 대한 업데이트들이 optimistic 잠금을 획득하는 것을 필요로 하는지 여부를 지정한다.
+ 달리 말해 이 프로퍼티가 dirty 일 때 버전 증가가 발생할 것인지 여부를 결정한다.
+ </para>
+ </callout>
+ <callout arearefs="component8">
+ <para>
+ <literal>unique</literal> (옵션 - 디폴트는 <literal>false</literal>):
+ 유일 컨스트레인트가 컴포넌트의 모든 매핑된 컬럼들에 대해 존재하는지 여부를 지정한다.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 자식 <literal><property></literal> 태그들은 자식 클래스의 프로퍼티들을 테이블 컬럼들로 매핑시킨다.
+ </para>
+
+ <para>
+ <literal><component></literal> 요소는 컴포넌트 클래스의 프로퍼티를 포함하는 엔티티에 대한 참조로서 매핑시키는
+ <literal><parent></literal> 서브요소를 허용한다.
+ </para>
+
+ <para>
+ <literal><dynamic-component></literal> 요소는 컴포넌트로서 매핑될<literal>Map</literal>을 허용한다.
+ 여기서 프로퍼티 이름들은 map의 키들을 참조한다. <xref linkend="components-dynamic"/>을 보라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-properties" revision="2">
+ <title>properties</title>
+
+ <para>
+ <literal><properties></literal> 요소는 클래스의 프로퍼티들의 명명된, 논리적 그룹핑에 대한 정의를 허용한다.
+ 그 구조에 대한 가장 중요한 사용은 그것이 프로퍼티들의 조합이 <literal>property-ref</literal>의 대상이 되는 것을
+ 허용해준다는 점이다. 또한 그것은 다중 컬럼 유일 컨스트레인느를 정의하는 편리한 방법이다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="properties1" coords="2 45"/>
+ <area id="properties2" coords="3 45"/>
+ <area id="properties3" coords="4 45"/>
+ <area id="properties4" coords="5 45"/>
+ <area id="properties5" coords="6 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<properties
+ name="logicalName"
+ insert="true|false"
+ update="true|false"
+ optimistic-lock="true|false"
+ unique="true|false"
+>
+
+ <property ...../>
+ <many-to-one .... />
+ ........
+</properties>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="properties1">
+ <para>
+ <literal>name</literal>: 그룹핑의 논리적 이름 - 실제 프로퍼티 이름이 <emphasis>아니다</emphasis>.
+ </para>
+ </callout>
+ <callout arearefs="properties2">
+ <para>
+ <literal>insert</literal>: 매핑된 컬럼들이 SQL <literal>INSERT</literal>들 내에 나타날 것인가?
+ </para>
+ </callout>
+ <callout arearefs="properties3">
+ <para>
+ <literal>update</literal>: 매핑된 컬럼들이 SQL <literal>UPDATE</literal>들 내에 나타날 것인가?
+ </para>
+ </callout>
+ <callout arearefs="properties4">
+ <para>
+ <literal>optimistic-lock</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ 이들 프로퍼티들에 대한 업데이트들이 optimistic 잠금의 획득을 필요로 하는지 여부를 지정한다. 달리 말해
+ 이 프로퍼티가 dirty 일 때 버전 증가가 발생할 것인지 여부를 결정한다.
+ </para>
+ </callout>
+ <callout arearefs="properties5">
+ <para>
+ <literal>unique</literal> (옵션 - 디폴트는 <literal>false</literal>):
+ 유일 컨스트레인트가 컴포넌트의 모든 매핑된 컬럼들에 대해 존재하는지 여부를 지정한다.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 예를 들어, 만일 우리가 다음 <literal><properties></literal> 매핑을 가질 경우:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="personNumber"/>
+ ...
+ <properties name="name"
+ unique="true" update="false">
+ <property name="firstName"/>
+ <property name="initial"/>
+ <property name="lastName"/>
+ </properties>
+</class>]]></programlisting>
+
+ <para>
+ 그 때 우리는 프라이머리 키가 아닌, <literal>Person</literal> 테이블의 이 유일 키를 참조하는 어떤 리거시 데이터 연관을
+ 가질 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="person"
+ class="Person" property-ref="name">
+ <column name="firstName"/>
+ <column name="initial"/>
+ <column name="lastName"/>
+</many-to-one>]]></programlisting>
+
+ <para>
+ 우리는 리거시 데이터를 매핑시키는 컨텍스트 바깥에서 이런 종류의 것을 사용하는 것을 권장하지 않는다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-subclass" revision="4">
+ <title>subclass</title>
+
+ <para>
+ 마지막으로, 다형성 영속성은 루트 영속 클래스에 대한 각각의 서브클래스 선언을 필요로 한다.(권장되는)
+ table-per-class-hierarchy(테이블 당 클래스 계층구조) 매핑 방도의 경우, <literal><subclass></literal>
+ 선언이 사용된다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="subclass1" coords="2 55"/>
+ <area id="subclass2" coords="3 55"/>
+ <area id="subclass3" coords="4 55"/>
+ <area id="subclass4" coords="5 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<subclass
+ name="ClassName"
+ discriminator-value="discriminator_value"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ entity-name="EntityName"
+ node="element-name"
+ extends="SuperclassName">
+
+ <property .... />
+ .....
+</subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="subclass1">
+ <para>
+ <literal>name</literal>: 서브클래스의 전체 수식어가 붙은 클래스 이름.
+ </para>
+ </callout>
+ <callout arearefs="subclass2">
+ <para>
+ <literal>discriminator-value</literal> (옵션 - 디폴트는 클래스 이름):
+ 개개의 서브클래스들을 구분짓는 값.
+ </para>
+ </callout>
+ <callout arearefs="subclass3">
+ <para>
+ <literal>proxy</literal> (옵션): lazy 초기화 프락시들을 사용하는데 클래스 또는 인터페이스를 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="subclass4">
+ <para>
+ <literal>lazy</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ <literal>lazy="false"</literal> 설정은 lazy 페칭의 사용을 불가능하게 만든다.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 각각의 서브클래스는 그것 자신의 영속 프로퍼티들과 서브클래스들을 선언할 것이다. <literal><version></literal>
+ 프로퍼티와 <literal><id></literal> 프로퍼티는 루트 클래스로부터 상속된다고 가정된다. 계층구조 내에서 각각의
+ 서브클래스는 유일한 <literal>discriminator-value</literal>를 정의해야 한다. none이 지정될 경우, 전체 수식어가
+ 붙은 자바 클래스 이름이 사용된다.
+ </para>
+
+ <para>
+ 상속 매핑들에 대한 정보는 <xref linkend="inheritance"/>을 보라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-joinedsubclass" revision="3">
+ <title>joined-subclass</title>
+
+ <para>
+ 다른 방법으로 각각의 서브클래스는 그것 자신이 테이블로 매핑될 수 있다(table-per-subclass 매핑 방도). 상속된 상태는
+ 슈퍼클래스의 테이블과 조인함으로써 검색된다. 우리는 <literal><joined-subclass></literal> 요소를 사용한다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="joinedsubclass1" coords="2 45"/>
+ <area id="joinedsubclass2" coords="3 45"/>
+ <area id="joinedsubclass3" coords="4 45"/>
+ <area id="joinedsubclass4" coords="5 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<joined-subclass
+ name="ClassName"
+ table="tablename"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ schema="schema"
+ catalog="catalog"
+ extends="SuperclassName"
+ persister="ClassName"
+ subselect="SQL expression"
+ entity-name="EntityName"
+ node="element-name">
+
+ <key .... >
+
+ <property .... />
+ .....
+</joined-subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="joinedsubclass1">
+ <para>
+ <literal>name</literal>: 서브클래스의 전체 수식어가 붙은 클래스 명.
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass2">
+ <para>
+ <literal>table</literal>: 서브클래스 테이블의 이름.
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass3">
+ <para>
+ <literal>proxy</literal> (옵션): 프락시들을 lazy 초기화 시키는데 사용할 클래스 또는 인터페이스를 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass4">
+ <para>
+ <literal>lazy</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ <literal>lazy="false"</literal> 설정은 lazy 페칭을 사용불가능하게 만든다
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 판별자(discriminator) 컬럼은 이 매핑 방도에 필요하지 않다. 하지만 각각의 서브클래스는 <literal><key></literal> 요소를
+ 사용하여 객체 식별자를 보관하는 테이블 컬럼을 선언해야 한다. 이 장의 시작 부분에 있는 매핑은 다음과 같이 다시 작성될 것이다:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class name="Cat" table="CATS">
+ <id name="id" column="uid" type="long">
+ <generator class="hilo"/>
+ </id>
+ <property name="birthdate" type="date"/>
+ <property name="color" not-null="true"/>
+ <property name="sex" not-null="true"/>
+ <property name="weight"/>
+ <many-to-one name="mate"/>
+ <set name="kittens">
+ <key column="MOTHER"/>
+ <one-to-many class="Cat"/>
+ </set>
+ <joined-subclass name="DomesticCat" table="DOMESTIC_CATS">
+ <key column="CAT"/>
+ <property name="name" type="string"/>
+ </joined-subclass>
+ </class>
+
+ <class name="eg.Dog">
+ <!-- mapping for Dog could go here -->
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 상속 매핑들에 대한 정보는 <xref linkend="inheritance"/>을 보라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-unionsubclass" revision="2">
+ <title>union-subclass</title>
+
+ <para>
+ 제3의 옵션은 상속 계층구조의 concrete 클래스들 만을 테이블들로 매핑하는 것이다 (table-per-concrete-class 방도). 여기서
+ 각각의 테이블은 상속된 상태를 포함하여 클래스의 모든 영속 상태를 정의한다. Hibernate에서, 그것은 그런 상속 계층구조들을
+ 명시적으로 매핑하는데 필수적이지 않다. 당신은 별도의 <literal><class></literal> 선언을 가진 각각의 클래스를
+ 간단히 매핑시킬 수 있다. 하지만 당신이 다형성 연관관계들(예를 들면 당신의 계층구조의 슈퍼클래스에 대한 연관)을 사용하고자 원할
+ 경우, 당신은 <literal><union-subclass></literal> 매핑을 사용할 필요가 있다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="unionsubclass1" coords="2 45"/>
+ <area id="unionsubclass2" coords="3 45"/>
+ <area id="unionsubclass3" coords="4 45"/>
+ <area id="unionsubclass4" coords="5 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<union-subclass
+ name="ClassName"
+ table="tablename"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ schema="schema"
+ catalog="catalog"
+ extends="SuperclassName"
+ abstract="true|false"
+ persister="ClassName"
+ subselect="SQL expression"
+ entity-name="EntityName"
+ node="element-name">
+
+ <property .... />
+ .....
+</union-subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="unionsubclass1">
+ <para>
+ <literal>name</literal>: 서브클래스의 전체 수식어가 붙은 클래스 명.
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass2">
+ <para>
+ <literal>table</literal>: 서브클래스 테이블의 이름.
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass3">
+ <para>
+ <literal>proxy</literal> (옵션): 프락시들을 lazy 초기화 시키는데 사용할 클래스 또는 인터페이스를 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass4">
+ <para>
+ <literal>lazy</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ <literal>lazy="false"</literal> 설정은 lazy 페칭을 사용불가능하게 만든다.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 이 매핑 방도에는 판별자 컬럼이나 키 컬럼이 필요하지 않다.
+ </para>
+
+ <para>
+ 상속 매핑들에 대한 정보는 <xref linkend="inheritance"/>을 보라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-join" revision="3">
+ <title>join</title>
+
+ <para>
+ <literal><join></literal>요소를 사용하면, 테이블들 사이에 1대일 관계가 존재할 때,
+ 하나의 클래스에 속한 프로퍼티들을 여러 테이블들로 매핑시키는 것이
+ 가능하다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="join1" coords="2 50"/>
+ <area id="join2" coords="3 50"/>
+ <area id="join3" coords="4 50"/>
+ <area id="join4" coords="5 50"/>
+ <area id="join5" coords="6 50"/>
+ <area id="join6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<join
+ table="tablename"
+ schema="owner"
+ catalog="catalog"
+ fetch="join|select"
+ inverse="true|false"
+ optional="true|false">
+
+ <key ... />
+
+ <property ... />
+ ...
+</join>]]></programlisting>
+
+ <calloutlist>
+ <callout arearefs="join1">
+ <para>
+ <literal>table</literal>: 조인된 테이블의 이름.
+ </para>
+ </callout>
+ <callout arearefs="join2">
+ <para>
+ <literal>schema</literal> (옵션): 루트 <literal><hibernate-mapping></literal> 요소에
+ 의해 지정된 스키마 이름을 오버라이드 시킨다
+ </para>
+ </callout>
+ <callout arearefs="join3">
+ <para>
+ <literal>catalog</literal> (옵션): 루트 <literal><hibernate-mapping></literal> 요소에
+ 의해 지정된 카타록 이름을 오버라이드 시킨다.
+ </para>
+ </callout>
+ <callout arearefs="join4">
+ <para>
+ <literal>fetch</literal> (옵션 - 디폴트는 <literal>join</literal>):
+ <literal>join</literal>으로 설정될 경우, 디폴트로 Hibernate는 하나의 클래스 또는 그것의 슈퍼 클래스들에 의해
+ 정의된 <literal><join></literal>을 검색하는데 inner join을 사용하고 서브클래스에 의해 정의된
+ <literal><join></literal>을 검색하는데 outer join을 사용할 것이다. 만일 <literal>select</literal>로
+ 설정할 경우, Hibernate는 서브클래스 상에 정의된 <literal><join></literal>에 대해 sequential
+ select를 사용할 것이고, 그것은 한 행이 서브클래스의 인스턴스를 표현하는 것으로 판명되는 경우에만 명령이 내려질 것이다.
+ inner join들은 여전히 클래스와 그것의 슈퍼클래스들에 의해 정의된 <literal><join></literal>을 검색하는데
+ 사용될 것이다.
+ </para>
+ </callout>
+ <callout arearefs="join5">
+ <para>
+ <literal>inverse</literal> (옵션 - 디폴트는 <literal>false</literal>):
+ 이용 가능할 경우, Hibernate는 이 조인에 의해 정의된 프로퍼티들을 삽입시키거나 업데이트하려고 시도하지
+ 않을 것이다.
+ </para>
+ </callout>
+ <callout arearefs="join6">
+ <para>
+ <literal>optional</literal> (옵션 - 디폴트는 <literal>false</literal>):
+ 이용 가능할 경우, Hibernate는 이 조인에 의해 정의된 프로퍼티들이 null이 아닐 경우에만 한 행을 삽입시킬 것이고
+ 그 프로퍼티들을 검색하는데 outer join을 항상 사용할 것이다.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 예를 들어, (모든 프로퍼티들에 대해 value 타입 의미를 유지하면서) 개인의 주소 정보는 별도의 테이블에 매핑될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person"
+ table="PERSON">
+
+ <id name="id" column="PERSON_ID">...</id>
+
+ <join table="ADDRESS">
+ <key column="ADDRESS_ID"/>
+ <property name="address"/>
+ <property name="zip"/>
+ <property name="country"/>
+ </join>
+ ...]]></programlisting>
+
+ <para>
+ 이 특징은 자주 리거시 데이터 모형들에 대해서만 유용하고, 우리는 클래스들과 잘 정제된 도메인 모형 보다 더 적은 테이블들을
+ 권장한다. 하지만 뒷 부분에 설명되어 있듯이, 그것은 하나의 계층구조 내에 있는 상속 매핑 방도들 사이를 전환하는 것에 유용하다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-key">
+ <title>key</title>
+
+ <para>
+ 우리는 지금까지 몇 번 나타났던 <literal><key></literal> 요소를 보았다. 그것은 부모 매핑 요소가 새로운 테이블에
+ 대한 조인을 정의하는 어느 곳에서나 나타나고, 그것은 조인된 테이블의 foreign 키를 정의하고, 그것은 원래의 테이블의
+ 프라이머리 키를 참조한다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="key1" coords="2 50"/>
+ <area id="key2" coords="3 50"/>
+ <area id="key3" coords="4 50"/>
+ <area id="key4" coords="5 50"/>
+ <area id="key5" coords="6 50"/>
+ <area id="key6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<key
+ column="columnname"
+ on-delete="noaction|cascade"
+ property-ref="propertyName"
+ not-null="true|false"
+ update="true|false"
+ unique="true|false"
+/>]]></programlisting>
+
+ <calloutlist>
+ <callout arearefs="key1">
+ <para>
+ <literal>column</literal> (옵션):
+ foreign key 컬럼의 이름. 이것은 또한 내포된 <literal><column></literal> 요소(들)에 의해 지정될 수 있다.
+ </para>
+ </callout>
+ <callout arearefs="key2">
+ <para>
+ <literal>on-delete</literal> (옵션 - 디폴트는 <literal>noaction</literal>):
+ foreign key 컨스트레인트가 데이터베이스 레벨의 cascade delete를 사용가능하도록 할 것인지 여부를 지정한다.
+ </para>
+ </callout>
+ <callout arearefs="key3">
+ <para>
+ <literal>property-ref</literal> (옵션):
+ foreign key가 원래의 테이블의 프라이머리 키가 아닌 컬럼들을 참조함을 지정한다. (리거시 데이터에 제공됨.)
+ </para>
+ </callout>
+ <callout arearefs="key4">
+ <para>
+ <literal>not-null</literal> (옵션):
+ foreign 키 컬럼들이 not null 임를 지정한다(이것은 foreign 키가 또한 프라이머리 키의 부분일 때마다 함축된다).
+ </para>
+ </callout>
+ <callout arearefs="key5">
+ <para>
+ <literal>update</literal> (옵션):
+ foreign 키가 결코 업데이트되지 않아야 함을 지정한다(이것은 foreign 키가 또한 프라이머리 키의 부분일 때마다
+ 함축된다).
+ </para>
+ </callout>
+ <callout arearefs="key6">
+ <para>
+ <literal>unique</literal> (옵션):
+ foreign 키가 유일 컨스트레인트를 가져야 함을 지정한다 (이것은 foreign 키가 또한 프라이머리 키의 부분일
+ 때마다 함축된다).
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 우리는 delete 퍼포먼스가 중요한 시스템들에 대해 권장하고, 모든 키들은 <literal>on-delete="cascade"</literal>로
+ 정의되고, Hibernate는 많은 <literal>DELETE</literal> 문장들 대신에, 데이터베이스 레벨의
+ <literal>ON CASCADE DELETE</literal> 컨스트레인트를 사용할 것이다. 이 특징은 Hibernate의 통상적인 버전화된
+ 데이터에 대한 optimistic 잠금 방도를 무시한다는 점을 알고 있어라.
+ </para>
+
+ <para>
+ <literal>not-null</literal> 속성과 <literal>update</literal> 속성들은 단방향 one to many 연관관계를 매핑할 때
+ 유용하다. 만일 당신이 단방향 one to many를 null이 허용되지 않는 foreign 키로 매핑할 경우, 당신은
+ <literal><key not-null="true"></literal>를 사용하여 그 키 컬럼을 선언<emphasis>해야 한다</emphasis>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-column" revision="4">
+ <title>column 요소와 formula 요소</title>
+ <para>
+ column 속성을 허용하는 임의의 매핑 요소는 대안적으로 하나의 <literal><column></literal> 서브요소를 수용할 것이다.
+ 비슷하게 <literal><formula></literal>는 <literal>formula</literal> 속성에 대한 대안이다.
+ </para>
+
+ <programlisting><![CDATA[<column
+ name="column_name"
+ length="N"
+ precision="N"
+ scale="N"
+ not-null="true|false"
+ unique="true|false"
+ unique-key="multicolumn_unique_key_name"
+ index="index_name"
+ sql-type="sql_type_name"
+ check="SQL expression"
+ default="SQL expression"/>]]></programlisting>
+
+ <programlisting><![CDATA[<formula>SQL expression</formula>]]></programlisting>
+
+ <para>
+ <literal>column</literal> 속성과 <literal>formula</literal> 속성은 예를 들어 신종 조인 조건들을 표현하기 위해
+ 동일한 property 또는 연관관계 매핑 내에 결합될 수 있다.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="homeAddress" class="Address"
+ insert="false" update="false">
+ <column name="person_id" not-null="true" length="10"/>
+ <formula>'MAILING'</formula>
+</many-to-one>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-import">
+ <title>import</title>
+
+ <para>
+ 당신의 어플리케이션이 동일한 이름을 가진 두 개의 영속 클래스들을 갖고, 당신이 Hibernate 질의들 내에서 전체 수식어가 붙은
+ (패키지)이름을 지정하는 것을 원하지 않는다고 가정하자. 클래스들은 <literal>auto-import="true"</literal>에 의존하기
+ 보다 명시적으로 "임포트 될 " 것이다. 당신은 심지어 명시적으로 매핑되지 않는 클래스들과 인터페이스들을 임포트 시킬 수(가져오기 할 수)
+ 있다.
+ </para>
+
+ <programlisting><![CDATA[<import class="java.lang.Object" rename="Universe"/>]]></programlisting>
+
+ <programlistingco>
+ <areaspec>
+ <area id="import1" coords="2 40"/>
+ <area id="import2" coords="3 40"/>
+ </areaspec>
+ <programlisting><![CDATA[<import
+ class="ClassName"
+ rename="ShortName"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="import1">
+ <para>
+ <literal>class</literal>: 임의의 Java 클래스의 전체 수식어가 붙은 클래스 이름.
+ </para>
+ </callout>
+ <callout arearefs="import2">
+ <para>
+ <literal>rename</literal> (옵션 - 디폴트는 수식어가 붙지 않은 클래스 이름):
+ 질의 언어 내에서 사용될 이름.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ </sect2>
+
+ <sect2 id="mapping-types-anymapping" revision="2">
+ <title>any</title>
+
+ <para>
+ 하나 이상의 프로퍼티 매핑 타입이 존재한다. <literal><any></literal> 매핑 요소는 여러 테이블들로부터 클래스들에
+ 대한 하나의 다형성 연관관계를 정의한다. 이 매핑 타입은 언제나 하나 이상의 컬럼을 필요로 한다. 첫 번째 컬럼은 연관된 엔티티의
+ 타입을 보관한다. 나머지 컬럼들은 식별자를 보관한다. 이런 종류의 연관관계들에 대해 foreign key 컨스트레인트를 지정하는 것이
+ 불가능해서, 이것은 (다형성) 연관관계들을 매핑하는 통상적인 방법으로서 가장 확실한 수단이 아니다. 당신은 매우 특별한 경우들
+ (예를 들어 감사 로그들, 사용자 세션 데이터 등)에서만 이것을 사용해야 한다.
+ </para>
+
+ <para>
+ <literal>meta-type</literal> 속성은 어플리케이션으로 하여금 데이터베이스 컬럼 값들을 <literal>id-type</literal>에
+ 의해 지정된 타입의 식별자 프로퍼티들을 가진 영속 클래스들로 매핑시키는 맞춤형 타입을 지정하도록 한다. 당신은 meta-type의
+ 값들로부터 클래스 이름들로의 매핑을 지정해야 한다.
+ </para>
+
+ <programlisting><![CDATA[<any name="being" id-type="long" meta-type="string">
+ <meta-value value="TBL_ANIMAL" class="Animal"/>
+ <meta-value value="TBL_HUMAN" class="Human"/>
+ <meta-value value="TBL_ALIEN" class="Alien"/>
+ <column name="table_name"/>
+ <column name="id"/>
+</any>]]></programlisting>
+
+ <programlistingco>
+ <areaspec>
+ <area id="any1" coords="2 50"/>
+ <area id="any2" coords="3 50"/>
+ <area id="any3" coords="4 50"/>
+ <area id="any4" coords="5 50"/>
+ <area id="any5" coords="6 50"/>
+ <area id="any6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<any
+ name="propertyName"
+ id-type="idtypename"
+ meta-type="metatypename"
+ cascade="cascade_style"
+ access="field|property|ClassName"
+ optimistic-lock="true|false"
+>
+ <meta-value ... />
+ <meta-value ... />
+ .....
+ <column .... />
+ <column .... />
+ .....
+</any>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="any1">
+ <para>
+ <literal>name</literal>: 프로퍼티 이름.
+ </para>
+ </callout>
+ <callout arearefs="any2">
+ <para>
+ <literal>id-type</literal>: 식별자 타입.
+ </para>
+ </callout>
+ <callout arearefs="any3">
+ <para>
+ <literal>meta-type</literal> (옵션 - 디폴트는 <literal>string</literal>):
+ discriminator 매핑에 허용되는 임의의 타입.
+ </para>
+ </callout>
+ <callout arearefs="any4">
+ <para>
+ <literal>cascade</literal> (optional- defaults to <literal>none</literal>):
+ cascade 스타일.
+ </para>
+ </callout>
+ <callout arearefs="any5">
+ <para>
+ <literal>access</literal> (옵션 - 디폴트는 <literal>property</literal>):
+ Hibernate가 프로퍼티 값에 접근하는데 사용할 방도.
+ </para>
+ </callout>
+ <callout arearefs="any6">
+ <para>
+ <literal>optimistic-lock</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ 이 프로퍼티에 대한 업데이트들이 optimistic 잠금 획득을 필요로 하는지 여부를 지정한다. 달리 말해,
+ 이 프로퍼티가 dirty일 경우에 버전증가가 발생할 것인지 여부를 정의한다.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="mapping-types">
+ <title>Hibernate 타입들</title>
+
+ <sect2 id="mapping-types-entitiesvalues" revision="1">
+ <title>엔티티들과 값들</title>
+
+ <para>
+ 영속 서비스에 관한 여러 Java 언어-레벨의 객체들을 이해하기 위해, 우리는 그것들을 다음 두 개의 그룹들로 분류할 필요가 있다:
+ </para>
+
+ <para>
+ <emphasis>entity</emphasis>는 엔티티에 대한 참조들을 보관하는 임의의 다른 객체들과는 독립적으로 존재한다. 참조되지 않은
+ 객체가 쓰레기 수집되는 통상의 자바 모형과 이것은 대조적이다. (저장들과 삭제들이 부모 엔티티로부터 그것의 자식으로의 케스케이드
+ 되는 경우를 제외하면) 엔티티들은 명시적으로 저장되고 삭제되어야 한다. 이것은 도달 가능성(reachablity)에 의한 객체 영속성의
+ ODMG 모형과는 다르다 - 그리고 어플리케이션 객체들이 대형 시스템들에서 대개 어떻게 사용되는가에 훨씬 더 가깝게 대응한다.
+ 엔티티들은 순환 참조와 공유 참조들을 지원한다. 그것들 또한 버전화 될 수 있다.
+ </para>
+
+ <para>
+ 엔티티의 영속 상태는 다른 엔티티들에 대한 참조들과 <emphasis>value</emphasis> 타입들로 구성된다. 값들은 원시 타입들,
+ 콜렉션들(하나의 콜렉션 내부에 있지 않는 것들), 컴포넌트들, 그리고 어떤 불변의 객체들이다. entities와는 달리, (특별한
+ 콜렉션들과 컴포넌트들에서) 값들은 도달가능성(reachability)에 의해 영속화 <emphasis>되고</emphasis> 삭제 된다.
+ value 객체들(과 원시 타입들)이 그것들의 포함하는 엔티티에 따라 영속화 되고 삭제 되므로, 그것들은 독립적으로 버전화 되지
+ 않는다. 값들은 독립적인 엔티티를 갖지 않아서, 그것들은 두 개의 엔티티들이나 콜렉션들에 의해 공유될 수 없다.
+ </para>
+
+ <para>
+ 지금까지 우리는 엔티티들을 참조하기 위해 "영속 클래스"를 사용해 왔다. 우리는 그것을 계속 사용할 것이다. 하지만 엄격히 말해,
+ 영속 상태를 가진 모든 사용자 정의 클래스들은 엔티티들이 아니다. <emphasis>컴포넌트</emphasis>는 value 의미를 가진
+ 사용자 정의 클래스이다. <literal>java.lang.String</literal> 타입의 자바 프로퍼티는 또한 value 의미를 갖는다.
+ 이 정의가 주어지면, 우리는 JDK에 의해 제공된 모든 타입들(클래스들)이 자바에서 value 타입 의미를 갖고, 반면에 사용자 정의
+ 타입들은 엔티티 또는 type 의미로서 매핑된다고 말할 수 있다. 이 판단은 어플리케이션 개발자에게 달려 있다. 도메인 모형에서
+ 엔티티 클래스에 대한 좋은 힌트는 그 클래스의 하나의 인스턴스에 대한 공유된 참조들인 반면에, composition이나 aggregation은
+ 대개 value 타입으로 변환된다.
+ </para>
+
+ <para>
+ 우리는 문서를 통해 두 개념들을 다시 고찰할 것이다.
+ </para>
+
+ <para>
+ 도점점은 Java type 시스템(과 엔티티들 및 value 타입들에 대한 개발자의 정의)를 SQL/데이터베이스 type 타입으로 매핑하는
+ 것이다. 두 시스템들 사이의 다리는 Hibernate에 의해 제공된다: 엔티티들의 경우 우리는 <literal><class></literal>,
+ <literal><subclass></literal> 등을 사용한다.value 타입들의 경우 우리는 대개<literal>type</literal> 속성을 가진
+ <literal><property></literal>, <literal><component></literal> 등을 사용한다. 이 속성의 값은
+ Hibernate <emphasis>매핑 타입</emphasis>의 이름이다. Hibernate는 (표준 JDK value 타입들에 대해) 많은 매핑들을
+ 제공한다. 나중에 보게 되듯이, 당신은 당신 자신의 매핑 타입들을 작성할 수 있고 마찬가지로 당신의 맞춤형 변환 방도들을 구현할 수
+ 있다.
+ </para>
+
+ <para>
+ 콜렉션들을 제외한 모든 미리 빌드된 Hibernate 타입들은 null 의미를 지원한다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-types-basictypes" revision="3">
+ <title>기본 value 타입들</title>
+
+ <para>
+ 미리-만들어진 <emphasis>기본 매핑 타입들</emphasis>은 대략 다음과 같이 카테고리로 분류된다
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>integer, long, short, float, double, character, byte,
+ boolean, yes_no, true_false</literal></term>
+ <listitem>
+ <para>
+ 자바 원시타입들이나 wrapper 클래스들로부터 적절한(벤더-지정적인) SQL 컬럼 타입들로의 타입 매핑.
+ <literal>boolean, yes_no</literal>와 <literal>true_false</literal>는
+ Java <literal>boolean</literal>이나 <literal>java.lang.Boolean</literal>에 대한
+ 모든 대체적인 인코딩들이다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>string</literal></term>
+ <listitem>
+ <para>
+ <literal>java.lang.String</literal>으로부터 <literal>VARCHAR</literal>
+ (또는 Oracle <literal>VARCHAR2</literal>)로의 타입 매핑.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>date, time, timestamp</literal></term>
+ <listitem>
+ <para>
+ <literal>java.util.Date</literal>와 그것의 서브클래스로부터 SQL 타입들인
+ <literal>DATE</literal>, <literal>TIME</literal>, <literal>TIMESTAMP</literal>
+ (또는 등가물)로의 타입 매핑들.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>calendar, calendar_date</literal></term>
+ <listitem>
+ <para>
+ <literal>java.util.Calendar</literal>로부터 SQL 타입들인
+ <literal>TIMESTAMP</literal>, <literal>DATE</literal> (또는 등가물)로의 타입 매핑들.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>big_decimal, big_integer</literal></term>
+ <listitem>
+ <para>
+ <literal>java.math.BigDecimal</literal>과 <literal>java.math.BigInteger</literal>로부터
+ <literal>NUMERIC</literal> (또는 Oracle <literal>NUMBER</literal>)로의 타입 매핑들.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>locale, timezone, currency</literal></term>
+ <listitem>
+ <para>
+ <literal>java.util.Locale</literal>, <literal>java.util.TimeZone</literal>, 그리고
+ <literal>java.util.Currency</literal>로부터 <literal>VARCHAR</literal>(또는 Oracle
+ <literal>VARCHAR2</literal>)로의 타입 매핑. <literal>Locale</literal>과 <literal>Currency</literal>의
+ 인스턴스들은 그것들의 ISO 코드들로 매핑된다. <literal>TimeZone</literal>의 인스턴스들은 그것들의
+ <literal>ID</literal>로 매핑된다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>class</literal></term>
+ <listitem>
+ <para>
+ <literal>java.lang.Class</literal>로부터 <literal>VARCHAR</literal> (또는 Oracle
+ <literal>VARCHAR2</literal>)로의 타입 매핑. <literal>Class</literal>는 그것의 전체
+ 수식어가 붙은 이름으로 매핑된다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>binary</literal></term>
+ <listitem>
+ <para>
+ byte 배열들을 적절한 SQL binary 타입으로 매핑시킨다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>text</literal></term>
+ <listitem>
+ <para>
+ long Java 문자열을 SQL <literal>CLOB</literal> 또는 <literal>TEXT</literal> 타입으로
+ 매핑시킨다
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>serializable</literal></term>
+ <listitem>
+ <para>
+ serializable Java 타입들을 적절한 SQL binary 타입으로 매핑시킨다. 당신은 또한 디폴트로 기본 타입이
+ 아닌 serializable 자바 클래스 또는 인터페이스의 이름을 가진 Hibernate 타입 <literal>serializable</literal>을
+ 나타낼 수도 있다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>clob, blob</literal></term>
+ <listitem>
+ <para>
+ <literal>java.sql.Clob</literal>와 <literal>java.sql.Blob</literal> JDBC 클래스들에 대한 타입 매핑들.
+ 이들 타입들은 몇몇 어플리케이션들에서는 불편하다. 왜냐하면 blob 또는 clob 객체는 트랜잭션 외부에서 재사용될 수 없기
+ 때문이다.(게다가 드라이버 지원이 비일관적이고 페치되어야 한다)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>imm_date, imm_time, imm_timestamp, imm_calendar, imm_calendar_date,
+ imm_serializable, imm_binary</literal>
+ </term>
+ <listitem>
+ <para>
+ 대개 가변적인 Java 타입들로 간주되는 것에 대한 타입 매핑들. 여기서 Hibernate는 불변적인 Java 타입들에 대해서만 적절한
+ 어떤 최적화를 행하고, 어플리케이션 그 객체를 변할 수 없는 것으로 취급한다. 예를 들어, 당신은 <literal>imm_timestamp</literal>로서
+ 매핑된 인스턴스에 대해 <literal>Date.setTime()</literal>을 호출하지 않을 것이다. 프로퍼티의 값을 변경시키고,
+ 그 변경을 영속화 시키기 위해서, 어플리케이션은 하나의 새로운 (동일하지 않은) 객체를 그 프로퍼티에 할당해야 한다.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+
+ <para>
+ 엔트리들과 콜렉션들의 유일 식별자들은 <literal>binary</literal>, <literal>blob</literal> 그리고 <literal>clob</literal>를
+ 제외한 기본 타입 중 어느 것일 수 있다. (Composite 식별자들이 또한 허용된다. 아래를 보라.)
+ </para>
+
+ <para>
+ 기본 value 타입들은 <literal>org.hibernate.Hibernate</literal>에 정의되어 있는 대응하는
+ <literal>Type</literal> 상수들을 갖는다. 예를 들어, <literal>Hibernate.STRING</literal>은
+ <literal>string</literal> 타입을 표현한다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-types-custom" revision="2">
+ <title>맞춤형 value 타입들</title>
+
+ <para>
+ 개발자들이 그들 자신들의 value 타입들을 생성시키는 것이 상대적으로 쉽다. 예를 들어, 당신은
+ <literal>java.lang.BigInteger</literal> 타입의 프로퍼티들을 <literal>VARCHAR</literal> 컬럼들로
+ 영속화 시키고자 원할 수 있다. Hibernate는 이것을 위한 미리 만들어진 타입을 제공하지 않는다. 그러나 맞춤형 타입들은
+ 프로퍼티(또는 콜렉션 요소)를 하나의 테이블 컬럼으로의 매핑하는 것에 제약되지 않는다. 따라서 예를 들어, 당신은
+ <literal>FIRST_NAME</literal>, <literal>INITIAL</literal>, <literal>SURNAME</literal> 컬럼들로
+ 영속화 되는 <literal>java.lang.String</literal> 타입의 자바 프로퍼티<literal>getName()</literal>/
+ <literal>setName()</literal>를 가질 수 있다.
+ </para>
+
+ <para>
+ 맞춤형 타입을 구현하려면, <literal>org.hibernate.UserType</literal> 또는 <literal>org.hibernate.CompositeUserType</literal>을
+ 구현하고 그 타입의 전체 수식어가 붙은 클래스명을 사용하여 프로퍼티들을 선언하라. 가능한 종류의 것들을 보려면
+ <literal>org.hibernate.test.DoubleStringType</literal>을 체크하라.
+ </para>
+
+ <programlisting><![CDATA[<property name="twoStrings" type="org.hibernate.test.DoubleStringType">
+ <column name="first_string"/>
+ <column name="second_string"/>
+</property>]]></programlisting>
+
+ <para>
+ 하나의 프로퍼티를 여러 개의 컬럼들로 매핑시키는 <literal><column></literal> 태그의 사용을 주목하라.
+ </para>
+
+ <para>
+ <literal>CompositeUserType</literal>, <literal>EnhancedUserType</literal>,
+ <literal>UserCollectionType</literal>, 그리고 <literal>UserVersionType</literal> 인터페이스들은
+ 더 많은 특화된 사용들을 위한 지원을 제공한다.
+ </para>
+
+ <para>
+ 당신은 매핑 파일 속에 <literal>UserType</literal>에 대한 파라미터들을 제공할 수도 있다. 이것을 행하기 위해,
+ 당신의 <literal>UserType</literal>은 <literal>org.hibernate.usertype.ParameterizedType</literal>
+ 인터페이스를 구현해야 한다. 당신의 맞춤형 타입에 파라미터들을 제공하기 위해, 당신은 당신의 매핑 파일들 속에
+ <literal><type></literal> 요소를 사용할 수 있다.
+ </para>
+
+ <programlisting><![CDATA[<property name="priority">
+ <type name="com.mycompany.usertypes.DefaultValueIntegerType">
+ <param name="default">0</param>
+ </type>
+</property>]]></programlisting>
+
+ <para>
+ <literal>UserType</literal>은 이제 그것에 전달된 <literal>Properties</literal> 객체로부터
+ <literal>default</literal>로 명명된 파라미터에 대한 값을 검색할 수 있다.
+ </para>
+
+ <para>
+ 만일 당신이 매우 자주 어떤 UserType을 사용할 경우, 그것은 그것에 대한 더 짧은 이름을 정의하는 것이 유용할 수 있다.
+ <literal><typedef></literal> 요소를 사용하여 이것을 행할 수 있다. Typedef들은 이름을 맞춤형 타입에
+ 할당하고, 또한 만일 그 타입이 파라미터화 된 경우에 디폴트 파라미터 값들의 리스트를 포함할 수도 있다.
+ </para>
+
+ <programlisting><![CDATA[<typedef class="com.mycompany.usertypes.DefaultValueIntegerType" name="default_zero">
+ <param name="default">0</param>
+</typedef>]]></programlisting>
+
+ <programlisting><![CDATA[<property name="priority" type="default_zero"/>]]></programlisting>
+
+ <para>
+ property 매핑 상에 type 파라미터들을 사용함으로써 경우에 맞게 typedef 내에 제공된 파라미터들을 오버라이드 시키는 것이
+ 가능하다.
+ </para>
+
+ <para>
+ 비록 Hibernate의 풍부한 범위의 미리 만들어진 타입들과 컴포넌트들에 대한 지원이 당신이 가끔 맞춤형 타입을 사용할 <emphasis>필요가</emphasis>
+ 거의 없을 것임을 의미할 지라도, 그럼에도 불구하고 그것은 당신의 어플리케이션에서 자주 발생하는 (엔티티가 아닌) 클래스들에 대해
+ 맞춤형 타입들을 사용하는 좋은 형식으로 간주된다. 예를 들어 <literal>MonetaryAmount</literal> 클래스는 비록 그것이
+ 컴포넌트로서 쉽게 매핑될 수 있을지라도, <literal>CompositeUserType</literal>에 대한 좋은 후보이다. 이것에 대한
+ 하나의 동기는 추상화이다. 맞춤형 타입으로, 당신의 매핑 문서들은 화폐 값들을 표현하는 당신의 방법에서 가능한 변경들에 대해 장차
+ 검증될 것이다.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="mapping-entityname">
+ <title>하나의 클래스를 한 번 이상 매핑하기</title>
+ <para>
+ 하나의 특정한 영속 클래스에 대해 하나 이상의 매핑을 제공하는 것이 가능하다. 이 경우에 당신은 두 개의 매핑된 엔티티들의
+ 인스턴스들 사이를 명확하게 하기 위해 <emphasis>하나의 엔티티 이름</emphasis>을 지정해야 한다. (디폴트로, 엔티티
+ 이름은 클래스 이름과 동일한 것이다.) Hibernate는 영속 객체들에 대해 작업할 때, 질의들을 작성할 때, 또는 명명된 엔티티에
+ 대한 연관들을 매핑할 때 당신으로 하여금 엔티티 이름을 지정하도록 한다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Contract" table="Contracts"
+ entity-name="CurrentContract">
+ ...
+ <set name="history" inverse="true"
+ order-by="effectiveEndDate desc">
+ <key column="currentContractId"/>
+ <one-to-many entity-name="HistoricalContract"/>
+ </set>
+</class>
+
+<class name="Contract" table="ContractHistory"
+ entity-name="HistoricalContract">
+ ...
+ <many-to-one name="currentContract"
+ column="currentContractId"
+ entity-name="CurrentContract"/>
+</class>]]></programlisting>
+
+ <para>
+ 연관들은 이제 <literal>class</literal> 대신에 <literal>entity-name</literal>을 사용하여 어떻게 지정되는지를
+ 주목하라.
+ </para>
+
+ </sect1>
+
+ <sect1 id="mapping-quotedidentifiers">
+ <title>SQL 인용부호 표시된 식별자들</title>
+ <para>
+ 당신은 매핑 문서 내에서 테이블 또는 컬럼 이름을 역인용기호(`)들 속에 넣어서 생성된 SQL에서 식별자를 인용부호 처리하도록
+ Hibernate에게 강제할 수도 있다. Hibernate는 SQL <literal>Dialect</literal>에 대해 정확한 인용 스타일을 사용할
+ 것이다(대개 이중 인용부호 이지만, SQL Server의 경우에는 모난 괄호들이고 MySQL의 경우에는 역인용부호(`)).
+ </para>
+
+ <programlisting><![CDATA[<class name="LineItem" table="`Line Item`">
+ <id name="id" column="`Item Id`"/><generator class="assigned"/></id>
+ <property name="itemNumber" column="`Item #`"/>
+ ...
+</class>]]></programlisting>
+
+ </sect1>
+
+
+ <sect1 id="mapping-alternatives">
+ <title>Metadata 대안들</title>
+
+ <para>
+ XML은 모든 사람들을 위한 것이 아니지만, Hibernate에서 O/R 매핑 메타데이터를 정의하는 몇몇 대안적인 방법들이 존재한다.
+ </para>
+
+ <sect2 id="mapping-xdoclet">
+ <title>XDoclet 마크업 사용하기</title>
+
+ <para>
+ 많은 Hibernate 사용자들은 XDoclet <literal>@hibernate.tags</literal>를 사용하여 소스 코드 속에
+ 직접 매핑 정보를 삽입시키는 것을 선호한다. 우리는 이 문서에서 이 접근법을 다루지 않을 것이다. 왜냐하면 그것은
+ 엄격하게는 XDoclet의 부분으로 간주되기 때문이다. 하지만 우리는 XDoclet 매핑들을 가진 <literal>Cat</literal>
+ 클래스에 관한 다음 예제를 포함한다.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+import java.util.Date;
+
+/**
+ * @hibernate.class
+ * table="CATS"
+ */
+public class Cat {
+ private Long id; // identifier
+ private Date birthdate;
+ private Cat mother;
+ private Set kittens
+ private Color color;
+ private char sex;
+ private float weight;
+
+ /*
+ * @hibernate.id
+ * generator-class="native"
+ * column="CAT_ID"
+ */
+ public Long getId() {
+ return id;
+ }
+ private void setId(Long id) {
+ this.id=id;
+ }
+
+ /**
+ * @hibernate.many-to-one
+ * column="PARENT_ID"
+ */
+ public Cat getMother() {
+ return mother;
+ }
+ void setMother(Cat mother) {
+ this.mother = mother;
+ }
+
+ /**
+ * @hibernate.property
+ * column="BIRTH_DATE"
+ */
+ public Date getBirthdate() {
+ return birthdate;
+ }
+ void setBirthdate(Date date) {
+ birthdate = date;
+ }
+ /**
+ * @hibernate.property
+ * column="WEIGHT"
+ */
+ public float getWeight() {
+ return weight;
+ }
+ void setWeight(float weight) {
+ this.weight = weight;
+ }
+
+ /**
+ * @hibernate.property
+ * column="COLOR"
+ * not-null="true"
+ */
+ public Color getColor() {
+ return color;
+ }
+ void setColor(Color color) {
+ this.color = color;
+ }
+ /**
+ * @hibernate.set
+ * inverse="true"
+ * order-by="BIRTH_DATE"
+ * @hibernate.collection-key
+ * column="PARENT_ID"
+ * @hibernate.collection-one-to-many
+ */
+ public Set getKittens() {
+ return kittens;
+ }
+ void setKittens(Set kittens) {
+ this.kittens = kittens;
+ }
+ // addKitten not needed by Hibernate
+ public void addKitten(Cat kitten) {
+ kittens.add(kitten);
+ }
+
+ /**
+ * @hibernate.property
+ * column="SEX"
+ * not-null="true"
+ * update="false"
+ */
+ public char getSex() {
+ return sex;
+ }
+ void setSex(char sex) {
+ this.sex=sex;
+ }
+}]]></programlisting>
+
+ <para>
+ XDoclet과 ibernate에 관한 추가 예제들은 Hibernate 웹 사이트를 보라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-annotations" revision="2">
+ <title>JDK 5.0 Annotations 사용하기</title>
+
+ <para>
+ JDK 5.0은 언어 레벨에서 XDoclet-스타일의 주석들, type-safe와 컴파일 시 체킹을 도입했다. 이 메커니즘은 XDoclet
+ 주석들 보다 더 강력하며 도구들과 IDE들에 의해 더 좋게 지원된다. 예를 들어 IntelliJ IDEA는 JDK 5.0 주석들에 대한
+ 자동-완성 기능과 구문 강조를 지원한다. EJB 명세서의 새로운 개정판(JSR-220)은 엔티티 빈즈에 대한 프라이머리 메타데이터
+ 메커니즘으로서 JDK 5.0 Annotations을 사용한다. Hibernate3는 JSR-220(영속 API)의 <literal>EntityManager</literal>를
+ 구현하고, 매핑 메타데이터에 대한 지원은 별도의 내려받기로서 <emphasis>Hibernate Annotations</emphasis> 패키지를
+ 통해 이용 가능하다. EJB3 (JSR-220)과 Hibernate3 metadata 양자가 지원된다.
+ </para>
+
+ <para>
+ 다음은 EJB 엔티티 빈으로서 주석이 붙은 POJO 클래스에 관한 예제이다:
+ </para>
+
+ <programlisting><![CDATA[@Entity(access = AccessType.FIELD)
+public class Customer implements Serializable {
+
+ @Id;
+ Long id;
+
+ String firstName;
+ String lastName;
+ Date birthday;
+
+ @Transient
+ Integer age;
+
+ @Embedded
+ private Address homeAddress;
+
+ @OneToMany(cascade=CascadeType.ALL)
+ @JoinColumn(name="CUSTOMER_ID")
+ Set<Order> orders;
+
+ // Getter/setter and business methods
+}]]></programlisting>
+
+ <para>
+ JDK 5.0 Annotations(그리고 JSR-220)에 대한 지원은 여전히 작업이 진행 중이고 완성되지 않았음을 노트하라. 상세한 것은
+ Hibernate Anotations를 참조하라.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="mapping-generated" revision="1">
+ <title>산출되는 프로퍼티들</title>
+ <para>
+ 산출되는 프로퍼티들은 데이터베이스에 의해 산출되는 그것들의 값들을 갖는 프로퍼티들이다. 전형적으로,
+ Hibernate 어플리케이션들은 데이터베이스가 값들을 생성시켰던 임의의 프로퍼티들을 포함하는 객체들을
+ <literal>갱신</literal>시킬 필요가 있었다.하지만 generated로 마크된 프로퍼티들은 어플리케이션으로
+ 하여금 이 책임을 Hibernate에게 위임시키도록 한다. 본질적으로 Hibernate가 산출되는 프로퍼티들을 정의했던 엔티티에
+ 대해 SQL INSERT 또는 UPDATE 명령을 내릴 때마다 바로 직후에 산출되는 값들을 검색하기 위해 하나의 select 명령을
+ 내린다.
+ </para>
+ <para>
+ generated로 마크된 프로퍼티들은 부가적으로 inser 가능하지 않아야 하고 update 불가능해야 한다. 오직
+ Properties marked as generated must additionally be non-insertable and non-updateable.
+ <xref linkend="mapping-declaration-version">versions</xref>,
+ <xref linkend="mapping-declaration-timestamp">timestamps</xref>, 그리고
+ <xref linkend="mapping-declaration-property">단순 프로퍼티들</xref> 만이 generated로
+ 마크될 수 있다.
+ </para>
+ <para>
+ <literal>never</literal> (디폴트) - 는 주어진 프로퍼티 값이 데이터베이스 내에 생성되지 않을 것임을 의미한다.
+ </para>
+ <para>
+ <literal>insert</literal> - 는 주어진 프로퍼티 값이 insert 시에 생성되지만, 차후의 업데이트들에서 다시
+ 생성되지 않을 것임을 기술한다. 생성-날짜와 같은 것들이 이 카테고리 내로 포함될 것이다. 비록
+ <xref linkend="mapping-declaration-version">version</xref>과
+ <xref linkend="mapping-declaration-timestamp">timestamp</xref> 프로퍼티들이 생성되는 것으로서
+ 마크될 수 있을 지라도, 이 옵션은 거기서 이용 불가능함을 노트하라...
+ </para>
+ <para>
+ <literal>always</literal> - 는 프로퍼티 값이 insert 시와 update 시 모두에 생성됨을 기술한다.
+ </para>
+ </sect1>
+
+ <sect1 id="mapping-database-object">
+ <title>보조 데이터베이스 객체들</title>
+ <para>
+ Hibernate 매핑 파일들 내에 사용자 스키마를 완전하게 정의하기 위한 능력을 제공하기 위해서,
+ Hibernate의 스키마 방출 도구들과 함께 임의적인 데이터베이스 객체들에 대한 CREATE와 DROP을 허용해준다.
+ 비록 트리거들 또는 내장 프로시저들과 같은 것들을 생성시키고 드롭시키기 이해 특별히 고안되었을지라도
+ 하나의 <literal>java.sql.Statement.execute()</literal> 메소드를 통해 실행될 수 있는 SQL 명령이
+ 여기서 유효하다(ALTERs, INSERTS, 기타). 보조 데0이터베이스 객체들을 정의하는 두 가지 모드들이 본질적으로
+ 존재한다...
+ </para>
+ <para>
+ 첫 번째 모드는 매핑 파일 바깥에서 CREATE 및 DROP 명령들을 명시적으로 나열하는 것이다:
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <create>CREATE TRIGGER my_trigger ...</create>
+ <drop>DROP TRIGGER my_trigger</drop>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ <para>
+ 두번째 모드는 CREATE 및 DROP 명령들을 생성시키는 방법을 알고 있는 하나의 맞춤 클래스를 제공하는 것이다.
+ 이 맞춤 클래스는 <literal>org.hibernate.mapping.AuxiliaryDatabaseObject</literal>
+ 인터페이스를 구현해야 한다.
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <definition class="MyTriggerDefinition"/>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ <para>
+ 덧붙여 이들 데이터베이스 객체들은 어떤 dialect들이 사용될 때 그것들이 단지 적용될 수 있도록 선택적으로
+ 변동될 수 있다.
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <definition class="MyTriggerDefinition"/>
+ <dialect-scope name="org.hibernate.dialect.Oracle9Dialect"/>
+ <dialect-scope name="org.hibernate.dialect.OracleDialect"/>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ </sect1>
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/batch.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/batch.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/batch.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/batch.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,320 @@
+<chapter id="batch">
+ <title>Batch 처리</title>
+
+ <para>
+ Hibernate를 사용하여 데이터베이스 내에서 100 000 개의 행들을 삽입시키는 본래의 접근법은 다음과 같다:
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+for ( int i=0; i<100000; i++ ) {
+ Customer customer = new Customer(.....);
+ session.save(customer);
+}
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ 이것은 50 000번째 행 가까운 곳에서 <literal>OutOfMemoryException</literal>으로 떨어질 것이다. 그것은 Hibernate가
+ session-level 캐시 속에 모든 새로이 삽입된 <literal>Customer</literal> 인스턴스들을 캐시시키기 때문이다.
+ </para>
+
+ <para>
+ 이 장에서 우리는 이 문제를 피하는 방법을 당신에게 보여줄 것이다. 하지만 먼저 당신이 배치 처리를 행하는 중이라면, 당신이 적당한 퍼포먼스를
+ 성취하려고 할 경우에 당신이 JDBC 배치 사용을 가능하게 하는 것은 절대적으로 필요하다. JDBC 배치 사이즈를 적당한 숫자(10-50)로 설정하라:
+ </para>
+
+<programlisting><![CDATA[hibernate.jdbc.batch_size 20]]></programlisting>
+
+ <para id="disablebatching" revision="1">
+ 만일 당신이 <literal>identiy</literal> 식별자 생성자를 사용할 경우
+ Hibernate가 JDBC 레벨에서 투명하게 insert 배치작업을 사용불가능하게 한다는 점을 노트하라.
+ </para>
+
+ <para>
+ 당신은 또한 second-level 캐시를 가진 상호작용이 완전하게 불가능한 프로세스 내에서 이런 종류의 작업을 행하고 싶어할 수도 있다:
+ </para>
+
+<programlisting><![CDATA[hibernate.cache.use_second_level_cache false]]></programlisting>
+
+ <para>
+ 하지만 이것은 절대적으로 필요하지 않다. 왜냐하면 우리는 second-level 캐시와의 상호작용을 불가능하도록 하기 위해
+ 명시적으로 <literal>CacheMode</literal>를 설정할 수 있기 때문이다.
+ </para>
+
+ <sect1 id="batch-inserts">
+ <title>Batch inserts</title>
+
+ <para>
+ 새로운 객체들을 영속화 시킬 때, 당신은 first-level 캐시의 사이즈를 제어하기 위해 세션을 정기적으로 <literal>flush()</literal>
+ 시키고 나서 <literal>clear()</literal> 시켜야 한다.
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+for ( int i=0; i<100000; i++ ) {
+ Customer customer = new Customer(.....);
+ session.save(customer);
+ if ( i % 20 == 0 ) { //20, same as the JDBC batch size
+ //flush a batch of inserts and release memory:
+ session.flush();
+ session.clear();
+ }
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="batch-update" >
+ <title>Batch updates</title>
+
+ <para>
+ 데이터 검색과 업데이트의 경우 동일한 개념들이 적용된다. 게다가 당신은 많은 데이터 행들을 반환하는 질의들에 대해 서버-측 커서들의 장점을
+ 취하는데 <literal>scroll()</literal>을 사용할 필요가 있다.
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+ScrollableResults customers = session.getNamedQuery("GetCustomers")
+ .setCacheMode(CacheMode.IGNORE)
+ .scroll(ScrollMode.FORWARD_ONLY);
+int count=0;
+while ( customers.next() ) {
+ Customer customer = (Customer) customers.get(0);
+ customer.updateStuff(...);
+ if ( ++count % 20 == 0 ) {
+ //flush a batch of updates and release memory:
+ session.flush();
+ session.clear();
+ }
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="batch-statelesssession">
+ <title>StatelessSession 인터페이스</title>
+ <para>
+ 다른 방법으로 Hibernate는 분리된(detached) 객체들의 형식으로 데이터베이스로 그리고 데이터베이스로부터
+ 데이터를 스트리밍하는데 사용될 수 있는 하나의 명령 지향 API를 제공한다. <literal>StatelessSession</literal>은
+ 그것과 연관된 영속 컨텍스트를 갖지 않고 많은 보다 높은 레벨의 생명 주기 의미를 제공하지 않는다.
+ 특히 하나의 상태 없는 세션은 첫 번째 레벨 캐시를 구현하지 않거나 임의의 두 번째 레벨 캐시 또는 질의 캐시와
+ 상호작용하지 않는다. 그것은 전통적인 쓰기-이면(write-behind)의 체킹이나 자동적인 dirty 체킹을 구현하지 않는다.
+ 하나의 상태 없는 세션을 사용하여 수행된 연산들은 연관된 인스턴스들에 대해 케스케이드 되지 않는다. 콜렉션들은
+ 상태 없는 세션에 의해 무시된다. 상태없는 세션을 통해 수행된 연산들은 Hibernate의 이벤트 모형과 인터셉터들을
+ 우회한다. 상태없는 세션들은 첫번째-레벨의 캐시의 부족으로 인해 데이터 alias 효과들에 취약하다. 상태없는 세션은
+ 기본 JDBC에 훨씬 더 가까운 하나의 보다 낮은 레벨의 추상화(abstraction)이다.
+ </para>
+
+<programlisting><![CDATA[StatelessSession session = sessionFactory.openStatelessSession();
+Transaction tx = session.beginTransaction();
+
+ScrollableResults customers = session.getNamedQuery("GetCustomers")
+ .scroll(ScrollMode.FORWARD_ONLY);
+while ( customers.next() ) {
+ Customer customer = (Customer) customers.get(0);
+ customer.updateStuff(...);
+ session.update(customer);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ 이 코드 예제에서, 질의에 의해 반환된 <literal>Customer</literal> 인스턴스들은 곧바고 분리된다(detached).
+ 그것들은 임의의 영속 컨텍스트와 결코 연관되지 않는다.
+ </para>
+
+ <para>
+ <literal>StatelessSession</literal> 인터페이스에 의해 정의된
+ <literal>insert(), update()</literal> 그리고 <literal>delete()</literal> 연산들은 직접적인
+ 데이터베이스 저급 연산들로 갖주되고, 그것은 각각 하나의 SQL <literal>INSERT, UPDATE</literal> 또는
+ <literal>DELETE</literal>의 즉각적인 실행으로 귀결된다. 따라서 그것들은 <literal>Session</literal>
+ 인터페이스에 의해 정의된 <literal>save(), saveOrUpdate()</literal>와 <literal>delete()</literal>
+ 연산들과는 매우 다른 의미들을 갖는다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="batch-direct" revision="3">
+ <title>DML-스타일 연산들</title>
+
+ <para>
+ 이미 논의했듯이, 자동적이고 투명한 객체/관계형 매핑은 객체 상태에 대한 관리에 관계된다. 이것은 객체 상태가 메모리 내에서 이용 가능함을
+ 의미하므로, (SQL <literal>Data Manipulation Language</literal>(DML) 문장들 : <literal>INSERT</literal>,
+ <literal>UPDATE</literal>, <literal>DELETE</literal>를 사용하여) 데이터베이스에서 직접 데이터를
+ 업데이트하거나 삭제하는 것은 메모리 내 상태에 영향을 주지 않을 것이다. 하지만 Hibernate는 Hibernate Query Language
+ (<xref linkend="queryhql">HQL</xref>)를 통해 실행되는 대량 SQL-스타일의 DML 문장 실행을 위한 메소드들을 제공한다.
+ </para>
+
+ <para>
+ <literal>UPDATE</literal>와 <literal>DELETE</literal> 문장들에 대한 유사 구문은 다음과 같다:
+ <literal>( UPDATE | DELETE ) FROM? EntityName (WHERE where_conditions)?</literal>. 노트할 몇 가지:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ from-절에서, FROM 키워드는 옵션이다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ from-절 내에 한 개의 명명된 엔티티가 오직 존재할 수 있다; 그것은 선택적으로 alias될 수 있다. 만일 엔티티
+ 이름이 alias되면, 그때 임의의 프로퍼티 참조들은 그 alias를 사용하여 수식되어야 한다; 만일 엔티티 이름이
+ alias되지 않을 경우, 임의의 프로퍼티 참조들에 대해 수식되는 것은 규칙에 어긋난다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <xref linkend="queryhql-joins-forms">join들</xref>은 (함축적이든 명시적이든)
+ 대량 HQL 질의 속에 지정될 수 없다. 서브-질의들이 where-절에 사용될 수 있다;
+ 서브질의들 그 자신들은 조인들을 포함할 수 있다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ where-절 또한 옵션이다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 하나의 예제로서, 한 개의 HQL <literal>UPDATE</literal>를 실행하기 위해, <literal>Query.executeUpdate()</literal>
+ 메소드(이 메소드는 JDBC의 <literal>PreparedStatement.executeUpdate()</literal>와 유사하게 명명된다)를 사용하라:
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName";
+// or String hqlUpdate = "update Customer set name = :newName where name = :oldName";
+int updatedEntities = s.createQuery( hqlUpdate )
+ .setString( "newName", newName )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ HQL <literal>UPDATE</literal> 문장들은 디폴트로 영향받는 엔티티들에 대한
+ <xref linkend="mapping-declaration-version">version</xref> 또는
+ <xref linkend="mapping-declaration-timestamp">timestamp</xref> 프로퍼티 값들에 영향을 주지 않는다;
+ 이것은 EJB3 명세서에서 유지되고 있다. 하지만 당신은 하이버네이트로 하여금 <literal>versioned update</literal>의
+ 사용을 통해 <literal>version</literal> 또는 <literal>timestamp</literal> 프로퍼티 값들을 적절하게
+ 재설정하도록 강제할 수 있다. 이것은 <literal>UPDATE</literal> 키워드 뒤에 <literal>VERSIONED</literal> 키워드를
+ 추가시켜서 성취된다.
+ </para>
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+String hqlVersionedUpdate = "update versioned Customer set name = :newName where name = :oldName";
+int updatedEntities = s.createQuery( hqlUpdate )
+ .setString( "newName", newName )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ 맞춤형 version 타입들(<literal>org.hibernate.usertype.UserVersionType</literal>)은
+ <literal>update versioned</literal> 문장과 함께 사용하는 것이 허용되지 않음을 노트하라.
+ </para>
+
+ <para>
+ HQL <literal>DELETE</literal>를 실행하려면, 같은 메소드 <literal>Query.executeUpdate()</literal>를
+ 사용하라:
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlDelete = "delete Customer c where c.name = :oldName";
+// or String hqlDelete = "delete Customer where name = :oldName";
+int deletedEntities = s.createQuery( hqlDelete )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ <literal>Query.executeUpdate()</literal> 메소드에 의해 반환되는 <literal>int</literal> 값은 그 오퍼레이션에 의해
+ 영향받은 엔티티들의 개수를 나타낸다. 이것이 데이터베이스 내에서 영향받은 행들의 개수와 상관이 있는지 없는지 여부를 살펴보자. HQL
+ 대량 오퍼레이션은 예를 들어 joined-subclass의 경우에 실행 중인 여러 개의 실제 SQL 문장들로 귀결될 수 있다. 반환되는 숫자는
+ 그 문장에 의해 영향받은 실제 엔티티들의 개수를 나타낸다. joined-subclass 예제로 되돌아가면, 서브 클래스들 중 하나에 대한 삭제는
+ 단지 그 서브클래스가 매핑되어 있는 테이블에 대한 삭제 뿐만 아니라 또한 "루트" 테이블과 상속 계층에서 더 내려온 잠정적으로
+ 조인된-서브클래스 테이블들에 대한 삭제들로 귀결될 수 있다.
+ </para>
+
+ <para>
+ 장래의 배포본들에서 전달될 대량 HQL 오퍼레이션들에 대한 몇 가지 제한들이 현재 존재함을 노트하라; 상세한 것은 JIRA 로드맵을 참조하라.
+ <literal>INSERT</literal> 문장들을 위한 유사-구문은 다음과 같다:
+ <literal>INSERT INTO EntityName properties_list select_statement</literal>. 노트할 몇 가지:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 오직 INSERT INTO ... SELECT ... 형식 만일 지원된다; INSERT INTO ... VALUES ... 형식은 지원되지 않는다.
+ </para>
+ <para>
+ properties_list는 SQL <literal>INSERT</literal> 내에서 <literal>column speficiation</literal>과 유사하다.
+ 매핑된 상속에 참여하는 엔티티들의 경우, 그 주어진 클래스-레벨 상에 직접 정의된 프로퍼티들 만이 properties_list에 사용될 수 있다.
+ 슈퍼클래스 프로퍼티들은 허용되지 않는다; 그리고 서브클래스 프로퍼티들은 의미가 없다. 달리 말해 <literal>INSERT</literal> 문장들은
+ 본래적으로 다형적이지 않다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ select_statement는 반환 타입들이 insert에 의해 기대되는 타입들과 일치해야 한다는 단서 하에 임의의 유효한 HQL select 질의일 수
+ 있다. 현재 이것은 체크를 데이터베이스로 이관시키는 것을 허용하기 보다는 질의 컴파일 동안에 체크된다. 하지만 이것은
+ <emphasis>equal</emphasis>과는 대조적으로 <emphasis>등가인(equivalent)</emphasis> Hibernate <literal>Type</literal>들
+ 사이에서 문제점들을 일으킬 수도 있음을 노트하라. 비록 데이터베이스가 구별짓지 않을 수 있거나 변환을 처리할 수 있을 지라도, 이것은
+ <literal>org.hibernate.type.DateType</literal>로서 정의된 프로퍼티와 <literal>org.hibernate.type.TimestampType</literal>으로
+ 정의된 프로퍼티 사이에 불일치 쟁점들을 일으킨다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ id 프로퍼티의 경우, insert 문장은 당신에게 두 개의 옵션을 준다. 당신은 properties_list 내에 id 프로퍼티를 명시적으로
+ 지정할 수 있거나(그것의 값이 대응하는 select 표현식으로부터 얻어진 경우) 또는 properties_list에서 그것을 생략할 수도 있다
+ (산출된 값이 사용되는 경우). 이 후자의 옵션은 데이터베이스 내에서 연산되는 id 연산자들을 사용할 때에만 이용 가능하다;
+ 임의의 "메모리 내" 타입 연산자들과 함께 이 옵션을 사용하려고 시도하는 것은 파싱 동안에 예외상황을 일으킬 것이다. 이 논의의
+ 목적 상, 데이터베이스 내 산출자(generator)들은 <literal>org.hibernate.id.SequenceGenerator</literal>
+ (그리고 그것의 서브클래스들) 그리고 임의의 <literal>org.hibernate.id.PostInsertIdentifierGenerator</literal>의
+ 구현자들이라고 간주됨을 노트하라. 여기서 가장 주목할 만한 예외상황은 그것이 그것의 값들을 얻기 위한 select 가능한 방법을
+ 노출시키지 않기 때문ㅇ에 사용될 수 없는 <literal>org.hibernate.id.TableHiLoGenerator</literal>이다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>version</literal> 또는 <literal>timestamp</literal>로서 매핑된 프로퍼티들의 경우에,
+ insert 문장은 당신에게 두 개의 옵션들을 준다. 당신은 properties_list 내에 그 프로퍼티를 지정할 수 있거나
+ (그 것의 값이 대응하는 select 표현식으로부터 얻어진 경우) 또는 properties_list에서 그것을 생략할 수 있다
+ (<literal>org.hibernate.type.VersionType</literal>에 의해 정의된 <literal>seed value</literal>
+ 값이 사용되는 경우).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 예제 HQL <literal>INSERT</literal> 문장 실행:
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlInsert = "insert into DelinquentAccount (id, name) select c.id, c.name from Customer c where ...";
+int createdEntities = s.createQuery( hqlInsert )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/best_practices.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/best_practices.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/best_practices.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/best_practices.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,204 @@
+<chapter id="best-practices" revision="3">
+ <title>최상의 실전 경험들</title>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>fine-grained 클래스들을 작성하고 <literal><component></literal>를 사용하여 그것들을 매핑하라. </term>
+ <listitem>
+ <para>
+ <literal>street</literal>, <literal>suburb</literal>, <literal>state</literal>, <literal>postcode</literal>를
+ 캡슐화 시키는데 <literal>Address</literal> 클래스를 사용하라. 이것은 코드 재사용성을 촉진시키고 리팩토링을 단순화 시킨다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>영속 클래스들에 대해 식별자 프로퍼티들을 선언하라.</term>
+ <listitem>
+ <para>
+ Hibernate는 식별자 프로퍼티들을 옵션으로 만든다. 왜 우리가 그것들을 사용해야 하는가에 대한 모든 종류의 이유들이 존재한다.
+ 우리는 식별자들이 '합성(synthetic)'이 되는(비지니스 의미 없이 생성되는) 것을 권장한다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>고유 키들을 식별하라.</term>
+ <listitem>
+ <para>
+ 모든 엔티티들에 대해 고유 키들을 식별하고, <literal><natural-id></literal>를 사용하여 그것들을 매핑하라.
+ 고유 키를 구성하는 프로퍼티들을 비교하기 위해 <literal>equals()</literal>와 <literal>hashCode()</literal>를
+ 구현하라.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term>각각의 클래스 매핑을 그것 자신의 파일 내에 위치지워라.</term>
+ <listitem>
+ <para>
+ 하나의 한덩어리 매핑 문서를 사용하지 말라. <literal>com/eg/Foo.hbm.xml</literal> 파일 속에
+ <literal>com.eg.Foo</literal>를 매핑하라. 이것은 팀 환경에서 특히 좋은 의미를 준다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>매핑들을 리소스들로서 로드시켜라.</term>
+ <listitem>
+ <para>
+ 그것들이 매핑하는 클래스들에 따라서 매핑들을 배치하라
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>질의 문자열들을 객관화 시키는 것을 고려하라.</term>
+ <listitem>
+ <para>
+ 당신의 질의들이 ANSI 표준이 아닌 SQL 함수들을 호출하는 경우는 좋은 실전연습이다. 질의 문자열들을 매핑 파일들에다가
+ 외부화 시키는 것은 어플리케이션을 보다 이식성 있도록 만들어줄 것이다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>바인드 변수들을 사용하라.</term>
+ <listitem>
+ <para>
+ JDBC에서처럼, 상수 아닌 값들을 "?"로 대체시켜라. 질의 속에 상수 아닌 값을 바인드 시키는데 문자열 처리를 결코
+ 사용하지 말라! 더 좋게는 질의들 속에 명명된 파라미터들을 사용하는 것을 고려하라.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>당신 자신의 JDBC 커넥션들을 관리하지 말라.</term>
+ <listitem>
+ <para>
+ Hibernate는 어플리케이션으로 하여금 JDBC 커넥션들을 관리하도록 한다. 이 접근법은 마지막 수단으로서 고려되어야 한다.
+ 만일 당신이 미리 만들어진 커넥션 프로바이더들을 사용할 수 없을 경우, <literal>org.hibernate.connection.ConnectionProvider</literal>에
+ 대한 당신 자신의 구현을 제공하는 것을 고려하라.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>맞춤형 타입 사용을 고려하라.</term>
+ <listitem>
+ <para>
+ 당신이 자바 타입을 갖고 있고, 어떤 라이브러리로부터 말하고, 그것이 영속화 될 필요가 있지만 그것을 컴포넌트로서 매핑시키는데
+ 필요한 accessor들을 제공할 필요가 없다고 가정하자. 당신은 <literal>org.hibernate.UserType</literal>을 구현하는
+ 것을 고려해야 할 것이다. 이 접근법은 Hibernate 타입으로/으로부터 변환들을 구현하는 것으로부터 어플리케이션 코드를 자유롭게
+ 해준다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>병목 지점들에서 수작업으로 코딩된 JDBC를 사용하라.</term>
+ <listitem>
+ <para>
+ 시스템의 퍼포먼스가 중대한 영역들에서, 몇몇 종류의 오퍼레이션들은 직접적인 JDBC에서 이득을 본다. 그러나 당신이 어떤 것이 병목인지를
+ <emphasis>알기</emphasis> 전까지 기다리길 바란다. 그리고 직접적인 JDBC가 반드시 더 빠르다고 가정하지 말라. 만일 당신이 직접적인
+ JDBC를 사용할 필요가 있을 경우, Hibernate <literal>Session</literal>을 열고 그 SQL 커넥션을 사용할 가치가 있다. 그 방법으로
+ 당신은 동일한 트랜잭션 방도와 기본 커넥션 프로바이더를 여전히 사용할 수 있다
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>Session</literal> flushing을 이해하라.</term>
+ <listitem>
+ <para>
+ 시간이 지남에 따라 Session은 그것의 영속 상태를 데이터베이스와 동기화 시킨다. 만일 이 과정이 너무 자주 발생할 경우 퍼포먼스가
+ 영향을 받을 것이다. 당신은 때때로 자동적인 flushing을 사용 불가능하게 만들거나 특정 트랜잭션 내에서 질의들의 순서와 다른
+ 오퍼레이션들의 순서를 변경시켜서 불필요한 flushing을 최소화 시킬 수 있다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>3-tier 아키텍처에서, <literal>saveOrUpdate()</literal> 사용을 고려하라.</term>
+ <listitem>
+ <para>
+ servlet / session 빈 아키텍처를 사용할 때, 당신은 sesson bean 내에 로드된 영속 객체들을 서블릿/JSP 계층으로/으로부터
+ 전달할/받을 수 있다. 각각의 요청을 서비스하는데 새로운 세션을 사용하라. 객체들을 데이터베이스와 동기화 시키기 위해서
+ <literal>Session.merge()</literal> 또는 <literal>Session.saveOrUpdate()</literal>를 사용하라.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>2-tier 아키텍처에서, 수명이 긴 영속 컨텍스트들을 사용하는 것을 고려하라.</term>
+ <listitem>
+ <para>
+ 데이터베이스 트랜잭션들은 최상의 가용성을 위해 가능한 한 짧아야 한다. 하지만 장기간 실행되는 <emphasis>어플리케이션 트랜잭션들</emphasis>,
+ 사용자의 뷰 관점에서 한 개의 단위 작업을 구현하는 것이 가끔 필수적이다. 하나의 어플리케이션 트랜잭션은 몇 개의 클라이언트 요청들과
+ 응답 주기들에 걸칠 수도 있다. 어플리케이션 트랜잭션들을 구현하는데 detached 객체들을 사용하는 것이 공통적이다. 2-티어 아키텍처에서
+ 매우 적절한 대안은 어플리케이션 트랜잭션의 전체 생명주기 동안에 한 개의 열려진 영속 접속 (세션)을 유지하는 것이고 각각의 요청의 끝에서
+ JDBC 커넥션을 간단하게 연결해제하고 차후의 요청의 시작 시에 다시 연결하는 것이다. 한 개 이상의 어플리케이션 트랜잭션을 가로질러서
+ 하나의 단일 세션을 결코 공유하지 말라. 공유할 경우에 당신은 실효성이 없는 데이터로 작업하게 될 것이다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>예외상황들을 복구가능한 것으로서 다루지 말라.</term>
+ <listitem>
+ <para>
+ 이것은 "최상의" 실전이 아닌 보다 필수적인 실전이다. 예외상황이 발생할 때, <literal>Transaction</literal>을 롤백시키고
+ <literal>Session</literal>을 닫아라. 만일 당신이 그렇게 하지 않을 경우, Hibernate는 메모리 내 상태가 영속 상태를 정확하게
+ 표현하는 것을 보증할 수 없다. 이 특별한 경우처럼, 만일 주어진 식별자를 가진 인스턴스가 데이터베이스 상에 존재하는지 여부를 결정하는데
+ <literal>Session.load()</literal>를 사용하지 말라; 대신에 <literal>Session.get()</literal> 또는 하나의 질의를
+ 사용하라.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>연관들에 대한 lazy 페칭을 선호하라.</term>
+ <listitem>
+ <para>
+ eager 페칭을 관대하게 사용하라. second-level 캐시 내에 완전하게 보관되지 않을 것 같은 클래스들에 대한 대붑분의 연관들에
+ 대해 프락시들과 lazy 콜렉션들을 사용하라. 캐시된 클래스들에 대한 연관들의 경우, 이곳은 캐시 성공의 매우 높은 확률이 존재하는
+ 곳이며, <literal>lazy="false"</literal>를 사용하여 eager 페칭을 명시적으로 사용 불가능하게 하라. 한의 join 페칭이
+ 특정 쓰임새에 대해 적절할 때, 하나의 <literal>left join fetch</literal>를 가진 질의를 사용하라.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ 페치되지 않은 데이터 문제점들을 피하기 위해 <emphasis>뷰 내에 열려진 세션(open session in view)</emphasis> 패턴 또는
+ 하나의 정리된 <emphasis>어셈블리 단계(assembly phase)</emphasis>를 사용하라.
+ </term>
+ <listitem>
+ <para>
+ Hibernate는 개발자들이 <emphasis>Data Transfer Objects</emphasis> (DTO)를 지루하게 작성하는 것으로부터
+ 자유롭게 해준다. 전통적인 EJB 아키텍처에서, DTO는 이중 용도로 기능한다: 첫 번째로 그것들은 엔티티 빈즈가 직렬화 가능하지 않는
+ 문제점에 대해 착수한다; 두 번째로 그것들은 뷰에 의해 사용되는 모든 데이터가 프리젠테이션 티어로 컨트롤을 반환하기 전에 DTO들 속으로
+ 페치되고 마샬링되는 어셈블리 단계를 암묵적으로 정의한다. Hibernate는 첫 번째 용도를 제거시킨다. 하지만 당신이 뷰 렌더링 프로세스를
+ 가로질러 열려져 있는 영속 컨텍스트(세션)을 보관할 준비가 되어 있지 않는 한, 당신은 여전히 어셈블리 단계를 필요로 할 것이다(detached
+ 객체들에서 이용가능한 데이터가 무엇인지에 대해 프리젠테이션 티어와 엄격하게 계약을 갖도록 당신의 비지니스 메소드들을 고려하라)
+ 이것은 Hibernate의 한계점이 아니다! 그것은 안전한 트랜잭션 데이터 접근의 필수 조건이다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Hibernate에서 당신의 비지니스 로직을 추상화 시키는 것을 고려하라.</term>
+ <listitem>
+ <para>
+ (Hibernate) 데이터 액세스 코드를 인터페이스 이면에 은폐시켜라. <emphasis>DAO</emphasis>와
+ <emphasis>Thread Local Session</emphasis> 패턴들을 결합시켜라. 당신은 심지어 <literal>UserType</literal>을
+ 통해 Hibernate에 연관된, 수작업으로 코딩된 JDBC로서 몇몇 클래스들을 영속화 시킬 수도 있다. (이 충고는 "충분히 큰"
+ 어플리케이션들에 대한 것이다; 그것은 5개의 테이블들을 가진 어플리케이션에 대해서는 적절하지 않다!)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>신종의 연관 매핑을 사용하지 말라.</term>
+ <listitem>
+ <para>
+ 실제의 many-to-many 연관들에 대한 좋은 쓰임새들은 드물다. 대부분의 시간 동안 당신은 "연결 테이블" 내에 저장된 추가적인 정보를 필요로 한다.
+ 이 경우에, 매개하는 연결 클래스에 대해 두 개의 one-to-many 연관들을 사용하는 것이 훨씬 더 좋다. 사실 우리는 대부분의 연관들이 one-to-many와
+ many-to-one이라고 생각하며, 당신은 다른 연관 스타일을 사용할 때 주의해야 하고 그것이 진정 필수적인지를 당신 스스로 질문하라.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>양방향 연관들을 선호하라.</term>
+ <listitem>
+ <para>
+ 단방향 연관들은 질의하기가 더 어렵다. 많은 어플리케이션에서, 거의 모든 연관들은 질의들 내에서 양 방향으로 네비게이트 가능해야 한다.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/collection_mapping.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/collection_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/collection_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/collection_mapping.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,1158 @@
+<chapter id="collections">
+ <title>콜렉션 매핑</title>
+
+ <sect1 id="collections-persistent" revision="3">
+ <title>영속 콜렉션들</title>
+
+ <para>
+ 예를 들어 Hibernate는 영속 콜렉션-값을 가진 필드들이 인터페이스 타입으로서 선언될 것을 필요로 한다:
+ </para>
+
+ <programlisting><![CDATA[public class Product {
+ private String serialNumber;
+ private Set parts = new HashSet();
+
+ public Set getParts() { return parts; }
+ void setParts(Set parts) { this.parts = parts; }
+ public String getSerialNumber() { return serialNumber; }
+ void setSerialNumber(String sn) { serialNumber = sn; }
+}]]></programlisting>
+
+ <para>
+ 실제 인터페이스는 <literal>java.util.Set</literal>, <literal>java.util.Collection</literal>,
+ <literal>java.util.List</literal>, <literal>java.util.Map</literal>, <literal>java.util.SortedSet</literal>,
+ <literal>java.util.SortedMap</literal> 또는 당신이 좋아하는 어떤 것일 수 있다!(여기서 "당신이 좋아하는 어떤 것"이란
+ 당신이 <literal>org.hibernate.usertype.UserCollectionType</literal>에 대한 구현을 작성해야 함을 의미한다.)
+ </para>
+
+ <para>
+ 우리가 <literal>HashSet</literal>의 인스턴스를 가진 인스턴스 변수를 초기화 시켰던 방법을 주목하라. 이것은 새로이
+ 초기화 된(비-영속) 인스턴스들을 가진 콜렉션 값 프로퍼티들을 초기화 시키는 최선의 방법이다. 당신이 -예를 들어
+ <literal>persist()</literal>를 호출하여- 인스턴스를 영속화 시킬 때 Hibernate는 실제로 <literal>HashSet</literal>을
+ <literal>Set</literal>에 대한 Hibernate 자신의 구현의 인스턴스로 대체시킬 것이다. 다음과 같은 오류들을 관찰하라:
+ </para>
+
+ <programlisting><![CDATA[Cat cat = new DomesticCat();
+Cat kitten = new DomesticCat();
+....
+Set kittens = new HashSet();
+kittens.add(kitten);
+cat.setKittens(kittens);
+session.persist(cat);
+kittens = cat.getKittens(); // Okay, kittens collection is a Set
+(HashSet) cat.getKittens(); // Error!]]></programlisting>
+
+ <para>
+ Hibernate에 의해 도입된 영속 콜렉션들은 인터페이스 타입에 따라 <literal>HashMap</literal>, <literal>HashSet</literal>,
+ <literal>TreeMap</literal>, <literal>TreeSet</literal> 또는 <literal>ArrayList</literal>와 같이 행위한다.
+ </para>
+
+ <para>
+ 콜렉션 인스턴스들은 value 타입들을 가진 통상의 특징을 갖는다. 그것들은 영속 객체에 의해 참조될 때 자동적으로 영속화 되고
+ 참조 해제될 때 자동적으로 삭제된다. 만일 하나의 콜렉션이 하나의 영속 객체로부터 또 다른 영속 객체로 전달될 때, 그것의 요소들은
+ 하나의 테이블로부터 다른 테이블로 이동될 수 있다. 두 개의 엔티티들은 동일한 콜렉션 인스턴스에 대한 참조를 공유하지 않는다.
+ 기본 관계형 모형 때문에 콜렉션 값 프로퍼티들은 null 값 의미들을 지원하지 않는다; Hibernate는 null 콜렉션 참조와 공백의
+ 콜렉션 사이를 구별 짓지 않는다.
+ </para>
+
+ <para>
+ 당신은 이것의 어떤 것에 대해 너무 많이 걱정하지 않아도 될 것이다. 당신이 통상의 자바 콜렉션들을 사용하는 것과 동일한 방법으로
+ 영속 콜렉션들을 사용하라. 단지 당신이 양방향 연관관계들에 대한 의미를 확실히 이해하도록 하라(나중에 논의됨).
+ </para>
+
+ </sect1>
+
+ <sect1 id="collections-mapping" revision="4">
+ <title>콜렉션 매핑들</title>
+
+ <para>
+ 콜렉션을 매핑하는데 사용되는 Hiberante 매핑 요소는 인터페이스의 타입에 의존한다. 예를 들어<literal><set></literal>
+ 요소는 <literal>Set</literal> 타입의 매핑 프로퍼티들에 사용된다
+ </para>
+
+ <programlisting><![CDATA[<class name="Product">
+ <id name="serialNumber" column="productSerialNumber"/>
+ <set name="parts">
+ <key column="productSerialNumber" not-null="true"/>
+ <one-to-many class="Part"/>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ <literal><set></literal>과는 별도로, 또한 <literal><list></literal>, <literal><map></literal>,
+ <literal><bag></literal>, <literal><array></literal>, 그리고 <literal><map></literal>
+ 매핑 요소들이 존재한다. <literal><map></literal> 요소가 대표적이다:
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="mappingcollection1" coords="2 65"/>
+ <area id="mappingcollection2" coords="3 65"/>
+ <area id="mappingcollection3" coords="4 65"/>
+ <area id="mappingcollection4" coords="5 65"/>
+ <area id="mappingcollection5" coords="6 65"/>
+ <area id="mappingcollection6" coords="7 65"/>
+ <area id="mappingcollection7" coords="8 65"/>
+ <area id="mappingcollection8" coords="9 65"/>
+ <area id="mappingcollection9" coords="10 65"/>
+ <area id="mappingcollection10" coords="11 65"/>
+ <area id="mappingcollection11" coords="12 65"/>
+ <area id="mappingcollection12" coords="13 65"/>
+ <area id="mappingcollection13" coords="14 65"/>
+ <area id="mappingcollection14" coords="15 65"/>
+ </areaspec>
+ <programlisting><![CDATA[<map
+ name="propertyName"
+ table="table_name"
+ schema="schema_name"
+ lazy="true|extra|false"
+ inverse="true|false"
+ cascade="all|none|save-update|delete|all-delete-orphan|delete-orphan"
+ sort="unsorted|natural|comparatorClass"
+ order-by="column_name asc|desc"
+ where="arbitrary sql where condition"
+ fetch="join|select|subselect"
+ batch-size="N"
+ access="field|property|ClassName"
+ optimistic-lock="true|false"
+ mutable="true|false"
+ node="element-name|."
+ embed-xml="true|false"
+>
+
+ <key .... />
+ <map-key .... />
+ <element .... />
+</map>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="mappingcollection1">
+ <para>
+ <literal>name</literal> 콜렉션 프로퍼티 이름
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection2">
+ <para>
+ <literal>table</literal> (옵션 - 디폴트는 프로퍼티 이름)
+ 콜렉션 테이블의 이름(one-to-many 연관관계들에 대해서는 사용되지 않음)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection3">
+ <para>
+ <literal>schema</literal> (옵션)
+ 루트 요소 상에 선언된 스키마를 오버라이드 시키는 테이블 스키마의 이름
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection4">
+ <para>
+ <literal>lazy</literal> (옵션 - 디폴트는 <literal>true</literal>)는
+ lazy 페칭을 사용 불가능하도록 하고 그 연관이 항상 eagerly 페치됨을 지정하는데 , 또는 대부분의
+ 연산들이 콜렉션을 초기화시키지 않는 곳에서 "extra-lazy" 페칭을 이용 가능하도록 하는데(매우 큰 콜렉션들에
+ 적당함) 사용될 수 있다
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection5">
+ <para>
+ <literal>inverse</literal> (옵션 - 디폴트는 <literal>false</literal>)
+ 이 콜렉션을 양방향 연관관계의 "inverse" 끝(end)으로 표시한다
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection6">
+ <para>
+ <literal>cascade</literal> (옵션 - 디폴트는 <literal>none</literal>)
+ 오퍼레이션들이 자식 엔티티들에 대해 케스케이드하는 것을 이용 가능하게 한다
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection7">
+ <para>
+ <literal>sort</literal> (옵션)
+ <literal>natural</literal> 정렬 순서로 정렬된(sorted) 콜렉션 또는 주어진 comparator 클래스를 지정한다
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection8">
+ <para>
+ <literal>order-by</literal> (옵션, JDK1.4에서만)
+ <literal>asc</literal> 또는 <literal>desc</literal> 옵션과 함께 <literal>Map</literal>,
+ <literal>Set</literal> 또는 bag의 반복 순서를 정의하는 테이블 컬럼(또는 컬럼들)을 지정한다
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection9">
+ <para>
+ <literal>where</literal> (옵션)
+ 콜렉션을 검색하거나 제거할 때 사용될 임의적인 SQL <literal>WHERE</literal> 조건을 지정한다
+ (콜렉션이 오직 이용 가능한 데이터의 부분집합 만을 포함할 경우에 유용하다)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection10">
+ <para>
+ <literal>fetch</literal> (옵션, 디폴트는 <literal>select</literal>)
+ outer-join 페칭, sequential select 페칭, 그리고 sequential subselect 페칭 사이에서 선택하라.
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection11">
+ <para>
+ <literal>batch-size</literal> (옵션, 디폴트는 <literal>1</literal>)
+ 이 콜렉션의 lazily fetching 인스턴스에 대해 "배치 사이즈"를 지정하라.
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection12">
+ <para>
+ <literal>access</literal> (옵션 - 디폴트는 <literal>property</literal>):
+ Hibernate가 콜렉션 프로퍼티 값에 접근하는데 사용할 방도.
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection13">
+ <para>
+ <literal>optimistic-lock</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ 콜렉션의 상태에 대한 변경들이 소유하는 엔티티의 버전의 증가로 귀결될 것인지를 지정한다.
+ (one to many 연관들에 대해, 이 설정을 사용 불가능하게 하는 것이 종종 합당하다.)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection14">
+ <para>
+ <literal>mutable</literal> (옵션 - 디폴트는 <literal>true</literal>):
+ <literal>false</literal> 값은 콜렉션의 요소들이 결코 변경되지 않음을 지정한다.
+ (몇몇 경우들에서 마이너 퍼포먼스 최적화).
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <sect2 id="collections-foreignkeys" >
+ <title>콜렉션 foreign 키들</title>
+
+ <para>
+ 콜렉션 인스턴스들은 그 콜렉션을 소유하는 엔티티의 foreign 키에 의해 데이터베이스 내에서 구별지워진다. 이 foreign 키는
+ 그 콜렉션 테이블의 <emphasis>콜렉션 키 컬럼</emphasis> (또는 컬럼들)로서 참조된다. 그 콜렉션 키 컬럼은
+ <literal><key></literal> 요소에 의해 매핑된다.
+ </para>
+
+ <para>
+ foreign 키 컬럼에 대한 null 허용 가능 컨스트레인트가 존재할 수 있다. 대부분의 콜렉션들에 대해, 이것이 당연히 수반된다.
+ 단방향 one to many 연관들의 경우, foreign 키는 디폴트로 null 허용 가능하여서, 당신은 <literal>not-null="true"</literal>를
+ 지정할 필요가 있을 수 있다.
+ </para>
+
+ <programlisting><![CDATA[<key column="productSerialNumber" not-null="true"/>]]></programlisting>
+
+ <para>
+ foreign 키 컨스트레인트는 <literal>ON DELETE CASCADE</literal>를 사용할 수도 있다.
+ </para>
+
+ <programlisting><![CDATA[<key column="productSerialNumber" on-delete="cascade"/>]]></programlisting>
+
+ <para>
+ <literal><key></literal> 요소에 대한 전체 정의는 앞 장을 보라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-elements" >
+ <title>콜렉션 요소들</title>
+
+ <para>
+ 콜렉션들은 모든 기본 타입들, 컴포넌트들, 그리고 물론 다른 엔티티들에 대한 참조들을 포함하여 거의 대부분의
+ 어떤 다른 Hibernate 타입을 포함할 수도 있다. 이것은 중요한 구분이다: 콜렉션 내에 있는 객체는 "값(value)"
+ 의미로 처리될 수도 있거나(그것의 생명주기는 콜렉션 소유자에 의존한다) 그것은 그것 자신의 생명주기를 가진
+ 또 다른 엔티티에 대한 참조일 수 있다. 후자의 경우, 두 개의 객체들 사이의 "링크" 만이 그 콜렉션에 의해 소유된
+ 상태로 간주된다.
+ </para>
+
+ <para>
+ 포함된 타입은 콜렉션 요소 타입으로서 불려진다. 콜렉션 요소들은 <literal><element></literal>
+ 또는 <literal><composite-element></literal>에 의해 매핑되거나, 엔티티 참조들의 경우에
+ <literal><one-to-many></literal> 또는 <literal><many-to-many></literal>로서
+ 매핑된다. 앞의 두 개는 value 의미를 가진 요소들을 매핑시키고, 뒤의 두개는 엔티티 연관들을 매핑하는데 사용된다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-indexed">
+ <title>인덱싱 된 콜렉션들</title>
+
+ <para>
+ set 과 bag 의미들을 가진 것들을 제외하면, 모든 콜렉션 매핑들은 콜렉션 테이블 내에 <emphasis>인덱스 컬럼</emphasis>-
+ 배열 인덱스, 또는 <literal>List</literal> 인덱스 또는 <literal>Map</literal> 키로 매핑되는 컬럼-을 필요로 한다.
+ <literal>Map</literal>의 인덱스는 <literal><map-key></literal>로 매핑된, 어떤 기본 타입일 수 있고,
+ 그것은 <literal><map-key-many-to-many></literal>로 매핑된 엔티티 참조일 수 있거나, 그것은
+ <literal><composite-map-key></literal>로 매핑된 composite 타입일 수 있다. 배열 또는 리스트의 인덱스는
+ 항상 <literal>integer</literal> 타입이고 <literal><list-index></literal> 요소를 사용하여 매핑된다.
+ 매핑된 컬럼은 순차적인 정수들을 포함한다(디폴트로 0에서 시작하는 번호가 붙여짐).
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="index1" coords="2 45"/>
+ <area id="index2" coords="3 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<list-index
+ column="column_name"
+ base="0|1|..."/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="index1">
+ <para>
+ <literal>column_name</literal> (필수):
+ 콜렉션 인덱스 값들을 보관하는 컬럼의 이름.
+ </para>
+ </callout>
+ <callout arearefs="index1">
+ <para>
+ <literal>base</literal> (옵션, 디폴트는 <literal>0</literal>):
+ 리스트 또는 배열의 첫 번째 요소에 대응하는 인덱스 컬럼의 값.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <programlistingco>
+ <areaspec>
+ <area id="mapkey1" coords="2 45"/>
+ <area id="mapkey2" coords="3 45"/>
+ <area id="mapkey3" coords="4 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<map-key
+ column="column_name"
+ formula="any SQL expression"
+ type="type_name"
+ node="@attribute-name"
+ length="N"/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="mapkey1">
+ <para>
+ <literal>column</literal> (옵션):
+ 콜렉션 인덱스 값들을 보관하는 컬럼의 이름.
+ </para>
+ </callout>
+ <callout arearefs="mapkey2">
+ <para>
+ <literal>formula</literal> (옵션):
+ map의 키를 평가하는데 사용되는 SQL formula.
+ </para>
+ </callout>
+ <callout arearefs="mapkey3">
+ <para>
+ <literal>type</literal> (필수): The type of the map 키들의 타입
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <programlistingco>
+ <areaspec>
+ <area id="indexmanytomany1" coords="2 45"/>
+ <area id="indexmanytomany2" coords="3 45"/>
+ <area id="indexmanytomany3" coords="3 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<map-key-many-to-many
+ column="column_name"
+ formula="any SQL expression"
+ class="ClassName"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="indexmanytomany1">
+ <para>
+ <literal>column</literal> (옵션):
+ 콜렉션 인덱스 값들에 대한 foreign 키 컬럼의 이름.
+ </para>
+ </callout>
+ <callout arearefs="indexmanytomany2">
+ <para>
+ <literal>formula</literal> (옵션):
+ map의 foreign 키를 평가하는데 사용되는 SQL formula.
+ </para>
+ </callout>
+ <callout arearefs="indexmanytomany3">
+ <para>
+ <literal>class</literal> (필수): map 키로서 사용되는 엔티티 클래스.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+
+ <para>
+ 만일 당신의 테이블이 인덱스 컬럼을 가지 않고, 당신이 여전히 프로퍼티 타입으로서 <literal>List</literal>를 사용하고자
+ 원할 경우, 당신은 그 프로퍼티를 Hibernate <emphasis><bag></emphasis>으로서 매핑해야 한다. bag이
+ 데이터베이스로부터 검색될 때 그것은 그것의 순서를 보유하지 않지만, 그것은 선택적으로 정렬(sorting)되거나 ordering될
+ 수도 있다.
+ </para>
+
+ </sect2>
+
+ <para>
+ 많은 공통된 관계형 모형들을 다루는, 콜렉션들에 대해 생성될 수 있는 매핑들의 영역이 꽤 존재한다. 여러가지 매핑 선언들이 데이터베이스
+ 테이블들로 변환되는 방법을 당신이 느끼려면 스키마 생성 도구로 실험할 것을 우리는 제안한다.
+ </para>
+
+ <sect2 id="collections-ofvalues" revision="2">
+ <title>값들을 가진 콜렉션들과 many-to-many 연관들</title>
+
+ <para>
+ 어떤 값들을 가진 콜렉션 또는 many-to-many 연관은 foreign 키 컬럼이나 컬럼들, <emphasis>콜렉션 요소 컬럼</emphasis>이나
+ 컬럼들 그리고 가능하면 인덱스 컬럼들이나 컬럼들을 가진 전용 <emphasis>콜렉션 테이블</emphasis>을 필요로 한다.
+ </para>
+
+ <para>
+ 값들을 가진 콜렉션의 경우, 우리는 <literal><element></literal> 태그를 사용한다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="element1b" coords="2 50"/>
+ <area id="element2b" coords="3 50"/>
+ <area id="element3b" coords="4 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<element
+ column="column_name"
+ formula="any SQL expression"
+ type="typename"
+ length="L"
+ precision="P"
+ scale="S"
+ not-null="true|false"
+ unique="true|false"
+ node="element-name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="element1b">
+ <para>
+ <literal>column</literal> (옵션): 콜렉션 요소 값들을 소유하는 컬럼의 이름.
+ </para>
+ </callout>
+ <callout arearefs="element2b">
+ <para>
+ <literal>formula</literal> (옵션): 요소를 평가하는데 사용되는 SQL formula.
+ </para>
+ </callout>
+ <callout arearefs="element3b">
+ <para>
+ <literal>type</literal> (필수): 콜렉션 요소의 타입.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <emphasis>many-to-many association</emphasis> 연관은 <literal><many-to-many></literal> 요소를
+ 사용하여 지정된다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="manytomany1" coords="2 60"/>
+ <area id="manytomany2" coords="3 60"/>
+ <area id="manytomany3" coords="4 60"/>
+ <area id="manytomany4" coords="5 60"/>
+ <area id="manytomany5" coords="6 60"/>
+ <area id="manytomany6" coords="7 60"/>
+ <area id="manytomany7" coords="8 60"/>
+ <area id="manytomany8" coords="9 60"/>
+ </areaspec>
+ <programlisting><![CDATA[<many-to-many
+ column="column_name"
+ formula="any SQL expression"
+ class="ClassName"
+ fetch="select|join"
+ unique="true|false"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ property-ref="propertyNameFromAssociatedClass"
+ node="element-name"
+ embed-xml="true|false"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="manytomany1">
+ <para>
+ <literal>column</literal> (옵션): 요소 foreign 키 컬럼의 이름.
+ </para>
+ </callout>
+ <callout arearefs="manytomany2">
+ <para>
+ <literal>formula</literal> (옵션): 요소 foreign 키 값을 평가하는데 사용되는 SQL formula.
+ </para>
+ </callout>
+ <callout arearefs="manytomany3">
+ <para>
+ <literal>class</literal> (필수): 연관된 클래스의 이름.
+ </para>
+ </callout>
+ <callout arearefs="manytomany4">
+ <para>
+ <literal>fetch</literal> (옵션 - 디폴트는 <literal>join</literal>):
+ 이 연관에 대해 outer-join 페칭 또는 sequential select 페칭을 이용 가능하게 만든다. 이것은 특별한 경우이다;
+ 엔티티 그리고 다른 엔티티들과 그것의 many-to-many 관계들에 대한 (하나의 <literal>SELECT</literal>
+ 내에서) 전체 eager 페칭의 경우, 당신은 콜렉션 그 자체에 대해서 뿐만 아니라 내포된 요소 <literal><many-to-many></literal>
+ 상의 이 속성에 대해 <literal>join</literal> 페칭을 이용 가능하게 할 것이다.
+ </para>
+ </callout>
+ <callout arearefs="manytomany5">
+ <para>
+ <literal>unique</literal> (옵션):
+ foreign-key 컬럼에 대한 유일 컨스트레인트의 DDL 생성을 가능하도록 한다. 이것은 연관 다중성
+ (association multiplicity)을 효율적으로 one to many로 만든다.
+ </para>
+ </callout>
+ <callout arearefs="manytomany6">
+ <para>
+ <literal>not-found</literal> (옵션 - 디폴트는 <literal>exception</literal>):
+ 누락된 행들을 참조하는 foreign 키들이 어떻게 처리될 것인지를 지정한다:
+ <literal>ignore</literal>는 누락된 한 행을 한 개의 연관으로 다룰 것이다.
+ </para>
+ </callout>
+ <callout arearefs="manytomany7">
+ <para>
+ <literal>entity-name</literal> (옵션): <literal>class</literal>에 대한 하나의 대안으로서,
+ 연관된 클래스의 엔티티 이름.
+ </para>
+ </callout>
+ <callout arearefs="manytomany8">
+ <para>
+ <literal>property-ref</literal>: (옵션) 이 foreign 키에 조인된 연관 클래스의 프로퍼티의 이름.
+ 지정되지 않을 경우, 연관 클래스의 프라이머리 키가 사용된다.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 몇몇 예제들, 먼저 문자열들을 가진 set:
+ </para>
+
+ <programlisting><![CDATA[<set name="names" table="person_names">
+ <key column="person_id"/>
+ <element column="person_name" type="string"/>
+</set>]]></programlisting>
+
+ <para>
+ (<literal>order-by</literal> 속성에 의해 결정되는 반복 순서를 가진) 정수들을 포함하는 bag :
+ </para>
+
+ <programlisting><![CDATA[<bag name="sizes"
+ table="item_sizes"
+ order-by="size asc">
+ <key column="item_id"/>
+ <element column="size" type="integer"/>
+</bag>]]></programlisting>
+
+ <para>
+ 엔티티들을 가진 배열 - 이 경우에, many to many 연관 :
+ </para>
+
+ <programlisting><![CDATA[<array name="addresses"
+ table="PersonAddress"
+ cascade="persist">
+ <key column="personId"/>
+ <list-index column="sortOrder"/>
+ <many-to-many column="addressId" class="Address"/>
+</array>]]></programlisting>
+
+ <para>
+ 날짜들에 대한 문자열 인덱스들을 가진 map :
+ </para>
+
+ <programlisting><![CDATA[<map name="holidays"
+ table="holidays"
+ schema="dbo"
+ order-by="hol_name asc">
+ <key column="id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ 컴포넌트들의 리스트(다음 장에서 논의됨):
+ </para>
+
+ <programlisting><![CDATA[<list name="carComponents"
+ table="CarComponents">
+ <key column="carId"/>
+ <list-index column="sortOrder"/>
+ <composite-element class="CarComponent">
+ <property name="price"/>
+ <property name="type"/>
+ <property name="serialNumber" column="serialNum"/>
+ </composite-element>
+</list>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="collections-onetomany">
+ <title>One-to-many 연관들</title>
+
+ <para>
+ <emphasis>one to many 연관</emphasis>은 중재하는 콜렉션 테이블 없이 foreign 키를 통해 두 개의 클래스들의 테이블들을
+ 연결시킨다. 이 매핑은 통상의 자바 콜렉션들의 어떤 의미를 상실한다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 포함된 엔티티 클래스의 인스턴스는 그 콜렉션의 하나 이상의 인스턴스에 속하지 않을 수 있다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 포함된 엔티티 클래스의 인스턴스는 콜렉션 인덱스의 하나 이상의 값에서 나타나지 않을 수 있다
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>Product</literal>로부터 <literal>Part</literal>로의 연관은 foreign 키 컬럼과 <literal>Part</literal>
+ 테이블에 대한 인덱스 컬럼의 존재를 필요로 한다. <literal><one-to-many></literal> 태그는 이것이 one to many
+ 연관임을 나타낸다.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="onetomany1" coords="2 60"/>
+ <area id="onetomany2" coords="3 60"/>
+ <area id="onetomany3" coords="4 60"/>
+ </areaspec>
+ <programlisting><![CDATA[<one-to-many
+ class="ClassName"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ node="element-name"
+ embed-xml="true|false"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="onetomany1">
+ <para>
+ <literal>class</literal> (필수): 연관된 클래스의 이름.
+ </para>
+ </callout>
+ <callout arearefs="onetomany2">
+ <para>
+ <literal>not-found</literal> (옵션 - 디폴트는 <literal>exception</literal>):
+ 누락된 행들을 참조하는 캐시된 식별자들이 어떻게 처리될 것인지를 지정한다:
+ <literal>ignore</literal>는 누락된 한 행을 한 개의 연관으로 다룰 것이다.
+ </para>
+ </callout>
+ <callout arearefs="onetomany3">
+ <para>
+ <literal>entity-name</literal> (옵션): <literal>class</literal>에 대한 대안으로서,
+ 연관된 클래스의 엔티티 이름.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <literal><one-to-many></literal> 요소는 어떤 컬럼들을 선언하는데 필요하지 않음을 주목하라. 어딘가에
+ <literal>table</literal> 이름을 지정하는 것도 필수적이지 않다.
+ </para>
+
+ <para>
+ <emphasis>매우 중요한 노트</emphasis>: 만일 <literal><one-to-many></literal> 연관의 foreign 키 컬럼이
+ <literal>NOT NULL</literal>로 선언될 경우, 당신은 <literal><key></literal> 매핑을 <literal>not-null="true"</literal>로
+ 선언해야 하거나 <literal>inverse="true"</literal>로 마크된 콜렉션 매핑을 가진 <emphasis>양방향 연관을 사용해야 한다</emphasis>.
+ 양방향 연관들에 대한 논의는 이 장의 뒷부분을 보라.
+ </para>
+
+ <para>
+ 이 예제는 name으로 <literal>Part</literal> 엔티티들을 가진 map을 보여준다(여기서 <literal>partName</literal>은
+ <literal>Part</literal>의 영속 프로퍼티이다). formula-기반 index의 사용을 주목하라.
+ </para>
+
+ <programlisting><![CDATA[<map name="parts"
+ cascade="all">
+ <key column="productId" not-null="true"/>
+ <map-key formula="partName"/>
+ <one-to-many class="Part"/>
+</map>]]></programlisting>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="collections-advancedmappings">
+ <title>개선된 콜렉션 매핑들</title>
+
+ <sect2 id="collections-sorted" revision="2">
+ <title>Sorted 콜렉션들</title>
+
+ <para>
+ Hibernate는 <literal>java.util.SortedMap</literal>과 <literal>java.util.SortedSet</literal>를 구현하는
+ 콜렉션들을 지원한다. 당신은 매핑 파일 속에 하나의 comparator를 지정해야 한다:
+ </para>
+
+ <programlisting><![CDATA[<set name="aliases"
+ table="person_aliases"
+ sort="natural">
+ <key column="person"/>
+ <element column="name" type="string"/>
+</set>
+
+<map name="holidays" sort="my.custom.HolidayComparator">
+ <key column="year_id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ <literal>sort</literal> 속성에 허용되는 값들은 <literal>unsorted</literal>, <literal>natural</literal>,
+ 그리고 <literal>java.util.Comparator</literal>를 구현하는 클래스의 이름이다.
+ </para>
+
+ <para>
+ Sorted 콜렉션들은 <literal>java.util.TreeSet</literal> 또는 <literal>java.util.TreeMap</literal>처럼 행동한다.
+ </para>
+
+ <para>
+ 만일 당신이 데이터베이스 그 자체가 콜렉션 요소들을 순서지우도록(order)원할 경우 <literal>set</literal>,
+ <literal>bag</literal> 또는<literal>map</literal> 매핑들에 대해 <literal>order-by</literal> 속성을 사용하라.
+ 이 해결책은 JDK 1.4 이상의 버전에서만 이용 가능하다(그것은 <literal>LinkedHashSet</literal> 또는 <literal>LinkedHashMap</literal>을
+ 사용하여 구현된다). 이것은 메모리 내가 아닌, SQL 질의 내에서 순서지움(ordering)을 수행한다.
+ </para>
+
+ <programlisting><![CDATA[<set name="aliases" table="person_aliases" order-by="lower(name) asc">
+ <key column="person"/>
+ <element column="name" type="string"/>
+</set>
+
+<map name="holidays" order-by="hol_date, hol_name">
+ <key column="year_id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ <literal>order-by</literal> 속성의 값은 HQL 순서지움(ordering)이 아니라 SQL 순서지움(ordering)임을 노트하라!
+ </para>
+
+ <para>
+ 연관들은 콜렉션 <literal>filter()</literal>를 사용하여 실행 시에 어떤 임의의 criteria(기준)을 사용하여 정렬(sort)될
+ 수도 있다.
+ </para>
+
+ <programlisting><![CDATA[sortedUsers = s.createFilter( group.getUsers(), "order by this.name" ).list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="collections-bidirectional" revision="1">
+ <title>양방향 연관들</title>
+
+ <para>
+ <emphasis>양방향 연관</emphasis>은 연관의 양 "끝(end)들"로부터 네비게이션을 허용한다.
+ 두 가지 종류의 양방향 연관들이 지원된다:
+
+ <variablelist>
+ <varlistentry>
+ <term>one-to-many</term>
+ <listitem>
+ <para>
+ 한쪽 끝에 set 또는 bag 값을 갖고, 다른 쪽 긑에 단일 값을 가진 연관
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>many-to-many</term>
+ <listitem>
+ <para>
+ 양 끝에서 set 또는 bag 값을 가진 연관
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+
+ <para>
+ 당신은 동일한 두 개의 many-to-many 연관들을 동일한 데이터베이스 테이블로 간단하게 매핑하고 한 쪽 끝을
+ <emphasis>inverse</emphasis>(당신의 선택은 하나이지만, 그것은 인덱싱된 콜렉션일 수 없다)로 선언함으로써 하나의 양방향
+ many-to-many 연관을 지정할 수도 있다.
+ </para>
+
+ <para>
+ 다음은 양방향 many-to-many 연관에 관한 예제이다; 각각의 카테고리는 많은 아이템들을 가질 수 있고 각각의 아이템은 많은
+ 카테고리들 속에 있을 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<class name="Category">
+ <id name="id" column="CATEGORY_ID"/>
+ ...
+ <bag name="items" table="CATEGORY_ITEM">
+ <key column="CATEGORY_ID"/>
+ <many-to-many class="Item" column="ITEM_ID"/>
+ </bag>
+</class>
+
+<class name="Item">
+ <id name="id" column="ITEM_ID"/>
+ ...
+
+ <!-- inverse end -->
+ <bag name="categories" table="CATEGORY_ITEM" inverse="true">
+ <key column="ITEM_ID"/>
+ <many-to-many class="Category" column="CATEGORY_ID"/>
+ </bag>
+</class>]]></programlisting>
+
+ <para>
+ 연관의 inverse 끝(end)에 대해서만 행해진 변경들은 영속화 되지 <emphasis>않는다</emphasis>. 이것은 Hibernate가
+ 모든 양방향 연관에 대해 메모리 내에 두 개의 표상들을 갖는다는 점을 의미한다: A로부터 B로의 하나의 링크와 B로부터 A로의 또 다른 링크.
+ 만일 당신이 자바 객체 모형에 대해 그리고 자바에서 many-to-many 관계를 생성시키는 방법에 대해 생각하면 이것은 이해하기가 더 쉽다:
+ </para>
+
+ <programlisting><![CDATA[
+category.getItems().add(item); // The category now "knows" about the relationship
+item.getCategories().add(category); // The item now "knows" about the relationship
+
+session.persist(item); // The relationship won't be saved!
+session.persist(category); // The relationship will be saved]]></programlisting>
+
+ <para>
+ non-inverse 측은 메모리 내 표상을 데이터베이스로 저장하는데 사용된다.
+ </para>
+
+ <para>
+ 당신은 하나의 one-to-many 연관을 하나의 many-to-one 연관으로서 동일한 테이블 컬럼(들)로 매핑하고 many-값을 가진 끝(end)을
+ <literal>inverse="true"</literal>로 선언함으로써 하나의 양방향 연관을 정의할 수도 있다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ 연관의 한쪽 끝을 <literal>inverse="true"</literal>로 매핑하는 것은 cascade들을 가진 오퍼레이션에 영향을 주지 않으며,
+ 이것들은 orthogonal(직교) 개념들이다!
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-indexedbidirectional">
+ <title>인덱싱된 콜렉션들을 가진 양방향 연관들</title>
+ <para>
+ 한쪽 끝이 하나의 <literal><list></literal> 또는 <literal><map></literal>으로서 표현되는 양방향
+ 연관은 특별한 검토를 필요로 한다. 만일 인덱스 컬럼으로 매핑되는 child 클래스의 프로퍼티가 하나 존재한다면 문제가 없고,
+ 우리는 콜렉션 매핑 상에 <literal>inverse="true"</literal>를 사용하여 계속할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <map name="children" inverse="true">
+ <key column="parent_id"/>
+ <map-key column="name"
+ type="string"/>
+ <one-to-many class="Child"/>
+ </map>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <property name="name"
+ not-null="true"/>
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ 그러나 만일 child 클래스 상에 그런 프로퍼티가 존재하지 않을 경우, 우리는 그 연관을 진정하게 양방향으로 간주할 수 없다
+ (다른 쪽 끝에서 이용가능하지 않은 그 연관의 끝에서 이용 가능한 정보가 존재한다). 이 경우에 우리는 그 콜렉션을
+ <literal>inverse="true"</literal>로 매핑시킬 수 없다. 대신에 우리는 다음 매핑을 사용할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <map name="children">
+ <key column="parent_id"
+ not-null="true"/>
+ <map-key column="name"
+ type="string"/>
+ <one-to-many class="Child"/>
+ </map>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ insert="false"
+ update="false"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ 이 매핑에서 그 연관의 콜렉션 값을 가진 끝이 foreign 키에 대한 업데이트 책임이 있음을 노트하라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-ternary">
+ <title>Ternary associations(세겹 연관들)</title>
+
+ <para>
+ 세 겹의 연관을 매핑하는 세 가지 가능한 접근법들이 존재한다. 하나의 접근법은 그것의 인덱스로서 연관관계를 가진
+ <literal>Map</literal>을 사용하는 것이다:
+ </para>
+
+ <programlisting><![CDATA[<map name="contracts">
+ <key column="employer_id" not-null="true"/>
+ <map-key-many-to-many column="employee_id" class="Employee"/>
+ <one-to-many class="Contract"/>
+</map>]]></programlisting>
+
+ <programlisting><![CDATA[<map name="connections">
+ <key column="incoming_node_id"/>
+ <map-key-many-to-many column="outgoing_node_id" class="Node"/>
+ <many-to-many column="connection_id" class="Connection"/>
+</map>]]></programlisting>
+
+ <para>
+ 두 번째 접근법은 그 연관을 엔티티 클래스로서 단순하게 리모델링 하는 것이다. 이것은 우리가 가장 공통적으로 사용하는 접근법이다.
+ </para>
+
+ <para>
+ 마지막 대안은 우리가 나중에 논의하게 될 composite 요소들을 사용하는 것이다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-idbag" revision="1">
+ <title><literal><idbag></literal> 사용하기</title>
+
+ <para>
+ 만일 당신이 composite 키들이 나쁜 것이고 엔티티들이 합성 식별자들(대용 키들, surrogate keys)을 가져야 한다는
+ 우리의 견해를 전적으로 수용할 경우, 당신은 우리가 지금까지 보여주었던 값들을 가진 콜렉션들과 many to many 연관들이 모두
+ composite 키들을 가진 테이블들로 매핑된다는 약간 이상한 점을 발견할 수도 있다! 이제 이 점은 꽤 논의의 여지가 있다; 순수한
+ 연관 테이블은 (비록 composite 값들을 가진 콜렉션<emphasis>일 수도</emphasis> 있을지라도) 대용 키로부터 많은 이점을
+ 취하지 않는 것처럼 보인다. 그럼에도 불구하고 Hibernate는 당신이 값들을 가진 콜렉션들과 many to many 연관들을 대용 키를 가진
+ 테이블로 매핑시키는 것을 당신에게 허용해주는 특징을 제공한다.
+ </para>
+
+ <para>
+ <literal><idbag></literal> 요소는 bag 의미를 가진 <literal>List</literal>(또는 <literal>Collection</literal>)을
+ 매핑하도록 당신에게 허용해준다.
+ </para>
+
+<programlisting><![CDATA[<idbag name="lovers" table="LOVERS">
+ <collection-id column="ID" type="long">
+ <generator class="sequence"/>
+ </collection-id>
+ <key column="PERSON1"/>
+ <many-to-many column="PERSON2" class="Person" fetch="join"/>
+</idbag>]]></programlisting>
+
+ <para>
+ 당신이 볼 수 있듯이, <literal><idbag></literal>은 마치 엔티티 클래스인양 synthetic id generator(합성 id 생성기)를
+ 갖는다! 다른 대용 키는 각각의 콜렉션 행에 할당된다. 하지만 Hibernate는 특정 행의 대용 키 값을 발견하는 메커니즘을 제공하지 않는다.
+ </para>
+
+ <para>
+ <literal><idbag></literal>의 업데이트 퍼포먼스는 정규 <literal><bag></literal> 보다 훨씬 좋다는 점을
+ 노트하라! Hibernate는 마치 list, map, 또는 set인양, 개별 행들을 효율적으로 위치지울 수 있고 그것들을 개별적으로 업데이트
+ 하거나 삭제시킬 수 있다.
+ </para>
+
+ <para>
+ 현재 구현에서, <literal>native</literal> 식별자 생성 방도는 <literal><idbag></literal> 콜렉션 식별자들에 대해
+ 지원되지 않는다.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <!--다음 요소를 문서화하지 않음 -->
+
+ <!--sect1 id="collections-heterogeneous">
+ <title>Heterogeneous Associations</title>
+
+ <para>
+ <literal><many-to-any></literal>와 <literal><index-many-to-any></literal> 요소들은
+ 진정한 이종의(heterogeneous) 연관들을 제공한다. 이들 매핑 요소들은 <literal><any></literal> 요소와
+ 동일한 방법으로 동작한다 - 그리고 또한 아마 드물게 사용될 수 있을 것이다.
+ </para>
+
+ </sect1-->
+
+ <sect1 id="collections-example" revision="1">
+ <title>콜렉션 예제들</title>
+
+ <para>
+ 앞의 절들은 꽤 혼동스럽다. 따라서 예제를 살펴보자. 다음 클래스:
+ </para>
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+
+public class Parent {
+ private long id;
+ private Set children;
+
+ public long getId() { return id; }
+ private void setId(long id) { this.id=id; }
+
+ private Set getChildren() { return children; }
+ private void setChildren(Set children) { this.children=children; }
+
+ ....
+ ....
+}]]></programlisting>
+
+ <para>
+ 는 <literal>Child</literal> 인스턴스들을 가진 하나의 콜렉션을 갖고 있다. 만일 각각의 자식이 최소한 한 개의 부모를 가질 경우,
+ 대부분의 고유한 매핑은 one-to-many 연관이다:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 이것은 다음 테이블 정의들로 매핑된다:
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null primary key, name varchar(255), parent_id bigint )
+alter table child add constraint childfk0 (parent_id) references parent]]></programlisting>
+
+ <para>
+ 만일 부모가 <emphasis>필수적</emphasis>이라면, 양방향 one-to-many 연관관계를 사용하라:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ <many-to-one name="parent" class="Parent" column="parent_id" not-null="true"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>NOT NULL</literal> 컨스트레인트를 주목하라:
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null
+ primary key,
+ name varchar(255),
+ parent_id bigint not null )
+alter table child add constraint childfk0 (parent_id) references parent]]></programlisting>
+
+ <para>
+ 대안적으로, 만일 당신이 이 연관관계가 단방향이어야 함을 절대적으로 역설할 경우, 당신은 <literal><key></literal>
+ 매핑 상에 <literal>NOT NULL</literal> 컨스트레인트를 선언할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children">
+ <key column="parent_id" not-null="true"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 반면에, 만일 자식이 여러 부모들을 가질 수 있을 경우, many-to-many 연관이 적절하다:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children" table="childset">
+ <key column="parent_id"/>
+ <many-to-many class="Child" column="child_id"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 테이블 정의들:
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null primary key, name varchar(255) )
+create table childset ( parent_id bigint not null,
+ child_id bigint not null,
+ primary key ( parent_id, child_id ) )
+alter table childset add constraint childsetfk0 (parent_id) references parent
+alter table childset add constraint childsetfk1 (child_id) references child]]></programlisting>
+
+ <para>
+ 부모/자식 관계 매핑을 연습하는 더 많은 예제들과 전체 리허설은 <xref linkend="example-parentchild"/>를 보라.
+ </para>
+
+ <para>
+ 비록 더 많은 신종 연관 매핑들이 가능할지라도, 우리는 다음 장에서 모든 가능성들을 분류할 것이다.
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/component_mapping.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/component_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/component_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/component_mapping.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,373 @@
+<chapter id="components">
+ <title>Component 매핑</title>
+
+ <para>
+ <emphasis>component</emphasis>의 개념은 Hibernate에서 다른 용도로 몇몇 다른 컨텍스트들 내에서 재사용된다.
+ </para>
+
+ <sect1 id="components-dependentobjects" revision="2" >
+ <title>종속 객체들</title>
+
+ <para>
+ 하나의 컴포넌트는 엔티티 참조가 아닌, value 타입으로서 영속화 되는 하나의 포함된 객체이다. "컴포넌트" 용어는
+ (아키텍처 수준의 컴포넌트들이 아닌) composition(구성,합성)에 대한 객체-지향적인 개념을 언급한다.
+ 예를 들어 당신은 다음과 같이 개인을 모형화 시킬 수도 있다:
+ </para>
+
+ <programlisting><![CDATA[public class Person {
+ private java.util.Date birthday;
+ private Name name;
+ private String key;
+ public String getKey() {
+ return key;
+ }
+ private void setKey(String key) {
+ this.key=key;
+ }
+ public java.util.Date getBirthday() {
+ return birthday;
+ }
+ public void setBirthday(java.util.Date birthday) {
+ this.birthday = birthday;
+ }
+ public Name getName() {
+ return name;
+ }
+ public void setName(Name name) {
+ this.name = name;
+ }
+ ......
+ ......
+}]]></programlisting>
+
+<programlisting><![CDATA[public class Name {
+ char initial;
+ String first;
+ String last;
+ public String getFirst() {
+ return first;
+ }
+ void setFirst(String first) {
+ this.first = first;
+ }
+ public String getLast() {
+ return last;
+ }
+ void setLast(String last) {
+ this.last = last;
+ }
+ public char getInitial() {
+ return initial;
+ }
+ void setInitial(char initial) {
+ this.initial = initial;
+ }
+}]]></programlisting>
+
+ <para>
+ 이제 <literal>Name</literal>은 <literal>Person</literal>의 컴포넌트로서 영속화 될 수도 있다. <literal>Name</literal>이
+ 그것의 영속 프로퍼티들에 대한 getter 메소드와 setter 메소드를 정의하지만, 어떤 인터페이스들이나 식별자 프로퍼티들을 선언하는 것을
+ 필요로 하지 않음을 주목하라.
+ </para>
+
+ <para>
+ 우리의 Hibernate 매핑은 다음과 같을 것이다:
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Person" table="person">
+ <id name="Key" column="pid" type="string">
+ <generator class="uuid"/>
+ </id>
+ <property name="birthday" type="date"/>
+ <component name="Name" class="eg.Name"> <!-- class attribute optional -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </component>
+</class>]]></programlisting>
+
+ <para>
+ person 테이블은
+ <literal>pid</literal>,
+ <literal>birthday</literal>,
+ <literal>initial</literal>,
+ <literal>first</literal>,
+ <literal>last</literal> 컬럼들을 가질 것이다.
+ </para>
+
+ <para>
+ 모든 값(value) 타입들처럼, 컴포넌트들은 공유된 참조들을 지원하지 않는다. 달리 말해, 두 명의 개인들은 동일한 이름을 가질 수
+ 있지만, 두 개의 person 객체들은 오직 값 만이 "동일한" 두 개의 독립적인 name 객체들을 포함할 것이다. 컴포넌트의 null 값 의미는
+ <emphasis>특별한 용도를 위한 것이다</emphasis>. 포함된 객체를 다시 로드시킬 때, Hibernate는 모든 컴포넌트 컬럼들이
+ null일 경우에 전체 컴포넌트가 null이라고 가정할 것이다. 이것은 대부분의 용도에 맞을 것이다.
+ </para>
+
+ <para>
+ 컴포넌트의 프로퍼티들은 임의의 Hibernate 타입일 수 있다(콜렉션들, many-to-one 연관들, 다른 컴포넌트들, 기타).
+ 내포된 컴포넌트들은 신종의 사용례로 간주되지 <emphasis>않을</emphasis> 것이다. Hibernate는 매우 잘 정제된 객체 모형을
+ 지원하도록 고안되어있다.
+ </para>
+
+ <para>
+ <literal><component></literal> 요소는 컴포넌트 클래스의 프로퍼티를 포함되는 엔티티에 대한 역 참조로서 매핑시키는
+ <literal><parent></literal> 서브요소를 허용한다.
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Person" table="person">
+ <id name="Key" column="pid" type="string">
+ <generator class="uuid"/>
+ </id>
+ <property name="birthday" type="date"/>
+ <component name="Name" class="eg.Name" unique="true">
+ <parent name="namedPerson"/> <!-- reference back to the Person -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </component>
+</class>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="components-incollections" revision="1">
+ <title>종속 객체들을 가진 콜렉션들</title>
+
+ <para>
+ 컴포넌트들을 가진 콜렉션들이 지원된다(예를 들면 <literal>Name</literal> 타입을 가진 배열).
+ <literal><element></literal> 태그를 <literal><composite-element></literal> 태그로
+ 대체시켜서 당신의 컴포넌트 콜렉션을 선언하라.
+ </para>
+
+ <programlisting><![CDATA[<set name="someNames" table="some_names" lazy="true">
+ <key column="id"/>
+ <composite-element class="eg.Name"> <!-- class attribute required -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </composite-element>
+</set>]]></programlisting>
+
+ <para>
+ 노트: 만일 당신이 composite 요소를 가진 하나의 <literal>Set</literal>를 정의할 경우, <literal>equals()</literal>와
+ <literal>hashCode()</literal>를 정확하게 구현하는 것이 매우 중요하다.
+ </para>
+
+ <para>
+ Composite 요소들은 컴포넌트들을 포함하지만 콜렉션들을 포함하지 않는다. 만일 당신의 composite 요소 자체가 컴포넌트들을 포함할
+ 경우, <literal><nested-composite-element></literal> 태그를 사용하라. 이것은 꽤 신종의 경우-그것들 자체가
+ 컴포넌트들을 갖고 있는 컴포넌트들의 콜렉션-이다. 이 단계에서 당신은 one-to-many 연관이 더 적절한지를 당신 스스로에게 질문하게
+ 될 것이다. 하나의 엔티티로서 composite 요소를 다시 모델링하려고 시도하라 - 그러나 자바 모형들이 동일할지라도,
+ 관계형 모형과 영속화 의미들은 여전히 약간 다르다.
+ </para>
+
+ <para>
+ 당신이 하나의 <literal><set></literal>을 사용 중이라면, 하나의 composite 요소 매핑은 null 가능한 프로퍼티들을
+ 지원하지 않음을 노트하길 바란다. Hibernate는 객체들을 삭제할 때 하나의 레코드를 식별하는데 각각의 컬럼들 값을 사용해야 하며
+ (composite 요소 테이블 내에 별도의 프라이머리 키 컬럼이 존재하지 않는다), 그것은 null 값들에 대해서는 불가능하다. 당신은
+ 하나의 composite-요소 내에 not-null 프로퍼티들 만을 사용해야 하거나 하나의 <literal><list></literal>,
+ <literal><map></literal>, <literal><bag></literal> 또는 <literal><idbag></literal>을
+ 선택해야 한다.
+ </para>
+
+ <para>
+ composite 요소에 대한 하나의 특별한 경우는 내포된 <literal><many-to-one></literal> 요소를 가진 composite 요소이다.
+ 이같은 매핑은 many-to-many 연관 테이블의 특별한 컬럼들을 composite 요소 클래스로 매핑시키는 것을 당신에게 허용해준다. 다음은
+ <literal>Order</literal>로부터 <literal>Item</literal>으로의 many-to-many 연관이다. 여기서
+ <literal>purchaseDate</literal>, <literal>price</literal>, 그리고 <literal>quantity</literal>는 연관의
+ 프로퍼티들이다:
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Order" .... >
+ ....
+ <set name="purchasedItems" table="purchase_items" lazy="true">
+ <key column="order_id">
+ <composite-element class="eg.Purchase">
+ <property name="purchaseDate"/>
+ <property name="price"/>
+ <property name="quantity"/>
+ <many-to-one name="item" class="eg.Item"/> <!-- class attribute is optional -->
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ 물론, 양방향 연관 네비게이션의 경우, 다른 측 상에 있는 purchase에 대한 참조가 존재할 수 없다. 컴포넌트들이 값(value) 타입들이고
+ 공유된 참조들을 허용하지 않음을 기억하라. 하나의 <literal>Purchase</literal>는<literal>Order</literal>를 가진 set
+ 내에 있을 수 있지만, 그것은 동시에 <literal>Item</literal>에 의해 참조될 수 없다.
+ </para>
+
+ <para>심지어 세겹의(또는 네 겹의, 기타) 연관들이 가능하다:</para>
+
+ <programlisting><![CDATA[<class name="eg.Order" .... >
+ ....
+ <set name="purchasedItems" table="purchase_items" lazy="true">
+ <key column="order_id">
+ <composite-element class="eg.OrderLine">
+ <many-to-one name="purchaseDetails class="eg.Purchase"/>
+ <many-to-one name="item" class="eg.Item"/>
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ composite 요소들은 다른 엔티티들에 대한 연관들과 동일한 구문을 사용하여 질의들 내에 나타날 수도 있다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="components-asmapindex">
+ <title>Map 인덱스들로서 컴포넌트들</title>
+
+ <para>
+ <literal><composite-map-key></literal> 요소는 당신에게 하나의 컴포넌트 클래스를 하나의 <literal>Map</literal>의
+ 키로서 매핑시키도록 한다. 당신은 컴포넌트 클래스 상에서 <literal>hashCode()</literal>와 <literal>equals()</literal>를
+ 정확하게 오버라이드 시키도록 하라.
+ </para>
+ </sect1>
+
+ <sect1 id="components-compositeid" revision="1">
+ <title>composite 식별자들로서 컴포넌트들</title>
+
+ <para>
+ 당신은 하나의 컴포넌트를 하나의 엔티티 클래스에 대한 하나의 식별자로서 사용할 수도 있다. 당신의 컴포넌트 클래스는 어떤 사양들을
+ 충족시켜야 한다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 그것은 <literal>java.io.Serializable</literal>을 구현해야 한다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 그것은 composite 키 등가(equality)에 대한 데이터베이스 개념과 일치되게, <literal>equals()</literal>와
+ <literal>hashCode()</literal>를 다시 구현해야 한다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <emphasis>노트: Hibernate3에서, 두 번째 사양은 Hibernate의 절대적으로 엄격한 사양이 아니다.
+ 그러나 아무튼 그것을 행하라.</emphasis>
+ </para>
+
+ <para>
+ 당신은 compsite 키들을 생성시키는데 <literal>IdentifierGenerator</literal>를 사용할 수 없다. 대신에 어플리케이션은
+ 그것 자신의 식별자들을 할당해야 한다.
+ </para>
+
+ <para>
+ 통상의 <literal><id></literal> 선언 위치에 (내포된 <literal><key-property></literal> 요소들을 가진)
+ <literal><composite-id></literal> 태그를 사용하라. 예를 들어, <literal>OrderLine</literal> 클래스는
+ <literal>Order</literal>의 (composite) 프라이머리 키에 의존하는 프라이머리 키를 갖는다.
+ </para>
+
+ <programlisting><![CDATA[<class name="OrderLine">
+
+ <composite-id name="id" class="OrderLineId">
+ <key-property name="lineId"/>
+ <key-property name="orderId"/>
+ <key-property name="customerId"/>
+ </composite-id>
+
+ <property name="name"/>
+
+ <many-to-one name="order" class="Order"
+ insert="false" update="false">
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </many-to-one>
+ ....
+
+</class>]]></programlisting>
+
+ <para>
+ 이제 <literal>OrderLine</literal> 테이블을 참조하는 임의의 foreign 키들이 또한 compsite이다. 당신은 다른 클래스들에 대한
+ 당신의 매핑들 속에 이것을 선언해야 한다. <literal>OrderLine</literal>에 대한 하나의 연관은 다음과 같이 매핑될 것이다:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="orderLine" class="OrderLine">
+<!-- the "class" attribute is optional, as usual -->
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+</many-to-one>]]></programlisting>
+
+ <para>
+ (<literal><column></literal> 태그가 모든 곳에서 <literal>column</literal> 속성에 대한 대안임을 노트하라.)
+ </para>
+
+ <para>
+ <literal>OrderLine</literal>에 대한 <literal>many-to-many</literal> 연관은 또한 composite foreign 키를 사용한다:
+ </para>
+
+ <programlisting><![CDATA[<set name="undeliveredOrderLines">
+ <key column name="warehouseId"/>
+ <many-to-many class="OrderLine">
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </many-to-many>
+</set>]]></programlisting>
+
+ <para>
+ <literal>Order</literal>에서 <literal>OrderLine</literal>들의 콜렉션이 사용될 것이다:
+ </para>
+
+ <programlisting><![CDATA[<set name="orderLines" inverse="true">
+ <key>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </key>
+ <one-to-many class="OrderLine"/>
+</set>]]></programlisting>
+
+ <para>
+ (통상적으로 <literal><one-to-many></literal> 요소는 컬럼들을 선언하지 않는다.)
+ </para>
+
+ <para>
+ 만일 <literal>OrderLine</literal> 자체가 하나의 콜렉션을 소유할 경우, 그것은 또한 하나의 composite foreign 키를 갖는다.
+ </para>
+
+ <programlisting><![CDATA[<class name="OrderLine">
+ ....
+ ....
+ <list name="deliveryAttempts">
+ <key> <!-- a collection inherits the composite key type -->
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </key>
+ <list-index column="attemptId" base="1"/>
+ <composite-element class="DeliveryAttempt">
+ ...
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="components-dynamic" revision="1">
+ <title>동적인 컴포넌트들</title>
+
+ <para>
+ 당신은 <literal>Map</literal> 타입의 프로퍼티를 매핑시킬 수도 있다:
+ </para>
+
+ <programlisting><![CDATA[<dynamic-component name="userAttributes">
+ <property name="foo" column="FOO" type="string"/>
+ <property name="bar" column="BAR" type="integer"/>
+ <many-to-one name="baz" class="Baz" column="BAZ_ID"/>
+</dynamic-component>]]></programlisting>
+
+ <para>
+ <literal><dynamic-component></literal> 매핑의 의미는 <literal><component></literal>와 동일하다.
+ 이런 종류의 매핑의 장점은 배치 시에 단지 매핑 문서를 편집함으로써 그 bean의 실제 프로퍼티들을 결정하는 가용성이다. 매핑 문서에
+ 대한 런타임 처리는 또한 DOM 파서를 사용하여 가능하다. 더 좋게는 당신이 <literal>Configuration</literal> 객체를 통해
+ Hibernate의 구성-시 메타모형에 접근할 수 있다(그리고 변경시킬 수 있다)
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/configuration.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/configuration.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/configuration.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/configuration.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,1648 @@
+<chapter id="session-configuration" revision="1">
+
+ <title>구성</title>
+
+ <para>
+ Hibernate가 많은 다른 환경들에서 동작하도록 설계되어 있으므로, 많은 개수의 구성 파라미터들이 존재한다. 다행히 대부분은 유의미한
+ 디폴트 값들이고 Hibernate는 다양한 옵션들을 보여주는 <literal>etc/</literal> 내의 예제 파일 <literal>hibernate.properties</literal>로
+ 배포된다. 당신은 단지 당신의 classpath 경로 속에 그 파일을 집어넣고 그것을 커스트마이징하기만 해야 한다.
+ </para>
+
+ <sect1 id="configuration-programmatic" revision="1">
+ <title>프로그램 상의 구성</title>
+
+ <para>
+ <literal>org.hibernate.cfg.Configuration</literal>의 인스턴스는 어플리케이션의 Java 타입들을 SQL 데이터베이스
+ 타입으로의 전체 매핑 집합을 표현한다. <literal>Configuration</literal>은 (불변의) <literal>SessionFactory</literal>를
+ 빌드하는데 사용된다. 매핑들은 여러 XML 매핑 파일들로부터 컴파일 된다.
+ </para>
+
+ <para>
+ 당신은 <literal>Configuration</literal> 인스턴스를 초기화 시키고 XML 매핑 문서들을 지정함으로써 <literal>Configuration</literal>
+ 인스턴스를 얻을 수 있다. 만일 매핑 파일들이 classpath 내에 있다면, <literal>addResource()</literal>를 사용하라:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addResource("Item.hbm.xml")
+ .addResource("Bid.hbm.xml");]]></programlisting>
+
+ <para>
+ (때때로 더 나은) 다른 방법은 매핑된 클래스를 지정하는 것이고, Hibernate로 하여금 당신을 위해 매핑 문서를 찾도록 하라:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addClass(org.hibernate.auction.Item.class)
+ .addClass(org.hibernate.auction.Bid.class);]]></programlisting>
+
+ <para>
+ 그때 Hibernate는 classpath 내에서 <literal>/org/hibernate/auction/Item.hbm.xml</literal>과
+ <literal>/org/hibernate/auction/Bid.hbm.xml</literal>로 명명된 매핑 파일들을 룩업할 것이다. 이 접근법은
+ 임의의 하드코딩된 파일 이름들을 제거한다.
+ </para>
+
+ <para>
+ <literal>Configuration</literal>은 또한 구성 프로퍼티들을 지정하는 것을 허용해준다:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addClass(org.hibernate.auction.Item.class)
+ .addClass(org.hibernate.auction.Bid.class)
+ .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
+ .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
+ .setProperty("hibernate.order_updates", "true");]]></programlisting>
+
+ <para>
+ 이것은 컨피그레이션 프로퍼티들을 Hibernate에 전달하는 유일한 방법이 아니다. 여러 가지 옵션들은 다음을 포함한다:
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>java.util.Properties</literal>의 인스턴스를 <literal>Configuration.setProperties()</literal>에
+ 전달한다 .
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ classpath의 루트 디렉토리에 <literal>hibernate.properties</literal>를 위치지운다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>java -Dproperty=value</literal>를 사용하여 <literal>System</literal> 프로퍼티들을 설정한다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>hibernate.cfg.xml</literal>에 <literal><property></literal> 요소들을 포함한다
+ (나중에 논의됨).
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ 당신이 빠르게 시작하고 원할 경우 <literal>hibernate.properties</literal>는 가장 쉬운 접근법이다.
+ </para>
+
+ <para>
+ <literal>Configuration</literal>은 시작 시(startup-time) 객체로서 일단 <literal>SessionFactory</literal>가
+ 생성되면 폐기되게끔 예정되어 있다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-sessionfactory">
+ <title>SessionFactory 얻기</title>
+
+ <para>
+ 모든 매핑들이 <literal>Configuration</literal>에 의해 파싱되었을 때, 어플리케이션은 <literal>Session</literal>
+ 인스턴스들에 대한 팩토리를 얻어야 한다. 이 팩토리는 모든 어플리케이션 쓰레드들에 의해 공유되도록 고안되었다:
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sessions = cfg.buildSessionFactory();]]></programlisting>
+
+ <para>
+ 하지만 Hibernate는 당신의 어플리케이션이 하나 이상의 <literal>SessionFactory</literal>를 초기화 시키는 것을 허용한다.
+ 이것은 당신이 하나 이상의 데이터베이스를 사용하는 경우에 유용하다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-hibernatejdbc" revision="1">
+ <title>JDBC 커넥션들</title>
+
+ <para>
+ 대개 당신은 <literal>SessionFactory</literal>로 하여금 당신을 위한 JDBC 커넥션들을 생성시키고 풀링시키는 것을 원한다.
+ 만일 당신이 이 접근법을 취할 경우, 한 개의 <literal>Session</literal>을 여는 것은 다음과 같이 간단하다:
+ </para>
+
+ <programlisting><![CDATA[Session session = sessions.openSession(); // open a new Session]]></programlisting>
+
+ <para>
+ 당신이 데이터베이스에 대한 접근을 요청하는 어떤 것을 행하자 마자, 한 개의 JDBC 커넥션이 그 풀로부터 얻어질 것이다.
+ </para>
+
+ <para>
+ 이것이 동작하도록 하기 위해서, 우리는 몇몇 JDBC 커넥션 프로퍼티들을 Hibernate에 전달할 필요가 있다. 모든 Hibernate 프로퍼티
+ 이름들과 의미론들은 <literal>org.hibernate.cfg.Environment</literal> 클래스 상에 정의되어 있다. 우리는 이제 JDBC
+ 커넥션 구성을 위한 가장 중요한 설정들을 설명할 것이다.
+ </para>
+
+ <para>
+ 만일 당신이 다음 프로퍼티들을 설정할 경우 Hibernate는 <literal>java.sql.DriverManager</literal>를 사용하여 커넥션들을
+ 얻을 것이다(그리고 풀링시킬 것이다):
+ </para>
+
+ <table frame="topbot">
+ <title>Hibernate JDBC 프로퍼티들</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>프로퍼티 이름</entry>
+ <entry>용도</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.connection.driver_class</literal>
+ </entry>
+ <entry>
+ <emphasis>jdbc 드라이버 클래스</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.url</literal>
+ </entry>
+ <entry>
+ <emphasis>jdbc URL</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.username</literal>
+ </entry>
+ <entry>
+ <emphasis>데이터베이스 사용자</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.password</literal>
+ </entry>
+ <entry>
+ <emphasis>데이터베이스 사용자 패스워드</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.pool_size</literal>
+ </entry>
+ <entry>
+ <emphasis>풀링된 커넥션들의 최대 개수</emphasis>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 하지만 Hibernate 자신의 커넥션 풀링 알고리즘은 아주 기본적이다. 그것은 당신이 시작하는 것을 도와주려고 의도되었고 <emphasis>제품
+ 시스템 용도 또는 퍼포먼스 테스트용으로는 고안되지 않았다</emphasis>. 최상의 퍼포먼스와 안정성을 위해서는 제 3의 풀을 사용하라. 즉
+ <literal>hibernate.connection.pool_size</literal> 프로퍼티를 커넥션 풀 지정 설정들로 대체하라. 이것은 Hibernate의 내부
+ pool을 오프시킬 것이다. 예를 들어 당신은 C3P0를 사용할 수도 있다.
+ </para>
+
+ <para>
+ C3P0는 <literal>lib</literal> 디펙토리 속에 Hibernate에 배포된 오픈 소스 JDBC 커넥션 풀이다. 당신이 <literal>hibernate.c3p0.*</literal>
+ 프로퍼티들을 설정할 경우 Hibernate는 커넥션 풀링을 위해 그것의 <literal>C3P0ConnectionProvider</literal>를 사용할 것이다.
+ 만일 당신이 Proxool을 사용하고자 원할 경우 패키지화 된 <literal>hibernate.properties</literal>를 참조하고 추가 정보는
+ Hibernate 웹 사이트를 참조하라.
+ </para>
+
+ <para>
+ 다음은 C3P0에 대한 사용하는 예제 <literal>hibernate.properties</literal> 파일이다:
+ </para>
+
+ <programlisting id="c3p0-configuration" revision="1"><![CDATA[hibernate.connection.driver_class = org.postgresql.Driver
+hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
+hibernate.connection.username = myuser
+hibernate.connection.password = secret
+hibernate.c3p0.min_size=5
+hibernate.c3p0.max_size=20
+hibernate.c3p0.timeout=1800
+hibernate.c3p0.max_statements=50
+hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
+
+ <para>
+ 어플리케이션 서버 내부의 용도로, 당신은 JNDI로 등록된 어플리케이션 서버 <literal>Datasource</literal>로부터 커넥션을 얻기
+ 위해 항상 Hibernate를 구성해야 한다. 당신은 적어도 다음 프로퍼티들 중 하나를 최소한으로 설정할 필요가 있을 것이다.
+ </para>
+
+ <table frame="topbot">
+ <title>Hibernate Datasource Properties</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>프로퍼티 이름</entry>
+ <entry>용도</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.connection.datasource</literal>
+ </entry>
+ <entry>
+ <emphasis>데이터소스 JNDI 이름</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.url</literal>
+ </entry>
+ <entry>
+ <emphasis>JNDI 프로바이더의 URL</emphasis> (옵션)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.class</literal>
+ </entry>
+ <entry>
+ <emphasis>JNDI <literal>InitialContextFactory</literal>의 클래스 </emphasis> (옵션)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.username</literal>
+ </entry>
+ <entry>
+ <emphasis>데이터베이스 사용자</emphasis> (옵션)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.password</literal>
+ </entry>
+ <entry>
+ <emphasis>데이터베이스 사용자 패스워드</emphasis> (옵션)
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 다음은 어플리케이션 서버 제공 JNDI 데이터소스용 예제 <literal>hibernate.properties</literal> 파일이다:
+ </para>
+
+ <programlisting><![CDATA[hibernate.connection.datasource = java:/comp/env/jdbc/test
+hibernate.transaction.factory_class = \
+ org.hibernate.transaction.JTATransactionFactory
+hibernate.transaction.manager_lookup_class = \
+ org.hibernate.transaction.JBossTransactionManagerLookup
+hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
+
+ <para>
+ JNDI datasource로부터 얻어진 JDBC 커넥션들은 어플리케이션 서버의 컨테이너에 의해 관리되는 트랜잭션들에 자동적으로 참여할 것이다.
+ </para>
+
+ <para>
+ 임의의 커넥션 프로퍼티들은 프로퍼티 이름 앞에 "<literal>hibernate.connnection</literal>"을 첨가하여 부여될 수 있다. 예를 들어
+ 당신은 <literal>hibernate.connection.charSet</literal>을 사용하여 <literal>charSet</literal>을 지정할 수도 있다.
+ </para>
+
+ <para>
+ 당신은 <literal>org.hibernate.connection.ConnectionProvider</literal> 인터페이스를 구현함으로써 JDBC 커넥션들을
+ 얻는 당신 자신의 플러그인 방도를 정의할수도 있다. 당신은 <literal>hibernate.connection.provider_class</literal>를
+ 설정하여 맞춤형 구현을 선택할 수도 있다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-optional" revision="1">
+ <title>선택적인 구성 프로퍼티들</title>
+
+ <para>
+ 실행 시에 Hibernate의 행위를 제어하는 많은 다른 프로퍼티들이 존재한다. 모든 것이 옵션이지만 합당한 디폴트 값들을 갖는다.
+ </para>
+
+ <para>
+ <emphasis>경고: 이들 프로퍼티들 중 몇몇은 "system-level" 전용이다.</emphasis> 시스템 레벨 프로퍼티들은 오직
+ <literal>java -Dproperty=value</literal> 또는 <literal>hibernate.properties</literal>를 통해서만 설정될 수
+ 있다. 그것들은 위에 설명된 다른 기법들에 의해 설정될 수 <emphasis>없다</emphasis>.
+ </para>
+
+ <table frame="topbot" id="configuration-optional-properties" revision="8">
+ <title>Hibernate 구성 프로퍼티들</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>프로퍼티 이름</entry>
+ <entry>용도</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.dialect</literal>
+ </entry>
+ <entry>
+ 특정 관계형 데이터베이스에 최적화 된 SQL을 생성시키는 것을 Hibernate에게 허용해주는
+ Hibernate <literal>Dialect</literal>의 클래스명.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>full.classname.of.Dialect</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.show_sql</literal>
+ </entry>
+ <entry>
+ 모든 SQL 문장들을 콘솔에 기록한다. 이것은 로그 카테고리 <literal>org.hibernate.SQL</literal>를
+ <literal>debug</literal>로 설정하는 것에 대한 하나의 다른 방법이다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.format_sql</literal>
+ </entry>
+ <entry>
+ 로그와 콘솔 속에 SQL을 깔끔하게 프린트한다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_schema</literal>
+ </entry>
+ <entry>
+ 생성된 SQL 내에 주어진 schema/tablespace로서 수식이 없는 테이블이름들을 수식한다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>SCHEMA_NAME</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_catalog</literal>
+ </entry>
+ <entry>
+ 주어진 SQL 내에 주어진 카타록으로서 수식이 없는 테이블이름들을 수식한다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>CATALOG_NAME</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.session_factory_name</literal>
+ </entry>
+ <entry>
+ <literal>SessionFactory</literal>는 그것이 생성된 후에 JNDI 내에서 이 이름에 자동적으로 바인드
+ 될 것이다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>jndi/composite/name</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.max_fetch_depth</literal>
+ </entry>
+ <entry>
+ single-ended 연관관계들(one-to-one, many-to-one)의 경우에 outer join fetch 트리의 최대 "깊이"를
+ 설정한다. <literal>0</literal>은 디폴트 outer join fetching을 사용불가능하게 만든다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>0</literal>과
+ <literal>3</literal> 사이의 값들이권장된다
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_batch_fetch_size</literal>
+ </entry>
+ <entry>
+ 연관들의 Hibernate 배치 페칭에 대한 디폴트 크기를 설정한다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ 권장되는 값들은 <literal>4</literal>, <literal>8</literal>,
+ <literal>16</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_entity_mode</literal>
+ </entry>
+ <entry>
+ 이 <literal>SessionFactory</literal>로부터 열려진 모든 세션들에 대해 엔티티 표현을 디폴트 모드로
+ 설정한다
+ <para>
+ <literal>dynamic-map</literal>, <literal>dom4j</literal>,
+ <literal>pojo</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.order_updates</literal>
+ </entry>
+ <entry>
+ 업데이트 중인 항목들의 프라이머리 키 값에 의해 SQL 업데이트들이 순서(ordering)지워지도록 Hibernate에게
+ 강제시킨다. 이것은 고도의 동시성 시스템들에서 더 적은 트랜잭션 데드락(deadlock)들로 귀결될 것이다
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.generate_statistics</literal>
+ </entry>
+ <entry>
+ 이용 가능하게 되면, Hibernate는 퍼포먼스 튜닝에 유용한 통계들을 수집할 것이다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.use_identifer_rollback</literal>
+ </entry>
+ <entry>
+ 이용 가능하게 되면, 객체가 삭제될 때 생성된 식별자 프로퍼티들은 디폴트 값들로 재설정될 것이다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.use_sql_comments</literal>
+ </entry>
+ <entry>
+ 이용 가능하게 되면, Hibernate는 보다 쉬운 디버깅을 위해 SQL 내에 주석들을 생성시킬 것이다.
+ 디폴트는 <literal>false</literal>.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-jdbc-properties" revision="8">
+ <title>Hibernate JDBC 및 커넥션 프로퍼티들</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>프로퍼티 이름</entry>
+ <entry>용도</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.fetch_size</literal>
+ </entry>
+ <entry>
+ 0 아닌 값은 JDBC fetch 사이즈를 결정한다(<literal>Statement.setFetchSize()</literal>을 호출한다 ).
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.batch_size</literal>
+ </entry>
+ <entry>
+ 0 아닌 값은 Hibernate에 의한 JDBC2 배치 업데이트의 사용을 이용 가능하게 한다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>5</literal>와 <literal>30</literal> 사이의 값들이 권장된다
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.batch_versioned_data</literal>
+ </entry>
+ <entry>
+ 당신의 JDBC 드라이버가 <literal>executeBatch()</literal>로부터 정확한 행 카운트들을 반환할 경우에
+ 이 프로퍼티를 <literal>true</literal>로 설정하라(대개 이 옵션을 사용 가능하게 하는 것이 안전하다).
+ 그러면 Hibernate는 자동적으로 버전화 된 데이터에 대해 배치화된(batched) DML을 사용할 것이다.
+ 디폴트는 <literal>false</literal>.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.factory_class</literal>
+ </entry>
+ <entry>
+ 맞춤형 <literal>Batcher</literal>를 선택한다. 대부분의 어플리케이션들은 이 구성 프로퍼티를 필요로 하지
+ 않을 것이다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>classname.of.BatcherFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.use_scrollable_resultset</literal>
+ </entry>
+ <entry>
+ Hibernate에 의한 JDBC2 스크롤 가능한 결과셋들의 사용을 가능하게 해준다. 이 프로퍼티는 사용자가 제공한
+ JDBC커넥션들을 사용할 때에만 필수적이고, 그 밖의 경우 Hibernate는 커넥션 메타데이터를 사용한다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.use_streams_for_binary</literal>
+ </entry>
+ <entry>
+ <literal>binary</literal> 또는 <literal>serializable</literal> 타입들을 JDBC로 기록하고
+ /JDBC로부터 <literal>binary</literal> 또는 <literal>serializable</literal> 타입들을 읽어들일 때
+ 스트림들을 사용한다(시스템-레벨 프로퍼티).
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.use_get_generated_keys</literal>
+ </entry>
+ <entry>
+ insert 후에 고유하게 생성된 키들을 검색하는데 JDBC3 <literal>PreparedStatement.getGeneratedKeys()</literal>의
+ 사용을 이용 가능하도록 만든다. JDBC3+ 드라이버와 JRE1.4+를 필요로 하고, 당신의 드라이버가 Hibernate
+ 식별자 생성자들에 문제가 있을 경우에 false로 설정하라. 디폴트로 커넥션 메타 데이터를 사용하여 드라이버
+ 가용성들을 결정하려고 시도하라.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.provider_class</literal>
+ </entry>
+ <entry>
+ Hibernate에 JDBC 커넥션들을 제공하는 맞춤형 <literal>ConnectionProvider</literal>의 클래스명.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>classname.of.ConnectionProvider</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.isolation</literal>
+ </entry>
+ <entry>
+ JDBC transaction isolation 레벨을 설정한다. 의미있는 값들로 <literal>java.sql.Connection</literal>을
+ 체크하지만 대부분의 데이터베이스들이 모든 격리(isolate) 레벨들을 지원하지 않음을 노트하라.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>1, 2, 4, 8</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.autocommit</literal>
+ </entry>
+ <entry>
+ JDBC 풀링된 커넥션들에 대해 자동커밋을 이용 가능하도록 한다(권장되지 않음).
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.release_mode</literal>
+ </entry>
+ <entry>
+ Hibernate가 JDBC 커넥션들을 해제하게 될 시점을 지정한다. 디폴트로 한 개의 JDBC 커넥션은 그 세션이 명시적으로
+ 닫히거나 연결해제되기 전까지 보관된다. 어플리케이션 트랜잭션 서버 JTA 데이터소스의 경우, 당신은 모든 JDBC
+ 호출 후에 커넥션들을 과감하게 해제시키기 위해 <literal>after_statement</literal>를 사용해야 한다. 비-JTA
+ 연결의 경우, <literal>after_transaction</literal>을 사용하여 각각의 트랜잭션의 끝에서 커넥션들을
+ 해제시키는 것이 종종 의미가 있다. <literal>auto</literal>는 JTA 및 CMT 트랜잭션 방도들의 경우에
+ <literal>after_statement</literal>를 선택하고 JDBC 트랜잭션 방도에 대해 <literal>after_transaction</literal>를
+ 선택할 것이다.
+ <para>
+ <emphasis role="strong">eg.</emphasis>
+ <literal>auto</literal> (디폴트) | <literal>on_close</literal> |
+ <literal>after_transaction</literal> | <literal>after_statement</literal>
+ </para>
+ <para>
+ 이 설정이 <literal>SessionFactory.openSession</literal>로부터 반환된 <literal>Session</literal>들에만
+ 영향을 준다는 점을 노트하라. <literal>SessionFactory.getCurrentSession</literal>을 통해 얻어진
+ <literal>Session</literal>들의 경우, 사용하기 위해 구성된 <literal>CurrentSessionContext</literal> 구현이
+ 그들 <literal>Session</literal>들에 대한 연결 해제를 제어한다. <xref linkend="architecture-current-session"/>를
+ 보라.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.<emphasis><propertyName></emphasis></literal>
+ </entry>
+ <entry>
+ JDBC 프로퍼티 <literal>propertyName</literal>을 <literal>DriverManager.getConnection()</literal>에
+ 전달한다.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.<emphasis><propertyName></emphasis></literal>
+ </entry>
+ <entry>
+ <literal>propertyName</literal> 프로퍼티를 JNDI <literal>InitialContextFactory</literal>에 전달한다.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-cache-properties" revision="7">
+ <title>Hibernate Cache 프로퍼티들</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>프로퍼티 이름</entry>
+ <entry>용도</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.cache.provider_class</literal>
+ </entry>
+ <entry>
+ 맞춤형 <literal>CacheProvider</literal>의 클래스명.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>classname.of.CacheProvider</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_minimal_puts</literal>
+ </entry>
+ <entry>
+ 읽기가 매우 빈번한 경우에, 쓰기를 최소화 시키기 위해 second-level 캐시 연산을 최적화 시킨다. 이 설정은 Hibernate3에서 클러스터링 된
+ 캐시들에 가장 유용하고, Hibernate3에서는 클러스터링된 캐시 구현들에 대해 디폴트로 이용 가능하다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_query_cache</literal>
+ </entry>
+ <entry>
+ 질의 캐시를 가능하게 만든다. 개별 질의들은 여전히 캐시 가능한 것으로 설정되어야 한다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_second_level_cache</literal>
+ </entry>
+ <entry>
+ second-level 캐시를 완전히 사용 불가능하게 하는데 사용될 수 있고, 그것은 <literal><cache></literal> 매핑을
+ 지정하는 클래스들에 대해 디폴트로 이용 가능이다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.query_cache_factory</literal>
+ </entry>
+ <entry>
+ 맞춤형 <literal>QueryCache</literal> 인터페이스의 클래스명. 디폴트는 미리 빌드된
+ <literal>StandardQueryCache</literal>.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>classname.of.QueryCache</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.region_prefix</literal>
+ </entry>
+ <entry>
+ second-level 캐시 영역 이름들에 사용할 접두어.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>prefix</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_structured_entries</literal>
+ </entry>
+ <entry>
+ 인간에게 보다 더 친숙한 형식으로 second-level 캐시 속에 데이터를 저장하도록 Hibernate에게 강제시킨다..
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-transaction-properties" revision="9">
+ <title>Hibernate 트랜잭션 프로퍼티들</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>프로퍼티 이름</entry>
+ <entry>용도</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.factory_class</literal>
+ </entry>
+ <entry>
+ Hibernate <literal>Transaction</literal> API 에 사용할 <literal>TransactionFactory</literal>의
+ 클래스 이름.(디폴트는 <literal>JDBCTransactionFactory</literal>).
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>classname.of.TransactionFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>jta.UserTransaction</literal>
+ </entry>
+ <entry>
+ 어플리케이션 서버로부터 JTA <literal>UserTransaction</literal>을 얻기 위해 <literal>JTATransactionFactory</literal>에
+ 의해 사용되는 JNDI 이름.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>jndi/composite/name</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.manager_lookup_class</literal>
+ </entry>
+ <entry>
+ <literal>TransactionManagerLookup</literal>의 클래스명- JVM 레벨의 캐싱이 이용 가능할 때 또는 JTA 환경에서
+ hilo generator를 사용할 때 필요하다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>classname.of.TransactionManagerLookup</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.flush_before_completion</literal>
+ </entry>
+ <entry>
+ 만일 사용가능하도록 되면, 세션은 트랜잭션의 before completion 단계 동안에 자동적으로 flush 될 것이다.
+ 빌드되어 있는 자동적인 세션 컨텍스트 관리가 선호되는데,
+ <xref linkend="architecture-current-session"/>를 보라.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.auto_close_session</literal>
+ </entry>
+ <entry>
+ 만일 사용가능토록 하면, after completion 단계 동안에 세션이 자동적으로 닫혀질 것이다.
+ (CMT에 대해 Hibernate를 사용할 때 매우 유용하다.)
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-misc-properties" revision="10">
+ <title>여러가지 프로퍼티들</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>프로퍼티 이름</entry>
+ <entry>용도</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.current_session_context_class</literal>
+ </entry>
+ <entry>
+ "현재" <literal>Session</literal>의 영역화를 위한 하나의 (맞춤) 방도를
+ 제공한다. 빌드되어 있는 방도들에 대한 추가 정보는
+ <xref linkend="architecture-current-session"/>를 보라.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>jta</literal> | <literal>thread</literal> |
+ <literal>managed</literal> | <literal>custom.Class</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.query.factory_class</literal>
+ </entry>
+ <entry>
+ Chooses the HQL 파서 구현을 선택한다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>org.hibernate.hql.ast.ASTQueryTranslatorFactory</literal> or
+ <literal>org.hibernate.hql.classic.ClassicQueryTranslatorFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.query.substitutions</literal>
+ </entry>
+ <entry>
+ Hibernate 질의들 내의 토큰들로부터 SQL 토큰들로의 매핑
+ (예를 들어 토큰들은 함수 이름 또는 리터럴 이름일 수 있다).
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.hbm2ddl.auto</literal>
+ </entry>
+ <entry>
+ <literal>SessionFactory</literal>가 생성될 때, 자동적으로 유효성을 검사하거나
+ schema DDL을 데이터베이스로 내보내기 한다. <literal>create-drop</literal>의 경우,
+ <literal>SessionFactory</literal>가 명시적으로 닫혀질 때 데이터베이스 스키마가
+ 드롭될 것이다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>validate</literal> | <literal>update</literal> |
+ <literal>create</literal> | <literal>create-drop</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cglib.use_reflection_optimizer</literal>
+ </entry>
+ <entry>
+ 런타임 reflection 대신에 CGLIB의 사용을 가능하도록 만든다(시스템 레벨 프로퍼티).
+ Reflection은 문제가 발생할 시에 때때로 유용할 수 있고,
+ 당신이 optimizer를 사용하지 않을 경우조차도 Hibernate는 항상 필요로 함을 유의하라.
+ 당신은 <literal>hibernate.cfg.xml</literal>
+ 속에 이 프로퍼티를 설정할수 없다.
+ <para>
+ <emphasis role="strong">예.</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="configuration-optional-dialects" revision="1">
+ <title>SQL Dialects</title>
+
+ <para>
+ 당신은 항상 당신의 데이터베이스를 위해 <literal>hibernate.dialect</literal> 프로퍼티를 정확한 <literal>org.hibernate.dialect.Dialect</literal>
+ 서브클래스로 설정해야 한다. 만일 당신이 dialect를 지정할 경우, 당신이 프로퍼티들을 수작업으로 지정하는 노력을 절약하도록 Hibernate는 위에 열거된 다른 프로퍼티들
+ 중 몇몇에 대해 의미있는 디폴트들을 사용할 것이다.
+ </para>
+
+ <table frame="topbot" id="sql-dialects" revision="2">
+ <title>Hibernate SQL Dialects (<literal>hibernate.dialect</literal>)</title>
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>RDBMS</entry>
+ <entry>Dialect</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>DB2</entry> <entry><literal>org.hibernate.dialect.DB2Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>DB2 AS/400</entry> <entry><literal>org.hibernate.dialect.DB2400Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>DB2 OS390</entry> <entry><literal>org.hibernate.dialect.DB2390Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>PostgreSQL</entry> <entry><literal>org.hibernate.dialect.PostgreSQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL</entry> <entry><literal>org.hibernate.dialect.MySQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL with InnoDB</entry> <entry><literal>org.hibernate.dialect.MySQLInnoDBDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL with MyISAM</entry> <entry><literal>org.hibernate.dialect.MySQLMyISAMDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Oracle (any version)</entry> <entry><literal>org.hibernate.dialect.OracleDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Oracle 9i/10g</entry> <entry><literal>org.hibernate.dialect.Oracle9Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>Sybase</entry> <entry><literal>org.hibernate.dialect.SybaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Sybase Anywhere</entry> <entry><literal>org.hibernate.dialect.SybaseAnywhereDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Microsoft SQL Server</entry> <entry><literal>org.hibernate.dialect.SQLServerDialect</literal></entry>
+ </row>
+ <row>
+ <entry>SAP DB</entry> <entry><literal>org.hibernate.dialect.SAPDBDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Informix</entry> <entry><literal>org.hibernate.dialect.InformixDialect</literal></entry>
+ </row>
+ <row>
+ <entry>HypersonicSQL</entry> <entry><literal>org.hibernate.dialect.HSQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Ingres</entry> <entry><literal>org.hibernate.dialect.IngresDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Progress</entry> <entry><literal>org.hibernate.dialect.ProgressDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Mckoi SQL</entry> <entry><literal>org.hibernate.dialect.MckoiDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Interbase</entry> <entry><literal>org.hibernate.dialect.InterbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Pointbase</entry> <entry><literal>org.hibernate.dialect.PointbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>FrontBase</entry> <entry><literal>org.hibernate.dialect.FrontbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Firebird</entry> <entry><literal>org.hibernate.dialect.FirebirdDialect</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-outerjoin" revision="4">
+ <title>Outer Join Fetching</title>
+
+ <para>
+ 만일 당신의 데이터베이스가 ANSI, Oracle, 또는 Sybase 스타일의 outer join들을 지원할 경우, <emphasis>outer join
+ fetching</emphasis>은 (데이터베이스 그 자체에 의해 보다 더 많은 작업이 수행되는 비용으로) 데이터베이스로의 그리고
+ 데이터베이스로부터의 라운드 트립들의 개수를 제한함으로써 종종 퍼포먼스를 증가시킬 것이다. Outer join fetching은
+ many-to-one, one-to-many, many-to-many,one-to-one 연관관계들이 에 의해 연결된 객체들의 전체 그래프가
+ 하나의 SQL <literal>SELECT</literal> 속에서 검색되게끔 허용해준다.
+ </para>
+
+ <para>
+ Outer join fetching은 hibernate.max_fetch_depth 프로퍼티를 <literal>0</literal>으로 설정함으로써
+ <emphasis>전역적으로</emphasis> 사용 불가능하게 할 수 있다. <literal>1</literal> 이상의 값을 설정하는
+ 것은 <literal>fetch="join"</literal>으로 매핑되었던 모든 one-to-one 및 many-to-one 연관관계들에 대해
+ outer join fetching을 사용 가능하도록 만든다.
+ </para>
+
+ <para>
+ 추가 정보는 <xref linkend="performance-fetching"/>를 보라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-binarystreams" revision="1">
+ <title>Binary Streams</title>
+
+ <para>
+ Oracle은 JDBC 드라이버 로/부터 전달되는 <literal>byte</literal> 배열들의 크기를 제한시킨다. 만일 당신이
+ <literal>binary</literal> 또는 <literal>serializable</literal> 타입의 대형 인스턴스를 사용하고자
+ 원할 경우에, 당신은 <literal>hibernate.jdbc.use_streams_for_binary</literal>를 사용 가능하게 해야
+ 할 것이다. <emphasis>이것은 오직 시스템 레벨 설정이다.</emphasis>
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-cacheprovider" revision="2">
+ <title>Second-level 캐시와 query 캐시</title>
+
+ <para>
+ <literal>hibernate.cache</literal> 접두어가 붙은 프로퍼티들은 Hibernate에 대해 프로세스 또는
+ 클러스터 범위의 두 번째 레벨 캐시 시스템을 사용하는 것을 허용해준다. 상세한 것은
+ <xref linkend="performance-cache"/>를 보라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-querysubstitution">
+ <title>Query Language 치환</title>
+
+ <para>
+ 당신은 <literal>hibernate.query.substitutions</literal>을 사용하여 새로운 Hibernate 질의 토큰들을
+ 정의할 수 있다. 예를 들어:
+ </para>
+
+ <programlisting>hibernate.query.substitutions true=1, false=0</programlisting>
+
+ <para>
+ 은<literal>true</literal>와 <literal>false</literal> 토큰들이 생성된 SQL 내에서
+ 정수 리터럴들로 번역되도록 강제할 것이다.
+ </para>
+
+ <programlisting>hibernate.query.substitutions toLowercase=LOWER</programlisting>
+
+ <para>
+ 은 SQL <literal>LOWER</literal> function 함수 이름을 변경하는 것을 당신에게 허용해 줄 것이다
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-statistics" revision="2">
+ <title>Hibernate 통계</title>
+
+ <para>
+ 만일 당신이 <literal>hibernate.generate_statistics</literal>를 사용 가능하도록 할 경우, Hibernate는
+ <literal>SessionFactory.getStatistics()</literal>를 통해 가동 중인 시스템을 튜닝할 때 유용한 많은 통계들을
+ 노출시킬 것이다. Hibernate는 심지어 JMX를 통해 이들 통계들을 노출시키도록 구성될 수 있다. 추가 정보는
+ <literal>org.hibernate.stats</literal>에 있는 인터페이스들에 관한 Javadoc를 읽어라.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="configuration-logging">
+ <title>로깅</title>
+
+ <para>
+ Hibernate는 Apache commons-logging를 사용하여 다양한 이벤트들을 로그시킨다.
+ </para>
+
+ <para>
+ commons-logging 서비스는 (만일 당신이 classpath 내에 <literal>log4j.jar</literal>를 포함할 경우) Apache Log4j로
+ 또는 (JDK1.4 이상의 버전에서 실행될 경우) JDK 1.4 로깅으로 직접 출력할 것이다. 당신은 <literal>http://jakarta.apache.org</literal>에서
+ Log4j를 다운로드 할 수 있다. Log4j를 사용하기 위해, 당신은 <literal>log4j.properties</literal> 파일을 당신의 classpath
+ 내에 위치지울 필요가 있을 것이고, 예제 properties 파일은 Hibernate의 <literal>src/</literal> 디렉토리 내에 배포되어 있다.
+ </para>
+
+ <para>
+ 우리는 당신이 Hibernate의 로그 메시지들에 익숙해지기를 강력히 권장한다. 읽기 불가능하지 않게끔 가능한 한 상세하게 Hibernate 로그를
+ 만들도록 많은 작업이 행해졌다. 그것은 본질적인 문제던지기 장치이다. 가장 흥미로운 로그 카테고리들이 다음에 있다:
+ </para>
+
+ <table frame="topbot" id="log-categories" revision="2">
+ <title>Hibernate 로그 카테고리들</title>
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>카테고리</entry>
+ <entry>기능</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>org.hibernate.SQL</literal></entry>
+ <entry>SQL DML 문장들이 실행될 때 그것들 모두를 로그 시킨다</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.type</literal></entry>
+ <entry>모든 JDBC 파라미터들을 로그시킨다</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.tool.hbm2ddl</literal></entry>
+ <entry>SQL DDL 문장들이 실행될 때 그것들 모두를 로그 시킨다</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.pretty</literal></entry>
+ <entry>
+ flush 시점에서 세션과 연관된 모든 엔티티들(최대 20개의 엔티티들)의 상태를 로그 시킨다
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.cache</literal></entry>
+ <entry>모든 second-level 캐시 액티비티를 로그시킨다</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction</literal></entry>
+ <entry>트랜잭션 관련 액티비티를 로그 시킨다</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.jdbc</literal></entry>
+ <entry>모든 JDBC 리소스 취득을 로그 시킨다</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.hql.ast.AST</literal></entry>
+ <entry>
+ 질의 파싱 동안에 HQL AST와 SQL AST를 로그시킨다
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.secure</literal></entry>
+ <entry>모든 JAAS 허가 요청들을 로그시킨다</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate</literal></entry>
+ <entry>
+ 모든 것을 로그시킨다(많은 정보이지만, 문제해결에 매우 유용하다)
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Hibernate로 어플리케이션들을 개발할 때, 당신은 거의 항상 <literal>org.hibernate.SQL</literal> 카테고리에 대해
+ 이용 가능한 <literal>debug</literal> 모드로 작업하거나, 다른 방법으로 <literal>hibernate.show_sql</literal>
+ 프로퍼티를 이용가능하게 하여 작업해야 할 것이다.
+ </para>
+
+
+ </sect1>
+
+ <sect1 id="configuration-namingstrategy">
+ <title><literal>NamingStrategy</literal> 구현하기</title>
+
+ <para>
+ <literal>org.hibernate.cfg.NamingStrategy</literal> 인터페이스는 데이터베이스 객체들과 스키마 요소들에 대한
+ "네이밍 표준"을 지정하는 것을 당신에게 허용해준다.
+ </para>
+
+ <para>
+ 당신은 Java 식별자들로부터 데이터베이스 식별자들을 자동적으로 생성시키거나 매핑 파일에 주어진 "논리적" 컬럼과 테이블
+ 이름들을 "물리적" 테이블과 컬럼 이름들로 자동적으로 처리하는 규칙들을 제공할 수 있다. 이 특징은 반복되는 잡음(예를 들어
+ <literal>TBL_</literal>접두어들)을 제거함으로써, 매핑 문서의 말많은 장황함을 감소시키도록 도와준다. Hibernate에
+ 의해 사용되는 디폴트 방도는 아주 작은 작품이다.
+ </para>
+
+ <para>
+ 당신은 매핑들을 추가하기 이전에 <literal>Configuration.setNamingStrategy()</literal>를 호출함으로써 다른 방도를
+ 지정할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration()
+ .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
+ .addFile("Item.hbm.xml")
+ .addFile("Bid.hbm.xml")
+ .buildSessionFactory();]]></programlisting>
+
+ <para>
+ <literal>org.hibernate.cfg.ImprovedNamingStrategy</literal>는 어떤 어플리케이션들에 대한 유용한 시작점일 수 있는
+ 미리 빌드된 방도이다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-xmlconfig" revision="2">
+ <title>XML 구성 파일</title>
+
+ <para>
+ 구성에 대한 다른 접근법은 <literal>hibernate.cfg.xml</literal>로 명명된 파일 속에 전체 구성을 지정하는 것이다. 이 파일은
+ <literal>hibernate.properties</literal> 파일에 대한 대용물로서 사용될 수 있거나, 만일 둘 다 존재할 경우에 프로퍼티들을
+ 중복정의하는데 사용될 수 있다.
+ </para>
+
+ <para>
+ XML 구성 파일은 디폴트로 당신의 <literal>CLASSPATH</literal>의 루트에 존재하는 것이 기대된다. 다음은 예제이다:
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <!-- a SessionFactory instance listed as /jndi/name -->
+ <session-factory
+ name="java:hibernate/SessionFactory">
+
+ <!-- properties -->
+ <property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
+ <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
+ <property name="show_sql">false</property>
+ <property name="transaction.factory_class">
+ org.hibernate.transaction.JTATransactionFactory
+ </property>
+ <property name="jta.UserTransaction">java:comp/UserTransaction</property>
+
+ <!-- mapping files -->
+ <mapping resource="org/hibernate/auction/Item.hbm.xml"/>
+ <mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
+
+ <!-- cache settings -->
+ <class-cache class="org.hibernate.auction.Item" usage="read-write"/>
+ <class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
+ <collection-cache collection="org.hibernate.auction.Item.bids" usage="read-write"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ 당신이 볼 수 있듯이, 이 접근법의 장점은 구성에 대한 매핑 파일 이름들을 구체화 시키는 것이다. <literal>hibernate.cfg.xml</literal>은
+ 또한 당신이 Hibernate 캐시를 튜닝해야할 때 보다 편리하다. <literal>hibernate.properties</literal> 또는
+ <literal>hibernate.cfg.xml</literal> 중 어느 것을 사용하는가는 당신의 선택이다. XML 구문을 사용하는 위에 언급된
+ 이점들을 제외하면 둘다 같은 것임을 노트하라.
+ </para>
+
+ <para>
+ Hibernate 구성으로, Hibernate를 시작하는 것은 다음과 같이 간단하다
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration().configure().buildSessionFactory();]]></programlisting>
+
+ <para>
+ 당신은 다음을 사용하여 다른 XML 구성 파일을 찾아낼 수 있다
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration()
+ .configure("catdb.cfg.xml")
+ .buildSessionFactory();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="configuration-j2ee" revision="1">
+ <title>J2EE 어플리케이션 서버 통합</title>
+
+ <para>
+ Hibernate는 J2EE 인프라스트럭처에 대한 다음 통합 점들을 갖고 있다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Container-managed datasources</emphasis>: Hibernate는 컨테이너에 의해 관리되는 JDBC 커넥션들을
+ 사용할 수 있고 JNDI를 통해 제공된다. 대개 JTA 호환 <literal>TransactionManager</literal>와 <literal>ResourceManager</literal>는
+ 트랜잭션 관리(CMT), 특히 몇몇 데이터소스들을 가로질러 분산된 트랜잭션 핸들링을 처리한다. 물론 당신은 또한 프로그램 상으로
+ 트랜잭션 경계들을 한정할 수도 있거나(BMT) 당신은 당신의 코드가 이식성을 유지하도록 이것에 대한 선택적인 Hibernate
+ <literal>Transaction</literal> API를 사용하고자 원할 수도 있다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>자동적인 JNDI 바인딩</emphasis>: Hibernate는 시작 후에 그것의 <literal>SessionFactory</literal>를
+ JNDI에 바인드 시킬 수 있다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>JTA Session 바인딩</emphasis>: Hibernate <literal>Session</literal>은
+ JTA 트랜잭션들의 영역(scope)에 자동적으로 바인드 시킬 수도 있다. 간단하게 JNDI로부터 <literal>SessionFactory</literal>를
+ 룩업하고 현재 <literal>Session</literal>을 얻어라. Hibernate로 하여금 당신의 JTA 트랜잭션이 완료될 때 <literal>Session</literal>을
+ flush시키고 닫는 것을 처리하도록 하라. 트랜잭션 경계 구분은 선언적(CMT)이거나 프로그래밍적((BMT/UserTransaction))이다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>JMX 배치</emphasis>: 만일 당신이 JMX 가용성이 있는 어플리케이션 서버(예를 들면 JBoss AS)를 갖고 있다면,
+ 당신은 Hibernate를 하나의 managed MBean으로서 배치하는 것을 선택할 수 있다. 이것은 <literal>Configuration</literal>으로부터
+ 당신의 <literal>SessionFactory</literal>를 빌드 시키는 한 줄의 시작 코드를 절약해준다. 컨테이너는 당신의 <literal>HibernateService</literal>를
+ 시작할 것이고, 또한 이상적으로 서비스 의존성들을 처리할 것이다(데이터소스는 Hibernate가 시작되기 전에 이용 가능해야 한다).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 당신의 환경에 따라, 당신은 당신의 어플리케이션 서버가 "connection containment(연결 봉쇄)" 예외상황들을 보일 경우에 구성 옵션
+ <literal>hibernate.connection.aggressive_release</literal>를 true로 설정해야 될 수도 있다.
+ </para>
+
+ <sect2 id="configuration-optional-transactionstrategy" revision="3">
+ <title>트랜잭션 방도 구성</title>
+
+ <para>
+ Hibernate <literal>Session</literal> API는 당신의 아카텍처 내에서 임의의 트랜잭션 관할 시스템에 독립적이다. 만일
+ 당신이 Hibernate로 하여금 커넥션 풀을 통해 직접 JDBC를 사용하도록 강제할 경우, 당신은 JDBC API를 호출하여 당신의 트랜잭션을
+ 시작하고 끝낼 수 있다. 만일 당신이 J2EE 어플리케이션 서버를 실행 중이라면, 당신은 필요할 때 bean-managed 트랜잭션들을 사용하고
+ JTA API와 <literal>UserTransaction</literal>을 호출하고자 원할 수 있다.
+ </para>
+
+ <para>
+ 이들 두 개의 (그리고 다른) 환경들에서 당신의 코드에 이식성을 유지하기 위해 우리는 기본 시스템을 포장하고 은폐시키는 선택적인
+ Hibernate <literal>Transaction</literal> API를 권장한다. 당신은 Hibernate 구성 프로퍼티 <literal>hibernate.transaction.factory_class</literal>를
+ 사용하여 <literal>Transaction</literal> 인스턴스들에 대한 팩토리 클래스를 지정해야 한다.
+ </para>
+
+ <para>
+ 세 개의 표준(미리 만들어진) 선택들이 존재한다:
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term><literal>org.hibernate.transaction.JDBCTransactionFactory</literal></term>
+ <listitem>
+ <para>데이터베이스 (JDBC) 트랜잭션들에게 위임시킨다(디폴트)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>org.hibernate.transaction.JTATransactionFactory</literal></term>
+ <listitem>
+ <para>
+ 기존의 트랜잭션이 이 컨텍스트(예를 들면 EJB session bean 메소드) 내에서 진행 중일 경우에
+ container-managed transaction에게 위임시키고, 그 밖의 경우 새로운 트랜잭션이 시작되고
+ bean-managed transaction이 사용된다.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>org.hibernate.transaction.CMTTransactionFactory</literal></term>
+ <listitem>
+ <para>container-managed JTA 트랜잭션들에게 위임시킨다</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ 당신은 또한 당신 자신의 트랜잭션 방도들(예를 들면 CORBA 트랜잭션 서비스)을 정의할 수도 있다.
+ </para>
+
+ <para>
+ Hibernate에 있는 몇몇 특징들(예를 들면. second level 캐시, JTA를 가진 컨텍스트 상의 세션들, 기타.)은 관리되는 환경에서
+ JTA <literal>TransactionManager</literal>에 대한 접근을 필요로 한다. 어플리케이션 서버에서 당신은 Hibernate가
+ <literal>TransactionManager</literal>에 대한 참조를 획득하는 방법을 지정해야 한다. 왜냐하면 J2EE가 한 개의 메커니즘을
+ 표준화 시키고 있지 않기 때문이다:
+ </para>
+
+ <table frame="topbot" id="jtamanagerlookup" revision="1">
+ <title>JTA TransactionManagers</title>
+ <tgroup cols="2">
+ <colspec colwidth="2.5*"/>
+ <colspec colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>트랜잭션 팩토리</entry>
+ <entry align="center">어플리케이션 서버</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>org.hibernate.transaction.JBossTransactionManagerLookup</literal></entry>
+ <entry align="center">JBoss</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.WeblogicTransactionManagerLookup</literal></entry>
+ <entry align="center">Weblogic</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.WebSphereTransactionManagerLookup</literal></entry>
+ <entry align="center">WebSphere</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</literal></entry>
+ <entry align="center">WebSphere 6</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.OrionTransactionManagerLookup</literal></entry>
+ <entry align="center">Orion</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.ResinTransactionManagerLookup</literal></entry>
+ <entry align="center">Resin</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.JOTMTransactionManagerLookup</literal></entry>
+ <entry align="center">JOTM</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.JOnASTransactionManagerLookup</literal></entry>
+ <entry align="center">JOnAS</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.JRun4TransactionManagerLookup</literal></entry>
+ <entry align="center">JRun4</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.BESTransactionManagerLookup</literal></entry>
+ <entry align="center">Borland ES</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-jndi" revision="3">
+ <title>JNDI-bound <literal>SessionFactory</literal></title>
+
+ <para>
+ 하나의 JNDI 바인드된 Hibernate <literal>SessionFactory</literal>는 그 팩토리에 대한 룩업과 새로운
+ <literal>Session</literal>들의 생성을 단순화 시킬 수 있다. 이것은 JNDI 바인드된 <literal>Datasource</literal>에
+ 관련되어 있지 않고, 단순하게 둘 다 동일한 레지스트리를 사용한다는 점을 노트하라!
+ </para>
+
+ <para>
+ 만일 당신이 <literal>SessionFactory</literal>를 하나의 JNDI namespace에 바인드 시키고자 원할 경우,
+ <literal>hibernate.session_factory_name</literal> 프로퍼티를 사용하여 한 개의 이름(예를 들면.
+ <literal>java:hibernate/SessionFactory</literal>)을 지정하라. 만일 이 프로퍼티가 생략될 경우,
+ <literal>SessionFactory</literal>는 JNDI에 바인드 되지 않을 것이다. (이것은 읽기-전용 JNDI 디폴트
+ 구현을 가진 환경들, 예를 들면 Tomcat에서 특히 유용하다.)
+ </para>
+
+ <para>
+ <literal>SessionFactory</literal>를 JNDI에 바인드 시킬 때, Hibernate는 초기 컨텍스트를 초기화 시키기 위해
+ <literal>hibernate.jndi.url</literal>, <literal>hibernate.jndi.class</literal>의 값들을 사용할 것이다.
+ 만일 그것들이 지정되어 있지 않을 경우, 디폴트 <literal>InitialContext</literal>가 사용될 것이다.
+ </para>
+
+ <para>
+ Hibernate는 당신이 <literal>cfg.buildSessionFactory()</literal>를 호출한 후에 <literal>SessionFactory</literal>를 JNDI 내에
+ 자동적으로 위치지울 것이다. 이것은 당신이 (나중에 논의되는) <literal>HibernateService</literal>를 가진 JMX 배치를
+ 사용하지 않는 한, 당신이 적어도 당신의 어플리케이션 내에 있는 어떤 시작 코드 (또는 유틸리티 클래스) 내에서 이것을 호출할 것임을
+ 의미한다.
+ </para>
+
+ <para>
+ 만일 당신이 하나의 JNDI <literal>SessionFactory</literal>를 사용할 경우, 하나의 EJB 또는 어떤 다른 클래스는 JNDI
+ 룩업을 사용하여 <literal>SessionFactory</literal>를 얻을 수 있다.
+ </para>
+
+ <para>
+ 우리는 관리되는 환경들에서 <literal>SessionFactory</literal>를 JNDI에 바인드 시키고 그 밖의 경우에는
+ 하나의 <literal>static</literal> 싱글톤을 사용하는 것을 권장한다. 이들 상세로부터 당신의 어플리케이션 코드를
+ 은폐시키기 위해, 우리는 또한 <literal>HibernateUtil.getSessionFactory()</literal>과 같은 하나의
+ helper 클래스 내에서 <literal>SessionFactory</literal>에 대한 실제 룩업 코드를 은폐시키기를 권장한다.
+ 그런 클래스는 또한 Hibernate를 시작하는 편리한 방법임을 노트하라— 1장을 보라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-j2ee-currentsession" revision="4">
+ <title>Current Session context management with JTA</title>
+
+ <para>
+ 당신 자신의 <literal>ThreadLocal</literal> 유틸리티를 작동시키는 대신에, 우리는 또한 Hibernate <literal>Session</literal>를
+ 얻기 위해 <literal>SessionFactory</literal> 상의 <literal>getCurrentSession()</literal> 메소드 사용을
+ 권장한다. <xref linkend="architecture-current-session">현재 세션들</xref>에 관한 논의를 보라. <literal>"jta"</literal>
+ 세션 컨텍스트를 사용하고 있는 경우에, 현재의 JTA 트랜잭션으로 시작되고 연관된 Hibernate <literal>Session</literal>이
+ 존재하지 않을 경우, 우리는 JTA 트랜잭션으로 시작되고 연관될 것이다. <literal>"jta"</literal> 컨텍스트에서
+ <literal>getCurrentSession()</literal>를 통해 검색된 <literal>Session</literal>들은 그 트랜잭션이 완료되기 전에
+ 자동적으로 flush될 것이고 트랜잭션 완료 후에 닫혀질 것이고, 그리고 각각의 문장 뒤에 JDBC 커넥션들을 적극적으로 해제할 것이다.
+ 이것은 그런 관리 사항들에 대해 사용자 코드를 명료하게 유지시켜서, 연관되어 있는 JTA 트랜잭션의 생명주기에 의해 <literal>Session</literal>들이
+ 관리되도록 허용해준다. 이것은 그런 관리 사항들에 대해 사용자 코드를 명료하게 유지시켜서, 세션이 연관되어 있는 JTA 트랜잭션의
+ 생명주기에 의해 관리되는 것을 <literal>Session</literal>들에게 허용해준다. 당신의 코드는
+
+ <literal>Session</literal>들과 트랜잭션들을 처리하는 가장 손쉬운 방법은 Hibernate의 자동적인 "현재"
+ <literal>Session</literal>이다.
+ <xref linkend="architecture-current-session">current sessions</xref>에 관한 논의를 보라.
+ <literal>"jta"</literal> 세션 컨텍스트를 사용하는 경우, 현재의 JTA 트랜잭션으로 시작되고 연관된
+ Hibernate <literal>Session</literal>들이 존재하지 않을 경우, 당신이
+ <literal>sessionFactory.getCurrentSession()</literal>을 처음 호출할 때 하나의 세션이 현재의 JTA 트랜잭션에 대해
+ 시작되고 연관될 것이다. <literal>"jta"</literal> 컨텍스트에서 <literal>getCurrentSession()</literal>을
+ 통해 검색된 <literal>Session</literal>들은 그 트랜잭션이 완료되기 전에 자동적으로 flush될 것이고
+ 그 트랜잭션 완료들 후에 닫혀질 것이고 각각의 문장 후에 JDBC 커넥션들을 적극적으로 해제할 것이다.
+ 이것은 그런 관리 사항들에 대해 사용자 코드를 명료하게 유지시켜서, 연관되어 있는 JTA 트랜잭션의 생명주기에 의해 <literal>Session</literal>들이
+ 관리되도록 허용해준다. 이것은 그런 관리 사항들에 대해 사용자 코드를 명료하게 유지시켜서, 세션이 연관되어 있는 JTA 트랜잭션의
+ 생명주기에 의해 관리되는 것을 <literal>Session</literal>들에게 허용해준다. 당신의 코드는 트랜잭션 경계들을 설정하는데
+ <literal>UserTransaction</literal>을 통해 프로그램 상으로 JTA를 사용하거나, Hibernate <literal>Transaction</literal> API를 (이식성을 위한 코드로 권장됨)
+ 사용할 수 있다. 만일 당신이 하나의 EJB 컨테이너에서 실행하고 있을 경우, CMT의 경우에 선언적인 트랜잭션 경계설정이 선호된다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-j2ee-jmx" revision="1">
+ <title>JMX 배치</title>
+
+ <para>
+ <literal>cfg.buildSessionFactory()</literal> 줄은 여전히 JNDI에 붙은 하나의 <literal>SessionFactory</literal>를 얻기 위해
+ 어딘가에서 실행되어야 한다. 당신은 (<literal>HibernateUtil</literal> 내에 있는 것처럼) <literal>static</literal> initializer
+ 블록 속에서 이것을 행할 수 있거나 당신은 Hibernate를 <emphasis>managed service</emphasis>로서 배치할 수 있다.
+ </para>
+
+ <para>
+ Hibernate는 JBoss AS와 같은 JMX 가용성들을 가진 어플리케이션 서버 상의 배치를 위해 <literal>org.hibernate.jmx.HibernateService</literal>를
+ 배포하고 있다. 실제 배치와 구성은 벤더 지정적이다. 다음은 JBoss 4.0.x를 위한 <literal>jboss-service.xml</literal> 예제이다:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<server>
+
+<mbean code="org.hibernate.jmx.HibernateService"
+ name="jboss.jca:service=HibernateFactory,name=HibernateFactory">
+
+ <!-- Required services -->
+ <depends>jboss.jca:service=RARDeployer</depends>
+ <depends>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>
+
+ <!-- Bind the Hibernate service to JNDI -->
+ <attribute name="JndiName">java:/hibernate/SessionFactory</attribute>
+
+ <!-- Datasource settings -->
+ <attribute name="Datasource">java:HsqlDS</attribute>
+ <attribute name="Dialect">org.hibernate.dialect.HSQLDialect</attribute>
+
+ <!-- Transaction integration -->
+ <attribute name="TransactionStrategy">
+ org.hibernate.transaction.JTATransactionFactory</attribute>
+ <attribute name="TransactionManagerLookupStrategy">
+ org.hibernate.transaction.JBossTransactionManagerLookup</attribute>
+ <attribute name="FlushBeforeCompletionEnabled">true</attribute>
+ <attribute name="AutoCloseSessionEnabled">true</attribute>
+
+ <!-- Fetching options -->
+ <attribute name="MaximumFetchDepth">5</attribute>
+
+ <!-- Second-level caching -->
+ <attribute name="SecondLevelCacheEnabled">true</attribute>
+ <attribute name="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>
+ <attribute name="QueryCacheEnabled">true</attribute>
+
+ <!-- Logging -->
+ <attribute name="ShowSqlEnabled">true</attribute>
+
+ <!-- Mapping files -->
+ <attribute name="MapResources">auction/Item.hbm.xml,auction/Category.hbm.xml</attribute>
+
+</mbean>
+
+</server>]]></programlisting>
+
+ <para>
+ 이 파일은 <literal>META-INF</literal>로 명명된 디렉토리 속에 배치되고 확장자 <literal>.sar</literal>
+ (service archive)를 가진 한 개의 JAR 파일 속에 패키징된다. 당신은 또한 Hibernate, 그것의 필요한 제 3의 라이브러리들, 당신의 컴파일된
+ 영속 클래스들 뿐만 아니라 당신의 매핑 파일들을 동일한 아카이브 속에 패키징할 필요가 있다. 당신의 엔터프라이즈 빈즈(대개 session beans)는
+ 그것들 자신의 JAR 파일 속에 유지될 수 있지만, 당신은 한 개의 (hot-)배치 가능한 단위를 얻기 위해 메인 서비스 아카이브 속에 이 EJB JAR 파일을
+ 포함시킬 수도 있다. JMX 서비스와 EJB 배치에 관한 추가 정보는 JBoss AS 문서를 참조하라.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/events.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/events.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/events.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/events.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,255 @@
+<chapter id="events">
+ <title>인터셉터들과 이벤트들</title>
+
+ <para>
+ 어플리케이션이 Hibernate 내부에서 발생하는 어떤 이벤트들에 대해 반응하는 것에 흔히 유용하다. 이것은 어떤 종류의 일반적인 기능,
+ 그리고 Hibernate의 확장 기능의 구현을 허용해준다.
+ </para>
+
+ <sect1 id="objectstate-interceptors" revision="3">
+ <title>인터셉터들</title>
+
+ <para>
+ <literal>Interceptor</literal> 인터페이스는 영속 객체가 저장되고, 업데이트되고, 삭제되거나 로드되기 전에 영속 객체의
+ 프로퍼티들을 조사하고/하거나 처리하는 것을 어플리케이션에 허용해줌으로써 세션으로부터 어플리케이션으로의 콜백들을 제공한다.
+ 이것에 대한 한 가지 가능한 사용은 감사 정보를 추적하는 것이다. 예를 들어, 다음 <literal>Interceptor</literal>는
+ <literal>Auditable</literal>이 생성될 때 <literal>createTimestamp</literal>를 자동적으로 설정하고
+ <literal>Auditable</literal>이 업데이트될 때 <literal>lastUpdateTimestamp</literal> 프로퍼티를 업데이트 한다.
+ </para>
+
+ <para>
+ 당신은 <literal>Interceptor</literal>를 직접 구현해야 하거나 (더 좋게는)
+ <literal>EmptyInterceptor</literal>를 확장(extend)해야 한다.
+ </para>
+
+ <programlisting><![CDATA[package org.hibernate.test;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.Transaction;
+import org.hibernate.type.Type;
+
+public class AuditInterceptor extends EmptyInterceptor {
+
+ private int updates;
+ private int creates;
+ private int loads;
+
+ public void onDelete(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+ // do nothing
+ }
+
+ public boolean onFlushDirty(Object entity,
+ Serializable id,
+ Object[] currentState,
+ Object[] previousState,
+ String[] propertyNames,
+ Type[] types) {
+
+ if ( entity instanceof Auditable ) {
+ updates++;
+ for ( int i=0; i < propertyNames.length; i++ ) {
+ if ( "lastUpdateTimestamp".equals( propertyNames[i] ) ) {
+ currentState[i] = new Date();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean onLoad(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+ if ( entity instanceof Auditable ) {
+ loads++;
+ }
+ return false;
+ }
+
+ public boolean onSave(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if ( entity instanceof Auditable ) {
+ creates++;
+ for ( int i=0; i<propertyNames.length; i++ ) {
+ if ( "createTimestamp".equals( propertyNames[i] ) ) {
+ state[i] = new Date();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void afterTransactionCompletion(Transaction tx) {
+ if ( tx.wasCommitted() ) {
+ System.out.println("Creations: " + creates + ", Updates: " + updates, "Loads: " + loads);
+ }
+ updates=0;
+ creates=0;
+ loads=0;
+ }
+
+}]]></programlisting>
+
+ <para>
+ 인터셉터들은 다음 두 개의 특징들로 나타난다: <literal>Session</literal>-영역화 그리고
+ <literal>SessionFactory</literal>-영역화.
+ </para>
+
+ <para>
+ <literal>Session</literal>-영역의 인터셉터는 세션이 하나의 <literal>Interceptor</literal>를 수용하는
+ 오버로드된 SessionFactory.openSession() 메소드들 중 하나를 사용하여 열릴 때
+ 지정된다.
+ </para>
+
+ <programlisting><![CDATA[Session session = sf.openSession( new AuditInterceptor() );]]></programlisting>
+
+ <para>
+ 당신은 또한 <literal>Configuration</literal>을 사용하여 인터셉터를 전역 레벨 상에 설정할 수도 있다.
+ 이 경우에, 인터셉터는 threadsafe이어야 한다.
+ </para>
+
+ <programlisting><![CDATA[Session session = sf.openSession( new AuditInterceptor() );]]></programlisting>
+
+ <para>
+ <literal>SessionFactory</literal>-영역의 인터셉터는 <literal>SessionFactory</literal>을 빌드하기에 앞서
+ <literal>Configuration</literal> 객체에 등록된다. 이 경우에, 공급되는 인터셉터는 그 <literal>SessionFactory</literal>로부터
+ 열려진 모든 세션들에 적용될 것이다; 하나의 세션이 사용할 인터셉터를 명시적으로 지정하여 열리지 않는 한 이것은 참이다.
+ <literal>SessionFactory</literal>-영역의 인터셉터들은 세션-지정적인 상태를 저장하지 않도록 주의하여 쓰레드-안전해야 한다.
+ 왜냐하면 다중 세션들은 (잠정적으로) 이 인터셉터를 동시적으로 사용할 것이기 때문이다.
+ </para>
+
+ <programlisting><![CDATA[new Configuration().setInterceptor( new AuditInterceptor() );]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="objectstate-events" revision="4">
+ <title>이벤트 시스템</title>
+
+ <para>
+ 만일 당신이 당신의 영속 계층에서 특정 이벤트들에 대해 반응해야 한다면, 당신은 또한 Hibernate3 <emphasis>event</emphasis>
+ 아키텍처를 사용할 수도 있다. 이벤트 시스템은 부가물로 사용될 수 있거나 인터셉터들에 대한 대체물로 사용될 수 있다.
+ </para>
+
+ <para>
+ 본질적으로 <literal>Session</literal> 인터페이스의 모든 메소드들은 이벤트와 서로 관련되어 있다.
+ 당신은 <literal>LoadEvent</literal>,
+ <literal>FlushEvent</literal>, 등을 갖는다 (정의된 이벤트 타입들의 전체 리스트에 대해서는 XML 구성 파일 DTD 또는
+ <literal>org.hibernate.event</literal> 패키지를 참조하라). 하나의 요청이 이들 메소드들 중 하나에 의해 만들어질 때,
+ Hibernate <literal>Session</literal>은 적절한 이벤트를 생성시키고 그것을 그 타입의 구성된 이벤트 리스너에게 전달한다.
+ 박싱없이, 이들 리스너들은 그들 메소드들이 항상 귀결되었던 동일한 프로세싱을 구현한다. 하지만 당신이 리스너 인터페이스들 중 하나의 맞춤을
+ 구현하는 것이 자유롭고(예를 들어 <literal>LoadEvent</literal>는 <literal>LoadEventListener</literal> 인터페이스의
+ 등록된 구현에 의해 처리된다), 그 경우에 그들 구현은 <literal>Session</literal>에 대해 행해진 임의의 <literal>load()</literal>
+ 요청들을 처리할 책임이 있을 것이다.
+ </para>
+
+ <para>
+ 리스너들은 효율적이게끔 싱글톤(singleton)들로 간주되어야 할 것이다; 이것은 그것들이 요청들 사이에서 공유되고, 따라서 임의의 상태를
+ 인스턴스 변수들로서 저장하지 말아야 함을 의미한다.
+ </para>
+
+ <para>
+ 맞춤형 리스너는 그것이 편의적인 기저 클래스들(또는 리스너들이 이 용도로 final이 아닌 것으로 선언되므로 Hibernate
+ out-of-the-box에 의해 사용된 디폴트 이벤트 리스너들) 중 하나를 처리하고/하거나 확장하고자 원하는 이벤트들에 대해
+ 적절한 인터페이스를 구현해야 한다. 맞춤형 리스너들은 <literal>Configuration</literal> 객체를 통해 프로그램 상으로
+ 등록될 수 있거나, Hibernate 구성 XML 속에 지정될 수 있다 (properties 파일을 통한 선언적인 구성은 지원되지 않는다).
+ 다음은 맞춤형 load 이벤트 리스너에 대한 예제이다:
+ </para>
+
+ <programlisting><![CDATA[public class MyLoadListener implements LoadEventListener {
+ // this is the single method defined by the LoadEventListener interface
+ public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType)
+ throws HibernateException {
+ if ( !MySecurity.isAuthorized( event.getEntityClassName(), event.getEntityId() ) ) {
+ throw MySecurityException("Unauthorized access");
+ }
+ }
+}]]></programlisting>
+
+ <para>
+ 당신은 또한 디폴트 리스너에 덧붙여 그 리스너를 사용하도록 Hibernate에게 알려주는 구성 엔트리를 필요로 한다:
+ </para>
+
+<programlisting><![CDATA[<hibernate-configuration>
+ <session-factory>
+ ...
+ <event type="load">
+ <listener class="com.eg.MyLoadListener"/>
+ <listener class="org.hibernate.event.def.DefaultLoadEventListener"/>
+ </event>
+ </session-factory>
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ 대신에 당신은 그것을 프로그래밍 방식으로 등록할 수도 있다:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration();
+LoadEventListener[] stack = { new MyLoadListener(), new DefaultLoadEventListener() };
+cfg.EventListeners().setLoadEventListeners(stack);]]></programlisting>
+
+ <para>
+ 선언적으로 등록된 리스너들은 인스턴스들을 공유할 수 없다. 만일 동일한 클래스 이름이 여러 개의 <literal><listener/></literal>
+ 요소들에서 사용될 경우, 각각의 참조는 그 클래스에 대한 별도의 인스턴스로 귀결될 것이다. 만일 당신이 리스너 타입들 사이에서 리스너 인스턴스들을
+ 공유할 가용성을 필요로 할 경우 당신은 프로그래밍 방식의 등록 접근법을 사용해야 한다.
+ </para>
+
+ <para>
+ 구성 동안에 왜 인터페이스를 구현하고 특정 타입을 지정하는가? 물론 리스너 구현은 여러 개의 이벤트 리스너 인터페이스들을
+ 구현할 수 있다. 등록 동안에 추가적으로 타입을 정의하는 것은 컨피그레이션 동안에 맞춤형 리스너들의 사용 여부를 전환시키는 것을
+ 더 쉽게 해준다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-decl-security" revision="2">
+ <title>Hibernate 선언적인 보안</title>
+ <para>
+ 대개 Hibernate 어플리케이션들에서 선언적인 보안은 session facade 계층 내에서 관리된다. 이제, Hibernate3는 어떤 액션들이
+ JACC를 통해 퍼미션을 주어지고, JAAS를 통해 인가되는 것을 허용해준다. 이것은 모든 아키텍처의 상단에 빌드된 옵션 기능이다.
+ </para>
+
+ <para>
+ 먼저, 당신은 JAAS authorization 사용을 이용 가능하도록 하기 위해 적절한 이벤트 리스터들을 구성해야 한다.
+ </para>
+
+ <programlisting><![CDATA[<listener type="pre-delete" class="org.hibernate.secure.JACCPreDeleteEventListener"/>
+<listener type="pre-update" class="org.hibernate.secure.JACCPreUpdateEventListener"/>
+<listener type="pre-insert" class="org.hibernate.secure.JACCPreInsertEventListener"/>
+<listener type="pre-load" class="org.hibernate.secure.JACCPreLoadEventListener"/>]]></programlisting>
+
+ <para>
+ <literal><listener type="..." class="..."/></literal>는 특정 이벤트 타입에 대해 정확히 한 개의
+ 리스너가 존재할 때 단지 <literal><event type="..."><listener class="..."/></event></literal>의
+ 단축형임을 노트하라.
+ </para>
+
+ <para>
+ 다음으로, 여전히 <literal>hibernate.cfg.xml</literal> 내에서 퍼미션들을 role들에 바인드 시킨다 :
+ </para>
+
+ <programlisting><![CDATA[<grant role="admin" entity-name="User" actions="insert,update,read"/>
+<grant role="su" entity-name="User" actions="*"/>]]></programlisting>
+
+ <para>
+ 역할(role) 이름들은 당신의 JACC 프로바이더에 의해 인지된 역할(role)들이다.
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/example_mappings.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/example_mappings.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/example_mappings.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/example_mappings.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,667 @@
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<chapter id="example-mappings">
+ <title>예제: 여러 가지 매핑들</title>
+
+ <para>
+ 이 장은 몇몇 보다 복잡한 연관 매핑들을 보여준다.
+ </para>
+
+ <sect1 id="example-mappings-emp">
+ <title>Employer/Employee</title>
+
+ <para>
+ <literal>Employer</literal>와 <literal>Employee</literal> 사이의 관계에 대한 다음 모형은 그 연관를 표현하는 데
+ 실제 엔티티 클래스(<literal>Employment</literal>)를 사용한다. 동일한 두 부분들에 대해 하나 이상의 채용 주기가 존재할 수 있기
+ 때문에 이것이 행해진다. 컴포넌트들이 화폐 값들과 종업원 이름들을 모형화 시키는데 사용된다.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/EmployerEmployee.png" format="PNG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/EmployerEmployee.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ 다음은 가능한 매핑 문서이다:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Employer" table="employers">
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employer_id_seq</param>
+ </generator>
+ </id>
+ <property name="name"/>
+ </class>
+
+ <class name="Employment" table="employment_periods">
+
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employment_id_seq</param>
+ </generator>
+ </id>
+ <property name="startDate" column="start_date"/>
+ <property name="endDate" column="end_date"/>
+
+ <component name="hourlyRate" class="MonetaryAmount">
+ <property name="amount">
+ <column name="hourly_rate" sql-type="NUMERIC(12, 2)"/>
+ </property>
+ <property name="currency" length="12"/>
+ </component>
+
+ <many-to-one name="employer" column="employer_id" not-null="true"/>
+ <many-to-one name="employee" column="employee_id" not-null="true"/>
+
+ </class>
+
+ <class name="Employee" table="employees">
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employee_id_seq</param>
+ </generator>
+ </id>
+ <property name="taxfileNumber"/>
+ <component name="name" class="Name">
+ <property name="firstName"/>
+ <property name="initial"/>
+ <property name="lastName"/>
+ </component>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 그리고 다음은 <literal>SchemaExport</literal>에 의해 생성된 테이블 스키마이다.
+ </para>
+
+ <programlisting><![CDATA[create table employers (
+ id BIGINT not null,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+create table employment_periods (
+ id BIGINT not null,
+ hourly_rate NUMERIC(12, 2),
+ currency VARCHAR(12),
+ employee_id BIGINT not null,
+ employer_id BIGINT not null,
+ end_date TIMESTAMP,
+ start_date TIMESTAMP,
+ primary key (id)
+)
+
+create table employees (
+ id BIGINT not null,
+ firstName VARCHAR(255),
+ initial CHAR(1),
+ lastName VARCHAR(255),
+ taxfileNumber VARCHAR(255),
+ primary key (id)
+)
+
+alter table employment_periods
+ add constraint employment_periodsFK0 foreign key (employer_id) references employers
+alter table employment_periods
+ add constraint employment_periodsFK1 foreign key (employee_id) references employees
+create sequence employee_id_seq
+create sequence employment_id_seq
+create sequence employer_id_seq]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-mappings-authorwork">
+ <title>Author/Work</title>
+
+ <para>
+ <literal>Work</literal>, <literal>Author</literal> 그리고 <literal>Person</literal> 사이의 관계들에 대한
+ 다음 모형을 검토하자. 우리는 <literal>Work</literal>과 <literal>Author</literal> 사이의 관계를 many-to-many
+ 연관으로 표현한다. 우리는 <literal>Author</literal>와 <literal>Person</literal> 사이의 관계를 one-to-one
+ 연관으로 표현하고자 선택한다. 또 다른 가능성은 <literal>Author</literal>가 <literal>Person</literal>을 확장하도록
+ 하는 것일 것이다.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/AuthorWork.png" format="PNG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/AuthorWork.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ 다음 매핑 문서는 이들 관계들을 정확하게 표현한다:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Work" table="works" discriminator-value="W">
+
+ <id name="id" column="id">
+ <generator class="native"/>
+ </id>
+ <discriminator column="type" type="character"/>
+
+ <property name="title"/>
+ <set name="authors" table="author_work">
+ <key column name="work_id"/>
+ <many-to-many class="Author" column name="author_id"/>
+ </set>
+
+ <subclass name="Book" discriminator-value="B">
+ <property name="text"/>
+ </subclass>
+
+ <subclass name="Song" discriminator-value="S">
+ <property name="tempo"/>
+ <property name="genre"/>
+ </subclass>
+
+ </class>
+
+ <class name="Author" table="authors">
+
+ <id name="id" column="id">
+ <!-- The Author must have the same identifier as the Person -->
+ <generator class="assigned"/>
+ </id>
+
+ <property name="alias"/>
+ <one-to-one name="person" constrained="true"/>
+
+ <set name="works" table="author_work" inverse="true">
+ <key column="author_id"/>
+ <many-to-many class="Work" column="work_id"/>
+ </set>
+
+ </class>
+
+ <class name="Person" table="persons">
+ <id name="id" column="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 이 매핑에는 네 개의 테이블들이 존재한다. <literal>works</literal>, <literal>authors</literal>와
+ <literal>persons</literal>은 각각 작업 데이터, 저자 데이터, 개인 데이터를 보관한다. <literal>author_work</literal>는
+ 저자들을 작업들에 연결시키는 연관 테이블이다. 다음은 <literal>SchemaExport</literal>에 의해 생성된 테이블
+ 스키마이다.
+ </para>
+
+ <programlisting><![CDATA[create table works (
+ id BIGINT not null generated by default as identity,
+ tempo FLOAT,
+ genre VARCHAR(255),
+ text INTEGER,
+ title VARCHAR(255),
+ type CHAR(1) not null,
+ primary key (id)
+)
+
+create table author_work (
+ author_id BIGINT not null,
+ work_id BIGINT not null,
+ primary key (work_id, author_id)
+)
+
+create table authors (
+ id BIGINT not null generated by default as identity,
+ alias VARCHAR(255),
+ primary key (id)
+)
+
+create table persons (
+ id BIGINT not null generated by default as identity,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+alter table authors
+ add constraint authorsFK0 foreign key (id) references persons
+alter table author_work
+ add constraint author_workFK0 foreign key (author_id) references authors
+alter table author_work
+ add constraint author_workFK1 foreign key (work_id) references works]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-mappings-customerorderproduct">
+ <title>Customer/Order/Product</title>
+
+ <para>
+ 이제 <literal>Customer</literal>, <literal>Order</literal>와 <literal>LineItem</literal>
+ 그리고 <literal>Product</literal> 사이의 관계들에 관한 모형을 검토하자. <literal>Customer</literal>와
+ <literal>Order</literal> 사이의 one-to-many 연관이 존재하지만, 우리는 어떻게
+ <literal>Order</literal> / <literal>LineItem</literal> / <literal>Product</literal>를
+ 표현할 것인가? 나는 <literal>Order</literal>와 <literal>Product</literal> 사이의 many-to-many
+ 연관를 나타내는 하나의 연관 클래스로서 <literal>LineItem</literal>을 매핑하기로 선택했다. Hibernate에서
+ 이것은 composite 요소로 명명된다.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/CustomerOrderProduct.png" format="PNG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/CustomerOrderProduct.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ 매핑 문서:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Customer" table="customers">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ <set name="orders" inverse="true">
+ <key column="customer_id"/>
+ <one-to-many class="Order"/>
+ </set>
+ </class>
+
+ <class name="Order" table="orders">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="date"/>
+ <many-to-one name="customer" column="customer_id"/>
+ <list name="lineItems" table="line_items">
+ <key column="order_id"/>
+ <list-index column="line_number"/>
+ <composite-element class="LineItem">
+ <property name="quantity"/>
+ <many-to-one name="product" column="product_id"/>
+ </composite-element>
+ </list>
+ </class>
+
+ <class name="Product" table="products">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="serialNumber"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>customers</literal>, <literal>orders</literal>, <literal>line_items</literal> 그리고
+ <literal>products</literal>는 각각 고객 데이터, 주문 데이터, 주문 라인 아이템 데이터, 그리고 제품 데이터를
+ 보관한다. <literal>line_items</literal>는 또한 주문들을 제품들과 연결시키는 연관 테이블로서 동작한다.
+ </para>
+
+ <programlisting><![CDATA[create table customers (
+ id BIGINT not null generated by default as identity,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+create table orders (
+ id BIGINT not null generated by default as identity,
+ customer_id BIGINT,
+ date TIMESTAMP,
+ primary key (id)
+)
+
+create table line_items (
+ line_number INTEGER not null,
+ order_id BIGINT not null,
+ product_id BIGINT,
+ quantity INTEGER,
+ primary key (order_id, line_number)
+)
+
+create table products (
+ id BIGINT not null generated by default as identity,
+ serialNumber VARCHAR(255),
+ primary key (id)
+)
+
+alter table orders
+ add constraint ordersFK0 foreign key (customer_id) references customers
+alter table line_items
+ add constraint line_itemsFK0 foreign key (product_id) references products
+alter table line_items
+ add constraint line_itemsFK1 foreign key (order_id) references orders]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="misc">
+ <title>기타 예제 매핑들</title>
+
+ <para>
+ 이들 예제들은 모두 Hiberante test suite로부터 취했다. 당신은 거기서 많은
+ 다른 유용한 예제 매핑들을 발견할 것이다. Hibernate 배포본의 <literal>test</literal>
+ 폴더를 살펴보라.
+ </para>
+
+ <para>TODO: 이 내용을 둘러싼 말들을 집어넣을 것.</para>
+
+ <sect2 id="example-mappings-typed-onetone">
+ <title>"형식화된(Typed)" one-to-one 연관</title>
+<programlisting><![CDATA[<class name="Person">
+ <id name="name"/>
+ <one-to-one name="address"
+ cascade="all">
+ <formula>name</formula>
+ <formula>'HOME'</formula>
+ </one-to-one>
+ <one-to-one name="mailingAddress"
+ cascade="all">
+ <formula>name</formula>
+ <formula>'MAILING'</formula>
+ </one-to-one>
+</class>
+
+<class name="Address" batch-size="2"
+ check="addressType in ('MAILING', 'HOME', 'BUSINESS')">
+ <composite-id>
+ <key-many-to-one name="person"
+ column="personName"/>
+ <key-property name="type"
+ column="addressType"/>
+ </composite-id>
+ <property name="street" type="text"/>
+ <property name="state"/>
+ <property name="zip"/>
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-composite-key">
+ <title>Composite 키 예제</title>
+<programlisting><![CDATA[<class name="Customer">
+
+ <id name="customerId"
+ length="10">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="name" not-null="true" length="100"/>
+ <property name="address" not-null="true" length="200"/>
+
+ <list name="orders"
+ inverse="true"
+ cascade="save-update">
+ <key column="customerId"/>
+ <index column="orderNumber"/>
+ <one-to-many class="Order"/>
+ </list>
+
+</class>
+
+<class name="Order" table="CustomerOrder" lazy="true">
+ <synchronize table="LineItem"/>
+ <synchronize table="Product"/>
+
+ <composite-id name="id"
+ class="Order$Id">
+ <key-property name="customerId" length="10"/>
+ <key-property name="orderNumber"/>
+ </composite-id>
+
+ <property name="orderDate"
+ type="calendar_date"
+ not-null="true"/>
+
+ <property name="total">
+ <formula>
+ ( select sum(li.quantity*p.price)
+ from LineItem li, Product p
+ where li.productId = p.productId
+ and li.customerId = customerId
+ and li.orderNumber = orderNumber )
+ </formula>
+ </property>
+
+ <many-to-one name="customer"
+ column="customerId"
+ insert="false"
+ update="false"
+ not-null="true"/>
+
+ <bag name="lineItems"
+ fetch="join"
+ inverse="true"
+ cascade="save-update">
+ <key>
+ <column name="customerId"/>
+ <column name="orderNumber"/>
+ </key>
+ <one-to-many class="LineItem"/>
+ </bag>
+
+</class>
+
+<class name="LineItem">
+
+ <composite-id name="id"
+ class="LineItem$Id">
+ <key-property name="customerId" length="10"/>
+ <key-property name="orderNumber"/>
+ <key-property name="productId" length="10"/>
+ </composite-id>
+
+ <property name="quantity"/>
+
+ <many-to-one name="order"
+ insert="false"
+ update="false"
+ not-null="true">
+ <column name="customerId"/>
+ <column name="orderNumber"/>
+ </many-to-one>
+
+ <many-to-one name="product"
+ insert="false"
+ update="false"
+ not-null="true"
+ column="productId"/>
+
+</class>
+
+<class name="Product">
+ <synchronize table="LineItem"/>
+
+ <id name="productId"
+ length="10">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="description"
+ not-null="true"
+ length="200"/>
+ <property name="price" length="3"/>
+ <property name="numberAvailable"/>
+
+ <property name="numberOrdered">
+ <formula>
+ ( select sum(li.quantity)
+ from LineItem li
+ where li.productId = productId )
+ </formula>
+ </property>
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-composite-key-manytomany">
+ <title>공유된 합성 키 속성을 가진 Many-to-many</title>
+<programlisting><![CDATA[<class name="User" table="`User`">
+ <composite-id>
+ <key-property name="name"/>
+ <key-property name="org"/>
+ </composite-id>
+ <set name="groups" table="UserGroup">
+ <key>
+ <column name="userName"/>
+ <column name="org"/>
+ </key>
+ <many-to-many class="Group">
+ <column name="groupName"/>
+ <formula>org</formula>
+ </many-to-many>
+ </set>
+</class>
+
+<class name="Group" table="`Group`">
+ <composite-id>
+ <key-property name="name"/>
+ <key-property name="org"/>
+ </composite-id>
+ <property name="description"/>
+ <set name="users" table="UserGroup" inverse="true">
+ <key>
+ <column name="groupName"/>
+ <column name="org"/>
+ </key>
+ <many-to-many class="User">
+ <column name="userName"/>
+ <formula>org</formula>
+ </many-to-many>
+ </set>
+</class>
+]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-content-discrimination">
+ <title>내용 기반 판별</title>
+<programlisting><![CDATA[<class name="Person"
+ discriminator-value="P">
+
+ <id name="id"
+ column="person_id"
+ unsaved-value="0">
+ <generator class="native"/>
+ </id>
+
+
+ <discriminator
+ type="character">
+ <formula>
+ case
+ when title is not null then 'E'
+ when salesperson is not null then 'C'
+ else 'P'
+ end
+ </formula>
+ </discriminator>
+
+ <property name="name"
+ not-null="true"
+ length="80"/>
+
+ <property name="sex"
+ not-null="true"
+ update="false"/>
+
+ <component name="address">
+ <property name="address"/>
+ <property name="zip"/>
+ <property name="country"/>
+ </component>
+
+ <subclass name="Employee"
+ discriminator-value="E">
+ <property name="title"
+ length="20"/>
+ <property name="salary"/>
+ <many-to-one name="manager"/>
+ </subclass>
+
+ <subclass name="Customer"
+ discriminator-value="C">
+ <property name="comments"/>
+ <many-to-one name="salesperson"/>
+ </subclass>
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-association-alternatekeys" revision="2">
+ <title>대체 키들에 대한 연관들</title>
+<programlisting><![CDATA[<class name="Person">
+
+ <id name="id">
+ <generator class="hilo"/>
+ </id>
+
+ <property name="name" length="100"/>
+
+ <one-to-one name="address"
+ property-ref="person"
+ cascade="all"
+ fetch="join"/>
+
+ <set name="accounts"
+ inverse="true">
+ <key column="userId"
+ property-ref="userId"/>
+ <one-to-many class="Account"/>
+ </set>
+
+ <property name="userId" length="8"/>
+
+</class>
+
+<class name="Address">
+
+ <id name="id">
+ <generator class="hilo"/>
+ </id>
+
+ <property name="address" length="300"/>
+ <property name="zip" length="5"/>
+ <property name="country" length="25"/>
+ <many-to-one name="person" unique="true" not-null="true"/>
+
+</class>
+
+<class name="Account">
+ <id name="accountId" length="32">
+ <generator class="uuid"/>
+ </id>
+
+ <many-to-one name="user"
+ column="userId"
+ property-ref="userId"/>
+
+ <property name="type" not-null="true"/>
+
+</class>]]></programlisting>
+ </sect2>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/example_parentchild.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/example_parentchild.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/example_parentchild.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/example_parentchild.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,343 @@
+<chapter id="example-parentchild">
+ <title>예제: 부모/자식</title>
+
+ <para>
+ 새로운 사용자들이 Hibernate로 행하고자 시도하는 바로 첫 번째 것들 중 하나는 부모/자식 타입의 관계를 모형화 시키는 것이다. 이것에 대한
+ 두 가지 다른 접근법들이 존재한다. 여러가지 이유들로 인해 특히 새로운 사용자들에게 가장 편한 접근법은 <literal>Parent</literal>로부터
+ <literal>Child</literal>로의 <literal><one-to-many></literal> 연관을 가진 엔티티 클래스들로서 <literal>Parent</literal>와
+ <literal>Child</literal> 양자를 모형화 시키는 것이다. (다른 접근법은 <literal>Child</literal>를
+ <literal><composite-element></literal>로 선언하는 것이다.) 이제, (Hibernate에서) one to many 연관에 대한 디폴트
+ 의미는 composite 요소 매핑의 의미보다 부모/자식 관계의 통상적인 의미에 훨씬 덜 가깝다는 것이 판명된다. 우리는 부모/자식 관계를 효율적이고
+ 강력하게 모형화 시키기 위해 <emphasis>케스케이드들을 가진 양방향 one to many 연관</emphasis>을 사용하는 방법을 설명할 것이다.
+ 그것은 전혀 어렵지 않다!
+ </para>
+
+ <sect1 id="example-parentchild-collections">
+ <title>콜렉션들에 관한 노트</title>
+
+ <para>
+ Hibernate 콜렉션들은 그것들의 소유하고 있는 엔티티의 논리적 부분으로 간주된다; 결코 포함된 엔티티들의 부분이 아니다. 이것은
+ 중대한 구분점이다! 그것은 다음은 다음 결과들을 갖는다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ 콜렉션으로부터 객체를 제거하고/콜렉션에 객체를 추가 시킬 때, 콜렉션 소유자의 버전 번호가 증가된다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 콜렉션으로부터 제거되었던 객체가 하나의 값 타입의 인스턴스(예를 들어 composite 요소)이면, 그 객체는 영속상태를 끝내고
+ 그것의 상태가 데이터베이스로부터 완전히 제거될 것이다. 마찬가지로 하나의 값 타입의 인스턴스를 콜렉션에 추가시키는 것은 그것의
+ 상태가 즉시 영속화 되도록 강제시킬 것이다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 반면에, 만일 엔티티가 콜렉션으로부터 제거될 경우(one-to-many 또는 many-to-many 연관), 그것은 디폴트로 삭제되지 않을
+ 것이다. 이 특징은 완전하게 일관적이다 - 다른 엔티티의 내부 상태에 대한 변경은 연관된 엔티티를 사라지도록 강제하지 않을 것이다!
+ 마찬가지로 콜렉션에 엔티티를 추가시키는 것은 디폴트로 그 엔티티가 영속화 되도록 강제시키지 않는다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 대신에 콜렉션으로의 엔티티 추가가 두 엔티티들 사이에 단지 하나의 링크를 생성시키는 반면에, 그것을 제거하는 것은 링크를 제거한다는 점이
+ 디폴트 특징이다. 이것은 모든 종류의 경우들에 대해 매우 적절하다. 그것이 전혀 적절하지 않은 곳은 부모/자식 관계인 경우이고, 여기서
+ 자식의 생애는 부모의 생명주기에 묶여져 있다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-bidir">
+ <title>양방향 one-to-many</title>
+
+ <para>
+ <literal>Parent</literal>로부터 <literal>Child</literal>로의 간단한 <literal><one-to-many></literal>
+ 연관관계로 시작한다고 가정하자.
+ </para>
+
+ <programlisting><![CDATA[<set name="children">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ 우리가 다음 코드를 실행시켰다면
+ </para>
+
+ <programlisting><![CDATA[Parent p = .....;
+Child c = new Child();
+p.getChildren().add(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ <para>
+ Hibernate는 두 개의 SQL 문장들을 실행할 것이다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>c</literal>에 대한 레코드를 생성시키는 <literal>INSERT</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>p</literal>로부터 <literal>c</literal>로의 링크를 생성시키는 <literal>UPDATE</literal></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 이것은 비효율적일 뿐만 아니라, 또한 <literal>parent_id</literal> 컬럼 상의 임의의 <literal>NOT NULL</literal>
+ 컨스트레인트에 위배된다. 우리는 콜렉션 매핑에서 <literal>not-null="true"</literal>를 지정함으로써 null 허용 가능
+ 컨스트레인트 위반을 정정할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<set name="children">
+ <key column="parent_id" not-null="true"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ 하지만 이것은 권장되는 해결책이 아니다.
+ </para>
+ <para>
+ 이 행위의 기본 원인은 <literal>p</literal>로부터 <literal>c</literal>로의 링크(foreign key <literal>parent_id</literal>)가
+ <literal>Child</literal> 객체의 상태의 부분으로 간주되지 않고 그러므로 <literal>INSERT</literal>로 생성되지 않는다는
+ 점이다. 따라서 해결책은 <literal>Child</literal> 매핑의 링크 부분을 만드는 것이다.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="parent" column="parent_id" not-null="true"/>]]></programlisting>
+
+ <para>
+ (우리는 또한 <literal>parent</literal> 프로퍼티를 <literal>Child</literal> 클래스에 추가시킬 필요가 있다.)
+ </para>
+
+ <para>
+ 이제 <literal>Child</literal> 엔티티가 링크의 상태를 관리한다는 점을 노트하고, 우리는 링크를 업데이트 시키지 말도록 콜렉션에게
+ 통보한다. 우리는 <literal>inverse</literal> 속성을 사용한다.
+ </para>
+
+ <programlisting><![CDATA[<set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ 다음 코드는 새로운 <literal>Child</literal>를 추가시키는데 사용될 것이다
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+c.setParent(p);
+p.getChildren().add(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ <para>
+ 그리고 이제, 유일하게 한 개의 SQL <literal>INSERT</literal>가 실행될 것이다!
+ </para>
+
+ <para>
+ 약간 거칠게, 우리는 <literal>Parent</literal>의 <literal>addChild()</literal> 메소드를 생성시킬 수 있다.
+ </para>
+
+ <programlisting><![CDATA[public void addChild(Child c) {
+ c.setParent(this);
+ children.add(c);
+}]]></programlisting>
+
+ <para>
+ 이제, <literal>Child</literal>를 추가하는 코드는 다음과 같다
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+p.addChild(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-cascades">
+ <title>케스케이딩 생명주기</title>
+
+ <para>
+ <literal>save()</literal>에 대한 명시적인 호출은 여전히 성가시다. 우리는 케스케이딩을 사용하여 이것을 얘기할 것이다.
+ </para>
+
+ <programlisting><![CDATA[<set name="children" inverse="true" cascade="all">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ 다음은 위의 코드를 단순화 시킨다
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+p.addChild(c);
+session.flush();]]></programlisting>
+
+ <para>
+ 유사하게, 우리는 <literal>Parent</literal>를 저장하거나 삭제할 때 자식들에 대해 반복하는 것을 필요로 하지 않는다. 다음은
+ 데이터베이스로부터 <literal>p</literal>와 모든 그것의 자식들을 제거시킨다.
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+session.delete(p);
+session.flush();]]></programlisting>
+
+ <para>
+ 하지만, 다음 코드
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = (Child) p.getChildren().iterator().next();
+p.getChildren().remove(c);
+c.setParent(null);
+session.flush();]]></programlisting>
+
+ <para>
+ 는 데이터베이스로부터 <literal>c</literal>를 제거하지 않을 것이다; 그것은 오직 <literal>p</literal>에 대한 링크만을 제거할
+ 것이다(그리고 이 경우에 <literal>NOT NULL</literal> 컨스트레인트 위반을 일으킬 것이다 ). 당신은 명시적으로
+ <literal>Child</literal>를 <literal>delete()</literal> 시킬 필요가 있다.
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = (Child) p.getChildren().iterator().next();
+p.getChildren().remove(c);
+session.delete(c);
+session.flush();]]></programlisting>
+
+ <para>
+ 이제 우리의 경우에 <literal>Child</literal>는 그것의 부모 없이는 진정으로 존재할 수 없다. 따라서 만일 우리가 콜렉션으로부터
+ 하나의 <literal>Child</literal>를 제거할 경우, 우리는 그것이 정말로 삭제되기를 원한다. 이를 위해 우리는
+ <literal>cascade="all-delete-orphan"</literal>을 사용해야 한다.
+ </para>
+
+ <programlisting><![CDATA[<set name="children" inverse="true" cascade="all-delete-orphan">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ 노트: 비록 콜렉션 매핑이 <literal>inverse="true"</literal>를 지정할 지라도, 케스케이드들은 여전히 콜렉션 요소들을
+ 반복함으로써 처리된다. 따라서 객체가 케스케이드에 의해 저장되고, 삭제되거나 업데이트 되는 것을 당신이 필요로 할 경우, 당신은
+ 그것을 그 콜렉션에 추가해야 한다. 단순히 <literal>setParent()</literal>를 호출하는 것으로는 충분하지 않다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-update">
+ <title>케스케이드들과 <literal>unsaved-value</literal></title>
+
+ <para>
+ 우리가 하나의 <literal>Session</literal> 속에 <literal>Parent</literal>를 로드시켰고 UI 액션에서 어떤 변경들을 행했고,
+ <literal>update()</literal>를 호출하여 새로운 세션에서 이들 변경들을 영속화 시키는 것을 원한다고 가정하자. <literal>Parent</literal>는
+ 자식들을 가진 콜렉션을 포함할 것이고, 케스케이딩 업데이트가 사용 가능하기 때문에, Hibernate는 어느 자식들이 새로이 초기화 되는지
+ 그리고 어느 것이 데이터베이스에서 현재 행들을 표현하는지를 알 필요가 있다. <literal>Parent</literal>와 <literal>Child</literal>
+ 모두 <literal>Long</literal> 타입의 식별자 프로퍼티들을 생성시켰다고 가정하자. Hibernate는 어느 자식들이 새로운 것인지를
+ 결정하는데 식별자와 version/timestamp 프로퍼티 값을 사용할 것이다.(<xref linkend="objectstate-saveorupdate"/>을 보라.)
+ <emphasis>Hibernate3에서는<literal>unsaved-value</literal>를 더이상 명시적으로 지정할 필요가 없다.</emphasis>
+ </para>
+
+ <para>
+ 다음 코드는 <literal>parent</literal>와 <literal>child</literal>를 업데이트하고 <literal>newChild</literal>를
+ 삽입시킬 것이다.
+ </para>
+
+ <programlisting><![CDATA[//parent and child were both loaded in a previous session
+parent.addChild(child);
+Child newChild = new Child();
+parent.addChild(newChild);
+session.update(parent);
+session.flush();]]></programlisting>
+
+ <para>
+ 물론 그것은 생성되는 식별자의 경우에는 모두 매우 좋지만, 할당되는 식별자들과 composite 식별자들에 대해서는 어떠한가? 이것은 보다
+ 어렵다. 왜냐하면 Hibernate는 (사용자에 의해 할당된 식별자를 가진) 새로이 초기화 된 객체와 이전 세션에서 로드되었던 객체 사이를
+ 구별짓는데 식별자 프로퍼티를 사용할 수 없기 때문이다. 이 경우에, Hibernate는 timestamp 프로퍼티 또는 version 프로퍼티를
+ 사용하거나 실제로 second-level 캐시를 질의하거나 가장 나쁜 경우에는 행이 존재하는지를 알기 위해 데이터베이스를 질의할 것이다.
+ </para>
+
+ <!-- undocumenting
+ <para>
+ There is one further possibility. The <literal>Interceptor</literal> method named
+ <literal>isUnsaved()</literal> lets the application implement its own strategy for distinguishing
+ newly instantiated objects. For example, you could define a base class for your persistent classes.
+ </para>
+
+ <programlisting><![CDATA[public class Persistent {
+ private boolean _saved = false;
+ public void onSave() {
+ _saved=true;
+ }
+ public void onLoad() {
+ _saved=true;
+ }
+ ......
+ public boolean isSaved() {
+ return _saved;
+ }
+}]]></programlisting>
+
+ <para>
+ (The <literal>saved</literal> property is non-persistent.)
+ Now implement <literal>isUnsaved()</literal>, along with <literal>onLoad()</literal>
+ and <literal>onSave()</literal> as follows.
+ </para>
+
+ <programlisting><![CDATA[public Boolean isUnsaved(Object entity) {
+ if (entity instanceof Persistent) {
+ return new Boolean( !( (Persistent) entity ).isSaved() );
+ }
+ else {
+ return null;
+ }
+}
+
+public boolean onLoad(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if (entity instanceof Persistent) ( (Persistent) entity ).onLoad();
+ return false;
+}
+
+public boolean onSave(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if (entity instanceof Persistent) ( (Persistent) entity ).onSave();
+ return false;
+}]]></programlisting>
+
+ <para>
+ Don't worry; in Hibernate3 you don't need to write any of this kind of code if you don't want to.
+ </para>
+ -->
+ </sect1>
+
+ <sect1 id="example-parentchild-conclusion">
+ <title>결론</title>
+
+ <para>
+ 여기에 숙지할 것이 약간 있고 그것은 처음에는 혼동스러운 것처럼 보일 수 있다. 하지만 실제로 그것은 모두 매우 좋게 동작한다. 대부분의
+ Hibernate 어플리케이션들은 많은 장소들에서 부모/자식 패턴을 사용한다.
+ </para>
+
+ <para>
+ 우리는 첫 번째 단락에서 대안을 언급했다. 위의 쟁점들 중 어느 것도 정확하게 부모/자식 관계의 의미를 가진,
+ <literal><composite-element></literal> 매핑들의 경우에는 존재하지 않는다. 불행히도, composite 요소 클래스들에
+ 대한 두 개의 커다란 제약들이 존재한다: composite 요소들은 콜렉션들을 소유하지 않고, 그것들은 유일한 부모가 아닌 다른 어떤
+ 엔티티의 자식일 수는 없다.
+ </para>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/example_weblog.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/example_weblog.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/example_weblog.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/example_weblog.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,428 @@
+<chapter id="example-weblog">
+ <title>예제: Weblog 어플리케이션</title>
+
+ <sect1 id="example-weblog-classes">
+ <title>영속 클래스들</title>
+
+ <para>
+ 영속 클래스들은 웹로그, 그리고 웹 로그 내에 게시된 항목을 표현한다.그것들은
+ 표준 부모/자식 관계로 모형화 될 것이지만, 우리는 set 대신에 순서지워진 bag를 사용할 것이다.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+import java.util.List;
+
+public class Blog {
+ private Long _id;
+ private String _name;
+ private List _items;
+
+ public Long getId() {
+ return _id;
+ }
+ public List getItems() {
+ return _items;
+ }
+ public String getName() {
+ return _name;
+ }
+ public void setId(Long long1) {
+ _id = long1;
+ }
+ public void setItems(List list) {
+ _items = list;
+ }
+ public void setName(String string) {
+ _name = string;
+ }
+}]]></programlisting>
+
+ <programlisting><![CDATA[package eg;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+
+public class BlogItem {
+ private Long _id;
+ private Calendar _datetime;
+ private String _text;
+ private String _title;
+ private Blog _blog;
+
+ public Blog getBlog() {
+ return _blog;
+ }
+ public Calendar getDatetime() {
+ return _datetime;
+ }
+ public Long getId() {
+ return _id;
+ }
+ public String getText() {
+ return _text;
+ }
+ public String getTitle() {
+ return _title;
+ }
+ public void setBlog(Blog blog) {
+ _blog = blog;
+ }
+ public void setDatetime(Calendar calendar) {
+ _datetime = calendar;
+ }
+ public void setId(Long long1) {
+ _id = long1;
+ }
+ public void setText(String string) {
+ _text = string;
+ }
+ public void setTitle(String string) {
+ _title = string;
+ }
+}]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-weblog-mappings">
+ <title>Hibernate 매핑들</title>
+
+ <para>
+ XML 매핑들은 이제 매우 간단해질 것이다.
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class
+ name="Blog"
+ table="BLOGS">
+
+ <id
+ name="id"
+ column="BLOG_ID">
+
+ <generator class="native"/>
+
+ </id>
+
+ <property
+ name="name"
+ column="NAME"
+ not-null="true"
+ unique="true"/>
+
+ <bag
+ name="items"
+ inverse="true"
+ order-by="DATE_TIME"
+ cascade="all">
+
+ <key column="BLOG_ID"/>
+ <one-to-many class="BlogItem"/>
+
+ </bag>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class
+ name="BlogItem"
+ table="BLOG_ITEMS"
+ dynamic-update="true">
+
+ <id
+ name="id"
+ column="BLOG_ITEM_ID">
+
+ <generator class="native"/>
+
+ </id>
+
+ <property
+ name="title"
+ column="TITLE"
+ not-null="true"/>
+
+ <property
+ name="text"
+ column="TEXT"
+ not-null="true"/>
+
+ <property
+ name="datetime"
+ column="DATE_TIME"
+ not-null="true"/>
+
+ <many-to-one
+ name="blog"
+ column="BLOG_ID"
+ not-null="true"/>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-weblog-code">
+ <title>Hibernate 코드</title>
+
+ <para>
+ 다음 클래스는 우리가 Hibernate를 사용하여 이들 클래스들로 행할 수 있는 몇몇 종류의 것들을 설명한다.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.tool.hbm2ddl.SchemaExport;
+
+public class BlogMain {
+
+ private SessionFactory _sessions;
+
+ public void configure() throws HibernateException {
+ _sessions = new Configuration()
+ .addClass(Blog.class)
+ .addClass(BlogItem.class)
+ .buildSessionFactory();
+ }
+
+ public void exportTables() throws HibernateException {
+ Configuration cfg = new Configuration()
+ .addClass(Blog.class)
+ .addClass(BlogItem.class);
+ new SchemaExport(cfg).create(true, true);
+ }
+
+ public Blog createBlog(String name) throws HibernateException {
+
+ Blog blog = new Blog();
+ blog.setName(name);
+ blog.setItems( new ArrayList() );
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.persist(blog);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return blog;
+ }
+
+ public BlogItem createBlogItem(Blog blog, String title, String text)
+ throws HibernateException {
+
+ BlogItem item = new BlogItem();
+ item.setTitle(title);
+ item.setText(text);
+ item.setBlog(blog);
+ item.setDatetime( Calendar.getInstance() );
+ blog.getItems().add(item);
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.update(blog);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return item;
+ }
+
+ public BlogItem createBlogItem(Long blogid, String title, String text)
+ throws HibernateException {
+
+ BlogItem item = new BlogItem();
+ item.setTitle(title);
+ item.setText(text);
+ item.setDatetime( Calendar.getInstance() );
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ Blog blog = (Blog) session.load(Blog.class, blogid);
+ item.setBlog(blog);
+ blog.getItems().add(item);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return item;
+ }
+
+ public void updateBlogItem(BlogItem item, String text)
+ throws HibernateException {
+
+ item.setText(text);
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.update(item);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ }
+
+ public void updateBlogItem(Long itemid, String text)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ BlogItem item = (BlogItem) session.load(BlogItem.class, itemid);
+ item.setText(text);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ }
+
+ public List listAllBlogNamesAndItemCounts(int max)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ List result = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "select blog.id, blog.name, count(blogItem) " +
+ "from Blog as blog " +
+ "left outer join blog.items as blogItem " +
+ "group by blog.name, blog.id " +
+ "order by max(blogItem.datetime)"
+ );
+ q.setMaxResults(max);
+ result = q.list();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return result;
+ }
+
+ public Blog getBlogAndAllItems(Long blogid)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ Blog blog = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "from Blog as blog " +
+ "left outer join fetch blog.items " +
+ "where blog.id = :blogid"
+ );
+ q.setParameter("blogid", blogid);
+ blog = (Blog) q.uniqueResult();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return blog;
+ }
+
+ public List listBlogsAndRecentItems() throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ List result = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "from Blog as blog " +
+ "inner join blog.items as blogItem " +
+ "where blogItem.datetime > :minDate"
+ );
+
+ Calendar cal = Calendar.getInstance();
+ cal.roll(Calendar.MONTH, false);
+ q.setCalendar("minDate", cal);
+
+ result = q.list();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return result;
+ }
+}]]></programlisting>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/filters.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/filters.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/filters.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/filters.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,138 @@
+<chapter id="filters">
+ <title>데이터 필터링하기</title>
+
+ <para>
+ Hibernate3은 혁신적인 "가시성(visibility)" 규칙들로서 데이터를 처리하는 새로운 접근법을 제공한다. <emphasis>Hibernate
+ 필터</emphasis>는 특정 Hibernate 세션에 대해 이용 가능하게 되거나 이용 불가능하게 될 수도 있는 전역, 명명된 파라미터화 된 필터이다.
+ </para>
+
+ <sect1 id="objectstate-filters" revision="1">
+ <title>Hibernate 필터들</title>
+
+ <para>
+ Hibernate3은 필터 기준(criteria)을 미리 정의하고 클래스 레벨과 콜렉션 레벨 양자에서 그들 필터들을 첨부할 능력을 추가시킨다.
+ 필터 기준(criteria)은 클래스 요소와 다양한 콜렉션 요소들에 대해 이용 가능한 기존의 "where" 속성과 매우 유사한 하나의 제한 절을
+ 정의하는 능력이다. 이것들을 제외하면 필터 조건들은 파라미터화 될 수 있다. 그때 어플리케이션은 주어진 필터들이 이용 가능한지 여부
+ 그리고 그들 파라미터 값들이 무엇이어야 하는지를 실행 시에 결정할 수 있다. 필터들은 데이터베이스 뷰들 처럼 사용될 수 있지만,
+ 어플리케이션 내부에 파라미터화 된다.
+ </para>
+
+ <para>
+ 필터들을 사용하기 위해서, 그것들은 먼저 정의되고 나서 적절한 매핑 요소들에 첨가되어야 한다. 필터를 정의하기 위해,
+ <literal><hibernate-mapping/></literal> 요소 내부에 <literal><filter-def/></literal> 요소를
+ 사용하라:
+ </para>
+
+ <programlisting><![CDATA[<filter-def name="myFilter">
+ <filter-param name="myFilterParam" type="string"/>
+</filter-def>]]></programlisting>
+
+ <para>
+ 그때 이 필터는 클래스에 첨가될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<class name="myClass" ...>
+ ...
+ <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/>
+</class>]]></programlisting>
+
+ <para>
+ 또는 콜렉션에 첨가될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<set ...>
+ <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/>
+</set>]]></programlisting>
+
+ <para>
+ 또는 동시에 양자에(또는 각각의 여러번) 첨가될 수 있다.
+ </para>
+
+ <para>
+ <literal>Session</literal> 상의 메소드들은 다음과 같다: <literal>enableFilter(String filterName)</literal>,
+ <literal>getEnabledFilter(String filterName)</literal>, <literal>disableFilter(String filterName)</literal>.
+ 디폴트로, 필터들은 주어진 세션에 대해 이용 가능하지 <emphasis>않다</emphasis>; 그것들은 <literal>Session.enabledFilter()</literal>
+ 메소드의 사용을 통해 명시적으로 이용 가능하게 되어야 한다. <literal>Session.enabledFilter()</literal>는
+ <literal>Filter</literal> 인터페이스의 인스턴스를 반환한다. 위에 정의된 간단한 필터를 사용하면, 이것은 다음과 같을 것이다:
+ </para>
+
+ <programlisting><![CDATA[session.enableFilter("myFilter").setParameter("myFilterParam", "some-value");]]></programlisting>
+
+ <para>
+ org.hibernate.Filter 인터페이스 상의 메소드들은 Hibernate에 매우 공통된 method-chaining을 허용한다는 점을 노트하라.
+ </para>
+
+ <para>
+ 유효한 기록 날짜 패턴을 가진 시간 데이터를 사용하는 전체 예제 :
+ </para>
+
+ <programlisting><![CDATA[<filter-def name="effectiveDate">
+ <filter-param name="asOfDate" type="date"/>
+</filter-def>
+
+<class name="Employee" ...>
+...
+ <many-to-one name="department" column="dept_id" class="Department"/>
+ <property name="effectiveStartDate" type="date" column="eff_start_dt"/>
+ <property name="effectiveEndDate" type="date" column="eff_end_dt"/>
+...
+ <!--
+ Note that this assumes non-terminal records have an eff_end_dt set to
+ a max db date for simplicity-sake
+ -->
+ <filter name="effectiveDate"
+ condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
+</class>
+
+<class name="Department" ...>
+...
+ <set name="employees" lazy="true">
+ <key column="dept_id"/>
+ <one-to-many class="Employee"/>
+ <filter name="effectiveDate"
+ condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ 그때 당신이 현재 유효한 레코드들을 항상 얻는 것을 확실히 하기 위해, employee 데이터를 검색하기 전에 세션 상에 필터를
+ 간단하게 이용 가능하게 하라:
+ </para>
+
+<programlisting><![CDATA[Session session = ...;
+session.enabledFilter("effectiveDate").setParameter("asOfDate", new Date());
+List results = session.createQuery("from Employee as e where e.salary > :targetSalary")
+ .setLong("targetSalary", new Long(1000000))
+ .list();
+]]></programlisting>
+
+ <para>
+ 위의 HQL 에서, 심지어 비록 우리가 결과들에 대한 봉급 컨스트레인트를 명시적으로 언급만 했을지라도, 이용 가능한 필터 때문에
+ 그 질의는 봉급이 백만달러 이상인 현재 채용중인 직원들만을 반환할 것이다.
+ </para>
+
+ <para>
+ 노트: 만일 당신이 outer 조인에 대해 필터들을 사용할 계획이라면 (HQL이든 로드 페칭이든) 조건 표현식의 방향을 주의하라.
+ 이것을 left outer join으로 설정하는 것이 가장 안전하다; 일반적으로 오퍼레이터 뒤에 있는 컬럼 이름(들)이 뒤따르는 첫번째에
+ 파라미터를 위치지워라.
+ </para>
+
+ </sect1>
+
+ <para>
+ 필터가 정의된 후에는 그것 자신의 조건에 대해 각각 여러 개의 엔티티들 그리고/또는 콜렉션들에 첨가될 수 있다.
+ 조건들이 매번 동일할 때 그것은 지루할 수 있다. 따라서 <literal><filter-def/></literal>은
+ attribute 든 CDATA 든 어느것이든 디폴트 조건을 정의하는 것을 허용해준다:
+ </para>
+
+ <programlisting><![CDATA[<filter-def name="myFilter" condition="abc > xyz">...</filter-def>
+<filter-def name="myOtherFilter">abc=xyz</filter-def>]]></programlisting>
+
+ <para>
+ 그때 이 디폴트 조건은 그 필터가 어떤 조건을 지정함이 없이 어떤 것에 첨가될때마다 사용될 수 있다.
+ 이것은 당신이 특정한 경우에 디폴트 조건을 오버라이드 시키는 필터의 첨가 부분으로서 특정 조건을
+ 부여할 수 있음을 의미함을 노트하라.
+ </para>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/inheritance_mapping.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/inheritance_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/inheritance_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/inheritance_mapping.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,459 @@
+<chapter id="inheritance">
+ <title>상속 매핑</title>
+
+ <sect1 id="inheritance-strategies" revision="3">
+ <title>세 가지 방도들</title>
+
+ <para>
+ Hibernate는 세 가지 기본적인 상속 매핑 방도들을 지원한다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ table per class hierarchy
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ table per subclass
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ table per concrete class
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 게다가 Hibernate는 네 번째의 약간 다른 종류의 다형성을 지원한다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ implicit polymorphism(함축적인 다형성)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 동일한 상속 계층구조의 다른 가지들에 대해 다른 매핑 방도들을 사용하는 것이 가능하고, 그런 다음 전체 계층 구조를 가로질러
+ 다형성을 성취하는데 함축적인 다형성을 사용하라. 하지만 Hibernate는 동일한 루트 <literal><class></literal> 요소
+ 하에서 <literal><subclass></literal> 그리고 <literal><joined-subclass></literal> 그리고
+ <literal><union-subclass></literal> 매핑들을 혼합하는 것을 지원하지 않는다. 동일한 <literal><class></literal>
+ 요소 하에서 <literal><subclass></literal> 요소와 <literal><join></literal> 요소를 결합시킴으로써
+ table per hierarchy 방도와 table per subclass 방도를 함께 혼합시키는 것이 가능하다(아래를 보라).
+ </para>
+
+ <para>
+ 별도의 매핑 문서 내에, <literal>hibernate-mapping</literal> 바로 밑에 <literal>subclass</literal>,
+ <literal>union-subclass</literal>, 그리고 <literal>joined-subclass</literal> 매핑들을 정의하는 것이
+ 가능하다. 이것은 단지 하나의 새로운 매핑 파일을 추가시켜서 하나의 class 계층구조를 확장하는 것을 당신에게 허용해준다.
+ 당신은 subclass 매핑 내에 앞서 매핑된 슈퍼클래스를 명명하여 <literal>extends</literal> 속성을 지정해야 한다.
+ 노트 : 명백하게 이 특징은 매핑 문서들의 순서를 중요하게끔 만들었다. Hibernate3 이후로, 매핑 파일들의 순서는 extends 키워드를
+ 사용할 때 상관없다. 하나의 매핑 파일 내의 순서는 여전히 서브클래스들에 앞서 슈퍼클래스들을 정의하는데 여전히 필요하다.
+ </para>
+
+ <programlisting><![CDATA[
+ <hibernate-mapping>
+ <subclass name="DomesticCat" extends="Cat" discriminator-value="D">
+ <property name="name" type="string"/>
+ </subclass>
+ </hibernate-mapping>]]></programlisting>
+
+
+ <sect2 id="inheritance-tableperclass" >
+ <title>Table per class hierarchy</title>
+
+ <para>
+ 우리가 <literal>CreditCardPayment</literal>, <literal>CashPayment</literal>, <literal>ChequePayment</literal>
+ 구현자들을 가진 하나의 인터페이스 <literal>Payment</literal>를 갖고 있다고 가정하자. table per hierarchy 매핑은
+ 다음과 같을 것이다:
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ ...
+ </subclass>
+ <subclass name="ChequePayment" discriminator-value="CHEQUE">
+ ...
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ 정확히 하나의 테이블이 필요하다. 이 매핑 방도에는 다음의 하나의 큰 제약이 존재한다: <literal>CCTYPE</literal>과 같이,
+ 서브 클래스들에 의해 선언된 컬럼들은 <literal>NOT NULL</literal> 컨스트레인트들을 가질 수 없다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tablepersubclass">
+ <title>Table per subclass</title>
+
+ <para>
+ table per subclass 매핑은 다음과 같을 것이다:
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="CashPayment" table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </joined-subclass>
+</class>]]></programlisting>
+
+ <para>
+ 네 개의 테이블들이 필요하다. 세 개의 서브클래스 테이블들은 슈퍼클래스 테이블에 대한 프라이머리 키 연관들을 갖는다
+ (따라서 그 관계형 모형은 실제로 one-to-one 연관이다).
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tablepersubclass-discriminator" revision="2">
+ <title>discriminator를 사용하는, table per subclass</title>
+
+ <para>
+ table-per-subclass에 대한 Hibernate의 구현은 discriminator(판별자) 컬럼을 필요로 하지 않음을 노트하라.
+ 다른 객체/관계형 매핑기들은 슈퍼클래스 테이블 속에 하나의 타입 판별자 컬럼을 필요로 하는 table-per-subclass에 대한 다른 구현을
+ 사용한다. Hibernate에 의해 채택된 접근법은 구현하기가 훨씬 더 어렵지만 관계형 관점에서는 아마 틀림없이 보다 더 정확하다.
+ 만일 당신이 table per subclass 방도에 대해 하나의 판별자 컬럼을 사용하고 싶다면, 당신은 다음과 같이
+ <literal><subclass></literal>와 <literal><join></literal>의 사용을 결합시킬 수도 있다:
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+ <join table="CREDIT_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ <join table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="ChequePayment" discriminator-value="CHEQUE">
+ <join table="CHEQUE_PAYMENT" fetch="select">
+ <key column="PAYMENT_ID"/>
+ ...
+ </join>
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ 선택적인 <literal>fetch="select"</literal> 선언은 슈퍼클래스를 질의할 때 outer join을 사용하여
+ <literal>ChequePayment</literal> 서브클래스 데이터를 페치시키지 않도록 Hibernate에게 알려준다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-mixing-tableperclass-tablepersubclass">
+ <title>table per class hierarchy와 table per subclass를 혼합하기</title>
+
+ <para>
+ 당신은 이 접근법을 사용하여 table per hierarchy 방도와 table per subclass 방도를 혼합시킬 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+ <join table="CREDIT_PAYMENT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ ...
+ </subclass>
+ <subclass name="ChequePayment" discriminator-value="CHEQUE">
+ ...
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ 이들 매핑 방도들 중 어떤 것에 대해, 루트 <literal>Payment</literal> 클래스에 대한 하나의 다형성 연관은
+ <literal><many-to-one></literal>을 사용하여 매핑된다.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="payment" column="PAYMENT_ID" class="Payment"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="inheritance-tableperconcrete" revision="2">
+ <title>Table per concrete class</title>
+
+ <para>
+ 우리가 table per concrete class 방도 매핑에 대해 취할 수 있는 두 가지 방법들이 존재한다. 첫 번째는
+ <literal><union-subclass></literal>를 사용하는 것이다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="sequence"/>
+ </id>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </union-subclass>
+ <union-subclass name="CashPayment" table="CASH_PAYMENT">
+ ...
+ </union-subclass>
+ <union-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+ ...
+ </union-subclass>
+</class>]]></programlisting>
+
+ <para>
+ 세 개의 테이블들이 슈퍼클래스들에 대해 수반된다. 각각의 테이블은 상속된 프로퍼티들을 포함하여, 그 클래스의 모든 프로퍼티들에 대한 컬럼들을 정의한다.
+ </para>
+
+ <para>
+ 이 접근법의 제약은 만일 하나의 프로퍼티가 슈퍼클래스 상으로 매핑될 경우, 그 컬럼 이름이 모든 서브클래스 테이블들 상에서 같아야 한다는
+ 점이다.(장래의 Hibernate 배포본에서 우리는 이 제약을 풀 수도 있다.) identity 생성기 방도는 union 서브클래스 상속에서 허용되지
+ 않으며, 진정 프라이머리 키 시드는 하나의 계층구조의 모든 unioned 서브클래스들을 가로질러 공유되어야 한다.
+ </para>
+
+ <para>
+ 만일 당신의 슈퍼클래스가 abstract일 경우에, 그것을 <literal>abstract="true"</literal>로 매핑하라.
+ 물론 만일 그것이 abstract가 아닐 경우, 추가적인 테이블(위의 예제에서는 디폴트로 <literal>PAYMENT</literal>)이
+ 슈퍼클래스의 인스턴스들을 소유하는데 필요하다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tableperconcreate-polymorphism">
+ <title>함축적인 다형성을 사용하는, table per concrete class</title>
+
+ <para>
+ 대안적인 접근법은 함축적인 다형성을 사용하는 것이다:
+ </para>
+
+ <programlisting><![CDATA[<class name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <id name="id" type="long" column="CREDIT_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CREDIT_AMOUNT"/>
+ ...
+</class>
+
+<class name="CashPayment" table="CASH_PAYMENT">
+ <id name="id" type="long" column="CASH_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CASH_AMOUNT"/>
+ ...
+</class>
+
+<class name="ChequePayment" table="CHEQUE_PAYMENT">
+ <id name="id" type="long" column="CHEQUE_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CHEQUE_AMOUNT"/>
+ ...
+</class>]]></programlisting>
+
+ <para>
+ 어느 곳에서도 우리가 명시적으로 <literal>Payment</literal> 인터페이스를 언급하지 않음을 주목하라.
+ 또한 <literal>Payment</literal>의 프로퍼티들이 서브클래스들 각각에서 매핑된다는 점을 주목하라.
+ 만일 당신이 중복을 피하고자 원한다면, XML 엔티티들을 사용하는 것을 고려하라(예를 들어 매핑에서
+ <literal>DOCTYPE</literal> 선언과 <literal>&allproperties;</literal>에서
+ <literal>[ <!ENTITY allproperties SYSTEM "allproperties.xml"> ]</literal>).
+ </para>
+
+ <para>
+ 이 접근법의 단점은 다형성 질의들을 수행할 때 Hibernate가 생성된 SQl <literal>UNION</literal>들을 생성시키는
+ 않는다는 점이다.
+ </para>
+
+ <para>
+ 이 매핑 방도의 경우, <literal>Payment</literal>에 대한 하나의 다형성 연관은 대개 <literal><any></literal>를
+ 사용하여 매핑된다.
+ </para>
+
+ <programlisting><![CDATA[<any name="payment" meta-type="string" id-type="long">
+ <meta-value value="CREDIT" class="CreditCardPayment"/>
+ <meta-value value="CASH" class="CashPayment"/>
+ <meta-value value="CHEQUE" class="ChequePayment"/>
+ <column name="PAYMENT_CLASS"/>
+ <column name="PAYMENT_ID"/>
+</any>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="inheritace-mixingpolymorphism">
+ <title>함축적인 다형성을 다른 상속 매핑들과 혼합하기</title>
+
+ <para>
+ 이 매핑에 대해 주목할 하나 이상의 것이 존재한다. 서브클래스들이 그것들 자신의<literal><class></literal> 요소 내에
+ 각각 매핑되므로(그리고 <literal>Payment</literal>가 단지 인터페이스이므로), 서브클래스들 각각은 쉽게 또 다른 상속 계층구조의
+ 부분일 수 있다! (그리고 당신은 <literal>Payment</literal> 인터페이스에 대해 여전히 다형성 질의들을 사용할 수 있다.)
+ </para>
+
+ <programlisting><![CDATA[<class name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <id name="id" type="long" column="CREDIT_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="CREDIT_CARD" type="string"/>
+ <property name="amount" column="CREDIT_AMOUNT"/>
+ ...
+ <subclass name="MasterCardPayment" discriminator-value="MDC"/>
+ <subclass name="VisaPayment" discriminator-value="VISA"/>
+</class>
+
+<class name="NonelectronicTransaction" table="NONELECTRONIC_TXN">
+ <id name="id" type="long" column="TXN_ID">
+ <generator class="native"/>
+ </id>
+ ...
+ <joined-subclass name="CashPayment" table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="amount" column="CASH_AMOUNT"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="amount" column="CHEQUE_AMOUNT"/>
+ ...
+ </joined-subclass>
+</class>]]></programlisting>
+
+ <para>
+ 다시 한번, 우리는 <literal>Payment</literal>를 명시적으로 언급하지 않는다. 만일 우리가 <literal>Payment</literal>
+ 인터페이스에 대해 하나의 질의를 실행할 경우-예를 들어, from Payment-, Hibernate는 <literal>CreditCardPayment</literal>
+ (와 그것의 서브클래스들, 왜냐하면 그것들 또한 <literal>Payment</literal>를 구현하므로), <literal>CashPayment</literal>
+ 그리고 <literal>ChequePayment</literal> 인스턴스들을 자동적으로 반환할 것이지만
+ <literal>NonelectronicTransaction</literal>의 인스턴스들을 반환하지 않는다.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="inheritance-limitations">
+ <title>제약들</title>
+
+ <para>
+ table per concrete-class 매핑 방도에 대한 "함축적인 다형성" 접근법에는 어떤 제약들이 존재한다.
+ <literal><union-subclass></literal> 매핑들에 대해서는 다소 덜 제한적인 제약들이 존재한다:
+ </para>
+
+ <para>
+ 다음 표는 Hibernate에서 table per concrete-class 매핑들에 대한 제약들, 그리고 함축적인 다형성에 대한 제약들을 보여준다.
+ </para>
+
+ <table frame="topbot">
+ <title>상속 매핑들의 특징들</title>
+ <tgroup cols='8' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="1*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <colspec colname='c6' colwidth="1*"/>
+ <colspec colname='c7' colwidth="1*"/>
+ <colspec colname='c8' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>상속 방도</entry>
+ <entry>다형성 다대일</entry>
+ <entry>다형성 일대일</entry>
+ <entry>다형성 일대다</entry>
+ <entry>다형성 다대다</entry>
+ <entry>다형성 <literal>load()/get()</literal></entry>
+ <entry>다형성 질의들</entry>
+ <entry>다형성 조인들</entry>
+ <entry>Outer 조인 페칭</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>table per class-hierarchy</entry>
+ <entry><literal><many-to-one></literal></entry>
+ <entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal></entry>
+ <entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class, id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment p</literal></entry>
+ <entry><emphasis>지원됨</emphasis></entry>
+ </row>
+ <row>
+ <entry>table per subclass</entry>
+ <entry><literal><many-to-one></literal></entry>
+ <entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal></entry>
+ <entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class, id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment p</literal></entry>
+ <entry><emphasis>지원됨</emphasis></entry>
+ </row>
+ <row>
+ <entry>table per concrete-class (union-subclass)</entry>
+ <entry><literal><many-to-one></literal></entry>
+ <entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal> (for <literal>inverse="true"</literal> only)</entry>
+ <entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class, id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment p</literal></entry>
+ <entry><emphasis>지원됨</emphasis></entry>
+ </row>
+ <row>
+ <entry>table per concrete class (implicit polymorphism)</entry>
+ <entry><literal><any></literal></entry>
+ <entry><emphasis>지원되지 않음</emphasis></entry>
+ <entry><emphasis>지원되지 않음</emphasis></entry>
+ <entry><literal><many-to-any></literal></entry>
+ <entry><literal>s.createCriteria(Payment.class).add( Restrictions.idEq(id) ).uniqueResult()</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><emphasis>지원되지 않음</emphasis></entry>
+ <entry><emphasis>지원되지 않음</emphasis></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/performance.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/performance.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/performance.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/performance.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,1293 @@
+<chapter id="performance">
+ <title>퍼포먼스 개선하기</title>
+
+ <sect1 id="performance-fetching" revision="2">
+ <title>페칭 방도들</title>
+
+ <para>
+ <emphasis>페칭 방도</emphasis>는 어플리케이션이 연관을 네비게이트할 필요가 있을 때 Hibernate가 연관된 객체들을 검색하는데
+ 사용하게 될 방도이다.페치 방도들은 O/R 매핑 메타데이터 내에서 선언될 수 있거나 하나의 특정 HQL 또는 <literal>Criteria</literal>
+ 질의에 의해 오버라이드 될 수도 있다.
+ </para>
+
+ <para>
+ Hibernate3는 다음 페칭 방도들을 정의한다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Join 페칭</emphasis> - Hibernate는 <literal>OUTER JOIN</literal>을 사용하여 연관된 인스턴스
+ 또는 동일한 <literal>SELECT</literal> 내에서 콜렉션을 검색한다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Select 페칭</emphasis> - 두 번째 <literal>SELECT</literal>는 연과된 엔티티 또는 콜렉션을 검색하는데
+ 사용된다. 당신이 <literal>lazy="false"</literal>를 지정함으로써 명시적으로 lazy 페칭을 사용 불가능하게 하지 않는
+ 한, 이 두 번째 select는 당신이 그 연관에 실제로 액세스할 때 오직 실행될 것이다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Subselect 페칭</emphasis> - 두 번째 <literal>SELECT</literal>는 이전 질의 또는 페치에서 검색된
+ 모든 엔티티들에 대해 연관된 콜렉션들을 검색하는데 사용된다. 당신이 <literal>lazy="false"</literal>를 지정하여
+ 명시적으로 lazy 페칭을 사용 불가능하게 하지 않는 한, 이 두 번째 select는 당신이 실제로 그 연관에 접근할 때 오직 실행될
+ 것이다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Batch 페칭</emphasis> - select 페칭을 위한 최적화 방도 - Hibernate는 프라이머리 키들이나 foreign
+ 키들의 리스트를 지정함으로써 하나의<literal>SELECT</literal> 내에서 엔티티 인스턴스들이나 콜렉션들에 대한 batch를
+ 검색한다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate는 또한 다음 사이를 구별 짓는다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>즉각적인 페칭</emphasis> - 소유자가 로드될 때, 연관, 콜렉션 또는 속성이 즉시 페치된다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Lazy 콜렉션 페칭</emphasis> - 어플리케이션이 그 콜렉션에 대해 하나의 오퍼레이션을 호출할 때
+ 콜렉션이 페치된다.(이것은 콜렉션들에 대해 디폴트이다.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>"Extra-lazy" 콜렉션 페칭</emphasis> - 콜렉션의 개별 요소들은 필요할 때
+ 데이터베이스로부터 접근된다. Hibernate는 절대적으로 필요하지 않은 한 전체 콜렉션을 메모리 내로
+ 페치하려고 시도하지 않는다(매우 큰 콜렉션에 적합함)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>프락시 페칭</emphasis> - 식별자 getter가 아닌 다른 메소드가 연관된 객체에 대해 호출될 때
+ 단일 값 연관이 페치된다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>"No-proxy" 페칭</emphasis> - 인스턴스 변수가 접근될 때 단일 값 연관이 페치된다.
+ 프락시 페칭과 비교할 때, 이 접근법은 다소 덜 lazy하지만(그 연관은 심지어 유일하게 식별자가 접근될 때에도
+ 페치된다)보다 투명하다. 왜냐하면 프락시는 어플리케이션에 가시적이지 않기 때문이다. 이 접근법은 빌드 시
+ 바이트코드 수단을 필요로 하며 드물게 필요하다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Lazy 속성 페칭</emphasis> - 인스턴스 변수가 접근될 때 속성 또는 단일 값 연관이 페치된다
+ 이 접근법은 빌드시 바이트코드 수단을 필요로 하며 드물게 필요하다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 우리는 여기서 두 개의 직교하는 개념들을 갖는다: 연관이 페치될 <emphasis>때</emphasis>, 그리고 그것이 페치되는
+ <emphasis>방법</emphasis>(사용되는 SQL). 그것들을 혼동하지 말라! 우리는 퍼포먼스를 튜팅하는데
+ <literal>페치</literal>를 사용한다. 우리는 특정 클래스의 어떤 detached 인스턴스 내에서 항상 이용 가능한
+ 데이터가 무엇인지에 대한 계약을 정의하는데 <literal>lazy</literal>를 사용할 수 있다.
+ </para>
+
+ <sect2 id="performance-fetching-lazy">
+ <title>lazy 연관들로 작업하기</title>
+
+ <para>
+ 디폴트로 Hibernate3는 콜렉션들에 대해 lazy select 페칭을 사용하고, 단일 값 연관들에 대해 lazy
+ 프락시 페칭을 사용한다. 이들 디폴트들은 거의 모든 어플리케이션들에서 거의 모든 연관들에 대해 유의미하다.
+ </para>
+
+ <para>
+ <emphasis>노트:</emphasis> 만일 당신이 <literal>hibernate.default_batch_fetch_size</literal>를 설정하는
+ 경우, Hibernate는 lazy 페칭을 위한 batch 페치 최적화를 사용할 것이다(이 최적화는 또한 더 많은 과립상의 레벨에서 이용 가능할
+ 수 있다).
+ </para>
+
+ <para>
+ 하지만, lazy 페칭은 당신이 알고 있어야 하는 한 가지 문제를 제기한다. 열려진 Hibernate 세션 컨텍스트 외부에서 lazy 연관에
+ 대한 접근은 예외상황으로 귀결될 것이다. 예를 들면 :
+ </para>
+
+ <programlisting><![CDATA[s = sessions.openSession();
+Transaction tx = s.beginTransaction();
+
+User u = (User) s.createQuery("from User u where u.name=:userName")
+ .setString("userName", userName).uniqueResult();
+Map permissions = u.getPermissions();
+
+tx.commit();
+s.close();
+
+Integer accessLevel = (Integer) permissions.get("accounts"); // Error!]]></programlisting>
+
+ <para>
+ <literal>Session</literal>이 닫혔을 때 permissions 콜렉션이 초기화 되지 않았으므로, 그 콜렉션은 그것의 상태를 로드시킬
+ 수가 없을 것이다. <emphasis>Hibernate 는 detached 객체들에 대한 lazy 초기화를 지원하지 않는다.</emphasis> 정정은
+ 콜렉션으로부터 읽어들이는 코드를 커밋 바로 직전으로 이동시키는 것이다.
+ </para>
+
+ <para>
+ 다른 방법으로 연관 매핑에 대해 <literal>lazy="false"</literal>를 지정함으로써, non-lazy 콜렉션 또는
+ non-lazy 연관을 사용할 수 있다. 하지만 lazy 초기화는 거의 모든 콜렉션들과 연관들에 대해 사용되도록 고안되어 있다.
+ 만일 당신이 당신의 객체 모형 내에 너무 많은 non-lazy 연관들을 정의할 경우, Hibernate는 모든 트랜잭션에서 전체
+ 데이터베이스를 메모리 속으로 페치하는 필요성을 끝내게 될 것이다!
+ </para>
+
+ <para>
+ 다른 한편으로, 우리는 특정 트랜잭션 내에서 select 페칭 대신에 (고유하게 non-lazy인) join 페칭을 선택하기를 자주 원한다.
+ 우리는 이제 페칭 방도를 맞춤화 시키는 방법을 알게 될 것이다. Hibernate3에서, 페치 방도를 선택하는 메커니즘은 단일 값 연관들과
+ 콜렉션들에 대해 동일하다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-custom" revision="4">
+ <title>페치 방도들을 튜닝하기</title>
+
+ <para>
+ select 페칭(디폴트)은 N+1 selects 문제점들에 매우 취약해서, 우리는 매핑 문서에서 join 페칭을 사용 가능하게 하기를 원할
+ 수도 있다:
+ </para>
+
+ <programlisting><![CDATA[<set name="permissions"
+ fetch="join">
+ <key column="userId"/>
+ <one-to-many class="Permission"/>
+</set]]></programlisting>
+
+ <programlisting><![CDATA[<many-to-one name="mother" class="Cat" fetch="join"/>]]></programlisting>
+
+ <para>
+ 매핑 문서 내에 정의된 <literal>fetch</literal> 방도는 다음에 영향을 준다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>get()</literal> 또는 <literal>load()</literal>를 통한 검색
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 연관이 네비게이트될 때 함축적으로 발생하는 검색
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Criteria</literal> 질의들
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>subselect</literal> 페칭이 사용될 경우에 HQL 질의들
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 당신이 사용하는 페칭 방도가 무엇인가에 상관없이, 정의된 비-lazy 그래프가 메모리 내로 로드되는 것이 보장된다.
+ 이것은 하나의 특별한 HQL 질의를 실행시키는데 사용되는 몇몇 즉시적인 select들로 귀결될 수 있음을 노트하라.
+ </para>
+
+ <para>
+ 대개, 우리는 페칭을 맞춤화 시키는데 매핑 문서를 사용하지 않는다. 대신에, 우리는 디폴트 특징을 유지하고, HQL에서
+ <literal>left join fetch</literal>를 사용하여, 특정 트랜잭션에 대해 그것을 오버라이드 시킨다. 이것은
+ outer join을 사용하여 첫 번째 select에서 초기에 그 연관을 eagerly 페치시킬 것을 Hibernate에게 알려준다.
+ <literal>Criteria</literal> query API에서, 우리는 <literal>setFetchMode(FetchMode.JOIN)</literal>을
+ 사용한다.
+ </para>
+
+ <para>
+ 만일 당신이 <literal>get()</literal> 또는 <literal>load()</literal>에 의해 사용된 페칭 방도를 변경시킬 수 있기를
+ 당신이 원한다고 느낄 경우, 단순하게 <literal>Criteria</literal> 질의를 사용하라. 예를 들면:
+ </para>
+
+ <programlisting><![CDATA[User user = (User) session.createCriteria(User.class)
+ .setFetchMode("permissions", FetchMode.JOIN)
+ .add( Restrictions.idEq(userId) )
+ .uniqueResult();]]></programlisting>
+
+ <para>
+ (이것은 몇몇 ORM 솔루션들이 "페치 계획"이라고 부르는 것에 대한 Hibernate의 등가물이다.)
+ </para>
+
+ <para>
+ N+1 개의 select들을 가진 문제점들을 피하는 완전히 다른 방법은 second-level 캐시를 사용하는 것이다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-proxies" revision="2">
+ <title>Single-ended 연관 프락시</title>
+
+ <para>
+ 콜렉션들에 대한 Lazy 페칭은 영속 콜렉션들에 대한 Hibernate 자신의 구현을 사용하여 구현된다. 하지만 다른 메커니즘은
+ single-ended 연관들에서 lazy 특징에 필요하다. 연관의 대상 엔티티는 프락시 되어야 한다. Hibernate는
+ (훌륭한 CGLIB 라이브러리를 통해) 런타임 바이트코드 증진을 사용하여 영속 객체들에 대한 lazy 초기화 프락시들을 구현한다.
+ </para>
+
+ <para>
+ 디폴트로, Hibernate3는 모든 영속 클래스들에 대해 (시작 시에) 프락시들을 생성시키고 <literal>many-to-one</literal>
+ 연관과 <literal>one-to-one</literal> 연관에 대해 lazy 페칭을 이용 가능하게 하는데 그것들을 사용한다.
+ </para>
+
+ <para>
+ 매핑 파일은 그 클래스에 대한 프락시 인터페이스로서 사용할, <literal>proxy</literal> 속성을 가진, 인터페이스를 선언할
+ 수도 있다. 디폴트로 Hibernate는 그 클래스의 서브클래스를 사용한다. <emphasis>프락시된 클래스는 최소한의 패키지 가시성
+ (visibility)을 가진 디폴트 생성자를 구현해야 함을 노트하라. 우리는 모든 영속 클래스들에 대해 이 생성자를 권장한다!</emphasis>
+ </para>
+
+ <para>
+ 다형성 클래스들에 대해 이 접근법을 확장할 때 의식해야 하는 몇몇 난처함들이 존재한다. 예를 들면.
+ </para>
+
+ <programlisting><![CDATA[<class name="Cat" proxy="Cat">
+ ......
+ <subclass name="DomesticCat">
+ .....
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ 첫 번째로, 심지어 기본 인스턴스가 <literal>DomesticCat</literal>의 인스턴스인 경우조차도,
+ <literal>Cat</literal>의 인스턴스들은 결코 <literal>DomesticCat</literal>으로 타입캐스트가 가능하지 않을 것이다:
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(Cat.class, id); // instantiate a proxy (does not hit the db)
+if ( cat.isDomesticCat() ) { // hit the db to initialize the proxy
+ DomesticCat dc = (DomesticCat) cat; // Error!
+ ....
+}]]></programlisting>
+
+ <para>
+ 두번째로, 프락시 <literal>==</literal>를 파기할 가능성이 있다.
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(Cat.class, id); // instantiate a Cat proxy
+DomesticCat dc =
+ (DomesticCat) session.load(DomesticCat.class, id); // acquire new DomesticCat proxy!
+System.out.println(cat==dc); // false]]></programlisting>
+
+ <para>
+ 하지만, 그 경우는 보이는 만큼 그렇게 나쁘지는 않다. 심지어 우리가 이제 다른 프락시 객체들에 대한 두 개의 참조를 가질지라도,
+ 기본 인스턴스는 여전히 동일한 객체들일 것이다:
+ </para>
+
+ <programlisting><![CDATA[cat.setWeight(11.0); // hit the db to initialize the proxy
+System.out.println( dc.getWeight() ); // 11.0]]></programlisting>
+
+ <para>
+ 세번째로, 당신은 <literal>final</literal> 클래스 또는 임의의 <literal>final</literal> 메소드들을 가진 클래스에
+ 대해 CGLIB 프락시를 사용하지 않을 수 있다.
+ </para>
+
+ <para>
+ 마지막으로, 만일 당신의 영속 객체가 초기화 시에 어떤 리소스들을 필요로 할 경우(예를 들어, initializer들 또는 디폴트 생성자
+ 내에서), 그때 그들 리소스들이 또한 프락시에 의해 획득될 것이다. 프락시 클래스는 영속 클래스에 대한 실제 서브클래스이다.
+ </para>
+
+ <para>
+ 이들 문제점들은 모두 자바의 단일 상속 모형의 기본적인 제약 때문이다. 만일 당신이 이들 문제점들을 피하고자 원할 경우 당신의 영속
+ 클래스들은 각각 그것의 비지니스 메소드들을 선언하는 인터페이스를 구현해야 한다. 당신은 매핑 파일 속에 이들 인터페이스들을
+ 지정해야 한다. 예를 들면.
+ </para>
+
+ <programlisting><![CDATA[<class name="CatImpl" proxy="Cat">
+ ......
+ <subclass name="DomesticCatImpl" proxy="DomesticCat">
+ .....
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ 여기서 <literal>CatImpl</literal>은 <literal>Cat</literal> 인터페이스를 구현하고 <literal>DomesticCatImpl</literal>은
+ <literal>DomesticCat</literal> 인터페이스를 구현한다. 그때 <literal>Cat</literal>과 <literal>DomesticCat</literal>의
+ 인스턴스들에 대한 프락시들은 <literal>load()</literal> 또는 <literal>iterate()</literal>에 의해 반환될 수 있다.
+ (<literal>list()</literal>가 대개 프락시들을 반환하지 않음을 노트하라.)
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(CatImpl.class, catid);
+Iterator iter = session.createQuery("from CatImpl as cat where cat.name='fritz'").iterate();
+Cat fritz = (Cat) iter.next();]]></programlisting>
+
+ <para>
+ 관계들은 또한 lazy 초기화 된다. 이것은 당신이 임의의 프로퍼티들을 <literal>CatImpl</literal> 타입이 아닌
+ <literal>Cat</literal> 타입으로 선언해야 함을 의미한다.
+ </para>
+
+ <para>
+ 어떤 오퍼레이션들은 프락시 초기화를 필요로 하지 <emphasis>않는다</emphasis>
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>equals()</literal>, 만일 영속 클래스가 <literal>equals()</literal>를 오버라이드 시키지 않는 경우
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>hashCode()</literal>, 만일 영속 클래스가<literal>hashCode()</literal>를 오버라이드 시키지
+ 않는 경우
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 식별자 getter 메소드
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate는 <literal>equals()</literal> 또는 <literal>hashCode()</literal>를 오버라이드 시키는 영속 클래스들을
+ 검출할 것이다.
+ </para>
+
+ <para>
+ 디폴트 <literal>lazy="proxy"</literal> 대신에 <literal>lazy="no-proxy"</literal>를 선택하여,
+ 우리는 타입캐스팅과 연관된 문제점들을 피할 수 있다. 하지만 우리는 빌드 시 바이트코드 수단을 필요로 할 것이고,
+ 모든 연산들은 즉각적인 프락시 초기화로 귀결될 것이다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-initialization" revision="1">
+ <title>콜렉션들과 프락시들을 초기화 시키기</title>
+
+ <para>
+ 만일 초기화 되지 않은 콜렉션이나 프락시가 <literal>Session</literal> 영역의 외부에서 접근될 경우에, 예를 들어 콜렉션을
+ 소유하거나 프락시에 대한 참조를 가진 엔티티가 detached 상태에 있을 때, <literal>LazyInitializationException</literal>이
+ Hibernate에 의해 던져질 것이다.
+ </para>
+
+ <para>
+ 때때로 우리는<literal>Session</literal>을 닫기 전에 프락시 또는 콜렉션이 초기화 됨을 확실히 할 필요가 있다. 물론 우리는
+ 예를 들어 <literal>cat.getSex()</literal> 또는 <literal>cat.getKittens().size()</literal>를 호출하여 항상
+ 초기화를 강제시킬 수 있다. 그러나 그것은 코드의 독자들에게는 혼동스럽고 일반적인 코드로 편의적이지 않다.
+ </para>
+
+ <para>
+ static 메소드들 <literal>Hibernate.initialize()</literal>와 <literal>Hibernate.isInitialized()</literal>는
+ lazy 초기화 된 콜렉션들이나 프락시들에 대해 작업하는 편리한 방법을 어플리케이션에 제공한다. <literal>Hibernate.initialize(cat)</literal>은
+ 그것의 <literal>Session</literal>이 여전히 열려져 있는 한 프락시 <literal>cat</literal>의 초기화를 강제할 것이다.
+ <literal>Hibernate.initialize( cat.getKittens())</literal>는 kittens의 콜렉션에 대해 유사한 효과를 갖는다.
+ </para>
+
+ <para>
+ 또 다른 옵션은 모든 필요한 콜렉션들과 프락시들이 로드되기 전까지 <literal>Session</literal>을 열린 채로 유지하는 것이다.
+ 몇몇 어플리케이션 아키텍처들, 특히 Hibernate를 사용하여 데이터에 접근하는 코드, 그리고 다른 어플리케이션 계층들이나 다른
+ 물리적 프로세스들 내에서 그것을 사용하는 코드에서, 그것은 콜렉션이 초기화 될 때 <literal>Session</literal>이 열려져
+ 있음을 확실히 하는 문제일 수 있다. 이 쟁점을 다루는 두 가지 기본 방법들이 존재한다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ 웹 기반 어플리케이션에서, 서블릿 필터는 뷰 렌더링이 완료되는, 사용자 요청의 바로 끝에서만 <literal>Session</literal>을
+ 닫는데 사용될 수 있다(<emphasis>Open Session in View</emphasis> 패턴). 물론 이것은 당신의 어플리케이션
+ 인프라스트럭처의 예외상황 처리의 정정에 관한 무거운 요구를 부과한다.
+ 뷰 렌더링 동안에 하나의 예외상황이 발생할때에도 사용자에게 반환되기 전에 <literal>Session</literal>이 닫혀지고
+ 트랜잭션이 종료되는 것은 지극히 중요하다. 이 "Open Session in View" 패턴에 관한 예제들은 Hibernate 위키를 보라.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 별도의 비지니스 티어를 가진 어플리케이션에서, 비지니스 로직은 반환 전에 웹 티어에 필요한 모든 콜렉션들을
+ "준비"해야 한다. 이것은 비지니스 티어가 모든 데이터를 로드시키고 이미 초기화된 모든 데이터를 특정 쓰임새에
+ 필요한 프리젠테이션/웹 티어로 반환해야 함을 의미한다. 대개 어플리케이션은 웹 티어에 필요하게 될 각각의 콜렉션에
+ 대해 <literal>Hibernate.initialize()</literal>를 호출하거나(이 호출은 세션이 닫히기 전에 발생해야 한다)
+ 또는 <literal>FETCH</literal> 절을 갖거나 또는 <literal>Criteria</literal> 내에
+ <literal>FetchMode.JOIN</literal>을 가진 Hibernate 질의를 사용하여 콜렉션을 열심히 검색한다. 이것은
+ 대개 당신이 <emphasis>Session Facade</emphasis> 대신 <emphasis>Command</emphasis> 패턴을 채택할
+ 경우에 더 쉽다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 당신은 또한 초기화 되지 않은 콜렉션들(또는 다른 프락시들)에 접근하기 전에 <literal>merge()</literal> 또는
+ <literal>lock()</literal>으로 앞서 로드된 객체를 새로운 <literal>Session</literal>n에 첨부할 수도 있다.
+ 아니다. Hibernate는 이것을 자동적으로 행하지 않고, 확실히 자동적으로 행하지 <emphasis>않을 것이다</emphasis>.
+ 왜냐하면 그것은 특별한 목적을 위한 트랜잭션 의미를 도입할 것이기 때문이다!
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 때때로 당신은 거대한 콜렉션을 초기화 시키는 것을 원하지 않지만, 여전히 (그것의 사이즈와 같은) 그것에 대한 어떤 정보 또는
+ 데이터의 부분집합을 필요로 한다.
+ </para>
+
+ <para>
+ 당신은 그것을 초기화 시키지 않고서 콜렉션의 사이즈를 얻는데 콜렉션 필터를 사용할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[( (Integer) s.createFilter( collection, "select count(*)" ).list().get(0) ).intValue()]]></programlisting>
+
+ <para>
+ <literal>createFilter()</literal> 메소드는 또한 전체 콜렉션을 초기화 시킬 필요 없이 콜렉션의 부분집합들을 효율적으로
+ 검색하는데 사용된다:
+ </para>
+
+ <programlisting><![CDATA[s.createFilter( lazyCollection, "").setFirstResult(0).setMaxResults(10).list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-batch">
+ <title>batch 페칭 사용하기</title>
+
+ <para>
+ Hibernate는 배치 페칭을 효율적으로 사용할 수 있다. 즉 하나의 프락시가 액세스 될 경우에 Hibernate는 몇몇 초기화 되지 않은
+ 프락시들을 로드시킬 수 있다(또는 콜렉션들). batch 페칭은 lazy select 페칭 방도에 대한 최적화이다. 당신이 batch
+ 페칭을 튜닝시킬 수 있는 두 가지 방법들이 존재한다: 클래스 레벨에서 그리고 콜렉션 레벨에서.
+ </para>
+
+ <para>
+ 클래스들/엔티티들에 대한 batch 페칭은 이해하기가 더 쉽다. 당신이 실행 시에 다음 상황에 처한다고 상상하라: 당신은 하나의
+ <literal>Session</literal> 속에 로드된 25개의 <literal>Cat</literal> 인스턴스들을 갖고 있고, 각각의
+ <literal>Cat</literal>은 그것의 <literal>소유자</literal> 즉, <literal>Person</literal>에 대한 참조를
+ 갖고 있다. <literal>Person</literal> 클래스는 프락시 <literal>lazy="true"</literal>로서 매핑된다. 만일
+ 당신이 이제 모든 cat들을 통해 반복하고 각각의 cat에 대해 <literal>getOwner()</literal>를 호출할 경우, Hibernate는
+ 프락시된 소유자들을 검색하기 위해 25개의 <literal>SELECT</literal> 문장들을 디폴트로 실행시킬 것이다. 당신은
+ <literal>Person</literal> 매핑에서 <literal>batch-size</literal>를 지정함으로써 이 동작을 튜닝시킬 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person" batch-size="10">...</class>]]></programlisting>
+
+ <para>
+ Hibernate는 이제 세 개의 질의들 만을 실행시킬 것이고, 그 패턴은 10,10, 5 이다.
+ </para>
+
+ <para>
+ 당신은 또한 콜렉션들에 대해 batch 페칭을 이용 가능하게 할 수도 있다. 예를 들어, 만일 각각의 <literal>Person</literal>이
+ <literal>Cat</literal>들을 가진 lazy 콜렉션을 갖고, 10개의 person들이 <literal>Sesssion</literal> 내에 현재
+ 로드되어 있을 경우, 모든 person들에 대한 반복은 10개의 <literal>SELECT</literal>들을 생성시킬 것이고, <literal>getCats()</literal>에
+ 대한 매번의 호출에 대해 하나의 <literal>SELECT</literal>를 생성시킬 것이다. 만일 당신이 <literal>Person</literal>
+ 매핑에서 <literal>cats</literal> 콜렉션에 대해 batch 페칭을 사용가능하게 할 경우, Hibernate는 콜렉션들을 미리-페치
+ 시킬 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <set name="cats" batch-size="3">
+ ...
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ <literal>batch-size</literal> 8로서, Hibernate는 4개의 SELECT들에서 3, 3, 3, 1 개의 콜렉션들을 로드시킬 것이다.
+ 다시 그 속성의 값은 특정 <literal>Session</literal> 내에서 초기화 되지 않은 콜렉션들의 예상되는 개수에 의존한다.
+ </para>
+
+ <para>
+ 만일 당신이 항목들의 포개진 트리를 가질 경우, 예를 들어 전형적인 bill-of-materials 패턴인 경우, (비록
+ <emphasis>내포된 set</emphasis> 또는 <emphasis>실체화된 경로(materialized path)</emphasis>가
+ 주로-읽기-트리들에 대해 더 좋은 옵션일 수 있을지라도) 콜렉션들에 대한 batch 페칭이 특히 유용하다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-subselect">
+ <title>subselect 페칭 사용하기</title>
+
+ <para>
+ 만일 한 개의 lazy 콜렉션이나 단일 값 프락시가 페치되어야 한다면, Hibernate는 하나의 subselect 내에서 원래의
+ 질의를 다시 실행하여 그것들 모두를 로드시킨다. 이것은 조각난 로딩 없이 batch 페칭과 동일한 방식으로 동작한다.
+ </para>
+
+ <!-- TODO: 이것에 대해 더 많이 작성할 것 -->
+
+ </sect2>
+
+ <sect2 id="performance-fetching-lazyproperties">
+ <title>lazy 프로퍼티 페칭 사용하기</title>
+
+ <para>
+ Hibernate3은 개별적인 프로퍼티들에 대한 lazy 페칭을 지원한다. 이 최적화 기술은 또한 <emphasis>fetch groups</emphasis>
+ 으로 알려져 있다. 이것이 대개 마케팅 특징임을 노트하길 바란다. 왜냐하면 실제로 행 읽기를 최적화 시키는 것이 컬럼 읽기에 대한
+ 최적화 보다 훨씬 더 중요하기 때문이다. 하지만 리거시 테이블들이 수백 개의 컬럼들을 갖고 데이터 모형이 개선될 수 없을 때,
+ 오직 클래스의 몇몇 프로퍼티들을 로드시키는 것 만이 유용할 수도 있다.
+ </para>
+
+ <para>
+ lazy 프로퍼티 로딩을 이용가능하게 하려면, 당신의 특정 property 매핑들에 대해 <literal>lazy</literal> 속성을 설정하라:
+ </para>
+
+ <programlisting><![CDATA[<class name="Document">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name" not-null="true" length="50"/>
+ <property name="summary" not-null="true" length="200" lazy="true"/>
+ <property name="text" not-null="true" length="2000" lazy="true"/>
+</class>]]></programlisting>
+
+ <para>
+ Lazy property 로딩은 빌드 시 바이트코드 수단을 필요로 한다! 만일 당신의 영속 클래스들이 개선되지 않을 경우,
+ Hibernate는 조용하게 lazy 프로퍼티 설정들을 무시하고 즉각적인 페칭으로 후퇴할 것이다.
+ </para>
+
+ <para>
+ bytecode 수단으로, 다음 Ant 태스크를 사용하라:
+ </para>
+
+ <programlisting><![CDATA[<target name="instrument" depends="compile">
+ <taskdef name="instrument" classname="org.hibernate.tool.instrument.InstrumentTask">
+ <classpath path="${jar.path}"/>
+ <classpath path="${classes.dir}"/>
+ <classpath refid="lib.class.path"/>
+ </taskdef>
+
+ <instrument verbose="true">
+ <fileset dir="${testclasses.dir}/org/hibernate/auction/model">
+ <include name="*.class"/>
+ </fileset>
+ </instrument>
+</target>]]></programlisting>
+
+ <para>
+ 불필요한 컬럼 읽기를 피하는 다른 (더 좋은?) 방법은 적어도 읽기 전용 트랜잭션의 경우에 HQL 질의 또는 Criteria 질의의
+ 투사(projection) 특징들을 사용하는 것이다. 이것은 빌드 시 바이트코드 처리에 대한 필요성을 피하게 해주고 확실히 선호되는
+ 해결책이다.
+ </para>
+
+ <para>
+ 당신은 HQL에서 <literal>fetch all properties</literal>를 사용하여 프로퍼티들에 대한 통상의 eager 페칭을
+ 강제시킬 수 있다.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="performance-cache" revision="1">
+ <title>두번째 레벨 캐시</title>
+
+ <para>
+ Hibernate <literal>Session</literal>은 영속 데이터에 대한 트랜잭션 레벨 캐시이다. class-by-class와
+ collection-by-collection 기반 위에 클러스터 또는 JVM-레벨(<literal>SessionFactory</literal>-레벨) 캐시를 구성하는
+ 것이 가능하다. 당신은 클러스터링 된 캐시 속에 플러그인 할 수도 있다. 주의하라. 캐시들은 (비록 그것들이 캐시된 데이터를 정기적으로
+ 만료되도록 구성되어 있을지라도) 또 다른 어플리케이션에 의해 영속 저장소에 대해 행해진 변경들을 결코 알지 못한다.
+ </para>
+
+ <para revision="1">
+ 디폴트로, Hibernate는 JVM-레벨의 캐싱에 EHCache를 사용한다. (JCS 지원은 이제 진부하게 되었고 Hibernate의 장래 버전에서
+ 제거될 것이다.) 당신은 <literal>hibernate.cache.provider_class</literal> 프로퍼티를 사용하여
+ <literal>org.hibernate.cache.CacheProvider</literal>를 구현하는 클래스의 이름을 지정함으로써 다른 구현을 선택할 수도
+ 있다.
+ You have the option to tell Hibernate which caching implementation to use by
+ specifying the name of a class that implements <literal>org.hibernate.cache.CacheProvider</literal>
+ using the property <literal>hibernate.cache.provider_class</literal>. Hibernate
+ comes bundled with a number of built-in integrations with open-source cache providers
+ (listed below); additionally, you could implement your own and plug it in as
+ outlined above. Note that versions prior to 3.2 defaulted to use EhCache as the
+ default cache provider; that is no longer the case as of 3.2.
+ 당신은 <literal>hibernate.cache.provider_class</literal> 프로퍼티를 사용하여
+ <literal>org.hibernate.cache.CacheProvider</literal>를 구현하는 클래스의 이름을 지정함으로써 어느 캐싱 구현을
+ 사용할 것인지를 Hibernate에게 알려주는 옵션을 갖는다. Hibernate는 (아래에 열거된) 오픈-소스 프로바이더들을 가진
+ 많은 빌드되어 있는 통합들을 번들로 갖고 있다; 추가적으로 당신은 위에서 언급했듯이 그것에 당신 자신의 것을 구현할 수 있고 그것에
+ 플러그 시킬 수 있다. 3.2 이번 버전들은 디플트 캐시 프로바이더로서 EhCache를 사용하도록 디포릍로 내장되어 있음을 노트하라;
+ 버전 3.2의 경우에 그것은 더이상 디폴트 내장이 아니다.
+ </para>
+
+ <table frame="topbot" id="cacheproviders" revision="1">
+ <title>캐시 프로바이더들</title>
+ <tgroup cols='5' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="3*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>캐시</entry>
+ <entry>프로바이더 클래스</entry>
+ <entry>타입</entry>
+ <entry>클러스터 안전</entry>
+ <entry>질의 캐시 지원</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Hashtable (제품 용도로 고안되어 있지 않음)</entry>
+ <entry><literal>org.hibernate.cache.HashtableCacheProvider</literal></entry>
+ <entry>memory</entry>
+ <entry></entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry>EHCache</entry>
+ <entry><literal>org.hibernate.cache.EhCacheProvider</literal></entry>
+ <entry>memory, disk</entry>
+ <entry></entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry>OSCache</entry>
+ <entry><literal>org.hibernate.cache.OSCacheProvider</literal></entry>
+ <entry>memory, disk</entry>
+ <entry>yes (clustered invalidation)</entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry>SwarmCache</entry>
+ <entry><literal>org.hibernate.cache.SwarmCacheProvider</literal></entry>
+ <entry>clustered (ip multicast)</entry>
+ <entry>yes (clustered invalidation)</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>JBoss TreeCache</entry>
+ <entry><literal>org.hibernate.cache.TreeCacheProvider</literal></entry>
+ <entry>clustered (ip multicast), transactional</entry>
+ <entry>yes (replication)</entry>
+ <entry>yes (clock sync req.)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="performance-cache-mapping" revision="2">
+ <title>Cache 매핑들</title>
+
+ <para>
+ 클래스 또는 콜렉션 매핑의 <literal><cache></literal> 요소는 다음 형식을 갖는다:
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="cache1" coords="2 70"/>
+ <area id="cache2" coords="3 70"/>
+ <area id="cache3" coords="4 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<cache
+ usage="transactional|read-write|nonstrict-read-write|read-only"
+ region="RegionName"
+ include="all|non-lazy"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="cache1">
+ <para>
+ <literal>usage</literal>(필수) 캐싱 방도를 지정한다:
+ <literal>transactional</literal>,
+ <literal>read-write</literal>,
+ <literal>nonstrict-read-write</literal> 또는
+ <literal>read-only</literal>
+ </para>
+ </callout>
+ <callout arearefs="cache2">
+ <para>
+ <literal>region</literal> (옵션, 디폴트는 class 또는 콜렉션 role 이름)
+ second level 캐시 영역의 이름을 지정한다
+ </para>
+ </callout>
+ <callout arearefs="cache3">
+ <para>
+ <literal>include</literal> (옵션, 디폴트는 <literal>all</literal>)
+ <literal>non-lazy</literal>는 <literal>lazy="true"</literal>로 매핑된 엔티티의
+ 프로퍼티들을 지정하며 속성-레벨 lazy 페칭이 이용 가능할 때 키시될 수 없다
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ 다른 방법으로 (선호적으로?), 당신은 <literal>hibernate.cfg.xml</literal> 내에 <literal><class-cache></literal>와
+ <literal><collection-cache></literal> 요소들을 지정할 수도 있다.
+ </para>
+
+ <para>
+ <literal>usage</literal> 속성은 <emphasis> 캐시 동시성 방도</emphasis>를 지정한다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-cache-readonly">
+ <title>방도: 읽기 전용</title>
+
+ <para>
+ 당신의 어플리케이션이 영속 클래스의 인스턴스들을 읽어들일 필요가 있지만 결코 변경할 필요가 없을 경우에 <literal>read-only</literal>
+ 캐시가 사용될 수 있다. 이것은 가장 간단한 최상의 퍼포먼스를 위한 방도이다. 그것은 클러스터 내 사용에는 완벽하게 안전하다.
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Immutable" mutable="false">
+ <cache usage="read-only"/>
+ ....
+</class>]]></programlisting>
+
+ </sect2>
+
+
+ <sect2 id="performance-cache-readwrite">
+ <title>방도: 읽기/쓰기</title>
+
+ <para>
+ 어플리케이션이 데이터를 업데이트 할 필요가 있을 경우, <literal>read-write</literal> 캐시가 적절하다. 만일
+ 직렬화 가능한(serializable) 트랜잭션 격리 레벨이 필요한 경우에는 이 캐시 방도가 결코 사용되지 말아야 한다. 만일 캐시가 JTA
+ 환경에서 사용될 경우, 당신은 JTA <literal>TransactionManager</literal>를 얻는 방도를 명명하는
+ <literal>hibernate.transaction.manager_lookup_class</literal> 프로퍼티를 지정해야 한다. 다른 환경들에서,
+ 당신은<literal>Session.close()</literal> 또는 <literal>Session.disconnect()</literal>가 호출될 때
+ 트랜잭션이 완료되는 것을 확실히 해야 한다. 만일 당신이 클러스터 내에 이 방도를 사용하고자 원할 경우, 당신은 기본 캐시 구현이
+ 잠금을 지원하도록 하는 것을 확실히 해야 한다. 미리 만들어진 캐시 프로바이더들은 그렇게 행하지 <emphasis>않는다</emphasis>.
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Cat" .... >
+ <cache usage="read-write"/>
+ ....
+ <set name="kittens" ... >
+ <cache usage="read-write"/>
+ ....
+ </set>
+</class>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-cache-nonstrict">
+ <title>방도: 엄격하지 않은 읽기/쓰기</title>
+
+ <para>
+ 만일 어플리케이션이 오직 데이터를 자주 업데이트할 필요가 있고(예를 들어, 만일 두 개의 트랜잭션들이 동시에 동일한 항목을 업데이트
+ 하려고 시도하는 정말 있음직하지 않은 경우) 그리고 엄격한 트랜잭션 격리가 필요하지 않은 경우, <literal>nonstrict-read-write</literal>
+ 캐시가 적절할 수 있다. 만일 그 캐시가 JTA 환경에서 사용될 경우, 당신은 <literal>hibernate.transaction.manager_lookup_class</literal>를
+ 지정해야 한다. 다른 환경들에서, 당신은 <literal>Session.close()</literal> 또는 <literal>Session.disconnect()</literal>가 호출될 때
+ 트랜잭션이 완료되도록 확실히 해야 한다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-cache-transactional">
+ <title>방도: transactional</title>
+
+ <para>
+ <literal>transactional</literal> 캐시 방도는 JBoss TreeCache와 같은 전체 트랜잭션적인 캐시 프로바이더들에 대한
+ 지원을 제공한다. 그런 캐시는 오직 JTA 환경 내에서 사용될 수 있고 당신은
+ <literal>hibernate.transaction.manager_lookup_class</literal>를 지정해야 한다.
+ </para>
+
+ </sect2>
+
+ <para>
+ 캐시 프로바이더들 중 어느 것도 모든 캐시 동시성 방도들을 지원하지 않는다. 다음 테이블은 어느 프로바이더들이 어느 동시성 방도들과
+ 호환되는지를 보여준다.
+ </para>
+
+ <table frame="topbot">
+ <title>캐시 동시성 방도 지원</title>
+ <tgroup cols='5' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="1*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>캐시</entry>
+ <entry>읽기 전용</entry>
+ <entry>엄격하지 않은 읽기-쓰기</entry>
+ <entry>읽기-쓰기</entry>
+ <entry>transactional</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Hashtable (제품용으로 고안되지 않음)</entry>
+ <entry>예</entry>
+ <entry>예</entry>
+ <entry>예</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>EHCache</entry>
+ <entry>예</entry>
+ <entry>예</entry>
+ <entry>예</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>OSCache</entry>
+ <entry>예</entry>
+ <entry>예</entry>
+ <entry>예</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>SwarmCache</entry>
+ <entry>예</entry>
+ <entry>예</entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>JBoss TreeCache</entry>
+ <entry>예</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>예</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="performance-sessioncache" revision="2">
+ <title>캐시들을 관리하기</title>
+
+ <para>
+ 당신이 객체를 <literal>save()</literal>, <literal>update()</literal> 또는 <literal>saveOrUpdate()</literal>에
+ 전달할 때마다 그리고 당신이 <literal>load()</literal>, <literal>get()</literal>, <literal>list()</literal>,
+ <literal>iterate()</literal> 또는 <literal>scroll()</literal>을 사용하여 객체를 검색할 때마다, 그 객체는
+ <literal>Session</literal>의 내부 캐시에 추가된다.
+ </para>
+ <para>
+ <literal>flush()</literal>가 차후적으로 호출될 때, 그 객체의 상태는 데이터베이스와 동기화 될 것이다. 만일 당신이 이 동기화가
+ 발생되는 것을 원하지 않거나 만일 당신이 대량의 객체들을 처리 중이고 메모리를 효율적으로 관리할 필요가 있을 경우, <literal>evict()</literal>
+ 메소드는 first-level 캐시로부터 그 객체와 그것의 콜렉션들을 제거하는데 사용될 수 있다.
+ </para>
+
+ <programlisting><![CDATA[ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set
+while ( cats.next() ) {
+ Cat cat = (Cat) cats.get(0);
+ doSomethingWithACat(cat);
+ sess.evict(cat);
+}]]></programlisting>
+
+ <para>
+ <literal>Session</literal>은 또한 인스턴스가 세션 캐시에 속하는지 여부를 결정하는데 <literal>contains()</literal>
+ 메소드를 제공한다.
+ </para>
+
+ <para>
+ 세션 캐시로부터 모든 객체들을 완전하게 퇴거시키기 위해, <literal>Session.clear()</literal>를 호출하라.
+ </para>
+
+ <para>
+ second-level 캐시의 경우, 하나의 인스턴스, 전체 클래스, 콜렉션 인스턴스 또는 전체 콜렉션 role의 캐시된 상태를 퇴거시키는
+ <literal>SessionFactory</literal> 상에 정의된 메소드들이 존재한다.
+ </para>
+
+ <programlisting><![CDATA[sessionFactory.evict(Cat.class, catId); //evict a particular Cat
+sessionFactory.evict(Cat.class); //evict all Cats
+sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
+sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections]]></programlisting>
+
+ <para>
+ <literal>CacheMode</literal>는 특정 세션이 second-level 캐시와 어떻게 상호작용하는지를 제어한다
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>CacheMode.NORMAL</literal> - second-level 캐시로부터 아이템들을 읽어들이고 second-level 캐시로
+ 아이템들을 기록한다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.GET</literal> - second-level 캐시로부터 아이템들을 읽어들이지만, 데이터를 업데이트할 때를 제외하면
+ second-level 캐시로 기록하지 않는다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.PUT</literal> - 아이템들을 second-level 캐시에 기록하지만, second-level 캐시로부터 읽어들이지
+ 않는다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.REFRESH</literal> - 아이템들을 second-level 캐시로기록하지만, second-level 캐시로부터
+ 읽어들이지 않고, 데이터베이스로부터 읽어들인 모든 아이템들에 대한 second-level 캐시의 갱신을 강제시켜,
+ <literal>hibernate.cache.use_minimal_puts</literal>의 효과를 무시한다
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ second-level 캐시 또는 질의 캐시 영역의 내용물을 브라우징하려면 <literal>Statistics</literal> API를 사용하라:
+ </para>
+
+ <programlisting><![CDATA[Map cacheEntries = sessionFactory.getStatistics()
+ .getSecondLevelCacheStatistics(regionName)
+ .getEntries();]]></programlisting>
+
+ <para>
+ 당신은 통계를 이용 가능하게 하고, 선택적으로 Hibernate로 하여금 캐시 엔트리들을 보다 인간에게 이해가능한 형식으로 유지시키도록
+ 강제시키는 것이 필요할 것이다:
+ </para>
+
+ <programlisting><![CDATA[hibernate.generate_statistics true
+hibernate.cache.use_structured_entries true]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="performance-querycache" revision="1">
+ <title>질의 캐시</title>
+
+ <para>
+ 질의 결과 셋들이 또한 캐시될 수도 있다. 이것은 동일한 파라미터들을 가지고 자주 실행되는 질의들에만 유용하다.
+ 질의 캐시를 사용하기 위해 당신은 먼저 그것을 이용 가능하도록 해야 한다:
+ </para>
+
+ <programlisting><![CDATA[hibernate.cache.use_query_cache true]]></programlisting>
+
+ <para>
+ 이 설정은 두 개의 새로운 캐시 영역들 - 캐시된 질의 결과 셋들을 보관하는 것
+ (<literal>org.hibernate.cache.StandardQueryCache</literal>), 질의 가능한 테이블들에 대한 가장
+ 최신 업데이트들에 대한 timestamp들을 보관하는 다른 것
+ (<literal>org.hibernate.cache.UpdateTimestampsCache</literal>)-의 생성을 강제한다 . 질의 캐시는
+ 결과 셋 내에 실제 엔티티들의 상태를 캐시시키지 않음을 노트하라; 그것은 오직 식별자 값들과 값 타입의 결과들
+ 만을 캐시시킨다. 따라서 질의 캐시는 항상 second-level 캐시와 함께 사용되어야 한다.
+ </para>
+
+ <para>
+ 대부분의 질의들은 캐싱으로부터 이점이 없기에, 디폴트로 질의들은 캐시되지 않는다. 캐싱을 이용 가능하도록 하려면,
+ <literal>Query.setCacheable(true)</literal>를 호출하라. 이 호출은 기존 캐시 결과들을 찾는 것을 질의에게
+ 허용해주거나 질의가 실행될 때 그것의 결과들을 캐시에 추가하는 것을 허용해준다.
+ </para>
+
+ <para>
+ 만일 당신이 질의 캐시 만료 정책들에 대한 세밀한 제어를 필요로 할 경우, 당신은
+ <literal>Query.setCacheRegion()</literal>을 호출함으로써 특별한 질의에 대해 명명되니 캐시 영역을
+ 지정할 수도 있다.
+ </para>
+
+ <programlisting><![CDATA[List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger")
+ .setEntity("blogger", blogger)
+ .setMaxResults(15)
+ .setCacheable(true)
+ .setCacheRegion("frontpages")
+ .list();]]></programlisting>
+
+ <para>
+ 만일 질의가 그것의 질의 캐시 영역의 갱신을 강제시켜야 하는 경우에, 당신은 <literal>Query.setCacheMode(CacheMode.REFRESH)</literal>를
+ 호출해야 한다. 이것은 기본 데이터가 별도의 프로세스를 통해 업데이트되었고(예를 들면, Hibernate를 통해 변경되지 않았고)
+ 특정 질의 결과 셋들을 선택적으로 갱신하는 것을 어플리케이션에게 허용해주는 경우들에서 특별히 유용하다. 이것은
+ <literal>SessionFactory.evictQueries()</literal>를 통해 질의 캐시 영역을 퇴거시키는 보다 효과적인 대안이다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="performance-collections">
+ <title>콜렉션 퍼포먼스 이해하기</title>
+
+ <para>
+ 우리는이미 콜렉션들에 관해 얘기하는데 꽤 많은 시간을 소요했다. 이 절에서 우리는 콜렉션들이 실행 시에 어떻게 행위하는지에 관한
+ 한 쌍의 쟁점들을 조명할 것이다.
+ </para>
+
+ <sect2 id="performance-collections-taxonomy">
+ <title>분류</title>
+
+ <para>Hibernate는 세 가지 기본적인 종류의 콜렉션들을 정의한다:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>값들을 가진 콜렉션들</para>
+ </listitem>
+ <listitem>
+ <para>one to many 연관들</para>
+ </listitem>
+ <listitem>
+ <para>many to many 연관들</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 이 분류는 여러 가지 테이블과 foreign key 관계들을 구별짓지만 우리가 관계형 모형에 대해 알 필요가 있는 모든 것을 우리에게
+ 말해주지 않는다. 관계형 구조와 퍼포먼스 특징들을 완전하게 이해하기 위해, 우리는 또한 콜렉션 행들을 업데이트하거나 삭제하기
+ 위해 Hibernate에 의해 사용되는 프라이머리 키의 구조를 검토해야 한다. 이것은 다음 분류를 제안한다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>인덱싱 된 콜렉션들 </para>
+ </listitem>
+ <listitem>
+ <para>set들</para>
+ </listitem>
+ <listitem>
+ <para>bag들</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 모든 인덱싱된 콜렉션들(map들, list들, array들)은 <literal><key></literal>와
+ <literal><index></literal> 컬럼들로 이루어진 프라이머리 키를 갖는다. 이 경우에 콜렉션 업데이트들은 대개
+ 극히 효율적이다 - Hibernate가 그것을 업데이트나 삭제를 시도할 때 프라이머리 키는 효율적으로 인덱싱될 수 있고 특정 행은
+ 효율적으로 위치지워질 수 있다.
+ </para>
+
+ <para>
+ Set들은 <literal><key></literal>와 요소 컬럼들로 구성된 프라이머리 키를 갖는다. 이것은 몇몇 유형의 콜렉션 요소,
+ 특히 composite 요소들 또는 대형 텍스트 또는 바이너리 필드들에 대해 덜 효율적일 수 있다; 데이터베이스는 복잡한 프라이머리
+ 키를 효율적으로 인덱싱하는 것이 불가능할 수도 있다. 반면에 one to many 또는 many to many 연관들의 경우, 특히 합성
+ 식별자들의 경우에는 효율적일 수 있을 것 같다.(부수-노트: 만일 당신이 당신을 위한 <literal><set></literal>의
+ 프라이머리 키를 실제로 생성시키기 위해 <literal>SchemaExport</literal>를 원한다면 당신은 모든 컬럼들을
+ <literal>not-null="true"</literal>로 선언해야 한다.)
+ </para>
+
+ <para>
+ <literal><idbag></literal> 매핑들은 대용 키를 정의하여서, 그것들은 항상 업데이트에 매우 효율적이다. 사실,
+ 그것들은 최상의 경우이다.
+ </para>
+
+ <para>
+ Bag들은 가장 나쁜 경우이다. 왜냐하면 하나의 bag은 중복 요소 값들을 허용하고 인덱스 컬럼을 갖지 않기 때문에, 프라이머리 키가
+ 정의될 수 없다. Hibernate는 중복 행들 사이를 구분 짓는 방법을 갖고 있지 않다. Hibernate는 그것이 변경될 때마다
+ (한 개의 DELETE로) 콜렉션을 완전하게 제거하고 다시 생성시킴으로써 이 문제를 해결한다. 이것은 매우 비효율적이다.
+ </para>
+
+ <para>
+ one-to-many 연관의 경우, "프라이머리 키"는 데이터베이스 테이블의 물리적인 프라이머리 키가 아닐 수도 있지만- 이 경우에서도
+ 위의 분류는 여전히 유용하다. (그것은 여전히 Hibernate가 콜렉션의 개별 행들을 어떻게 "위치지우는"지를 반영한다.)
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-collections-mostefficientupdate">
+ <title>List, map, idbag, set들은 update에 가장 효율적인 콜렉션들이다</title>
+
+ <para>
+ 위의 논의에서, 인덱싱된 콜렉션들과 (대개) set들이 요소들을 추가하고, 제거하고 업데이트함에 있어 가장 효율적인 오퍼레이션을
+ 허용해준다.
+ </para>
+
+ <para>
+ 아마 인덱싱 된 콜렉션들이 many to many 연관들을 위한 또는 값들을 가진 콜렉션들을 위한 set들에 대해 갖고 있는 하나 이상의
+ 장점들이 존재한다. <literal>Set</literal>의 구조 때문에, Hibernate는 요소가 "변경"될 때 행을 <literal>UPDATE</literal>
+ 하지 않는다. <literal>Set</literal>에 대한 변경들은 항상 (개별 행들에 대한) <literal>INSERT</literal>와
+ <literal>DELETE</literal>를 통해 동작한다. 다시 이 검토는 one to many 연관들에 적용되지 않는다.
+ </para>
+
+ <para>
+ 배열들이 lazy 될 수 없음을 관찰 한 후에, 우리는 list들, map들, 그리고 idbag들이 단독이 아닌 set들을 가진 가장 퍼포먼스가
+ 좋은(non-inverse) 콜렉션 타입들임을 결론 지을 것이다. Set들은 Hibernate 어플리케이션들에서 가장 공통된 종류의 콜렉션이
+ 될 것이라 예상된다. 이것은 "set" 의미가 관계형 모형에서 가장 고유한 것이기 때문이다.
+ </para>
+
+ <para>
+ 하지만, 잘 설계된 Hibernate 도메인 모형들에서, 우리는 대개 대부분의 콜렉션들이 사실 <literal>inverse="true"</literal>를
+ 가진 one-to-many 연관들임을 보게 된다. 이들 연관들의 경우, 업데이트는 연관의 many-to-one 엔드에 의해 처리되고, 따라서
+ 콜렉션 업데이트 퍼포먼스에 대한 검토들은 단순히 적용되지 않는다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-collections-mostefficentinverse">
+ <title>Bag들과 list들은 가장 효율적인 inverse 콜렉션들이다</title>
+
+ <para>
+ 단지 당신이 영원히 bag들을 버리기 전에, bag들(과 또한 list들)이 set들보다 훨씬 더 성능이 좋은 특별한 경우들이 존재한다.
+ <literal>inverse="true"</literal>를 가진 콜렉션들(예를 들어, 표준 양방향 one-to-many 관계 특질)의 경우, 우리는
+ bag 요소들을 초기화(페치) 시킬 필요 없이 bag 또는 list에 요소들을 추가시킬 수 있다! 이것은 <literal>Collection.add()</literal>
+ 또는 <literal>Collection.addAll()</literal>이 (<literal>Set</literal>과는 달리) 항상 bag 또는
+ <literal>List</literal>에 대해 true를 반환해야하기 때문이다. 이것은 훨씬 다음 공통적인 코드를 더 빠르게 만들 수 있다.
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) sess.load(Parent.class, id);
+Child c = new Child();
+c.setParent(p);
+p.getChildren().add(c); //no need to fetch the collection!
+sess.flush();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-collections-oneshotdelete">
+ <title>원 샷 delete</title>
+
+ <para>
+ 종종 콜렉션 요소들을 하나씩 삭제하는 것은 극히 비효율적일 수 있다! Hibernate는 완전하게 바보가 아니어서, 그것은 새로운 공백의
+ 콜렉션의 경우(예를 들어 당신이 <literal>list.clear()</literal>를 호출했을 경우)에 그것을 행하지 않을 것임을 알고 있다.
+ 이 경우에, Hibernate는 하나의 <literal>DELETE</literal> 명령을 내릴 것이고 우리는 모두 행했다!
+ </para>
+
+ <para>
+ 우리가 길이 20인 하나의 콜렉션에 한 개의 요소를 추가하고 그런 다음 두 개의 요소들을 제거한다고 가정하자. Hibernate는
+ (콜렉션이 bag가 아닌 한) 한 개의 <literal>INSERT</literal> 문장과 두 개의 <literal>DELETE</literal> 문장을 명령
+ 내릴 것이다. 이것은 확실히 마음에 든다.
+ </para>
+
+ <para>
+ 하지만, 우리가 두 개의 요소들을 남겨둔채 18 개의 요소들을 제거하고 나서 세 개의 새로운 요소들을 추가한다고 가정하자.
+ 두 가지 가능한 처리 방법들이 존재한다.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>하나씩 열 여덟 개의 행들을 삭제한 다음에 세 개의 행들을 삽입시킨다</para>
+ </listitem>
+ <listitem>
+ <para>
+ (한 개의 SQL <literal>DELETE</literal>로)전체 콜렉션을 삭제하고 모든 다섯개의 현재 요소들을 (하나씩) insert 시킨다
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate는 두 번째 옵션이 아마 이 경우에 더 빠르다는 점을 알 만큼 충분히 영리하지 않다.(그리고 Hibernate가 그렇게 영리해지는 것을 희망
+ 하는 것은 가능하지 않을 것이다; 그런 특징은 데이터베이스 트리거들 등을 혼동스럽게 할 수도 있다.)
+ </para>
+
+ <para>
+ 다행히, 당신은 원래의 콜렉션을 폐기시키고(예를 들어 참조 해제하고) 모든 현재 요소들을 가진 새로이 초기화된 콜렉션을
+ 반환함으로써 아무때든지 이 특징을 강제시킬 수 있다. 이것은 시간이 흐름에 따라 매우 유용하고 강력해질 수 있다.
+ </para>
+
+ <para>
+ 물론 단 한번의 삭제(one-shot-delete)는 <literal>inverse="true"</literal>로 매핑된 콜렉션들에 적용되지 않는다.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="performance-monitoring" revision="1">
+ <title>퍼포먼스 모니터링하기</title>
+
+ <para>
+ 최적화는 퍼포먼스 관련 숫자들에 대한 모니터링과 접근 없이는 많이 사용되지 않는다. Hibernate는 그것의 내부적인 오퍼레이션들에 대한
+ 전체 영역의 특징들을 제공한다. Hibernate에서 Statistics는 <literal>SessionFactory</literal>에 대해 이용 가능하다.
+ </para>
+
+ <sect2 id="performance-monitoring-sf" revision="2">
+ <title>SessionFactory 모니터링 하기</title>
+
+ <para>
+ 당신은 두 가지 방법들로 <literal>SessionFactory</literal> metrics에 접근할 수 있다. 당신의 첫 번째 옵션은
+ <literal>sessionFactory.getStatistics()</literal>를 호출하고 당신 스스로 <literal>Statistics</literal>를
+ 읽거나 디스플레이 하는 것이다.
+ </para>
+
+ <para>
+ 만일 당신이 <literal>StatisticsService</literal> MBean을 이용 가능하도록 할 경우 Hibernate는 또한 metrics를
+ 발표하는데 JMX를 사용할 수 있다. 당신은 모든 당신의<literal>SessionFactory</literal>에 대해 한 개의 MBean 또는
+ 팩토리 당 한 개를 이용 가능하게 할 수 있다. 최소한의 구성 예제들은 다음 코드를 보라:
+ </para>
+
+ <programlisting><![CDATA[// MBean service registration for a specific SessionFactory
+Hashtable tb = new Hashtable();
+tb.put("type", "statistics");
+tb.put("sessionFactory", "myFinancialApp");
+ObjectName on = new ObjectName("hibernate", tb); // MBean object name
+
+StatisticsService stats = new StatisticsService(); // MBean implementation
+stats.setSessionFactory(sessionFactory); // Bind the stats to a SessionFactory
+server.registerMBean(stats, on); // Register the Mbean on the server]]></programlisting>
+
+
+<programlisting><![CDATA[// MBean service registration for all SessionFactory's
+Hashtable tb = new Hashtable();
+tb.put("type", "statistics");
+tb.put("sessionFactory", "all");
+ObjectName on = new ObjectName("hibernate", tb); // MBean object name
+
+StatisticsService stats = new StatisticsService(); // MBean implementation
+server.registerMBean(stats, on); // Register the MBean on the server]]></programlisting>
+
+ <para>
+ TODO: 이것은 의미가 없다: 첫번째 경우에, 우리는 직접 MBean을 검색하고 사용한다.
+ 두 번째 경우에 우리는 JNDI 이름을 사용하기 전에 세션 팩토리가 보관하고 있는 JNDI 이름을 부여해야 한다.
+ <literal>hibernateStatsBean.setSessionFactoryJNDIName("my/JNDI/Name")</literal>을 사용하라.
+ </para>
+ <para>
+ 당신은 <literal>SessionFactory</literal>에 대한 모니터링을 (비)활성화 시킬 수 있다
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ 구성 시 : <literal>hibernate.generate_statistics</literal>, 디폴트는 <literal>false</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>
+ 실행 시 : <literal>sf.getStatistics().setStatisticsEnabled(true)</literal> 또는
+ <literal>hibernateStatsBean.setStatisticsEnabled(true)</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Statistics(통계량들)은 <literal>clear()</literal> 메소드를 사용하여 프로그래밍 방식으로 재설정 될 수 있다. 요약은
+ <literal>logSummary()</literal> 메소드를 사용하여 logger(info 레벨)에게 전송될 수 있다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-monitoring-metrics" revision="1">
+ <title>Metrics</title>
+
+ <para>
+ Hibernate는 매우 기본적인 것에서부터 어떤 시나리오들에만 관련된 전문 정보에 이르는 많은 metrics를 제공한다.
+ 모든 이용 가능한 카운터들은 <literal>Statistics</literal> interface API에서 3개의 카테고리로 설명되어 있다:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ 열려진 세션들의 개수, 검색된 JDBC 커넥션들의 개수 등과 같은 일반적인 <literal>Session</literal> 사용에
+ 관련된 metrics.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 전체적으로 엔티티들, 콜렉션들, 질의들, 그리고 캐시들에 관련된 metrics(전역 metrics로 알려져 있음),
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 특정한 엔티티, 콜렉션, 질의 또는 캐시 영역에 관련된 상세 metrics.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 예를 들어 당신은 엔티티, 콜렉션, 질의들의 캐시 성공율 및 실패율, put(역자 주, 캐시 시도, putt) 비율, 콜렉션들과 질의들,
+ 그리고 평균 질의 요구 시간 등을 찾을 수 있다. 수 밀리초들가 자바에서 근사치에 종속됨을 의식하라. Hibernate는 JVM 정밀도에
+ 묶여 있고, 몇몇 플랫폼들에서 이것은 심지어 약 10초가 될 수도 있다.
+ </para>
+
+ <para>
+ 간단한 getter들은 (예를 들어 특정 엔티티, 콜렉션, 캐시 영역에 묶이지 않은) 전역 metrics에 접근하는데 사용된다. 당신은
+ 그것(특정 엔티티, 콜렉션, 또는 캐시 영역)의 이름을 통해, 그리고 질의들에 대한 그것의 HQL 또는 SQL 표현을 통해 특정 엔티티,
+ 콜렉션, 또는 캐시 영역의 metrics에 접근할수 있다. 추가 정보는 <literal>Statistics</literal>, <literal>EntityStatistics</literal>,
+ <literal>CollectionStatistics</literal>, <literal>SecondLevelCacheStatistics</literal>, 그리고
+ <literal>QueryStatistics</literal>를 참조하라. 다음 코드는 간단한 예제를 보여준다:
+ </para>
+
+ <programlisting><![CDATA[Statistics stats = HibernateUtil.sessionFactory.getStatistics();
+
+double queryCacheHitCount = stats.getQueryCacheHitCount();
+double queryCacheMissCount = stats.getQueryCacheMissCount();
+double queryCacheHitRatio =
+ queryCacheHitCount / (queryCacheHitCount + queryCacheMissCount);
+
+log.info("Query Hit ratio:" + queryCacheHitRatio);
+
+EntityStatistics entityStats =
+ stats.getEntityStatistics( Cat.class.getName() );
+long changes =
+ entityStats.getInsertCount()
+ + entityStats.getUpdateCount()
+ + entityStats.getDeleteCount();
+log.info(Cat.class.getName() + " changed " + changes + "times" );]]></programlisting>
+
+ <para>
+ 모든 엔티티들, 콜렉션들, 콜렉션들,질의들 그리고 영역 캐시들에 대해 작업하기 위해, 당신은 다음 메소드들로서 엔티티들,
+ 콜렉션들, 질의들, 그리고 영역 캐시들에 대한 이름들의 목록을 검색할 수 있다: <literal>getQueries()</literal>,
+ <literal>getEntityNames()</literal>, <literal>getCollectionRoleNames()</literal>, 그리고
+ <literal>getSecondLevelCacheRegionNames()</literal>.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/persistent_classes.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/persistent_classes.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/persistent_classes.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/persistent_classes.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,502 @@
+<chapter id="persistent-classes" revision="2">
+ <title>영속 클래스들</title>
+
+ <para>
+ 영속 클래스들은 비지니스 문제의 엔티티들(예를 들어 E-Commerce 어플리케이션에서 고객이나 주문)을 구현하는
+ 어플리케이션 내의 클래스들이다. 영속 클래스들의 인스턴스들은 영속 상태에 있는 것으로 전혀 간주되지 않는다 -
+ 대신에 하나의 인스턴스는 transient 또는 detached 상태일 수 있다.
+ </para>
+
+ <para>
+ Hibernate는 이들 클래스들이 Plain Old Java Object (POJO) 프로그래밍 모형으로서 알려진, 몇몇 간단한
+ 규칙들을 따를 경우에 가장 잘 동작한다. 하지만 이들 규칙들 중 어떤 것도 어려운 사양들이 아니다. 진정 Hibernate3는
+ 당신의 영속 객체들의 특징에 대해 매우 적은 것을 가정한다. 당신은 다른 방법들로 도메인 모형을 표현할 수 있다 :
+ 예를 들어 <literal>Map</literal> 인스턴스의 트리들을 사용하기.
+ </para>
+
+ <sect1 id="persistent-classes-pojo">
+ <title>간단한 POJO 예제</title>
+
+ <para>
+ 대부분의 자바 어플리케이션들은 고양이과들을 표현하는 영속 클래스를 필요로 한다.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+import java.util.Date;
+
+public class Cat {
+ private Long id; // identifier
+
+ private Date birthdate;
+ private Color color;
+ private char sex;
+ private float weight;
+ private int litterId;
+
+ private Cat mother;
+ private Set kittens = new HashSet();
+
+ private void setId(Long id) {
+ this.id=id;
+ }
+ public Long getId() {
+ return id;
+ }
+
+ void setBirthdate(Date date) {
+ birthdate = date;
+ }
+ public Date getBirthdate() {
+ return birthdate;
+ }
+
+ void setWeight(float weight) {
+ this.weight = weight;
+ }
+ public float getWeight() {
+ return weight;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+ void setColor(Color color) {
+ this.color = color;
+ }
+
+ void setSex(char sex) {
+ this.sex=sex;
+ }
+ public char getSex() {
+ return sex;
+ }
+
+ void setLitterId(int id) {
+ this.litterId = id;
+ }
+ public int getLitterId() {
+ return litterId;
+ }
+
+ void setMother(Cat mother) {
+ this.mother = mother;
+ }
+ public Cat getMother() {
+ return mother;
+ }
+ void setKittens(Set kittens) {
+ this.kittens = kittens;
+ }
+ public Set getKittens() {
+ return kittens;
+ }
+
+ // addKitten not needed by Hibernate
+ public void addKitten(Cat kitten) {
+ kitten.setMother(this);
+ kitten.setLitterId( kittens.size() );
+ kittens.add(kitten);
+ }
+}]]></programlisting>
+
+ <para>
+ 준수할 네 개의 주요 규칙들이 다음에 있다:
+ </para>
+
+
+ <sect2 id="persistent-classes-pojo-constructor" revision="1">
+ <title>아규먼트 없는 생성자를 구현하라 </title>
+
+ <para>
+ <literal>Cat</literal>은 아규먼트 없는 생성자를 갖는다. 모든 영속 클래스들은 Hibernate는
+ <literal>Constructor.newInstance()</literal>를 사용하여 그것들을 초기화 시킬 수 있도록 디폴트 생성자
+ (public이 아닐 수 있다)를 가져야 한다. 우리는 Hibernate 내에서 런타임 프락시 생성을 위한 최소한의
+ <emphasis>패키지</emphasis> 가시성(visibility)를 가진 디폴트 생성자를 가질 것을 강력하게 권장한다.
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-identifier" revision="2">
+ <title>identifier 프로퍼티를 제공하라(옵션)</title>
+
+ <para>
+ <literal>Cat</literal>은 <literal>id</literal>로 명명된 하나의 프로퍼티를 갖는다. 이 프로퍼티는
+ 데이터베이스 테이블의 프라이머리 키 컬럼으로 매핑된다. 이 프로퍼티는 어떤 것으로 명명될 수도 있고, 그것의 타입은
+ 임의의 원시 타입, 원시 "wrapper" 타입, <literal>java.lang.String</literal> 또는 <literal>java.util.Date</literal>일
+ 수 있다. (만일 당신의 리거시 데이터베이스 테이블이 composite 키들을 갖고 있다면, 당신은 이들 타입들을 가진
+ 사용자 정의 클래스를 사용할 수도 있다 - 나중에 composite 식별자들에 대한 절을 보라)
+ </para>
+
+ <para>
+ identifier 프로퍼티는 엄격하게 옵션이다. 당신은 그것을 생략할 수도 있고, Hibernate로 하여금 내부적으로
+ 객체 식별자들을 추적하도록 할 수 있다. 하지만 우리는 이것을 권장하지 않는다.
+ </para>
+
+ <para>
+ 사실, 어떤 기능은 identifier 프로퍼티를 선언하는 클래스들에 대해서만 이용 가능하다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ detached 객체들에 대한 Transitive reattachment(cascade update 또는 cascade merge)
+ - <xref linkend="objectstate-transitive"/>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.saveOrUpdate()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.merge()</literal>
+ </para>
+ <para>
+ 를 보라
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 우리는 당신이 영속 클래스들에 대해 일관되게 명명된 identifier 프로퍼티들을 선언할 것을 권장한다. 게다가 우리는
+ 당신이 nullable 타입(예를 들어 non-primitive)을 사용할 것을 권장한다.
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-final">
+ <title>final이 아닌 클래스들을 선호하라(옵션)</title>
+ <para>
+ Hibernate의 중심 특징인, 프락시(<emphasis>proxies</emphasis>)들은 final이 아닌 영속 클래스들 또는 모두
+ public 메소드들로 선언된 인터페이스의 구현인 영속 클래스들에 의존한다.
+ </para>
+ <para>
+ 당신은 Hibernate로 인터페이스를 구현하지 않은 <literal>final</literal> 클래스들을 영속화 시킬 수 있지만
+ 당신은 lazy 연관 페칭(lazy association fetching)에 대해 프락시들을 사용할 수 없을 것이다 -그것은 퍼포먼스
+ 튜닝을 위한 당신의 옵션들을 제한시킬 것이다.
+ </para>
+ <para>
+ 당신은 또한 non-final 클래스들 상에 <literal>public final</literal> 메소드들을 선언하는 것을 피해야 한다.
+ 만일 당신이 <literal>public final</literal> 메소드를 가진 클래스를 사용하고자 원할 경우, 당신은
+ <literal>lazy="false"</literal>를 설정함으로써 명시적으로 프락싱을 사용 불가능하도록 해야 한다.
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-accessors" revision="2">
+ <title>영속 필드들을 위한 accessor들과 mutator들을 선언하라(옵션)</title>
+
+ <para>
+ <literal>Cat</literal>은 그것의 모든 영속 필드들에 대해 accessor 메소드들을 선언한다. 많은 다른 ORM 도구들은
+ 인스턴스 변수들을 직접 영속화 시킨다. 우리는 관계형 스키마와 클래스의 내부적인 데이터 구조들 사이에 간접적인 수단을
+ 제공하는 것이 더 좋다고 믿고 있다. 디폴트로 Hibernate는 자바빈즈 스타일 프로퍼티들을 영속화 시키고, <literal>getFoo</literal>,
+ <literal>isFoo</literal>와 <literal>setFoo</literal> 형식의 메소드 이름들을 인지한다. 당신은 진정으로
+ 특정 프로퍼티에 대한 직접적인 필드 접근으로 전환할 수도 있다.
+ </para>
+
+ <para>
+ 프로퍼티들은 public으로 선언될 필요가 <emphasis>없다</emphasis> - Hibernate는 디폴트로
+ <literal>protected</literal> get/set 쌍 또는 <literal>private</literal> get/set
+ 쌍을 가진 프로퍼티를 영속화 시킬 수 있다.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-inheritance">
+ <title>상속 구현하기</title>
+
+ <para>
+ 서브클래스는 또한 첫 번째 규칙들과 두 번째 규칙들을 주시해야 한다. 그것은 슈퍼클래스 <literal>Cat</literal>으로부터
+ 그것의 identifier 프로퍼티를 상속받는다.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+public class DomesticCat extends Cat {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+ protected void setName(String name) {
+ this.name=name;
+ }
+}]]></programlisting>
+ </sect1>
+
+ <sect1 id="persistent-classes-equalshashcode" revision="1">
+ <title><literal>equals()</literal>와 <literal>hashCode()</literal> 구현하기</title>
+
+ <para>
+ 만일 당신이 다음의 경우라면, 당신은 <literal>equals()</literal>와 <literal>hashCode()</literal>
+ 메소드들을 오버라이드 시켜야 한다.
+ </para>
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 하나의 <literal>Set</literal> 속에 영속 클래스들의 인스턴스들을 집어넣고자 의도하고
+ (many-valued 연관들에 대해 권장되는 방법)
+ <emphasis>그리고</emphasis>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ detached 인스턴스들의 reattachment(재첨부)를 사용하고자 의도하는
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate는 특정 session 범위 내에서만 persistent identity(데이터베이스 행)과 Java identity의 같음을 보장한다.
+ 따라서 우리가 다른 세션들에서 검색된 인스턴스들을 혼합시키자마자, 우리가 <literal>Set</literal>들에 대해 유의미하게
+ 만들고자 원할 경우, 우리는 <literal>equals()</literal>와 <literal>hashCode()</literal>를 구현해야 한다.
+ </para>
+
+ <para>
+ 가장 명백한 방법은 두 객체들의 identifier 값을 비교함으로써 <literal>equals()</literal>/<literal>hashCode()</literal>를
+ 구현하는 것이다. 만일 그 값이 동일하다면, 둘다 동일한 데이터베이스 행이어야 하고, 그러므로 그것들은 같다(둘다 하나의
+ <literal>Set</literal>에 추가되는 경우에, 우리는 <literal>Set</literal> 속에서 하나의 요소만을 갖게 될 것이다).
+ 불행하게도, 우리는 생성되는 식별자들을 갖는 그 접근법을 사용할 수 없다! Hibernate는 오직 식별자 값들을 영속화 되는 객체들에
+ 할당할 것이고, 새로이 생성된 인스턴스는 임의의 identifier 값을 갖지 않을 것이다! 만일 인스턴스가 저장되지 않고 현재 하나의
+ <literal>Set</literal> 속에 있을 경우에, 그것을 저장하는것은 하나의 식별자 값을 그 객체에게 할당할 것이다. 만일
+ <literal>equals()</literal>와 <literal>hashCode()</literal>가 그 식별자 값에 기초할 경우, hash 코드는
+ <literal>Set</literal>의 계약을 파기하여 변경될 것이다. 이 문제에 대한 전체 논의에 대해서는 Hibernate 웹 사이트를 보라.
+ 이것은 Hibernate 쟁점이 아닌, 객체 identity와 equality에 관한 통상의 자바 의미론임을 노트하라.
+ </para>
+
+ <para>
+ 우리는 <emphasis>Business key equality</emphasis>를 사용하여 <literal>equals()</literal>와 <literal>hashCode()</literal>를
+ 구현할 것 권장한다. Business key equality는 <literal>equals()</literal> 메소드가 비지니스 키, 즉 실세계에서 우리의 인스턴스를
+ 식별하게 될 키(<emphasis>natural</emphasis> 후보 키)를 형성하는 프로퍼티들만을 비교한다는 점을 의미한다 :
+ </para>
+
+ <programlisting><![CDATA[public class Cat {
+
+ ...
+ public boolean equals(Object other) {
+ if (this == other) return true;
+ if ( !(other instanceof Cat) ) return false;
+
+ final Cat cat = (Cat) other;
+
+ if ( !cat.getLitterId().equals( getLitterId() ) ) return false;
+ if ( !cat.getMother().equals( getMother() ) ) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = getMother().hashCode();
+ result = 29 * result + getLitterId();
+ return result;
+ }
+
+}]]></programlisting>
+
+ <para>
+ 하나의 비지니스 키는 데이터베이스 프라이머리 키 후보 만큼 견고하지 않아야 한다(<xref linkend="transactions-basics-identity"/>를 보라).
+ 대개 변경할 수 없는 프로퍼티 또는 유일한(unique) 프로퍼티는 대개 비지니스 키에 대한 좋은 후보들이다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-dynamicmodels">
+ <title>동적인 모형들</title>
+
+ <para>
+ <emphasis>다음 특징들은 현재 실험적으로 고려되고 있으며 장래에는 변경될 수 있음을 노트하라.</emphasis>
+ </para>
+
+ <para>
+ 영속 엔티티들은 반드시 실행시에 POJO 클래스들로 또는 자바빈즈 객체들로 표현되어야할 필요는 없다. Hibernate는
+ 또한 (실행 시에 <literal>Map</literal>들을 가진 <literal>Map</literal>들을 사용하여) 동적인 모형들을 지원하고
+ DOM4J 트리들로서 엔티티들에 대한 표현을 지원한다. 이 접근법으로, 당신은 영속 클래스들을 작성하지 않고, 오직 매핑 파일들
+ 만을 작성한다.
+ </para>
+
+ <para>
+ 디폴트로, Hibernate는 통산의 POJO 모드로 동작한다. 당신은 <literal>default_entity_mode</literal> 구성 옵션을
+ 사용하여 특별한 <literal>SessionFactory</literal>에 대해 디폴트 엔티티 표현 모드를 설정할 수 있다
+ (<xref linkend="configuration-optional-properties"/>을 보라).
+ </para>
+
+ <para>
+ 다음 예제들은<literal>Map</literal>들을 사용하는 표현을 설명한다. 먼저 매핑 파일에서, <literal>entity-name</literal>은
+ 클래스 이름 대신에(또는 클래스 이름에 덧붙여) 선언되어야 한다:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class entity-name="Customer">
+
+ <id name="id"
+ type="long"
+ column="ID">
+ <generator class="sequence"/>
+ </id>
+
+ <property name="name"
+ column="NAME"
+ type="string"/>
+
+ <property name="address"
+ column="ADDRESS"
+ type="string"/>
+
+ <many-to-one name="organization"
+ column="ORGANIZATION_ID"
+ class="Organization"/>
+
+ <bag name="orders"
+ inverse="true"
+ lazy="false"
+ cascade="all">
+ <key column="CUSTOMER_ID"/>
+ <one-to-many class="Order"/>
+ </bag>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 심지어 비록 연관들이 대상(target) 클래스 이름들을 사용하여 선언될지라도, 연관들의 대상(target) 타입은 또한 POJO가 아닌
+ 동적인 엔티티일 수 있음을 노트하라.
+ </para>
+
+ <para>
+ <literal>SessionFactory</literal>에 대한 디폴트 엔티티 모드를 <literal>dynamic-map</literal>으로 설정한 후에,
+ 우리는 <literal>Map</literal>들을 가진 <literal>Map</literal>들에 대해 실행 시에 작업할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[Session s = openSession();
+Transaction tx = s.beginTransaction();
+Session s = openSession();
+
+// Create a customer
+Map david = new HashMap();
+david.put("name", "David");
+
+// Create an organization
+Map foobar = new HashMap();
+foobar.put("name", "Foobar Inc.");
+
+// Link both
+david.put("organization", foobar);
+
+// Save both
+s.save("Customer", david);
+s.save("Organization", foobar);
+
+tx.commit();
+s.close();]]></programlisting>
+
+ <para>
+ dynamic 매핑의 장점들은 엔티티 클래스 구현에 대한 필요 없이도 프로토타이핑을 위한 빠른 전환 시간이다. 하지만 당신은
+ 컴파일 시 타입 체킹을 잃고 실행 시에 많은 예외상황들을 다루게 될 것이다. Hibernate 매핑 덕분에,
+ 나중에 고유한 도메인 모형 구현을 상단에 추가하는 것이 허용되어서, 데이터베이스 스키마가 쉽게 정규화 되고 소리가 울려 퍼질 수 있다.
+ </para>
+
+ <para>
+ 엔티티 표현 모드들은 또한 하나의 단위 <literal>Session</literal> 기준에 대해 설정될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[Session dynamicSession = pojoSession.getSession(EntityMode.MAP);
+
+// Create a customer
+Map david = new HashMap();
+david.put("name", "David");
+dynamicSession.save("Customer", david);
+...
+dynamicSession.flush();
+dynamicSession.close()
+...
+// Continue on pojoSession
+]]></programlisting>
+
+
+ <para>
+ <literal>EntityMode</literal>를 사용하는 <literal>getSession()</literal>에 대한 호출은
+ <literal>SessionFactory</literal>가 아닌, <literal>Session</literal> API에 대한 것임을 노트하길 바란다.
+ 그 방법으로, 새로운 <literal>Session</literal>은 기본 JDBC 커넥션, 트랜잭션, 그리고 다른 컨텍스트 정보를 공유한다.
+ 이것은 당신이 두 번째 <literal>Session</literal> 상에서 <literal>flush()</literal>와 <literal>close()</literal>를
+ 호출하지 말아야 하고, 또한 트랜잭션 및 커넥션 핸들링을 주된 작업 단위에게 맡긴다는 점을 의미한다.
+ </para>
+
+ <para>
+ XML 표현 가용성들에 대한 추가 정보는 <xref linkend="xml"/>에서 찾을 수 있다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-tuplizers" revision="1">
+ <title>Tuplizer들</title>
+
+ <para>
+ <literal>org.hibernate.tuple.Tuplizer</literal>, 그리고 그것의 서브-인터페이스들은 데이터의 조각에 대한
+ 특별한 표현의 <literal>org.hibernate.EntityMode</literal>가 주어지면 그 표현을 관리하는 책임이 있다. 만일
+ 주어진 데이터 조각이 하나의 데이터 구조로 간주될 경우, 그때 하나의 tuplizer는 그런 데이터 구조를 생성시키는 방법과
+ 그런 데이터 구조로부터 값들을 추출시키는 방법 그리고 그런 데이터구조 속으로 값들을 삽입시키는 방법을 알고 있는 것이다.
+ 예를 들어, POJO 엔티티 모드의 경우, 대응하는 tuplizer는 그것의 생성자를 통해 POJO를 생성시키는 방법, 그리고 정의된
+ 프로퍼티 접근자들을 사용하여 POJO 프로퍼티들에 접근하는 방법을 안다.
+ <literal>org.hibernate.tuple.entity.EntityTuplizer</literal> 인터페이스와
+ <literal>org.hibernate.tuple.component.ComponentTuplizer</literal> 인터페이스에 의해 표현되는 두 가지 고급 유형의
+ Tuplizer들이 존재한다. <literal>EntityTuplizer</literal>들은 엔티티들에 관해서는 위에 언급된 계약들을 매핑할
+ 책임이 있는 반면에, <literal>ComponentTuplizer</literal>들은 컴포넌트들에 대해서도 동일한 것을 행한다.
+ </para>
+
+ <para>
+ 사용자들은 또한 그들 자신의 tuplizer들을 플러그 시킬 수 있다. 아마 당신은 dynamic-map entity-mode 동안에 사용되는
+ <literal>java.util.HashMap</literal> 대신에 하나의 <literal>java.util.Map</literal> 구현을 필요로 한다;
+ 또는 아마 당신은 디폴트로 사용되는 방도 보다는 하나의 다른 다른 프릭시 산출 방도를 필요로 한다. 둘다 하나의 맞춤형 tuplizer를
+ 정의함으로써 성취될 것이다. Tuplizer들 정의들은 그것들이 관리할 수단인 엔티티 매핑 또는 컴포넌트 매핑에 첨부된다. 우리의
+ 고객 엔티티에 대한 예제로 되돌아가면:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+ <class entity-name="Customer">
+ <!--
+ Override the dynamic-map entity-mode
+ tuplizer for the customer entity
+ -->
+ <tuplizer entity-mode="dynamic-map"
+ class="CustomMapTuplizerImpl"/>
+
+ <id name="id" type="long" column="ID">
+ <generator class="sequence"/>
+ </id>
+
+ <!-- other properties -->
+ ...
+ </class>
+</hibernate-mapping>
+
+
+public class CustomMapTuplizerImpl
+ extends org.hibernate.tuple.entity.DynamicMapEntityTuplizer {
+ // override the buildInstantiator() method to plug in our custom map...
+ protected final Instantiator buildInstantiator(
+ org.hibernate.mapping.PersistentClass mappingInfo) {
+ return new CustomMapInstantiator( mappingInfo );
+ }
+
+ private static final class CustomMapInstantiator
+ extends org.hibernate.tuple.DynamicMapInstantitor {
+ // override the generateMap() method to return our custom map...
+ protected final Map generateMap() {
+ return new CustomMap();
+ }
+ }
+}]]></programlisting>
+
+
+ </sect1>
+
+ <para>
+ TODO: property 패키지와 proxy 패키지 내에 user-extension 프레임웍을 문서화 할 것.
+ </para>
+
+</chapter>
+
Added: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/preface.xml
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/preface.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/preface.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,110 @@
+<?xml version='1.0' encoding="UTF-8"?>
+
+<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<preface id="preface" revision="2">
+ <title>머리말</title>
+
+ <para>
+ 객체 지향 소프트웨어와 관계형 데이터베이스로 작업하는 것은 오늘날의 엔터프라이즈 환경들에서 성가시고 시간이
+ 소비될 수 있다. Hibernate는 자바 환경들을 위한 객체/관계형 매핑 도구이다.
+ object/relational mapping(ORM) 용어는 객체 모형으로부터 SQL-기반의 스키마를 가진
+ 관계형 데이터 모형으로의 데이터 표상을 매핑하는 기술을 언급한다.
+ </para>
+
+ <para>
+ Hibernate는 자바 클래스들로부터 데이터베이스로의 매핑(그리고 자바 데이터 타입들로부터 SQL 데이터
+ 타입들로의 매핑)을 처리할 뿐만 아니라, 또한 데이터 질의와 검색 편의들을 제공하며, SQL과 JDBC로
+ 수작업 데이터 핸들링에 소요되는 개발 시간을 현저하게 단축시켜줄 수 있다.
+ </para>
+
+ <para>
+ Hibernate의 목적은 공통된 데이터 영속화 관련 프로그래밍 작업들의 95%를 덜어주는 것이다.
+ Hibernate는 데이터베이스에서 비지니스 로직을 구현하는데 내장 프로시저들을 전용으로 사용하는 데이터
+ 중심적 어플리케이션에 대한 최상의 솔루션이 아닐 수도 있지만, 그것은 자바 기반 미들-티어에서 객체 지향
+ 도메인 모형들과 비지니스 로직에 가장 유용하다. 하지만 Hibernate는 벤더 지정적인 SQL 코드를
+ 제거하거나 캡슐화 시키는 당신을 확실히 도와줄 수 있고 테이블 형식의 표현으로부터 객체들의 그래프로 결과
+ 셋을 변환하는 공통된 태스크를 도와줄 것이다.
+ </para>
+
+ <para>
+ 만일 당신이 Hibernate와 Object/Relational 매핑 또는 심지어 자바에 초심자라면, 다음
+ 단계들을 따르기 바란다:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ 더 많은 단계적인 사용 설명서들을 가진 더 긴 튜토리얼은
+ <xref linkend="tutorial"/>
+ 을 읽어라. 튜토리얼을 위한 소스 코드는 <literal>doc/reference/tutorial/</literal>
+ 디렉토리에 포함되어 있다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Hibernate가 사용될 수 있는 환경을 이해려면
+ <xref linkend="architecture" />
+ 를 읽어라.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Hibernate 배포본 내의
+ <literal>eg/</literal>
+ 디렉토리를 살펴 보라. 이 디렉토리는 간단한 스탠드얼론 어플리케이션을 포함하고 있다. 당신의
+ JDBC 드라이버를
+ <literal>lib/</literal>
+ 디렉토리에 복사하고 당신의 데이터베이스에 맞는 정확한 값을 지정하여
+ <literal>etc/hibernate.properties</literal>
+ 를 편집하라. 배보본 디렉토리에서 명령 라인 프롬프트에서 (Ant를 사용하여)
+ <literal>ant eg</literal>
+ 를 타이핑 하거나 , Windows 하에서
+ <literal>build eg</literal>
+ 를 타이프 하라.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 당신의 주된 정보의 소스로서 이 참조 문서를 사용하라. 만일 어플리케이션 설계에 대해 더 많은
+ 도움을 필요로 하거나 당신이 단계적인 튜토리얼을 선호한다면
+ <emphasis>Java Persistence with Hibernate</emphasis>
+ (http://www.manning.com/bauer2)을 읽는 것을 고려하라.또한
+ http://caveatemptor.hibernate.org에 방문하여 Java Persistence
+ with Hibernate용 예제 어플리케이션을 다운로드 하라.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ FAQ들은 Hibernate 웹 사이트 상에 답변되어 있다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 제 3의 데모들, 예제들, 그리고 튜토리얼들은 Hibernate 웹 사이트 상에 링크되어
+ 있다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Hibernate 웹사이트 상의 공동체 영역은 설계 패턴과 다양한 통합 솔루션들(Tomcat,
+ JBoss AS, Struts, EJB 등.)에 관한 좋은 리소스이다.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ 질문이 있다면, Hibernate 상에 링크되어 있는 사용자 포럼을 사용하라. 우리는 또한 버그 보고와 특징
+ 요청들을 위한 JIRA 쟁점 추적 시스템을 제공한다. 당신이 Hibernate의 개발에 관심이 있다면,
+ 개발자 메일링 리스트에 참여하라. 만일 당신이 이 문서를 당신의 언어로 번역하는 것에 관심이 있다면, 개발자
+ 메일링 리스트에 접촉하라.
+ </para>
+
+ <para>
+ Hibernate를 위한 상용 개발 지원, 제품 지원, 그리고 교육은 JBoss Inc를 통해 이용 가능하다
+ (http://www.hibernate.org/SupportTraining/를 보라). Hibernate는
+ JBoss Professional Open Source product 프로젝트이고 제품들에 대한 JBoss
+ Enterprise Middleware System (JEMS) suite의 중대한 컴포넌트이다.
+ </para>
+
+</preface>
\ No newline at end of file
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/query_criteria.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/query_criteria.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/query_criteria.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/query_criteria.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,418 @@
+<chapter id="querycriteria">
+ <title>Criteria 질의들</title>
+
+ <para>
+ Hibernate는 직관적인, 확장 가능한 criteria query API를 특징 짓는다.
+ </para>
+
+ <sect1 id="querycriteria-creating">
+ <title><literal>Criteria</literal> 인스턴스 생성하기</title>
+
+ <para>
+ <literal>org.hibernate.Criteria</literal>인터페이스는 특정 영속 클래스에 대한 질의를 표현한다.
+ <literal>Session</literal>은 <literal>Criteria</literal> 인스턴스들에 대한 팩토리이다.
+ </para>
+
+ <programlisting><![CDATA[Criteria crit = sess.createCriteria(Cat.class);
+crit.setMaxResults(50);
+List cats = crit.list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-narrowing">
+ <title>결과 셋 제한하기</title>
+
+ <para>
+ 개별적인 질의 기준은 <literal>org.hibernate.criterion.Criterion</literal> 인터페이스의 인스턴스이다.
+ <literal>org.hibernate.criterion.Restrictions</literal> 클래스는 어떤 미리 만들어진 <literal>Criterion</literal>
+ 타입들을 얻는 팩토리 메소드들을 정의한다.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .add( Restrictions.between("weight", minWeight, maxWeight) )
+ .list();]]></programlisting>
+
+ <para>
+ 제한들은 논리적으로 그룹지워질 수도 있다.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .add( Restrictions.or(
+ Restrictions.eq( "age", new Integer(0) ),
+ Restrictions.isNull("age")
+ ) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
+ .add( Restrictions.disjunction()
+ .add( Restrictions.isNull("age") )
+ .add( Restrictions.eq("age", new Integer(0) ) )
+ .add( Restrictions.eq("age", new Integer(1) ) )
+ .add( Restrictions.eq("age", new Integer(2) ) )
+ ) )
+ .list();]]></programlisting>
+
+ <para>
+ 미리 만들어진 criterion 타입들(<literal>Restrictions</literal> 서브클래스들)의 영역이 꽤 존재하지만, 특히 유용한 것은
+ 당신으로 하여금 SQL을 직접 지정하도록 해준다.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.sqlRestriction("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) )
+ .list();]]></programlisting>
+
+ <para>
+ 질의된 엔티티의 행 alias에 의해 대체된 <literal>{alias}</literal> placeholder.
+ </para>
+
+ <para>
+ criterion을 얻는 대안적인 접근법은 <literal>Property</literal> 인스턴스로부터 그것을 얻는 것이다. 당신은
+ <literal>Property.forName()</literal>을 호출하여 <literal>Property</literal>를 생성시킬 수 있다.
+ </para>
+
+ <programlisting><![CDATA[
+Property age = Property.forName("age");
+List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.disjunction()
+ .add( age.isNull() )
+ .add( age.eq( new Integer(0) ) )
+ .add( age.eq( new Integer(1) ) )
+ .add( age.eq( new Integer(2) ) )
+ ) )
+ .add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-ordering">
+ <title>결과들을 순서지우기(ordering)</title>
+
+ <para>
+ 당신은 <literal>org.hibernate.criterion.Order</literal>를 사용하여 결과들을 순서(ordering)지울 수 있다.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "F%")
+ .addOrder( Order.asc("name") )
+ .addOrder( Order.desc("age") )
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Property.forName("name").like("F%") )
+ .addOrder( Property.forName("name").asc() )
+ .addOrder( Property.forName("age").desc() )
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-associations" revision="2">
+ <title>연관들</title>
+
+ <para>
+ 당신은 <literal>createCriteria()</literal>를 사용하여 연관들을 네비게이트함으로써 관계된 엔티티들에 대한 컨스트레인트들을
+ 쉽게 지정할 수 있다.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "F%") )
+ .createCriteria("kittens")
+ .add( Restrictions.like("name", "F%") )
+ .list();]]></programlisting>
+
+ <para>
+ 두 번째 <literal>createCriteria()</literal>는 <literal>Criteria</literal>의 새로운 인스턴스를 반환하며, 그것은
+ <literal>kittens</literal> 콜렉션의 요소들을 참조한다는 점을 노트하라.
+ </para>
+
+ <para>
+ 다음 대체 형식은 어떤 환경들에서 유용하다.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .createAlias("kittens", "kt")
+ .createAlias("mate", "mt")
+ .add( Restrictions.eqProperty("kt.name", "mt.name") )
+ .list();]]></programlisting>
+
+ <para>
+ (<literal>createAlias()</literal>는 <literal>Criteria</literal>의 새로운 인스턴스를 생성시키지 않는다.)
+ </para>
+
+ <para>
+ 앞의 두 개의 질의들에 의해 반환된 <literal>Cat</literal> 인스턴스들에 의해 보관된 kittens 콜렉션들은 criteria에 의해
+ 사전-필터링되지 <emphasis>않는다</emphasis>는 점을 노트하라! 만일 당신이 criteria(기준)과 일치하는 고양이 새끼들을
+ 단지 검색하고자 원할 경우, 당신은 하나의 <literal>ResultTransformer</literal>를 사용해야 한다.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .createCriteria("kittens", "kt")
+ .add( Restrictions.eq("name", "F%") )
+ .setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP)
+ .list();
+Iterator iter = cats.iterator();
+while ( iter.hasNext() ) {
+ Map map = (Map) iter.next();
+ Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
+ Cat kitten = (Cat) map.get("kt");
+}]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-dynamicfetching" revision="1">
+ <title>동적인 연관 페칭</title>
+
+ <para>
+ 당신은 <literal>setFetchMode()</literal>를 사용하여 실행 시에 연관 페칭 의미를 지정할 수 있다.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .setFetchMode("mate", FetchMode.EAGER)
+ .setFetchMode("kittens", FetchMode.EAGER)
+ .list();]]></programlisting>
+
+ <para>
+ 이 질의는 outer 조인으로 <literal>mate</literal>와 <literal>kittens</literal> 모두를 페치할 것이다. 추가 정보는
+ <xref linkend="performance-fetching"/>을 보라.
+ </para>
+
+ </sect1>
+
+ <sect1 id="querycriteria-examples">
+ <title>예제 질의들</title>
+
+ <para>
+ <literal>org.hibernate.criterion.Example</literal> 클래스는 주어진 인스턴스로부터 질의 기준(criterion)을 구조화
+ 시키는 것을 당신에게 허용해준다.
+ </para>
+
+ <programlisting><![CDATA[Cat cat = new Cat();
+cat.setSex('F');
+cat.setColor(Color.BLACK);
+List results = session.createCriteria(Cat.class)
+ .add( Example.create(cat) )
+ .list();]]></programlisting>
+
+ <para>
+ 버전 프로퍼티들, 식별자들, 연관관계들이 무시된다. 디폴트로 null 값 프로퍼티들이 제외된다.
+ </para>
+
+ <para>
+ 당신은 <literal>Example</literal>이 적용되는 방법을 조정할 수 있다.
+ </para>
+
+ <programlisting><![CDATA[Example example = Example.create(cat)
+ .excludeZeroes() //exclude zero valued properties
+ .excludeProperty("color") //exclude the property named "color"
+ .ignoreCase() //perform case insensitive string comparisons
+ .enableLike(); //use like for string comparisons
+List results = session.createCriteria(Cat.class)
+ .add(example)
+ .list();]]></programlisting>
+
+ <para>
+ 당신은 연관된 객체들에 대한 criteria(기준)을 위치지우는데 examples를 사용할 수 있다.
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .add( Example.create(cat) )
+ .createCriteria("mate")
+ .add( Example.create( cat.getMate() ) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-projection">
+ <title>Projections, aggregation 그리고 grouping</title>
+ <para>
+ <literal>org.hibernate.criterion.Projections</literal> 클래스는 <literal>Projection</literal> 인스턴스들에
+ 대한 팩토리이다. 우리는 <literal>setProjection()</literal>을 호출하여 하나의 질의에 projection(투사,투영)을 적용시킨다.
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.rowCount() )
+ .add( Restrictions.eq("color", Color.BLACK) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount() )
+ .add( Projections.avg("weight") )
+ .add( Projections.max("weight") )
+ .add( Projections.groupProperty("color") )
+ )
+ .list();]]></programlisting>
+
+ <para>
+ criteria 질의 내에서는 명시적인 "group by"가 필수적이지 않다. 어떤 projection 타입들은
+ <emphasis>grouping projections</emphasis>들이게끔 정의되고, 그것은 또한 SQL <literal>group by</literal> 절 속에
+ 나타난다.
+ </para>
+
+ <para>
+ alias는 선택적으로 projection에 할당될 수 있어서, 투사된(projected) 값은 제한(restriction)들 또는 ordering들 내에서
+ 참조될 수 있다. 다음은 이것을 행하는 두 개의 다른 방법들이다:
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
+ .addOrder( Order.asc("colr") )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.groupProperty("color").as("colr") )
+ .addOrder( Order.asc("colr") )
+ .list();]]></programlisting>
+
+ <para>
+ <literal>alias()</literal> 메소드와 <literal>as()</literal> 메소드는 또 다른 alias 된
+ <literal>Projection</literal>의 인스턴스 내에 하나의 projection 인스턴스를 간단하게 포장한다. 지름길로서,
+ 당신이 projection을 projection 리스트에 추가할 때 당신은 alias를 할당할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount(), "catCountByColor" )
+ .add( Projections.avg("weight"), "avgWeight" )
+ .add( Projections.max("weight"), "maxWeight" )
+ .add( Projections.groupProperty("color"), "color" )
+ )
+ .addOrder( Order.desc("catCountByColor") )
+ .addOrder( Order.desc("avgWeight") )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Domestic.class, "cat")
+ .createAlias("kittens", "kit")
+ .setProjection( Projections.projectionList()
+ .add( Projections.property("cat.name"), "catName" )
+ .add( Projections.property("kit.name"), "kitName" )
+ )
+ .addOrder( Order.asc("catName") )
+ .addOrder( Order.asc("kitName") )
+ .list();]]></programlisting>
+
+ <para>
+ 당신은 또한 projection들을 표현하는데 <literal>Property.forName()</literal>을 사용할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Property.forName("name") )
+ .add( Property.forName("color").eq(Color.BLACK) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount().as("catCountByColor") )
+ .add( Property.forName("weight").avg().as("avgWeight") )
+ .add( Property.forName("weight").max().as("maxWeight") )
+ .add( Property.forName("color").group().as("color" )
+ )
+ .addOrder( Order.desc("catCountByColor") )
+ .addOrder( Order.desc("avgWeight") )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-detachedqueries">
+ <title>Detached 질의들과 서브질의들</title>
+ <para>
+ <literal>DetachedCriteria</literal> 클래스는 당신에게 세션 영역의 외부에서 질의를 생성시키도록 하고, 그런 다음 나중에
+ 어떤 임의의 <literal>Session</literal>을 사용하여 그것을 실행하도록 한다.
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria query = DetachedCriteria.forClass(Cat.class)
+ .add( Property.forName("sex").eq('F') );
+
+Session session = ....;
+Transaction txn = session.beginTransaction();
+List results = query.getExecutableCriteria(session).setMaxResults(100).list();
+txn.commit();
+session.close();]]></programlisting>
+
+ <para>
+ <literal>DetachedCriteria</literal>는 또한 서브질의를 표현하는데 사용된다. 서브질의들을 포함하는 Criterion 인스턴스들은
+ <literal>Subqueries</literal> 또는 <literal>Property</literal>를 통해 얻어질 수 있다.
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)
+ .setProjection( Property.forName("weight").avg() );
+session.createCriteria(Cat.class)
+ .add( Property.forName("weight").gt(avgWeight) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)
+ .setProjection( Property.forName("weight") );
+session.createCriteria(Cat.class)
+ .add( Subqueries.geAll("weight", weights) )
+ .list();]]></programlisting>
+
+ <para>
+ 심지어 상관관계 지워진 서브질의들이 가능하다:
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")
+ .setProjection( Property.forName("weight").avg() )
+ .add( Property.forName("cat2.sex").eqProperty("cat.sex") );
+session.createCriteria(Cat.class, "cat")
+ .add( Property.forName("weight").gt(avgWeightForSex) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <!--TODO: ResultSetTransformer + aliasing. AliasToBeanTransformer는 -JDO2에서 setResultClass와 유사한- 임의적인
+ 사용자 객체들을 반환하는 것을 허용한다. ResultTransformer에 대한 일반적인 사용이 또한 설명될 수 있다. -->
+
+ <sect1 id="query-criteria-naturalid">
+ <title>natural 식별자에 의한 질의들</title>
+
+ <para>
+ 대부분의 질의들에서, criteria 질의들을 포함하여, 질의 캐시는 매우 효율적이지 않다. 왜냐하면 질의 캐시 비유효성이
+ 너무 자주 발생하기 때문이다. 하지만, 우리가 캐시 비유효성 알고리즘을 최적화 시킬 수 있는 한 가지 특별한 종류의 질의가
+ 존재한다: 상수 natural 키에 의한 룩업. 몇몇 어플리케이션들에서, 이런 종류의 질의가 자주 발생한다. criteria API는
+ 이 쓰임새를 위한 특별한 설비를 제공한다.
+ </para>
+
+ <para>
+ 첫번째로 당신은 <literal><natural-id></literal>를 사용하여 당신의 엔티티에 대한 natural 키를 매핑
+ 시켜야 하고, second-level 캐시 사용을 가능하게 해야 한다.
+ </para>
+
+ <programlisting><![CDATA[<class name="User">
+ <cache usage="read-write"/>
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <natural-id>
+ <property name="name"/>
+ <property name="org"/>
+ </natural-id>
+ <property name="password"/>
+</class>]]></programlisting>
+
+ <para>
+ 이 기능은 <emphasis>가변성 있는</emphasis> natural 키들을 가진 엔티티들의 용도로 고안되어 있지 않음을 노트하라.
+ </para>
+
+ <para>
+ 다음으로 , Hibernate 질의 캐시를 사용 가능하도록 하라.
+ </para>
+
+ <para>
+ 이제 <literal>Restrictions.naturalId()</literal>는 캐시 알고리즘을 보다 효율적으로 사용할 수 있도록 우리에게 허용해준다.
+ </para>
+
+ <programlisting><![CDATA[session.createCriteria(User.class)
+ .add( Restrictions.naturalId()
+ .set("name", "gavin")
+ .set("org", "hb")
+ ).setCacheable(true)
+ .uniqueResult();]]></programlisting>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/query_hql.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/query_hql.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/query_hql.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/query_hql.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,1178 @@
+<chapter id="queryhql" revision="1">
+ <title>HQL: 하이버네이트 질의 언어(Hibernate Query Language)</title>
+
+ <para>
+ Hibernate는 (아주 의도적으로) SQL과 매우 흡사하게 보이는 극히 강력한 질의 언어를 구비하고 있다. 그러나 그 구문에 의해 우롱당하지 말라;
+ HQL은 상속, 다형성 그리고 연관과 같은 개념들을 이해하여서, 전체적으로 객체 지향적이다.
+ </para>
+
+ <sect1 id="queryhql-casesensitivity">
+ <title>대소문자 구분</title>
+
+ <para>
+ 질의들은 Java 클래스들과 프로퍼티들의 이름들을 제외하면 대소문자를 구분하지 않는다. 따라서 <literal>SeLeCT</literal>는
+ <literal>SELECT</literal>와 같고 <literal>SELECT</literal>와도 같지만 <literal>org.hibernate.eg.FOO</literal>는
+ <literal>org.hibernate.eg.Foo</literal>과 같지 않고 <literal>foo.barSet</literal>은
+ <literal>foo.BARSET</literal>과 같지 않다.
+ </para>
+
+ <para>
+ 이 매뉴얼은 소문자 HQL 키워드를 사용한다. 몇몇 사용자들은 보다 나은 가독성을 위해 대문자 키워드들을 가진 질의들을 찾지만, 우리는
+ 자바 코드 속에 삽입될 때 이 컨벤션이 추하다는 점을 발견한다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-from">
+ <title>from 절</title>
+
+ <para>
+ 가장 간단한 가능한 Hibernate 질의는 다음 형식이다:
+ </para>
+
+ <programlisting><![CDATA[from eg.Cat]]></programlisting>
+
+ <para>
+ 이것은 <literal>eg.Cat</literal> 클래스의 모든 인스턴스들을 간단하게 반환한다. 우리는 대개 클래스 이름을 수식할 필요가 없다.
+ 왜냐하면, <literal>auto-import</literal>가 디폴트이기 때문이다. 따라서 우리는 대개 항상 단지 다음과 같이 작성한다:
+ </para>
+
+ <programlisting><![CDATA[from Cat]]></programlisting>
+
+ <para>
+ 대개 당신은 한 개의 <emphasis>alias</emphasis>를 할당할 필요가 있을 것이다. 왜냐하면 당신은 질의의 다른 부분들에서
+ <literal>Cat</literal>을 참조하고자 원할 것이기 때문이다.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat]]></programlisting>
+
+ <para>
+ 이 질의는 alias <literal>cat</literal>을 <literal>Cat</literal> 인스턴스들에 할당하여서, 우리는 나중에 질의 속에서
+ 그 alias를 사용할 수 있을 것이다. <literal>as</literal> 키워드는 옵션이다; 우리는 또한 다음과 같이 작성할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[from Cat cat]]></programlisting>
+
+ <para>
+ 여러 개의 클래스들은 cartesian product(카티젼 곱) 또는 "크로스" 조인으로 귀결되어 나타날 수도 있다.
+ </para>
+
+ <programlisting><![CDATA[from Formula, Parameter]]></programlisting>
+ <programlisting><![CDATA[from Formula as form, Parameter as param]]></programlisting>
+
+ <para>
+ 로컬 변수들에 대한 Java 네이밍 표준들과 일치되게, 첫 소문자를 사용하여 질의 alias들을 명명하는 것은 좋은 습관으로 간주된다
+ (예를 들면 <literal>domesticCat</literal>).
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-joins" revision="2">
+ <title>연관들과 조인들</title>
+
+ <para>
+ 우리는 또한 <literal>join</literal>을 사용하여 , 연관된 엔티티들에 또는 값들을 가진 콜렉션의 요소들에도 alias들을 할당할 수도
+ 있다.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join cat.mate as mate
+ left outer join cat.kittens as kitten]]></programlisting>
+
+ <programlisting><![CDATA[from Cat as cat left join cat.mate.kittens as kittens]]></programlisting>
+
+ <programlisting><![CDATA[from Formula form full join form.parameter param]]></programlisting>
+
+ <para>
+ 지원되는 join 타입들은 ANSI SQL로부터 빌려왔다
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>inner join</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>left outer join</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>right outer join</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>full join</literal> (대개 유용하지 않음)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>inner join</literal>, <literal>left outer join</literal>, 그리고 <literal>right outer join</literal>
+ 구조체들이 약칭될 수 있다.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ join cat.mate as mate
+ left join cat.kittens as kitten]]></programlisting>
+
+ <para>
+ 당신은 HQL <literal>with</literal> 키워드를 사용하여 특별한 조인 조건들을 제공할 수 있다.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ left join cat.kittens as kitten
+ with kitten.bodyWeight > 10.0]]></programlisting>
+
+ <para>
+ 게다가, "fetch" join은 값들을 가진 콜렉션들이나 연관관계들이 한 개의 select를 사용하여, 그것들의 부모 객체들에 따라 초기화 되는
+ 것을 허용해준다. 이것은 콜렉션의 경우에 특히 유용하다. 그것은 연관관계들과 콜렉션들에 대한 매핑 파일의 outer join과 lazy 선언들을
+ 효율적으로 오버라이드 시킨다. 추가 정보는 <xref linkend="performance-fetching"/>을 보라.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join fetch cat.mate
+ left join fetch cat.kittens]]></programlisting>
+
+ <para>
+ fetch join은 대개 alias를 할당할 필요가 없다. 왜냐하면, 연관된 객체들이 <literal>where</literal> 절(또는 어떤 다른 절)
+ 속에 사용되지 않을 것이기 때문이다. 또한 연관된 객체들은 질의 결과들 속에 직접 반환되지 않는다. 대신 그것들은 부모 객체를 통해
+ 접근될 수 있다. 우리가 alias를 필요로 할 수 있는 유일한 이유는 더 많은 콜렉션들을 재귀적으로 조인 페칭시키는 경우이다:
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join fetch cat.mate
+ left join fetch cat.kittens child
+ left join fetch child.kittens]]></programlisting>
+
+ <para>
+ (비록 <literal>scroll()</literal>이 사용될 수 있을지라도) <literal>fetch</literal> 구조체는
+ <literal>iterate()</literal>를 사용하여 호출되는 질의들 내에 사용될 수 없음을 노트하라. 이들 오퍼레이션들이 결과 행들에
+ 기초하고 있기 때문에 <literal>fetch</literal>는 <literal>setMaxResults()</literal> 또는
+ <literal>setFirstResult()</literal>과 함께 사용되지 말아야 하며, 그것들(결과 행들)은 대개 각각의 eager 콜렉션 페칭에 대해
+ 중복들을 포함하므로 많은 행들이 당신이 기대하는 것이 아니다.
+ <literal>fetch</literal>는 특별한 용도의 <literal>with</literal> 조건과도 함께 사용될 수 없다.한 개의 질의 내에 하나
+ 이상의 콜렉션을 조인 페칭시켜 카티젼 곱을 생성시키는 것이 가능한데, 이 경우에 주의하라. 다중 콜렉션 role들을 조인 페칭시키는 것은
+ 또한 때때로 bag 매핑들에 대해 예기치 않은 결과들을 가져다주기 때문에, 당신이 이 경우에 당신의 질의들을 처방하는 방법에 대해 주의하라.
+ 마지막으로 <literal>full join fetch</literal>와 <literal>right join fetch</literal>는 의미가 없다.
+ </para>
+
+ <para>
+ 만일 당신이 (바이트코드 방편으로) property-레벨 lazy 페칭을 사용할 경우, Hibernate로 하여금 <literal>fetch all properties</literal>를
+ 사용하여 (첫 번째 질의에서) lazy 프로퍼티들을 즉시 페치하도록 강제시키는 것이 가능하다.
+ </para>
+
+ <programlisting><![CDATA[from Document fetch all properties order by name]]></programlisting>
+ <programlisting><![CDATA[from Document doc fetch all properties where lower(doc.name) like '%cats%']]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-joins-forms">
+ <title>join 구문의 형식들</title>
+
+ <para>
+ HQL은 두 가지 형식의 연관 조인을 지원한다: <literal>암묵적</literal> 그리고 <literal>명시적</literal>.
+ </para>
+
+ <para>
+ 앞의 절에서 보여진 질의들은 모두 join 키워드가 from 절 내에 명시적으로 사용되는 <literal>명시적인</literal> 형식을
+ 사용한다. 이것은 권장되는 형식이다.
+ </para>
+
+ <para>
+ <literal>함축적인</literal> 형식은 join 키워드를 사용하지 않는다. 대신에, 연관들은 dot(.) 표기를
+ 사용하여 "dot-참조된다(dereferenced)". <literal>함축적인</literal> 조인들은 임의의 HQL 절들내에
+ 나타날 수 있다. <literal>함축적인</literal> join은 결과되는 SQL 문장에서 inner join으로 귀결된다.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.mate.name like '%s%']]></programlisting>
+ </sect1>
+
+ <sect1 id="queryhql-identifier-property">
+ <title>식별자 속성 참조하기</title>
+
+ <para>
+ 개략적으로 말하자면, 엔티티의 식별자 속성을 참조하는 2가지 방법들이 존재한다:
+ </para>
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <emphasis>엔티티가 id로 명명된 비식별자 속성을 정의하지 않는다고 가정하면</emphasis>
+ 특별한 속성(소문자) <literal>id</literal>가 엔티티의 식별자 속성을 참조하는데 사용될 수 있다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 그 엔티티가 명명된 식별자 속성을 정의하는 경우, 당신은 그 속성 이름을 사용할 수도 있다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ composite 식별자 속성들에 대한 참조들은 동일한 네이밍 규칙들을 따른다. 만일 그 엔티티가 id로 명명된 비식별자를
+ 갖고 있을 경우, composite 속성은 오직 그것의 정의된 명명에 의해 참조될 수 있다; 그밖의 경우 특별한 <literal>id</literal>
+ 속성이 식별자 속성을 참조하는데 사용될 수 있다.
+ </para>
+
+ <para>
+ 노트: 이것은 버전 3.2.2에서 시작될 때 현격하게 변경되었다. 이전 버전들에서, <literal>id</literal>는 <emphasis>항상</emphasis>
+ 그것의 실제 이름에 관계없이 식별자 속성을 참조했다. 그 결정의 분기점은 <literal>id</literal>로 명명된 비식별자 속성들이
+ Hibernate 질의들 내에서 결코 참조될 수 없었다는 점이었다.
+ </para>
+ </sect1>
+
+ <sect1 id="queryhql-select">
+ <title>select 절</title>
+
+ <para>
+ <literal>select</literal> 절은 질의 결과 셋 속에 반환할 객체들과 프로퍼티들이 어느 것인지를 골라 내도록 강제한다. 다음을
+ 검토하자:
+ </para>
+
+ <programlisting><![CDATA[select mate
+from Cat as cat
+ inner join cat.mate as mate]]></programlisting>
+
+ <para>
+ 질의는 다른 <literal>Cat</literal>들의 <literal>mate</literal>들을 select 할 것이다. 실제로 당신은 이 질의들을 다음과
+ 같이 보다 축약형으로 표현할수도 있다:
+ </para>
+
+ <programlisting><![CDATA[select cat.mate from Cat cat]]></programlisting>
+
+ <para>
+ 질의들은 컴포넌트 타입의 프로퍼티들을 포함하는 임의의 값 타입의 프로퍼티들을 반환할 수도 있다:
+ </para>
+
+ <programlisting><![CDATA[select cat.name from DomesticCat cat
+where cat.name like 'fri%']]></programlisting>
+
+ <programlisting><![CDATA[select cust.name.firstName from Customer as cust]]></programlisting>
+
+ <para>
+ <literal>Family</literal> 클래스가 적당한 생성자를 갖고 있음을 가정하면,
+ 질의들은 여러 객체들 그리고/또는 프로퍼티들을 <literal>Object[]</literal> 타입의 배열로서,
+ </para>
+
+ <programlisting><![CDATA[select mother, offspr, mate.name
+from DomesticCat as mother
+ inner join mother.mate as mate
+ left outer join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ 또는 <literal>List</literal>로서,
+ </para>
+
+ <programlisting><![CDATA[select new list(mother, offspr, mate.name)
+from DomesticCat as mother
+ inner join mother.mate as mate
+ left outer join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ 또는 실제 typesafe 자바 객체로서,
+ </para>
+
+ <programlisting><![CDATA[select new Family(mother, mate, offspr)
+from DomesticCat as mother
+ join mother.mate as mate
+ left join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ 반환할 수도 있다.
+ </para>
+
+ <para>
+ 당신은 <literal>as</literal>를 사용하여 select되는 표현식들에 alias들을 할당할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n
+from Cat cat]]></programlisting>
+
+ <para>
+ 다음은 <literal>select new map</literal>과 함께 사용될 때 가장 유용하다:
+ </para>
+
+ <programlisting><![CDATA[select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n )
+from Cat cat]]></programlisting>
+
+ <para>
+ 이 질의는 select된 값들에 대한 alias로부터 한 개의 <literal>Map</literal>을 반환한다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-aggregation">
+ <title>집계 함수들</title>
+
+ <para>
+ HQL 질의들은 프로퍼티들에 대한 집계(aggregate) 함수들의 결과들을 반환할수도 있다:
+ </para>
+
+ <programlisting><![CDATA[select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)
+from Cat cat]]></programlisting>
+
+<!-- NO LONGER SUPPORTED
+ <para>
+ Collections may also appear inside aggregate functions in the <literal>select</literal>
+ clause.
+ </para>
+
+ <programlisting><![CDATA[select cat, count( elements(cat.kittens) )
+from Cat cat group by cat]]></programlisting>
+-->
+
+ <para>
+ 지원되는 집계 함수들은 다음과 같다
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>avg(...), sum(...), min(...), max(...)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>count(*)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>count(...), count(distinct ...), count(all...)</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 당신은 select 절 속에 산술 연산자들, 연결 연산자, 그리고 인지된 SQL 함수들을 사용할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[select cat.weight + sum(kitten.weight)
+from Cat cat
+ join cat.kittens kitten
+group by cat.id, cat.weight]]></programlisting>
+
+ <programlisting><![CDATA[select firstName||' '||initial||' '||upper(lastName) from Person]]></programlisting>
+
+ <para>
+ <literal>distinct</literal> 키워드와 all <literal>all</literal>가 사용될 수 있고 SQL의 경우와 동일한 의미를 갖는다.
+ </para>
+
+ <programlisting><![CDATA[select distinct cat.name from Cat cat
+
+select count(distinct cat.name), count(cat) from Cat cat]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-polymorphism">
+ <title>Polymorphic(다형성) 질의들</title>
+
+ <para>
+ 다음과 같은 질의:
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat]]></programlisting>
+
+ <para>
+ 은 <literal>Cat</literal>의 인스턴스들 뿐만 아니라, 또한 <literal>DomesticCat</literal>과 같은 서브클래스들 또한
+ 반환한다. Hibernate 질의들은 <literal>from</literal> 절 내에 <emphasis>임의의</emphasis> 자바 클래스나 인터페이스를
+ 명명할 수 있다. 질의는 그 클래스를 확장하거나 그 인터페이스를 구현하는 모든 영속 클래스들의 인스턴스들을 반환할 것이다. 다음 질의는
+ 모든 영속 객체들을 반환할 것이다:
+ </para>
+
+ <programlisting><![CDATA[from java.lang.Object o]]></programlisting>
+
+ <para>
+ 인터페이스 <literal>Named</literal>는 여러 가지 영속 클래스들에 의해 구현될 수도 있다:
+ </para>
+
+ <programlisting><![CDATA[from Named n, Named m where n.name = m.name]]></programlisting>
+
+ <para>
+ 이들 마지막 두 개의 질의들은 하나 이상의 SQL <literal>SELECT</literal>를 필요로 할 것임을 노트하라. 이것은 <literal>order by</literal>
+ 절이 정확하게 전체 결과 셋을 순서지우지 않음을 의미한다.(그것은 또한 당신이 <literal>Query.scroll()</literal>을 사용하여
+ 이들 질의들을 호출할 수 없음을 의미한다).
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-where" revision="1">
+ <title>where 절</title>
+
+ <para>
+ <literal>where</literal> 절은 반환된 인스턴스들의 목록을 제한시키는 것을 당신에게 허용해준다. 만일 alias가 존재하지 않을 경우,
+ 당신은 이름에 의해 프로퍼티들을 참조할 수도 있다:
+ </para>
+
+ <programlisting><![CDATA[from Cat where name='Fritz']]></programlisting>
+
+ <para>
+ 만일 한 개의 alias가 존재할 경우, 하나의 수식어가 붙은 프로퍼티 이름을 사용하라:
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.name='Fritz']]></programlisting>
+
+ <para>
+ 는 'Fritz'로 명명된 <literal>Cat</literal>의 인스턴스들을 반환한다.
+ </para>
+
+ <programlisting><![CDATA[select foo
+from Foo foo, Bar bar
+where foo.startDate = bar.date]]></programlisting>
+
+ <para>
+ 는 <literal>Foo</literal>의 <literal>startDate</literal> 프로퍼티와 동일한 <literal>date</literal> 프로퍼티를
+ 가진 <literal>bar</literal>의 인스턴스가 존재하는 <literal>Foo</literal>의 모든 인스턴스를 반환할 것이다. 합성 경로
+ 표현식들은 <literal>where</literal> 절을 매우 강력하게 만들어준다. 다음을 검토하자:
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.mate.name is not null]]></programlisting>
+
+ <para>
+ 이 질의는 테이블 (inner) join을 가진 SQL 질의로 번역된다. 만일 당신이 다음과 같은 어떤 것을 작성했다면
+ </para>
+
+ <programlisting><![CDATA[from Foo foo
+where foo.bar.baz.customer.address.city is not null]]></programlisting>
+
+ <para>
+ 당신은 SQL에서 네 개의 테이블 join들을 필요로 하는 하나의 질의로 끝낼 것이다.
+ </para>
+
+ <para>
+ <literal>=</literal> 연산자는 프로퍼티들 뿐만 아니라 또한 인스턴스들을 비교하는데 사용될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[from Cat cat, Cat rival where cat.mate = rival.mate]]></programlisting>
+
+ <programlisting><![CDATA[select cat, mate
+from Cat cat, Cat mate
+where cat.mate = mate]]></programlisting>
+
+ <para>
+ 특별한 프로퍼티(소문자) <literal>id</literal>는 객체의 유일 식별자를 참조하는데 사용될 수 있다.
+ 추가 정보는 <xref linkend="queryhql-identifier-property"/>를 보라.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.id = 123
+
+from Cat as cat where cat.mate.id = 69]]></programlisting>
+
+ <para>
+ 두 번째 질의가 효율적이다. 테이블 join이 필요 없다!
+ </para>
+
+ <para>
+ composite(합성) 식별자들의 프로퍼티들이 또한 사용될 수 있다. <literal>Person</literal>이
+ <literal>country</literal>와 <literal>medicareNumber</literal>로 구성된 composite 식별자를 갖는다고
+ 가정하자. 식별자 속성들을 참조하는 것과 관련된 추가 정보는 다시 <xref linkend="queryhql-identifier-property"/>를 보라.
+ </para>
+
+ <programlisting><![CDATA[from bank.Person person
+where person.id.country = 'AU'
+ and person.id.medicareNumber = 123456]]></programlisting>
+
+ <programlisting><![CDATA[from bank.Account account
+where account.owner.id.country = 'AU'
+ and account.owner.id.medicareNumber = 123456]]></programlisting>
+
+ <para>
+ 다시 한번, 두 번째 질의는 테이블 join을 필요로 하지 않는다.
+ </para>
+
+ <para>
+ 마찬가지로, 특별한 프로퍼티 <literal>class</literal>는 다형적인 영속성(polymorphic persistence)의 경우에 인스턴스의
+ 판별자(discriminator) 값에 액세스한다. where 절 속에 삽입된 Java 클래스 이름은 그것의 판별자(discriminator) 값으로
+ 변환될 것이다.
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.class = DomesticCat]]></programlisting>
+
+ <para>
+ 당신은 또한 컴포넌트들 또는 composite 사용자 타입들, 또는 명명된 컴포넌트 타입들의 속성들을 사용할 수도 있다. 상세한 것은
+ <xref linkend="queryhql-components"/>를 보라.
+ </para>
+
+ <para>
+ "임의의" 타입은 다음 방법으로 join을 표현하는 것을 우리에게 허용해주는, 특별한 프로퍼티들 <literal>id</literal>와
+ <literal>class</literal>를 갖는다(여기서 <literal>AuditLog.item</literal>은 <literal><any></literal>로
+ 매핑된 프로퍼티이다).
+ </para>
+
+ <programlisting><![CDATA[from AuditLog log, Payment payment
+where log.item.class = 'Payment' and log.item.id = payment.id]]></programlisting>
+
+ <para>
+ <literal>log.item.class</literal>와 <literal>payment.class</literal>는 위의 질의 내에서 완전히 다른 데이터베이스
+ 컬럼들의 값들을 참조할 것임을 노트하라.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-expressions">
+ <title>표현식들</title>
+
+ <para>
+ <literal>where</literal> 절 속에 허용되는 표현식들은 당신이 SQL로 작성할 수 있는 대부분의 종류의 것들을 포함한다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 산술 연산자들 <literal>+, -, *, /</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 바이너리 비교 연산자들 <literal>=, >=, <=, <>, !=, like</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 논리 연산들 <literal>and, or, not</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 그룹핑을 나타내는 괄호들 <literal>( )</literal>, indicating grouping
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>in</literal>,
+ <literal>not in</literal>,
+ <literal>between</literal>,
+ <literal>is null</literal>,
+ <literal>is not null</literal>,
+ <literal>is empty</literal>,
+ <literal>is not empty</literal>,
+ <literal>member of</literal> and
+ <literal>not member of</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ "간단한" 경우, <literal>case ... when ... then ... else ... end</literal>, 그리고
+ "검색인" 경우, <literal>case when ... then ... else ... end</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 문자열 연결 <literal>...||...</literal> or <literal>concat(...,...)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>current_date()</literal>, <literal>current_time()</literal>,
+ <literal>current_timestamp()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>second(...)</literal>, <literal>minute(...)</literal>,
+ <literal>hour(...)</literal>, <literal>day(...)</literal>,
+ <literal>month(...)</literal>, <literal>year(...)</literal>,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ EJB-QL 3.0에 의해 정의된 임의의 함수 또는 오퍼레이터: <literal>substring(), trim(),
+ lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>coalesce()</literal> 그리고 <literal>nullif()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ numeric 값들이나 temporal 값들을 가독성 있는 문자열로 변환시키는 <literal>str()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>cast(... as ...)</literal>, 여기서 두번 째 아규먼트는 Hibernate 타입의 이름이고,
+ ANSI <literal>cast()</literal>와 <literal>extract()</literal>가 기반 데이터베이스에 의해
+ 지원될 경우에는 <literal>extract(... from ...)</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 조인된 인덱싱된 콜렉션의 alias들에 적용되는, HQL <literal>index()</literal> 함수
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 콜렉션 값을 가진 경로 표현식들을 취하는 HQL 함수들 : <literal>some, all, exists, any, in</literal>을
+ 사용하여 정량화 될 수 있는 특별한 <literal>elements()</literal>와 <literal>indices</literal>
+ 함수들과 함께 <literal>size(), minelement(), maxelement(), minindex(), maxindex()</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>sign()</literal>, <literal>trunc()</literal>, <literal>rtrim()</literal>,
+ <literal>sin()</literal>과 같이 임의의 데이터베이스 지원 SQL 스칼라 함수
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ JDBC-스타일 위치 파라미터들 <literal>?</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 명명된 파라미터들 <literal>:name</literal>, <literal>:start_date</literal>, <literal>:x1</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ SQL 리터럴들 <literal>'foo'</literal>, <literal>69</literal>, <literal>6.66E+2</literal>,
+ <literal>'1970-01-01 10:00:01.0'</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Java <literal>public static final</literal> 상수들. <literal>eg.Color.TABBY</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>in</literal> 과 <literal>between</literal>은 다음과 같이 사용될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name between 'A' and 'B']]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )]]></programlisting>
+
+ <para>
+ 그리고 부정형들은 다음과 같이 작성될 수 있다
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name not between 'A' and 'B']]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )]]></programlisting>
+
+ <para>
+ 마찬가지로, <literal>is null</literal>과 <literal>is not null</literal>은 null 값들을 테스트하는데 사용될 수 있다.
+ </para>
+
+ <para>
+ Boolean들은 Hibernate 구성 내에 HQL 질의 치환들을 선언함으로써 표현식들 내에 쉽게 사용될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<property name="hibernate.query.substitutions">true 1, false 0</property>]]></programlisting>
+
+ <para>
+ 이것은 키워드 <literal>true</literal>와 <literal>false</literal> 키워드들을 이 HQL로부터 번역된 SQL에서
+ 리터럴 <literal>1</literal>과 <literal>0</literal>으로 대체될 것이다:
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.alive = true]]></programlisting>
+
+ <para>
+ 당신은 특별한 프로퍼티 <literal>size</literal>로서 또는 특별한 <literal>size()</literal> 함수로서 콜렉션의 사이즈를
+ 테스트할 수 있다.
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.kittens.size > 0]]></programlisting>
+
+ <programlisting><![CDATA[from Cat cat where size(cat.kittens) > 0]]></programlisting>
+
+ <para>
+ 인덱싱된 콜렉션들에 대해, 당신은<literal>minindex</literal>와 <literal>maxindex</literal> 함수들을 사용하여
+ 최소 인덱스과 최대 인덱스를 참조할 수 있다. 유사하게 당신은 <literal>minelement</literal>와
+ <literal>maxelement</literal> 함수를 사용하여 기본 타입을 가진 콜렉션의 최소 요소 및 최대 요소를 참조할 수 있다.
+ </para>
+
+ <programlisting><![CDATA[from Calendar cal where maxelement(cal.holidays) > current_date]]></programlisting>
+
+ <programlisting><![CDATA[from Order order where maxindex(order.items) > 100]]></programlisting>
+
+ <programlisting><![CDATA[from Order order where minelement(order.items) > 10000]]></programlisting>
+
+ <para>
+ SQL 함수들 <literal>any, some, all, exists, in</literal>은 콜렉션의 요소 또는 인덱스 세트(<literal>elements</literal>
+ 함수와 <literal>indices</literal> 함수), 또는 서브질의의 결과를 전달했을 때 지원된다(아래를 보라).
+ </para>
+
+ <programlisting><![CDATA[select mother from Cat as mother, Cat as kit
+where kit in elements(foo.kittens)]]></programlisting>
+
+ <programlisting><![CDATA[select p from NameList list, Person p
+where p.name = some elements(list.names)]]></programlisting>
+
+ <programlisting><![CDATA[from Cat cat where exists elements(cat.kittens)]]></programlisting>
+
+ <programlisting><![CDATA[from Player p where 3 > all elements(p.scores)]]></programlisting>
+
+ <programlisting><![CDATA[from Show show where 'fizard' in indices(show.acts)]]></programlisting>
+
+ <para>
+ 이들 구조체들-<literal>size</literal>, <literal>elements</literal>, <literal>indices</literal>,
+ <literal>minindex</literal>, <literal>maxindex</literal>, <literal>minelement</literal>,
+ <literal>maxelement</literal>-는 Hibernate3에서 where 절 내에서만 사용될 것임을 노트하라.
+ </para>
+
+ <para>
+ 인덱싱 된 콜렉션들의 요소들(배열들, 리스트들, map들)은 인덱스에 의해 참조될 수 있다(where 절 안에서만):
+ </para>
+
+ <programlisting><![CDATA[from Order order where order.items[0].id = 1234]]></programlisting>
+
+ <programlisting><![CDATA[select person from Person person, Calendar calendar
+where calendar.holidays['national day'] = person.birthDay
+ and person.nationality.calendar = calendar]]></programlisting>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11]]></programlisting>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ maxindex(order.items) ] = item and order.id = 11]]></programlisting>
+
+ <para>
+ <literal>[]</literal> 내부의 표현식은 산술 표현실일 수 있다.
+ </para>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ size(order.items) - 1 ] = item]]></programlisting>
+
+ <para>
+ HQL은 또한 one-to-many 연관 또는 값들을 가진 콜렉션의 요소들에 대해 미리 만들어진 <literal>index()</literal> 함수를
+ 제공한다.
+ </para>
+
+ <programlisting><![CDATA[select item, index(item) from Order order
+ join order.items item
+where index(item) < 5]]></programlisting>
+
+ <para>
+ 기본 데이터베이스에 의해 제공되는 Scalar SQL 함수들이 사용될 수도 있다
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where upper(cat.name) like 'FRI%']]></programlisting>
+
+ <para>
+ 당신이 아직 이 모든 것을 납득하지 못한다면, SQL 내에서 다음 질의가 가독성이 얼마나 많고 적은지를 생각해보라:
+ </para>
+
+ <programlisting><![CDATA[select cust
+from Product prod,
+ Store store
+ inner join store.customers cust
+where prod.name = 'widget'
+ and store.location.name in ( 'Melbourne', 'Sydney' )
+ and prod = all elements(cust.currentOrder.lineItems)]]></programlisting>
+
+ <para>
+ <emphasis>힌트</emphasis> : 다음과 같은 어떤 것
+ </para>
+
+ <programlisting><![CDATA[SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order
+FROM customers cust,
+ stores store,
+ locations loc,
+ store_customers sc,
+ product prod
+WHERE prod.name = 'widget'
+ AND store.loc_id = loc.id
+ AND loc.name IN ( 'Melbourne', 'Sydney' )
+ AND sc.store_id = store.id
+ AND sc.cust_id = cust.id
+ AND prod.id = ALL(
+ SELECT item.prod_id
+ FROM line_items item, orders o
+ WHERE item.order_id = o.id
+ AND cust.current_order = o.id
+ )]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-ordering">
+ <title>order by 절</title>
+
+ <para>
+ 질의에 의해 반환된 리스트는 반환된 클래스 또는 컴포넌트들의 프로퍼티에 의해 순서(ordering)지워질 수 있다:
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat
+order by cat.name asc, cat.weight desc, cat.birthdate]]></programlisting>
+
+ <para>
+ <literal>asc</literal> 옵션 또는 <literal>desc</literal> 옵션은 각각 오름차순 또는 내림차순 정렬을 나타낸다.
+ </para>
+ </sect1>
+
+ <sect1 id="queryhql-grouping" revision="1">
+ <title>group by 절</title>
+
+ <para>
+ aggregate 값들을 반환하는 질의는 반환된 클래스나 컴포넌트들의 프로퍼티에 의해 그룹지워질 수 있다:
+ </para>
+
+ <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat)
+from Cat cat
+group by cat.color]]></programlisting>
+
+ <programlisting><![CDATA[select foo.id, avg(name), max(name)
+from Foo foo join foo.names name
+group by foo.id]]></programlisting>
+
+ <para>
+ 또한 <literal>having</literal> 절이 허용된다.
+ </para>
+
+ <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat)
+from Cat cat
+group by cat.color
+having cat.color in (eg.Color.TABBY, eg.Color.BLACK)]]></programlisting>
+
+ <para>
+ SQL 함수들과 집계 함수들이 기본 데이터베이스에 의해 지원될 경우(예를 들어 MySQL은 지원되지 않는다)
+ <literal>having</literal> 절과 <literal>order by</literal> 절 속에 허용된다.
+ </para>
+
+ <programlisting><![CDATA[select cat
+from Cat cat
+ join cat.kittens kitten
+group by cat.id, cat.name, cat.other, cat.properties
+having avg(kitten.weight) > 100
+order by count(kitten) asc, sum(kitten.weight) desc]]></programlisting>
+
+ <para>
+ <literal>group by</literal> 절도 <literal>order by</literal> 절 어느 것도 산술 표현식들을 포함할 수 없다는 점을
+ 노트하라. 또한 Hibernate는 현재 그룹지워진 엔티티를 확장하지 않아서 만일 <literal>cat</literal>의
+ 모든 속성들이 집계되지 않을 경우에 당신이 <literal>group by cat</literal>을 쓸수 없음을 노트하라.
+ 당신은 명시적으로 모든 집계되지 않는 속성들을 리스트해야 한다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-subqueries" revision="3">
+ <title>서브질의들</title>
+
+ <para>
+ subselect들을 지원하는 데이터베이스들의 경우, Hibernate는 질의들 내에 서브질의들을 지원한다. 서브질의는 괄호로 묶여져야
+ 한다(자주 SQL 집계함수 호출에 의해). 심지어 서로 상관된 서브질의들(외부 질의 내에서 alias를 참조하는 서브질의들)이 허용된다.
+ </para>
+
+ <programlisting><![CDATA[from Cat as fatcat
+where fatcat.weight > (
+ select avg(cat.weight) from DomesticCat cat
+)]]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat as cat
+where cat.name = some (
+ select name.nickName from Name as name
+)]]></programlisting>
+
+ <programlisting><![CDATA[from Cat as cat
+where not exists (
+ from Cat as mate where mate.mate = cat
+)]]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat as cat
+where cat.name not in (
+ select name.nickName from Name as name
+)]]></programlisting>
+
+ <programlisting><![CDATA[select cat.id, (select max(kit.weight) from cat.kitten kit)
+from Cat as cat]]></programlisting>
+
+ <para>
+ HQL 서브질의들이 select 절 또는 where 절 내에서만 일어날 수 있음을 노트하라.
+ </para>
+
+
+ <para>
+ 서브질의들은 또한 <literal>row value constructor</literal> 구문을 활용할 수 있다. 상세한 것은
+ <xref linkend="queryhql-tuple"/>를 보라.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-examples">
+ <title>HQL 예제들</title>
+
+ <para>
+
+ Hibernate 질의들은 매우 강력하고 복잡할 수 있다. 사실, 질의 언어의 힘은 Hibernate의 주요 판매 포인트들 중 하나이다. 다음은
+ 내가 최근의 프로젝트에서 사용했던 질의들과 매우 유사한 몇몇 예제 질의들이다. 당신이 작성하게 될 대부분의 질의들은 이것들보다 훨씬
+ 간단하다는 점을 노트하라!
+ </para>
+
+ <para>
+ 다음 질의는 특정 고객에 대한 모든 지불되지 않은 주문들의 주문 id, 항목들의 개수, 그리고 주문의 전체 합계값 그리고 주어진
+ 최소 전체 합계를 전체 합계값에 따라 결과들을 순서지워서 반환한다. 가격 결정에 있어, 그것은 현재의 카타록을 사용한다.
+ 귀결되는 SQL 질의는 <literal>ORDER</literal>, <literal>ORDER_LINE</literal>, <literal>PRODUCT</literal>,
+ <literal>CATALOG</literal>, <literal>PRICE</literal> 테이블들에 대한 네 개의 inner 조인들과 한 개의(상관지워지지
+ 않은) subselect를 갖고 있다.
+ </para>
+
+ <programlisting><![CDATA[select order.id, sum(price.amount), count(item)
+from Order as order
+ join order.lineItems as item
+ join item.product as product,
+ Catalog as catalog
+ join catalog.prices as price
+where order.paid = false
+ and order.customer = :customer
+ and price.product = product
+ and catalog.effectiveDate < sysdate
+ and catalog.effectiveDate >= all (
+ select cat.effectiveDate
+ from Catalog as cat
+ where cat.effectiveDate < sysdate
+ )
+group by order
+having sum(price.amount) > :minAmount
+order by sum(price.amount) desc]]></programlisting>
+
+ <para>
+ 괴물 같은 것! 실제로 실 생활에서, 나는 서브질의들을 매우 좋아하지 않아서, 나의 질의는 실제로 다음과 같았다:
+ </para>
+
+ <programlisting><![CDATA[select order.id, sum(price.amount), count(item)
+from Order as order
+ join order.lineItems as item
+ join item.product as product,
+ Catalog as catalog
+ join catalog.prices as price
+where order.paid = false
+ and order.customer = :customer
+ and price.product = product
+ and catalog = :currentCatalog
+group by order
+having sum(price.amount) > :minAmount
+order by sum(price.amount) desc]]></programlisting>
+
+ <para>
+ 다음 질의는 현재 사용자에 의해 가장 최근의 상태 변경이 행해졌던 <literal>AWAITING_APPROVAL</literal> 상태에 있는 모든
+ 지불들을 제외한, 각각의 상태에 있는 지불들의 개수를 카운트 한다. 그것은 <literal>PAYMENT</literal>,
+ <literal>PAYMENT_STATUS</literal>, <literal>PAYMENT_STATUS_CHANGE</literal> 테이블들에 대한 두 개의 inner
+ 조인들과 하나의 상관관계 지워진 subselect를 가진 SQL 질의로 변환된다.
+ </para>
+
+ <programlisting><![CDATA[select count(payment), status.name
+from Payment as payment
+ join payment.currentStatus as status
+ join payment.statusChanges as statusChange
+where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
+ or (
+ statusChange.timeStamp = (
+ select max(change.timeStamp)
+ from PaymentStatusChange change
+ where change.payment = payment
+ )
+ and statusChange.user <> :currentUser
+ )
+group by status.name, status.sortOrder
+order by status.sortOrder]]></programlisting>
+
+ <para>
+ 만일 내가 <literal>statusChanges</literal> 콜렉션을 set가 아닌 list로 매핑했다면, 그 질의는 작성하기가 훨씬 더
+ 간단했을 것이다.
+ </para>
+
+ <programlisting><![CDATA[select count(payment), status.name
+from Payment as payment
+ join payment.currentStatus as status
+where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
+ or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :currentUser
+group by status.name, status.sortOrder
+order by status.sortOrder]]></programlisting>
+
+ <para>
+ 다음 질의는 현재의 사용자가 속해 있는 조직의 모든 계정들과 지불되지 않은 지불들을 반환하는데 MS SQL Server
+ <literal>isNull()</literal> 함수를 사용한다. 그것은 <literal>ACCOUNT</literal>, <literal>PAYMENT</literal>,
+ <literal>PAYMENT_STATUS</literal>, <literal>ACCOUNT_TYPE</literal>, <literal>ORGANIZATION</literal>,
+ <literal>ORG_USER</literal> 테이블들에 대한 세 개의 inner 조인들, 하나의 outer 조인, 그리고 하나의 subselect를 가진
+ 한 개의 SQL 질의로 번역된다.
+ </para>
+
+ <programlisting><![CDATA[select account, payment
+from Account as account
+ left outer join account.payments as payment
+where :currentUser in elements(account.holder.users)
+ and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
+order by account.type.sortOrder, account.accountNumber, payment.dueDate]]></programlisting>
+
+ <para>
+ 몇몇 데이터베이스들의 경우, 우리는 (상관관계 지워진) subselect를 없앨 필요가 있을 것이다.
+ </para>
+
+ <programlisting><![CDATA[select account, payment
+from Account as account
+ join account.holder.users as user
+ left outer join account.payments as payment
+where :currentUser = user
+ and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
+order by account.type.sortOrder, account.accountNumber, payment.dueDate]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-bulk" revision="2">
+ <title>대량 update와 delete</title>
+
+ <para>
+ HQL은 이제 <literal>update</literal>, <literal>delete</literal> 그리고
+ <literal>insert ... select ...</literal> 문장들을 지원한다.
+ 상세한 것은 <xref linkend="batch-direct"/>를 보라.
+ </para>
+ </sect1>
+
+ <sect1 id="queryhql-tipstricks">
+ <title>팁들 & 트릭들</title>
+
+ <para>
+ 당신은 실제로 질의 결과들을 반환하지 않고서 그것들(질의 결과들)의 개수를 카운트할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue()]]></programlisting>
+
+ <para>
+ 콜렉션의 크기에 따라 결과를 순서(ordering)지우려면, 다음 질의를 사용하라:
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User as usr
+ left join usr.messages as msg
+group by usr.id, usr.name
+order by count(msg)]]></programlisting>
+
+ <para>
+ 만일 당신의 데이터베이스가 subselect들을 지원할 경우, 당신은 당신의 질의의 where 절 내에 selection 사이즈에 대한 조건을
+ 위치지울 수 있다:
+ </para>
+
+ <programlisting><![CDATA[from User usr where size(usr.messages) >= 1]]></programlisting>
+
+ <para>
+ 만일 당신의 데이터베이스가 subselect를 지원하지 않을 경우, 다음 질의를 사용하라:
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User usr.name
+ join usr.messages msg
+group by usr.id, usr.name
+having count(msg) >= 1]]></programlisting>
+
+ <para>
+ 이 해결책이 inner 조인 때문에 0개의 메시지를 가진 <literal>User</literal>를 반환할 수 없으므로, 다음 형식이 또한 유용하다:
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User as usr
+ left join usr.messages as msg
+group by usr.id, usr.name
+having count(msg) = 0]]></programlisting>
+
+ <para>
+ 하나의 JavaBean의 프로퍼티들은 명명된 질의 파라미터들에 바인드될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[Query q = s.createQuery("from foo Foo as foo where foo.name=:name and foo.size=:size");
+q.setProperties(fooBean); // fooBean has getName() and getSize()
+List foos = q.list();]]></programlisting>
+
+ <para>
+ 콜렉션들은 필터를 가진 <literal>Query</literal> 인터페이스를 사용하여 쪼매김하는 것이 가능하다:
+ </para>
+
+ <programlisting><![CDATA[Query q = s.createFilter( collection, "" ); // the trivial filter
+q.setMaxResults(PAGE_SIZE);
+q.setFirstResult(PAGE_SIZE * pageNumber);
+List page = q.list();]]></programlisting>
+
+ <para>
+ 콜렉션 요소들은 질의 필터를 사용하여 순서(ordering)지워지거나 그룹지워질 수 도 있다:
+ </para>
+
+ <programlisting><![CDATA[Collection orderedCollection = s.filter( collection, "order by this.amount" );
+Collection counts = s.filter( collection, "select this.type, count(this) group by this.type" );]]></programlisting>
+
+ <para>
+ 당신은 콜렉션을 초기화 하지 않고서 그것(콜렉션)의 크기를 찾을 수 있다:
+ </para>
+
+ <programlisting><![CDATA[( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-components">
+ <title>컴포넌트들</title>
+
+ <para>
+ 컴포넌트들은 단지 간단한 값 유형들이 HQL 질의들 내에 사용될 수 있는 모든 방법으로 사용될 수 있다. 그것들은
+ <literal>select</literal> 절 내에 나타날 수 있다.
+ </para>
+
+ <programlisting><![CDATA[select p.name from from Person p]]></programlisting>
+ <programlisting><![CDATA[select p.name.first from from Person p]]></programlisting>
+
+ <para>
+ 여기서 Person의 name 속성은 컴포넌트이다. 컴포넌트들은 또한 <literal>where</literal> 절 내에 사용될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[from from Person p where p.name = :name]]></programlisting>
+ <programlisting><![CDATA[from from Person p where p.name.first = :firstName]]></programlisting>
+
+ <para>
+ 컴포넌트들은 또한 <literal>order by</literal> 절 내에 사용될 수 있다:
+ </para>
+
+ <programlisting><![CDATA[from from Person p order by p.name]]></programlisting>
+ <programlisting><![CDATA[from from Person p order by p.name.first]]></programlisting>
+
+ <para>
+ 컴포넌트들에 대한 또 다른 공통적인 사용은 <xref linkend="queryhql-tuple">row value constructors</xref>에 있다.
+ </para>
+ </sect1>
+
+ <sect1 id="queryhql-tuple">
+ <title>Row value constructor 구문</title>
+
+ <para>
+ HQL은 ANSI SQL <literal>row value constructor</literal> 구문(종종 <literal>tuple</literal> 구문이라 명명된다)의 사용을 지원한다.
+ 비록 데이터베이스가 그 개념을 지원하지 않을지라도 그러하다. 여기서 우리는 전형적으로 컴포넌트들과 연관되어 있는 다중-값 비교들을
+ 일반적으로 언급하고 있다. name 컴포넌트를 정의하는 Person 엔티티를 검토하자:
+ </para>
+
+ <programlisting><![CDATA[from Person p where p.name.first='John' and p.name.last='Jingleheimer-Schmidt']]></programlisting>
+
+ <para>
+ 비록 약간 장황스럽지만 그것은 유효한 구문이다. 이것을 약간 더 간결하게 만들고
+ <literal>row value constructor</literal> 구문을 사용하는 것이 좋다:
+ </para>
+
+ <programlisting><![CDATA[from Person p where p.name=('John', 'Jingleheimer-Schmidt')]]></programlisting>
+
+ <para>
+ <literal>select</literal>절 내에 이것을 지정하는 것이 또한 유용할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[select p.name from from Person p]]></programlisting>
+
+ <para>
+ <literal>row value constructor</literal> 구문을 사용하는 또 다른 경우는 다중 값들에 대해 비교할 필요가 있는
+ 서브 질의들을 사용할 때이다:
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+where not ( cat.name, cat.color ) in (
+ select cat.name, cat.color from DomesticCat cat
+)]]></programlisting>
+
+ <para>
+ 만일 당신이 이 구문을 사용하고자 원할 경우에 고려해야 할 한 가지는 질의가 메타데이터 내에 있는
+ 컴포넌트 서브-속성들의 순서에 종속될 것이라는 점이다.
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/query_sql.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/query_sql.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/query_sql.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/query_sql.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,694 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter id="querysql" revision="2">
+ <title>Native SQL</title>
+
+ <para>당신은 또한 당신의 데이터베이스의 native SQL dialect로 질의들을 표현할 수도 있다.
+ 당신이 오라클의 질의 힌트들 또는 <literal>CONNECT</literal> 키워드와 같은
+ 데이터베이스 지정적인 특징들을 활용하고자 원할 경우에 이것이 유용하다.
+ 그것은 또한 직접적인 SQL/JDBC 기반의 어플리케이션으로부터 Hibernate로의 보다 명료한
+ 이전 경로를 제공한다.</para>
+
+ <para>Hibernate3은 또한 모든 create, update, delete, load 오퍼레이션들에 대해
+ (내장 프로시저들을 포함하여) 손으로 작성된 SQL을 지정하는 것을 당신에게 허용해준다.</para>
+
+ <sect1 id="querysql-creating" revision="4">
+ <title><literal>SQLQuery</literal> 사용하기</title>
+
+ <para>native SQL 질의들의 실행은 <literal>SQLQuery</literal> 인터페이스를 통해
+ 제어되며, 그것은 <literal>Session.createSQLQuery()</literal>을 호출하여
+ 획득된다. 다음은 이 API를 질의에 사용하는 방법을 설명한다.</para>
+
+ <sect2>
+ <title>스칼라 질의들</title>
+
+ <para>가장 기본적인 SQL 질의는 스칼라들(값들)의 목록을 얻는
+ 것이다.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS").list();
+sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").list();
+]]></programlisting>
+
+ <para>이것들은 둘다 CATS 테이블 내에 있는 각각의 컬럼에 대한 스칼라 값들을 가진 Object
+ 배열들의 List를 반환할 것이다. Hibernate는 반환되는 스칼라 값들의 실제 순서와 타입들을
+ 도출하는데 ResultSetMetadata를 사용할 것이다.</para>
+
+ <para><literal>ResultSetMetadata</literal> 사용의 오버헤드를 피하거나
+ 간단하게는 반환되는 것을 보다 명시적이게끔 하기 위해 우리는
+ <literal>addScalar()</literal>를 사용할 수 있다.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS")
+ .addScalar("ID", Hibernate.LONG)
+ .addScalar("NAME", Hibernate.STRING)
+ .addScalar("BIRTHDATE", Hibernate.DATE)
+]]></programlisting>
+
+ <para>이 질의는 다음을 지정했다:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL 질의 문자열</para>
+ </listitem>
+
+ <listitem>
+ <para>반환할 컬럼들과 타입들</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>이것은 여전히 Object 배열들을 반환할 것이지만, 이제 그것은
+ <literal>ResultSetMetdata</literal>를 사용하지 않을 것이고 대신에
+ 기반 결과셋으로부터 ID, NAME 그리고 BIRTHDATE 컬럼을 각각 Long, String
+ 그리고 Short 타입으로 반환할 것이다. 심지어 그 질의가 <literal>*</literal>를
+ 사용하고 세 개의 열거된 컬럼들 보다 더 많은 것을 반환할 수 있을지라도, 이것은
+ 또한 오직 이들 세 개의 컬럼들 만이 반환될 것임을 의미한다.</para>
+
+ <para>스칼라들 중 몇몇 또는 전부에 대한 타입 정보를 남겨두는 것이 가능하다.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS")
+ .addScalar("ID", Hibernate.LONG)
+ .addScalar("NAME")
+ .addScalar("BIRTHDATE")
+]]></programlisting>
+
+ <para>이것은 본질적으로 앞의 것과 동일한 질의이지만, 이제
+ <literal>ResultSetMetaData</literal>는 ID의 타입이 명시적으로 지정되어 있으므로
+ NAME과 BIRTHDATE의 타입을 결정하는데 사용된다.</para>
+
+ <para>java.sql.Types returned from ResultSetMetaData이 Hibernate
+ 타입들로 매핑되는 방법은 Dialect에 의해 제어된다. 만일 특정 타입이 매핑되지 않거나
+ 예상되는 타입으로 귀결되지 않을 경우에 Dialect 내에 있는
+ <literal>registerHibernateType</literal>에 대한 호출들을 통해 그것을
+ 맞춤화 시키는 것이 가능하다.</para>
+ </sect2>
+
+ <sect2>
+ <title>Entity 질의들</title>
+
+ <para>위의 질의들은 스칼라 값들을 반환하는 것, 결과셋들로부터 "원래의" 값들을
+ 기본적으로 반환하는 것에 대한 전부였다. 다음은 <literal>addEntity()</literal>를
+ 통해 native sql 질의로부터 엔티티 객체들을 얻는 방법을 보여준다.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS").addEntity(Cat.class);
+sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").addEntity(Cat.class);
+]]></programlisting>
+
+ <para>이 질의는 다음을 지정했다:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL 질의 문자열</para>
+ </listitem>
+
+ <listitem>
+ <para>그 질의에 의해 반환되는 엔티티</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Cat이 컬럼 ID, NAME 그리고 BIRTHDATE로서 매핑된다고 가정하면,
+ 위의 질의들은 둘다 각각의 요소가 하나의 Cat 엔티티인 하나의 List를 반환할 것이다.</para>
+
+ <para>만일 그 엔티티가 또 다른 엔티티에 대해 <literal>many-to-one</literal>로
+ 매핑되어 있다면 또한 native 질의를 실행할 때 이것을 반환하는 것이 필수적고, 그 밖의 경우
+ 데이터베이스 지정적인 "컬럼이 발견되지 않았습니다" 오류가 일어날 것이다. 추가적인
+ 컬럼은 * 표기를 사용할 자동적으로 반환될 것이지만, 우리는 다음 <literal>Dog</literal>에
+ 대한 <literal>many-to-one</literal> 예제에서처럼 명시적인 것을 더 선호한다:</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE, DOG_ID FROM CATS").addEntity(Cat.class);
+]]></programlisting>
+
+ <para>이것은 cat.getDog()이 고유하게 기능하는 것을 허용한다.</para>
+ </sect2>
+
+ <sect2>
+ <title>연관들과 콜렉션들을 처리하기</title>
+
+ <para>프락시를 초기화 시킴에 있어 가능한 특별한 라운드트립을 피하기 위해서
+ <literal>Dog</literal>에서 eagerly join시키는 것이 간으하다. 이것은
+ <literal>addJoin()</literal> 메소드를 통해 행해지는데, 그것은
+ 연관이나 콜렉션 내에서 조인시키는 것을 당신에게 허용해준다.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT c.ID, NAME, BIRTHDATE, DOG_ID, D_ID, D_NAME FROM CATS c, DOGS d WHERE c.DOG_ID = d.D_ID")
+ .addEntity("cat", Cat.class)
+ .addJoin("cat.dog");
+]]></programlisting>
+
+ <para>이 예제에서 반환되는 <literal>Cat</literal>들은 데이터베이스에
+ 대한 임의의 특별한 라운드크립 없이 전체적으로 초기화된 그것들의 <literal>dog</literal>
+ 프로퍼티를 갖는다. 우리가 join의 대상 프로퍼티 경로를 지정하는 것을 가능하도록 하기 위해
+ 하나의 alias 이름("cat")을 추가했음을 주지하라. 대신에 예를 들어 <literal>Cat</literal>이
+ <literal>Dog</literal>에 대해 one-to-many를 가질 경우, 콜렉션들에 대해 동일한 eager joining을
+ 행하는 것이 가능하다.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE, D_ID, D_NAME, CAT_ID FROM CATS c, DOGS d WHERE c.ID = d.CAT_ID")
+ .addEntity("cat", Cat.class)
+ .addJoin("cat.dogs");
+]]></programlisting>
+
+ <p>이 단계에서 우리는 Hibernate에서 native 질의들을 사용가능하도록 만들기 위해
+ sql 질의들을 강화시키지는 것을 시작하지 않고서도 native 질의들로서 가능한 것의 한계에
+ 도달하고 있다; 문제점들은 동일한 타입의 여러 엔티티들을 반환할 때 또는 디폴트 alias/column
+ 이름들이 충분하지 않을 때 발생하기 시작한다.</p>
+ </sect2>
+
+ <sect2>
+ <title>여러 개의 엔티티들을 반환하기</title>
+
+ <para>지금까지 결과 셋 컬럼 이름들은 매핑 문서 내에 지정된 컬럼 이름들과 동일하다고 가정되어 있다.
+ 동일한 컬럼이 하나 이상의 테이블 내에서 나타날 수 있기 때문에, 이것은 여러 개의 테이블들을 조인시키는
+ SQL 질의들에 대해 문제가 될 수 있다.</para>
+
+ <para>컬럼 alias 주입은 다음 질의(아마 실패할 것이다)에서 필요하다:</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT c.*, m.* FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
+ .addEntity("cat", Cat.class)
+ .addEntity("mother", Cat.class)
+]]></programlisting>
+
+ <para>이 질의의 목적은 단위 행 당 두 개의 Cat 인스턴스들, 하나의 cat 그리고 그것의 mother를
+ 반환하는 것이다. 왜냐하면 그것들이 동일한 컬럼 이름들로 매핑되어 있기 때문에 이것은 실패할 것이고
+ 데이베이스 상에서 반환된 컬럼 alias들은 아마 매핑들 내에 지정된 컬럼들("ID" 와 "NAME")과 같지 않은
+ "c.ID", "c.NAME" 등의 형식일 것이다.</para>
+
+ <para>다음 형식은 컬럼 이름 중복 취약점을 갖지 않는다:</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT {cat.*}, {mother.*} FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
+ .addEntity("cat", Cat.class)
+ .addEntity("mother", Cat.class)
+]]></programlisting>
+
+ <para>이 질의는 다음을 지정했다:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>컬럼 alias들을 주입하기 위한 Hibernate용 placeholder들을 가진 SQL 질의 문자열</para>
+ </listitem>
+
+ <listitem>
+ <para>그 질의에 의해 반환되는 엔티티들</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>위에 사용된 {cat.*} 과 {mother.*} 표기는 "모든 프로퍼티들"에 대한 생략이다.
+ 다른 방법으로 당신은 컬럼들을 명시적으로 열거할 수도 있지만, 이 경우에 우리는 Hibernate로 하여금
+ SQL 컬럼 alias들을 각각의 컬럼에 주입시키도록 강제한다. 컬럼 alias를 위한 placeholder는 단지
+ 그 테이블 alias에 의해 수식된 프로퍼티 이름이다. 다음 예제에서, 우리는 다른 테이블(cat_log)로부터
+ 매핑 메타데이터 내에 선언된 것으로의 Cat들과 그것들의 mother들을 검색한다. 우리는 우리가 좋다면
+ 심지어 where 절 내에 프로퍼티 alias를 사용할 수도 있음을 주지하라.</para>
+
+ <programlisting><![CDATA[String sql = "SELECT ID as {c.id}, NAME as {c.name}, " +
+ "BIRTHDATE as {c.birthDate}, MOTHER_ID as {c.mother}, {mother.*} " +
+ "FROM CAT_LOG c, CAT_LOG m WHERE {c.mother} = c.ID";
+
+List loggedCats = sess.createSQLQuery(sql)
+ .addEntity("cat", Cat.class)
+ .addEntity("mother", Cat.class).list()
+]]></programlisting>
+
+ <sect3 id="querysql-aliasreferences" revision="2">
+ <title>alias 참조와 프로퍼티 참조</title>
+
+ <para>대부분의 경우에 위의 alias 주입이 필요하지만, composite 프로퍼티들, 상속 판별자들
+ (inheritance discriminators), 콜렉션 등과 같은 보다 복잡한 매핑들과 관련된 질의들의 경우에는
+ 고유한 alias들을 주입시키는 것을 Hibernate에게 허용하는데 사용될 몇몇 특별한 alias들이 존재한다.</para>
+
+ <para>다음 테이블은 alias 주입을 사용하는 다른 가능성들을 보여준다. 노트: 결과 내에 있는 alias 이름들이
+ 예제이며, 각각의 alias는 사용될 때 하나의 유일한 이름과 아마 다른 이름을 가질 것이다.</para>
+
+ <table frame="topbot" id="aliasinjection-summary">
+ <title>alias 주입 이름들</title>
+
+ <tgroup cols="3">
+ <colspec colwidth="1*" />
+
+ <colspec colwidth="1*" />
+
+ <colspec colwidth="2.5*" />
+
+ <thead>
+ <row>
+ <entry>설명</entry>
+
+ <entry>구문</entry>
+
+ <entry>예제</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>간단한 프로퍼티</entry>
+ <entry><literal>{[aliasname].[propertyname]</literal></entry>
+
+ <entry><literal>A_NAME as {item.name}</literal></entry>
+ </row>
+
+ <row>
+ <entry>composite 프로퍼티</entry>
+
+ <entry><literal>{[aliasname].[componentname].[propertyname]}</literal></entry>
+
+ <entry><literal>CURRENCY as {item.amount.currency}, VALUE as {item.amount.value}</literal></entry>
+ </row>
+
+ <row>
+ <entry>엔티티의 판별자(Discriminator)</entry>
+ <entry><literal>{[aliasname].class}</literal></entry>
+
+ <entry><literal>DISC as {item.class}</literal></entry>
+ </row>
+
+ <row>
+ <entry>엔티티의 모든 프로퍼티들</entry>
+ <entry><literal>{[aliasname].*}</literal></entry>
+
+ <entry><literal>{item.*}</literal></entry>
+ </row>
+
+ <row>
+ <entry>콜렉션 키</entry>
+ <entry><literal>{[aliasname].key}</literal></entry>
+
+ <entry><literal>ORGID as {coll.key}</literal></entry>
+ </row>
+
+ <row>
+ <entry>콜렉션의 id</entry>
+ <entry><literal>{[aliasname].id}</literal></entry>
+
+ <entry><literal>EMPID as {coll.id}</literal></entry>
+ </row>
+
+ <row>
+ <entry>콜렉션의 요소</entry>
+ <entry><literal>{[aliasname].element}</literal></entry>
+
+ <entry><literal>XID as {coll.element}</literal></entry>
+ <entry></entry>
+ </row>
+
+ <row>
+ <entry>콜렉션 내에 있는 요소의 프로퍼티</entry>
+ <entry><literal>{[aliasname].element.[propertyname]}</literal></entry>
+
+ <entry><literal>NAME as {coll.element.name}</literal></entry>
+ </row>
+
+ <row>
+ <entry>콜렉션 내에 있는 요소의 모든 프로퍼티들</entry>
+ <entry><literal>{[aliasname].element.*}</literal></entry>
+
+ <entry><literal>{coll.element.*}</literal></entry>
+ </row>
+
+ <row>
+ <entry>콜렉션의 모든 프로퍼티들</entry>
+ <entry><literal>{[aliasname].*}</literal></entry>
+
+ <entry><literal>{coll.*}</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>non-managed 엔티티들을 반환하기</title>
+
+ <para>native sql 질의에 ResultTransformer를 적용하는 것이 가능하다. 예를 들어
+ non-managed 엔티티들을 반환하기 위해 ResultTransformer를 허용하는 것.</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT NAME, BIRTHDATE FROM CATS")
+ .setResultTransformer(Transformers.aliasToBean(CatDTO.class))]]></programlisting>
+
+ <para>이 질의는 다음을 지정했다:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL 질의 문자열</para>
+ </listitem>
+
+ <listitem>
+ <para>결과 변환자(transformer)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 위의 질의는 초기화되어 있고 NAME과 BIRTHNAME의 값들을 <literal>CatDTO</literal>의
+ 대응하는 프로퍼티들과 필드들 속으로 주입시킨 <literal>CatDTO</literal>의 리스트를 반환할 것이다.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>상속 처리하기</title>
+
+ <para>상속의 부분으로서 매핑되는 엔티티들을 질의하는 native sql 질의들은 baseclass의
+ 모든 프로퍼티들을 포함해야 하고 그 모든 것이 서브클래스화 되어야 한다.</para>
+ </sect2>
+
+ <sect2>
+ <title>파라미터들</title>
+
+ <para>Native sql 질의들은 위치 파라미터들 뿐만 아니라 명명된 파라미터들을 지원한다:</para>
+
+ <programlisting><![CDATA[Query query = sess.createSQLQuery("SELECT * FROM CATS WHERE NAME like ?").addEntity(Cat.class);
+List pusList = query.setString(0, "Pus%").list();
+
+query = sess.createSQLQuery("SELECT * FROM CATS WHERE NAME like :name").addEntity(Cat.class);
+List pusList = query.setString("name", "Pus%").list(); ]]></programlisting>
+ </sect2>
+
+
+
+ </sect1>
+
+ <sect1 id="querysql-namedqueries" revision="3">
+ <title>명명된 SQL 질의들</title>
+
+ <para>
+ 명명된 SQL 질의들은 HQL 질의와 동일한 방법으로 매핑 문서 속에 정의될 수 있고 정확하게 호출될 수도 있다. 이 경우에, 우리는
+ <literal>addEntity()</literal> 호출을 필요로 하지 <emphasis>않는다</emphasis>.
+ </para>
+
+ <programlisting><![CDATA[<sql-query name="persons">
+ <return alias="person" class="eg.Person"/>
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex}
+ FROM PERSON person
+ WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+ <programlisting><![CDATA[List people = sess.getNamedQuery("persons")
+ .setString("namePattern", namePattern)
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ <para><literal><return-join></literal> 요소와
+ <literal><load-collection></literal>
+ 요소는 연관들을 조인시키고 콜렉션들을 각각 초기화 시키는 질의들을
+ 정의하는데 사용된다.</para>
+
+ <programlisting><![CDATA[<sql-query name="personsWith">
+ <return alias="person" class="eg.Person"/>
+ <return-join alias="address" property="person.mailingAddress"/>
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex},
+ address.STREET AS {address.street},
+ address.CITY AS {address.city},
+ address.STATE AS {address.state},
+ address.ZIP AS {address.zip}
+ FROM PERSON person
+ JOIN ADDRESS address
+ ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
+ WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+ <para>명명된 SQL 질의는 스칼라 값을 반환할수도 있다. 당신은
+ <literal><return-scalar></literal> 요소를 사용하여
+ 컬럼 alias와 Hibernate 타입을 선언해야 한다:</para>
+
+ <programlisting><![CDATA[<sql-query name="mySqlQuery">
+ <return-scalar column="name" type="string"/>
+ <return-scalar column="age" type="long"/>
+ SELECT p.NAME AS name,
+ p.AGE AS age,
+ FROM PERSON p WHERE p.NAME LIKE 'Hiber%'
+</sql-query>]]></programlisting>
+
+ <para>당신은 여러 개의 명명된 질의들을 가로질러 재사용하거나 <literal>setResultSetMapping()</literal> API를 통해 결과셋
+ 매핑정보들을 재사용하기 위해 <literal><resultset></literal> 요소 속에 결과셋 매핑 정보들을 구체화 시킬 수 있다.</para>
+
+ <programlisting><![CDATA[<resultset name="personAddress">
+ <return alias="person" class="eg.Person"/>
+ <return-join alias="address" property="person.mailingAddress"/>
+</resultset>
+
+<sql-query name="personsWith" resultset-ref="personAddress">
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex},
+ address.STREET AS {address.street},
+ address.CITY AS {address.city},
+ address.STATE AS {address.state},
+ address.ZIP AS {address.zip}
+ FROM PERSON person
+ JOIN ADDRESS address
+ ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
+ WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+ <para>다른방법으로 당신은 당신의 hbm 파일들 내에 직접 자바 코드로 된 결과셋 매핑 정보를 사용할 수 있다.</para>
+
+ <programlisting><![CDATA[List cats = sess.createSQLQuery(
+ "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id"
+ )
+ .setResultSetMapping("catAndKitten")
+ .list();]]></programlisting>
+
+ <sect2 id="propertyresults">
+ <title>명시적으로 column/alias 이름들을 지정하는데 return-property 사용하기</title>
+
+ <para>Hibernate로 하여금 그것 자신의 alias들을 끼워넣도록 하기 위해
+ <literal>{}</literal>-구문을 사용하는 것 대신에,
+ <literal><return-property></literal>로서 당신은 사용할
+ 컬럼 alias들이 무엇인지를 Hibernate에게 명시적으로 알려줄 수 있다.</para>
+
+ <programlisting><![CDATA[<sql-query name="mySqlQuery">
+ <return alias="person" class="eg.Person">
+ <return-property name="name" column="myName"/>
+ <return-property name="age" column="myAge"/>
+ <return-property name="sex" column="mySex"/>
+ </return>
+ SELECT person.NAME AS myName,
+ person.AGE AS myAge,
+ person.SEX AS mySex,
+ FROM PERSON person WHERE person.NAME LIKE :name
+</sql-query>
+]]></programlisting>
+
+ <para><literal><return-property></literal>는 또한 다중 컬럼들에 대해 동작한다.
+ 이것은 다중-컬럼 프로퍼티들에 대한 fine grained 제어를 허용할 수 없는
+ <literal>{}</literal>-구문을 가진 제약을 해결해준다.</para>
+
+ <programlisting><![CDATA[<sql-query name="organizationCurrentEmployments">
+ <return alias="emp" class="Employment">
+ <return-property name="salary">
+ <return-column name="VALUE"/>
+ <return-column name="CURRENCY"/>
+ </return-property>
+ <return-property name="endDate" column="myEndDate"/>
+ </return>
+ SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer},
+ STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},
+ REGIONCODE as {emp.regionCode}, EID AS {emp.id}, VALUE, CURRENCY
+ FROM EMPLOYMENT
+ WHERE EMPLOYER = :id AND ENDDATE IS NULL
+ ORDER BY STARTDATE ASC
+</sql-query>]]></programlisting>
+
+ <para>이 예제에서 우리는 끼워넣기(injection)를 위해 <literal>{}</literal>-구문과 함께 <literal><return-property></literal>를
+ 사용했음을 주목하라. 사용자들이 컬럼과 프로퍼티들을 참조하고자 원하는 방법을 선택하는 것을 사용자들에게 허용해줌으로써.</para>
+
+ <para>만일 당신의 매핑이 한 개의 판별자(discriminator )를 가질 경우 당신은 판별자 컬럼을 지정하는데
+ <literal><return-discriminator></literal>를 사용해야 한다.</para>
+ </sect2>
+
+ <sect2 id="sp_query" revision="1">
+ <title>질의를 위한 내장 프로시저 사용하기</title>
+
+ <para>Hibernate 3은 내장 프로시저들과 함수들을 통한 질의 지원을 도입한다. 대부분의 다음 문서는 양자 모두에 동일하게 적용된다.
+ 내장 프로시저/함수는 Hibernate와 동작하는 것이 가능하도록 첫 번째 out-파라미터로서 한 개의 결과셋을 반환해야 한다.
+ Oracle9 이상의 버전에서 그런 내장 프로시저에 대한 예제는 다음과 같다:</para>
+
+ <programlisting><![CDATA[CREATE OR REPLACE FUNCTION selectAllEmployments
+ RETURN SYS_REFCURSOR
+AS
+ st_cursor SYS_REFCURSOR;
+BEGIN
+ OPEN st_cursor FOR
+ SELECT EMPLOYEE, EMPLOYER,
+ STARTDATE, ENDDATE,
+ REGIONCODE, EID, VALUE, CURRENCY
+ FROM EMPLOYMENT;
+ RETURN st_cursor;
+ END;]]></programlisting>
+
+ <para>Hibernate에서 이 질의를 사용하기 위해 당신은 하나의 명명된 질의(a named query)를 통해
+ 그것을 매핑할 필요가 있다.</para>
+
+ <programlisting><![CDATA[<sql-query name="selectAllEmployees_SP" callable="true">
+ <return alias="emp" class="Employment">
+ <return-property name="employee" column="EMPLOYEE"/>
+ <return-property name="employer" column="EMPLOYER"/>
+ <return-property name="startDate" column="STARTDATE"/>
+ <return-property name="endDate" column="ENDDATE"/>
+ <return-property name="regionCode" column="REGIONCODE"/>
+ <return-property name="id" column="EID"/>
+ <return-property name="salary">
+ <return-column name="VALUE"/>
+ <return-column name="CURRENCY"/>
+ </return-property>
+ </return>
+ { ? = call selectAllEmployments() }
+</sql-query>]]></programlisting>
+
+ <para>내장 프로시저들은 현재 스칼라들과 엔티티들 만을 반환함을 주목하라. <literal><return-join></literal>과
+ <literal><load-collection></literal>은 지원되지 않는다.</para>
+
+ <sect3 id="querysql-limits-storedprocedures" revision="1">
+ <title>내장 프로시저들을 사용하는 규칙들/제약들</title>
+
+ <para>Hibernate에서 내장 프로시저들을 사용하기 위해서 프로시저들/함수들은 다음 몇몇 규칙들을 따라야 한다. 만일 그것들이 그들 규칙들을
+ 따르지 않을 경우 그것들은 Hibernate와 함께 사용 불가능하다. 만일 당신이 여전히 이들 프로시저들을 사용하고자 원할 경우,
+ 당신은 <literal>session.connection()</literal>을 통해 그것들을 실행시켜야 한다. 데이터베이스 벤더들이 다른 내장
+ 프로시저 의미론/구문을 갖고 있기 때문에, 규칙들은 각각의 데이터베이스에 따라 차이가 난다.</para>
+
+ <para>내장 프로시저 질의들은 <literal>setFirstResult()/setMaxResults()</literal>로서 쪽매김 될 수 없다.</para>
+
+ <para>권장되는 호출 형식은 표준 SQL92이다: <literal>{ ? = call
+ functionName(<parameters>) }</literal> 또는 <literal>{ ? = call
+ procedureName(<parameters>}</literal>. Native 호출 구문은 지원되지 않는다.</para>
+
+ <para>Oracle의 경우 다음 규칙들이 적용된다:</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>하나의 함수는 하나의 결과 셋을 반환해야 한다. 프로시저의 첫 번째 파라미터는 하나의 결과 셋을 반환하는
+ 하나의 <literal>OUT</literal>이어야 한다. 이것은 Oracle 9 또는 10에서 하나의
+ <literal>SYS_REFCURSOR</literal>를 사용하여 행해진다. Oracle에서 당신은
+ <literal>REF CURSOR</literal> 타입을 정의할 필요가 있는데, Oracle 보고서를 보라.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Sybase 또는 MS SQL server의 경우 다음 규칙들이 적용된다:</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>프로시저는 한 개의 결과 셋을 반환해야 한다. 이들 서버들이 여러 개의 결과셋들과 업데이트 카운트들을 반환 할수 있다/할 것이이므로,
+ Hibernate는 결과들을 반복 순환할 것이고 그것의 반환 값으로서 하나의 결과 셋인 첫 번째 결과를 취할 것이다. 그 밖의 모든 것은
+ 폐기될 것이다.</para>
+ </listitem>
+ <listitem>
+ <para>만일 당신이 당신의 프로시저 내에 <literal>SET NOCOUNT ON</literal>을 이용 가능하게 할 수 있다면 그것은 아마
+ 보다 효율적이게 될 것이지만 이것은 필요 조건이 아니다.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 id="querysql-cud">
+ <title>create, update 그리고 delete를 위한 맞춤형 SQL</title>
+
+ <para>Hibernate3는 create, update, delete 오퍼레이션들을 위한 맞춤형 문장들을 사용할 수 있다. Hibernate에서 클래스와 콜렉션
+ 영속자들은 구성 시에 생성된 문자열들의 집합(insertsql, deletesql, updatesql 등)을 이미 포함하고 있다.
+ <literal><sql-insert></literal>, <literal><sql-delete></literal>,
+ <literal><sql-update></literal> 매핑 태그들은 이들 문자열들을 오버라이드 시킨다:</para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ? )</sql-insert>
+ <sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete>
+</class>]]></programlisting>
+
+ <para>SQL이 당신의 데이터베이스 내에서 직접 실행되어서, 당신이 좋아하는 임의의 dialect를 사용하는 것이 자유롭다. 만일 당신이 데이터베이스
+ 지정적인 SQL을 사용할 경우 이것은 물론 당신의 매핑의 이식성을 감소시킬 것이다.</para>
+
+ <para>만일 <literal>callable</literal> 속성이 설정되면 내장 프로시저들이 지원된다:</para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <sql-insert callable="true">{call createPerson (?, ?)}</sql-insert>
+ <sql-delete callable="true">{? = call deletePerson (?)}</sql-delete>
+ <sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update>
+</class>]]></programlisting>
+
+ <para>위치 파라미터들은 Hibernate가 그것들을 기대하는 것과 같은 순서가 되어야 하므로,
+ 위치 파라미터들의 순서는 현재 절대적으로 중요하다.</para>
+
+ <para>당신은 <literal>org.hiberate.persister.entity</literal> 레벨로 디버그 로깅을 사용 가능하게 함으로써 예상된 순서를 볼 수
+ 있다. 이 레벨을 이용 가능하게 하면 Hibernate는 엔티티들을 생성시키고, 업데이트하고, 삭제하는데 사용되는 정적인 SQL을 출력할 것이다.
+ (예상되는 결과를 보려면, Hibernate 생성된 정적인 sql을 오버라이드 시키게 매핑 파일들 속에 당신의 맞춤형 SQL을 포함시키지 않도록 염두에
+ 두라.)</para>
+
+ <para>Hibernate가 문장의 성공을 위해 몇몇 실행 시 체크들을 행하므로, 내장 프로시저들은 대부분의 경우들(읽기:다른 경우들 보다 그것을 더 잘
+ 행한다)에서 insert되고/업데이트되고/삭제된 행들의 개수를 반환하는데 필요하다. Hibernate는 항상 CUD 오퍼레이션들에 대한 숫자
+ 출력 파라미터로서 첫 번째 문장 파라미터를 등록시킨다:</para>
+
+ <programlisting><![CDATA[CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname IN VARCHAR2)
+ RETURN NUMBER IS
+BEGIN
+
+ update PERSON
+ set
+ NAME = uname,
+ where
+ ID = uid;
+
+ return SQL%ROWCOUNT;
+
+END updatePerson;]]></programlisting>
+ </sect1>
+
+ <sect1 id="querysql-load">
+ <title>로딩을 위한 맞춤형 SQL</title>
+
+ <para>당신은 또한 엔티티 로딩을 위한 당신 자신의 SQL (또는 HQL)을 선언할 수도 있다:</para>
+
+ <programlisting><![CDATA[<sql-query name="person">
+ <return alias="pers" class="Person" lock-mode="upgrade"/>
+ SELECT NAME AS {pers.name}, ID AS {pers.id}
+ FROM PERSON
+ WHERE ID=?
+ FOR UPDATE
+</sql-query>]]></programlisting>
+
+ <para>이것은 앞서 논의했듯이 단지 명명된 질의 선언이다. 당신은 class 매핑 속에 이 명명된 질의를 참조할 수 있다:</para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <loader query-ref="person"/>
+</class>]]></programlisting>
+
+ <para>이것은 심지어 내장 프로시저들에 동작한다.</para>
+
+ <para>당신은 콜렉션 로딩을 위한 한 개의 질의를 정의할 수도 있다:</para>
+
+ <programlisting><![CDATA[<set name="employments" inverse="true">
+ <key/>
+ <one-to-many class="Employment"/>
+ <loader query-ref="employments"/>
+</set>]]></programlisting>
+
+ <programlisting><![CDATA[<sql-query name="employments">
+ <load-collection alias="emp" role="Person.employments"/>
+ SELECT {emp.*}
+ FROM EMPLOYMENT emp
+ WHERE EMPLOYER = :id
+ ORDER BY STARTDATE ASC, EMPLOYEE ASC
+</sql-query>]]></programlisting>
+
+ <para>당신은 심지어 조인 페칭에 의해 하나의 콜렉션을 로드시키는 하나의 엔티티를 정의할 수 있다:</para>
+
+ <programlisting><![CDATA[<sql-query name="person">
+ <return alias="pers" class="Person"/>
+ <return-join alias="emp" property="pers.employments"/>
+ SELECT NAME AS {pers.*}, {emp.*}
+ FROM PERSON pers
+ LEFT OUTER JOIN EMPLOYMENT emp
+ ON pers.ID = emp.PERSON_ID
+ WHERE ID=?
+</sql-query>]]></programlisting>
+ </sect1>
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/quickstart.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/quickstart.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/quickstart.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/quickstart.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,572 @@
+<chapter id="quickstart">
+ <title>Tomcat으로 빠른 시작</title>
+
+ <sect1 id="quickstart-intro" revision="2">
+ <title>Hibernate 시작하기</title>
+
+ <para>
+ 이 튜토리얼은 웹 기반의 어플리케이션 용 Apache Tomcat 서블릿 컨테이너에 대한 Hibernate 3.0 셋업을
+ 설명한다(우리는 버전 4.1을 사용했다. 5.0에 대한 차이점들은 적을 것이다). Hibernate는 모든 주요 J2EE
+ 어플리케이션 서버들의 관리되는 환경에서 잘 동작하고, 또는 심지어 스탠드얼론 어플리케이션들에서도 잘 동작
+ 한다. 이 튜토리얼에 사용되는 데이터베이스 시스템은 PostgreSQL 7.4이고, 다른 데이터베이스에 대한 지원은
+ 단지 Hibernate SQL dialect 구성과 커넥션 프로퍼티들을 변경시키는 것에만 관계된다.
+ </para>
+
+ <para>
+ 먼저 우리는 모든 필수적인 라이브러리들을 Tomcat 설치 장소에 복사해야 한다. 우리는 이 튜토리얼을 위해 별도의
+ 웹 컨텍스트(<literal>webapps/quickstart</literal>)를 사용하며, 따라서 우리는 전역 라이브러리 검색 경로
+ (<literal>TOMCAT/common/lib</literal>)와 <literal>webapps/quickstart/WEB-INF/lib</literal>
+ (JAR 파일들의 경우)와 <literal>webapps/quickstart/WEB-INF/classes</literal> 내 에 있는 컨텍스트
+ 레벨에서 클래스로더 양자를 고려해야 한다. 우리는 두 개의 클래스로더 레벨들을 전역 classpath와 컨텍스트
+ classpath로서 언급한다.
+ </para>
+
+ <para>
+ 이제 라이브러리들을 두 개의 classpath들에 복사하라:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ 데이터베이스 용 JDBC 드라이버를 전역 classpath로 복사하라. 이것은 Tomcat에 번들로구성된 DBCP 커넥션
+ 풀 소프트웨어에 필요하다. Hibernate는 데이터베이스 상에서 SQL을 실행시키는데 JDBC 커넥션들을 사용하므로,
+ 당신은 풀링된 JDBC 커넥션들을 제공해야 하거나, 직접 지원되는 풀들(C3P0, Proxool) 중 하나를 사용하기
+ 위해 Hibernate를 구성해야 한다. 이 튜토리얼을 위해, (PostgreSQL 7.4와 JDK 1.4용) <literal>pg74jdbc3.jar</literal>
+ 라이브러리를 전역 classloaders 경로로 복사하라. 만일 당신이 다른 데이터베이스를 사용하고자 원할 경우,
+ 간단하게 그것의 적절한 JDBC 드라이버를 복사하라.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 그 밖의 어떤 것을 Tomcat 내의 전역 클래스로더 경로에 복사하지 말라. 또는 당신은 Log4j, commons-logging
+ 그리고 다른 것들을 포함하는 여러 가지 도구들에 관련된 문제점들을 얻게 될 것이다. 각각의 웹 어플리케이션에 대해
+ 컨텍스트 classpath를 사용하라. 즉 라이브러리들을 <literal>WEB-INF/lib</literal>에 복사하고, 당신 자신의 클래스들과
+ 구성 파일들/프로퍼티 파일들을 <literal>WEB-INF/classes</literal>에 복사하라. 두 디렉토리들 양자는 디폴트로 컨텍스트
+ classpath 내에 있다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Hibernate는 JAR 라이브러리로서 패키지화 되어 있다. <literal>hibernate3.jar</literal> 파일은 어플리케이션의 다른 클래스들과
+ 함께 컨텍스트 classpath 속에 복사되어야 한다. Hibernate는 실행 시에 어떤 제 3의 라이브러리들을 필요로하고,
+ 이것들은 <literal>lib/</literal> 디렉토리 내의 Hibernate 배포본에 번들화되어 있다; <xref linkend="3rdpartylibs"/>를
+ 보라. 필요한 제3의 라이브러리들을 컨텍스트 classpath로 복사하라.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <table frame="topbot" id="3rdpartylibs">
+ <title>
+ Hibernate 제3의 라이브러리
+ </title>
+ <tgroup cols="2" rowsep="1" colsep="1">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry align="center">
+ 라이브러리
+ </entry>
+ <entry align="center">
+ 설명
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ antlr (필수)
+ </entry>
+ <entry>
+ Hibernate는 질의 파서들을 산출하는데 ANTLR을 사용하고, 이 라이브러리는 또한
+ 실행 시에 필요하다.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ dom4j (필수)
+ </entry>
+ <entry>
+ Hibernate는 XML 구성과 XML 매핑 메타데이터 파일들을 파싱하는데 dom4j를 사용
+ 한다.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ CGLIB, asm (필수)
+ </entry>
+ <entry>
+ Hibernate는 (Java reflection과 결합하여) 런타임 시에 클래스들을 고양시키는데
+ 코드 생성 라이브러리를 사용한다.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Commons Collections, Commons Logging (필수)
+ </entry>
+ <entry>
+ Hibernate는 Apache Jakarta Commons 프로젝트로부터 다양한 유틸리티 라이브러리
+ 들을 사용한다.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ EHCache (필수)
+ </entry>
+ <entry>
+ Hibernate는 second-level 캐시를 위한 다양한 캐시 프로바이더들을 사용할 수 있다.
+ 만일 구성에서 변하지 않을 경우 EHCache가 디폴트 캐시 프로바이더이다.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Log4j (옵션)
+ </entry>
+ <entry>
+ Hibernate는 기본 로깅 메커니즘으로서 Log4j를 사용할 수 있는, Commons Logging
+ API를 사용한다. 만일 Log4j 라이브러리가 컨텍스트 라이브러리 디렉토리 속에서 이용
+ 가능하다면, Commons Logging은 Log4j와 컨텍스트 classpath 내에 있는 <literal>log4j.properties</literal>
+ 구성을 사용할 것이다. Log4j에 대한 예제 properties 파일은 Hibernate 배포본에
+ 번들화 되어 있다. 따라서 당신이 이면에서 무엇이 진행되는 지을 보고자 원할 경우에 log4j.jar와
+ (<literal>src/</literal>에 있는) 구성 파일을 당신의 컨텍스트 classpath 속으로 복사하라.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ 필수 여부?
+ </entry>
+ <entry>
+ Hibernate 배포본 내에 있는 <literal>lib/README.txt</literal> 파일을 살펴보라.
+ 이것은 Hibernate에 배포된 제 3의 라이브러리들의 최신 목록이다. 당신은 그곳에 열거된
+ 모든 필수 라이브러리들과 옵션 라이브러리들을 찾게 될 것이다(여기서 "빌드 시 필요함"은
+ 당신의 어플리케이션이 아니라 Hibernate에 대한 의미임을 노트하라).
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 우리는 이제 Tomcat과 Hibernate 양자에서 데이터베이스 커넥션 풀링과 공유를 설정한다. 이것은 Tomcat이
+ (그것의 미리 빌드되어 있는 DBCP 풀링 특징을 사용하여) 풀링된 JDBC 커넥션들을 제공할 것이고, Hibernate가
+ JNDI를 통해 이들 커넥션들을 요청한다는 것을 의미한다. 달리 당신은 Hibernate로 하여금 커넥션 풀을 관리하도록
+ 할 수 있다. Tomcat은 그것의 커넥션 풀을 JNDI에 바인드 시킨다; 우리는 리소스 선언을 Tomcat 메인 구성 파일인
+ <literal>TOMCAT/conf/server.xml</literal>에 추가한다:
+ </para>
+
+ <programlisting><![CDATA[<Context path="/quickstart" docBase="quickstart">
+ <Resource name="jdbc/quickstart" scope="Shareable" type="javax.sql.DataSource"/>
+ <ResourceParams name="jdbc/quickstart">
+ <parameter>
+ <name>factory</name>
+ <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+ </parameter>
+
+ <!-- DBCP database connection settings -->
+ <parameter>
+ <name>url</name>
+ <value>jdbc:postgresql://localhost/quickstart</value>
+ </parameter>
+ <parameter>
+ <name>driverClassName</name><value>org.postgresql.Driver</value>
+ </parameter>
+ <parameter>
+ <name>username</name>
+ <value>quickstart</value>
+ </parameter>
+ <parameter>
+ <name>password</name>
+ <value>secret</value>
+ </parameter>
+
+ <!-- DBCP connection pooling options -->
+ <parameter>
+ <name>maxWait</name>
+ <value>3000</value>
+ </parameter>
+ <parameter>
+ <name>maxIdle</name>
+ <value>100</value>
+ </parameter>
+ <parameter>
+ <name>maxActive</name>
+ <value>10</value>
+ </parameter>
+ </ResourceParams>
+</Context>]]></programlisting>
+
+ <para>
+ 우리가 이 예제에서 구성하는 컨텍스트는 <literal>quickstart</literal>로 명명되고, 그것의 베이스는
+ <literal>TOMCAT/webapp/quickstart</literal> 디렉토리이다. 임의의 서블릿들에 접근하기 위해,
+ (물론 당신의 <literal>web.xml</literal> 속에 매핑된 서블릿의 이름을 추가하여) 당신의 브라우저에서
+ <literal>http://localhost:8080/quickstart</literal> 경로를 호출하라. 당신은 또한 계속 진행하고
+ 이제 공백의 <literal>process()</literal> 메소드를 가진 간단한 서블릿을 생성시킬 수 있다.
+ </para>
+
+ <para>
+ Tomcat은 이제 <literal>java:comp/env/jdbc/quickstart</literal>로 JNDI을 통해 커넥션들을 제공한다.
+ 만일 당신이 실행 중인 커넥션 풀을 얻는 것에 문제가 있다면 Tomcat 문서를 참조하라. 당신이 JDBC 드라이버 예외상황
+ 메시지를 얻을 경우, 먼저 Hibernate 없이 JDBC 커넥션 풀을 셋업하라. Tomcat & JDBC 튜토리얼들은
+ 그 웹 서이트에서 이용 가능하다.
+ </para>
+
+ <para>
+ 당신의 다음 단계는 Hibernate를 구성하는 것이다. Hibernate는 그것이 JDBC 커넥션들을 얻는 방법을 알고 있어야 한다.
+ 우리는 Hibernate의 XML 기반 구성을 사용한다. properties 파일을 사용하는 다른 접근법은 거의 동일하지만 XML
+ 구문이 허용하는 몇몇 특징들을 누락하고 있다. XML 구성 파일은 <literal>hibernate.cfg.xml</literal>로서
+ 컨텍스트 classpath (<literal>WEB-INF/classes</literal>) 내에 위치해 있다:
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <session-factory>
+
+ <property name="connection.datasource">java:comp/env/jdbc/quickstart</property>
+ <property name="show_sql">false</property>
+ <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
+
+ <!-- Mapping files -->
+ <mapping resource="Cat.hbm.xml"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ 우리는 SQL 명령들에 대한 로깅을 사용하지 않고 Hibernate에게 사용되는 데이터베이스 SQL direct가 무엇인지
+ 그리고 (Tomcat 바인드된 풀의 JNDI 주소를 선언하여) JDBC 커넥션들을 얻는 곳을 알려준다. dialect는
+ 필수적인 설정이고, 데이터베이스들은 SQL "표준"에 대한 그것들의 해석을 달리한다. Hibernate는 차이점들을
+ 처리하고 모든 주요 상용 데이터베이스들 및 오픈 소스 데이터베이스들 용도의 direct들을 번들로 포함하고 있다.
+ </para>
+
+ <para>
+ <literal>SessionFactory</literal>는 단일 데이터저장소에 관한 개념이고, 여러 데이터베이스들은 여러
+ 개의 XML 구성 파일들을 생성시키고 당신의 어플리케이션 속에서 여러 개의 <literal>Configuration</literal>
+ 및 <literal>SessionFactory</literal> 객체들을 생성시켜서 사용될 수 있다.
+ </para>
+
+ <para>
+ <literal>hibernate.cfg.xml</literal>의 마지막 요소는 영속 클래스 <literal>Cat</literal>에 대한
+ Hibernate XML 매핑 파일의 이름으로써 <literal>Cat.hbm.xml</literal>을 선언한다. 이 파일은 데이터베이스
+ 테이블(또는 테이블들)로 POJO 클래스 <literal>Cat</literal> 을 매핑시키는 메타데이터를 포함한다. 우리는
+ 곧 그 파일로 되돌아 갈 것이다. 먼저 POJO 클래스를 작성하고 그런 다음 그것을 위한 매핑 메타데이터를 선언하자.
+ </para>
+
+ </sect1>
+
+ <sect1 id="quickstart-persistentclass" revision="1">
+ <title>첫 번째 영속 클래스</title>
+
+ <para>
+ Hibernate는 영속 클래스들에 대한 Plain Old Java Objects (POJOs, 종종 Plain Ordinary Java Objects로
+ 명명된다) 프로그래밍 모형으로 가장 잘 동작한다. POJO는 공용으로 가시적인 인터페이스로부터 내부적인 표상을 은폐시켜,
+ getter와 setter 메소드들을 통해 접근가능한 클래스들의 프로퍼티들을 가진 자바빈과 꽤 유사하다(필요하다면 Hibernate는
+ 또한 필드들에 직접 접근할 수 있다):
+ </para>
+
+ <programlisting><![CDATA[package org.hibernate.examples.quickstart;
+
+public class Cat {
+
+ private String id;
+ private String name;
+ private char sex;
+ private float weight;
+
+ public Cat() {
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ private void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public char getSex() {
+ return sex;
+ }
+
+ public void setSex(char sex) {
+ this.sex = sex;
+ }
+
+ public float getWeight() {
+ return weight;
+ }
+
+ public void setWeight(float weight) {
+ this.weight = weight;
+ }
+
+}]]></programlisting>
+
+ <para>
+ Hibernate는 그것의 프로퍼티 타입들의 사용에 제약되지 않고, 자바 콜렉션 프레임웍에서의 클래스들을 포함하여, 모든
+ 자바 JDK 타입들과 (<literal>String</literal>, <literal>char</literal>와 <literal>Date</literal>
+ 같은) 원시타입들이 매핑될 수 있다. 당신은 그것을 값들로서, 값들을 가진 콜렉션들로서, 또는 다른 엔티티들에 대한
+ 연관들로서 매핑시킬 수 있다. <literal>id</literal>는 그 클래스의 데이터베이스 식별자(프라이머리 키)를 표현하는
+ 특별한 프로퍼티이고, 그것은 <literal>Cat</literal>과 같은 엔티티들에 대해 매우 권장된다. Hibernate는 내부적으로만
+ 식별자들을 사용할 수 있지만, 우리는 우리의 어플리케이션 아키텍처에서 어떤 유연성을 상실하게 될 것이다.
+ </para>
+
+ <para>
+ 특정 인터페이스는 영속 클래스들에 대해 구현되지 말아야 하거나 특정 루트 영속 클래스로부터 서브 클래스로 만들지 말아야 한다.
+ Hibernate는 또한 바이트 코드 처리와 같은, 어떤 빌드 시 처리를 필요로 하지 않고, 그것은 오직 자바 reflection과
+ (CGLIB를 통한) 런타임 클래스 고양에만 의존한다. 따라서 Hibernate에 대한 POJO 클래스의 어떤 의존성 없이도, 우리는
+ 그것을 데이터베이스 테이블로 매핑할 수 있다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="quickstart-mapping" revision="2">
+ <title>cat 매핑하기</title>
+
+ <para>
+ <literal>Cat.hbm.xml</literal> 매핑파일은 객체/관계형 매핑에 필요한 메타데이터를 포함한다. 메타데이터는 영속
+ 클래스들의 선언과 데이터베이스 테이블들에 대한 (컬럼들과 다른 엔티티들에 대한 foreign 키 관계들에 대한) 프로퍼티들의
+ 매핑을 포함한다.
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping>
+
+ <class name="org.hibernate.examples.quickstart.Cat" table="CAT">
+
+ <!-- A 32 hex character is our surrogate key. It's automatically
+ generated by Hibernate with the UUID pattern. -->
+ <id name="id" type="string" unsaved-value="null" >
+ <column name="CAT_ID" sql-type="char(32)" not-null="true"/>
+ <generator class="uuid"/>
+ </id>
+
+ <!-- A cat has to have a name, but it shouldn' be too long. -->
+ <property name="name">
+ <column name="NAME" length="16" not-null="true"/>
+ </property>
+
+ <property name="sex"/>
+
+ <property name="weight"/>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 모든 영속 클래스는 식별자 속성을 가져야 한다(실제로 value-타입의 클래스들에 의존하지 않는, 엔티티들을 표현하는 유일한
+ 클래스들은 엔티티을 가진 컴포넌트들로 매핑된다). 이 프로퍼티는 영속 객체들을 구별짓는데 사용된다: 만일
+ <literal>catA.getId().equals(catB.getId())</literal>가 true일 경우, 두 개의 cat들은 같고, 이 개념은
+ <emphasis>database identity</emphasis>로 명명된다. Hibernate는 (데이터베이스 시퀀스, hi/lo 식별자 테이블들,
+ 그리고 어플리케이션 할당 식별자들에 대한 native 생성기들을 포함하는) 다른 시나리오들에 대해 여러 가지 식별자 생성기들을
+ 번들로 갖고 있다. 우리는 UUID 생성기(데이터이스에 의해 생성된 정수 대용 키들이 선호될 것이므로, 테스트용으로만 권장됨)를
+ 사용하고 또한 Hibernate 생성된 식별자 값을 위한 <literal>CAT</literal> 테이블의 <literal>CAT_ID</literal>
+ 컬럼을 (테이블의 프라이머리 키로서) 지정한다.
+ </para>
+
+ <para>
+ <literal>Cat</literal>의 모든 다른 프로퍼티들은 동일한 테이블로 매핑된다. <literal>name</literal> 프로퍼티의 경우에,
+ 우리는 그것을 명시적인 데이터베이스 컬럼 선언으로 매핑시켰다. 데이터베이스 스키마가 Hibernate의 <emphasis>SchemaExport</emphasis>
+ 도구에 의해 매핑 선언으로부터 (SQL DDL 문장들로) 자동적으로 생성될 때 이것이 특별히 유용하다. 모든 다른 프로퍼티들은
+ Hibernate의 디폴트 설정들을 사용하여 매핑되고, 디폴트 설정들은 당신이 가장 많은 시간을 필요로 하는 것이다. 데이터베이스
+ 내의 테이블 <literal>CAT</literal>은 다음과 같다:
+ </para>
+
+ <programlisting><![CDATA[ Column | Type | Modifiers
+--------+-----------------------+-----------
+ cat_id | character(32) | not null
+ name | character varying(16) | not null
+ sex | character(1) |
+ weight | real |
+Indexes: cat_pkey primary key btree (cat_id)]]></programlisting>
+
+ <para>
+ 당신은 이제 수작업으로 당신의 데이터베이스 내에 이 테이블을 생성시킬 것이고, 만일 당신이 <literal>hbm2ddl</literal>
+ 도구로 이 단계를 자동화 시키고자 원할 경우 <xref linkend="toolsetguide"/>를 읽어라. 이 도구는 테이블 정의, 맞춤형
+ 컬럼 타입 컨스트레인트들, 유일 컨스트레인트들과 인덱스들을 포함하는, 전체 SQL DDL을 생성시킬 수 있다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="quickstart-playingwithcats" revision="3">
+ <title>cat들에 작업하기</title>
+
+ <para>
+ 우리는 이제 Hibernate의 <literal>Session</literal>을 시작할 준비가 되어 있다. 그것은 <emphasis>persistence manager</emphasis>
+ (영속 관리자)이고, 우리는 데이터베이스로 <literal>Cat</literal>들을 저장하고 데이터베이스로부터
+ <literal>Cat</literal>들을 검색하는데 그것을 사용한다. 그러나 먼저 우리는 <literal>SessionFactory</literal>로부터
+ <literal>Session</literal>(Hibernate의 작업 단위)를 얻어야 한다:
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sessionFactory =
+ new Configuration().configure().buildSessionFactory();]]></programlisting>
+
+ <para>
+ <literal>configure()</literal> 호출은 <literal>hibernate.cfg.xml</literal> 구성 파일을 로드시키고
+ <literal>Configuration</literal> 인스턴스를 초기화 시킨다. 당신이 SessionFactory(불변적임)를 빌드하기
+ <emphasis>이전에</emphasis> 당신은 <literal>Configuration</literal>에 접근함으로써 다른 프로퍼티들을
+ 설정할 수 있다(그리고 심지어 매핑 메타데이터를 변경시킬 수 있다). 우리는 어디서 <literal>SessionFactory</literal>를
+ 생성시키고 우리의 어플리케이션 속에서 어떻게 그것에 접근할 수 있나?
+ </para>
+
+ <para>
+ <literal>SessionFactory</literal>는 대개 오직 한번만, 예를 들어 대개 <emphasis>load-on-startup</emphasis>
+ 서블릿으로 시작 시에 빌드된다. 이것은 또한 당신이 당신의 서블릿들 내에 있는 인스턴스 변수 속에 그것을 유지하지 않을 것이지만
+ 어떤 다른 위치에 유지시킬 것임을 의미한다. 더구나 우리는 어떤 종류의 <emphasis>Singleton</emphasis>을 필요로 하며,
+ 따라서 우리는 어플리케이션 코드로 쉽게 <literal>SessionFactory</literal>에 액세스 할 수 있다. 다음에 보여진 접근법은
+ 두 문제 모두를 해결한다: 시작 구성과 <literal>SessionFactory</literal>에 대한 쉬운 접근.
+ </para>
+
+ <para>
+ 우리는 <literal>HibernateUtil</literal> helper 클래스를 구현한다:
+ </para>
+
+ <programlisting><![CDATA[import org.hibernate.*;
+import org.hibernate.cfg.*;
+
+public class HibernateUtil {
+
+ private static Logger log = LoggerFactory.getLogger(HibernateUtil.class);
+
+ private static final SessionFactory sessionFactory;
+
+ static {
+ try {
+ // Create the SessionFactory
+ sessionFactory = new Configuration().configure().buildSessionFactory();
+ } catch (Throwable ex) {
+ // Make sure you log the exception, as it might be swallowed
+ log.error("Initial SessionFactory creation failed.", ex);
+ throw new ExceptionInInitializerError(ex);
+ }
+ }
+
+ public static final ThreadLocal session = new ThreadLocal();
+
+ public static Session getCurrentSession() {
+ Session s = (Session) session.get();
+ // Open a new Session, if this Thread has none yet
+ if (s == null) {
+ s = sessionFactory.openSession();
+ session.set(s);
+ }
+ return s;
+ }
+
+ public static void closeSession() {
+ Session s = (Session) session.get();
+ if (s != null)
+ s.close();
+ session.set(null);
+ }
+}]]></programlisting>
+
+ <para>
+ 이 클래스는 static 초기자를 가진 <literal>SessionFactory</literal>를 처리할 뿐만 아니라 또한 현재의 쓰레드를
+ 위한 <literal>Session</literal>을 소유하는 <literal>ThreadLocal</literal> 변수를 갖는다. 이 helper를
+ 사용하려고 시도하기 전에 thread-local 변수에 대한 자바 개념을 이해해야 한다. 보다 복잡하고 강력한 <literal>HibernateUtil</literal>
+ 클래스는 http://caveatemptor.hibernate.org/의 <literal>CaveatEmptor</literal>에서 찾을 수 있다.
+ </para>
+
+ <para>
+ <literal>SessionFactory</literal>는 threadsafe이고, 많은 쓰레드들이 동시에 그것에 접근할 수 있고
+ <literal>Session</literal>들을 요청할 수 있다. 하나의 <literal>Session</literal>은 데이터베이스에 대해
+ 한 개의 단위 작업을 나타내는 non-threadsafe 객체이다. <literal>Session</literal>들은 <literal>SessionFactory</literal>
+ 로부터 열려지고 모든 작업이 완료될 때 닫혀진다. 당신의 서블릿의 <literal>process()</literal> 메소드 내에 있는
+ 예제는 다음과 같을 수 있다(예외상황 처리 없이):
+ </para>
+
+ <programlisting><![CDATA[Session session = HibernateUtil.getCurrentSession();
+Transaction tx = session.beginTransaction();
+
+Cat princess = new Cat();
+princess.setName("Princess");
+princess.setSex('F');
+princess.setWeight(7.4f);
+
+session.save(princess);
+
+tx.commit();
+HibernateUtil.closeSession();]]></programlisting>
+
+ <para>
+ 하나의 <literal>Session</literal> 내에서 모든 데이터베이스 오퍼레이션은 데이터베이스 오퍼레이션들(심지어 읽기 전용
+ 오퍼레이션들 조차도)을 격리시키는 하나의 트랜잭션 내부에서 발생한다. 우리는 기본 트랜잭션 방도(우리의 경우, JDBC
+ 트랜잭션들)로부터 추상화시키는데 Hibernates <literal>Transaction</literal> API 를 사용한다. 이것은 우리의
+ 코드가 임의의 변경들 없이도 (JTA를 사용하는) 컨테이너-관리되는 트랜잭션들에 배치되는 것을 허용해준다.
+ </para>
+
+ <para>
+ 당신이 원하는 만큼 당신이 <literal>HibernateUtil.getCurrentSession();</literal>을 호출할 수 있고, 당신은
+ 이 쓰레드의 현재 <literal>Session</literal>을 항상 얻을 것임을 노트하라. 당신은 서블릿 코드 내에서든 또는 서블릿 필터
+ 내에서든 HTTP response가 전송되기 전에, 당신의 단위 작업이 완료된 후에 <literal>Session</literal>이 확실히
+ 닫혀지도록 해야 한다. 두 번째 옵션의 좋은 측면은 쉬운 lazy 초기화이다: 뷰가 렌더링 될 때 <literal>Session</literal>이
+ 여전히 열려져 있어서, Hibernate는 당신이 현재 객체 그래프를 네비게이트 하는 동안 초기화 되지 않은 객체들을 로드시킬 수 있다.
+ </para>
+
+ <para>
+ Hibernate는 데이터베이스로부터 객체들을 검색하는데 사용될 수 있는 다양한 메소드들을 갖고 있다. 가장 유연한 방법은 Hibernate
+ Query Language (HQL)을 사용하는 것이다. Hibernate Query Language (HQL)은 배우기가 쉽고 SQL에 대한 강력한 객체 지향
+ 확장이다:
+ </para>
+
+ <programlisting><![CDATA[Transaction tx = session.beginTransaction();
+
+Query query = session.createQuery("select c from Cat as c where c.sex = :sex");
+query.setCharacter("sex", 'F');
+for (Iterator it = query.iterate(); it.hasNext();) {
+ Cat cat = (Cat) it.next();
+ out.println("Female Cat: " + cat.getName() );
+}
+
+tx.commit();]]></programlisting>
+
+ <para>
+ Hibernate는 또한 type-safe 질의들을 공식화 시키는데 사용될 수 있는 객체-지향 <emphasis>query by criteria</emphasis>
+ API을 제공한다. 물론 Hibernate는 데이터베이스와의 모든 SQL 통신을 위해 <literal>PreparedStatement</literal>들과
+ 파라미터 바인딩을 사용한다. 당신은 또한 Hibernate 직접적인 SQL 질의 특징을 사용할 수도 있거나 드문 경우에
+ <literal>Session</literal>으로부터 plain JDBC 커넥션을 얻을 수도 있다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="quickstart-summary" revision="1">
+ <title>마지막으로</title>
+
+ <para>
+ 우리는 이 작은 튜토리얼 내에서 단지 Hibernate의 표면을 훑기만 했다. 우리는 우리의 예제들 속에 어떤 서블릿 지정적 코드를
+ 포함하지 않음을 노트하라. 당신이 적합한지를 알려고 할 때 당신은 당신 자신의 서블릿을 생성시켜야 하고 Hibernate 코드를
+ 삽입해야 한다.
+ </para>
+
+ <para>
+ 데이터 접근 계층으로서 Hibernate는 당신의 어플리케이션에 강하게 통합됨을 염두에 두라. 대개 모든 다른 레이어들은 영속
+ 메커니즘에 의존했다. 당신은 이 설계의 함축을 확실히 이해하도록 하라.
+ </para>
+
+ <para>
+ 보다 복잡한 어플리케이션 예제는 http://caveatemptor.hibernate.org/ 를 보고 http://caveatemptor.hibernate.org/에
+ 있는 다른 튜토리얼들을 살펴보라.
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/session_api.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/session_api.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/session_api.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/session_api.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,1133 @@
+<chapter id="objectstate">
+ <title>객체들로 작업하기</title>
+
+ <para>
+ Hibernate는 기본 데이터베이스 관리 시스템의 상세로부터 개발자들을 은폐시켜줄 뿐만 아니라, 또한 객체들에 대한
+ <emphasis>상태 관리</emphasis>를 제공하는 하나의 완전한 객체/관계형 매핑 솔루션이다. 이것은 공통적인
+ JDBC/SQL 영속 계층들 내에서의 SQL <literal>문장들</literal>에 대한 관리와는 반대로, 자바 어플리케이션들에서
+ 영속에 관한 매우 고유한 객체-지향적 관점이다.
+ </para>
+
+ <para>
+ 달리 말해, Hibernate 어플리케이션 개발자들은 그들의 객체들의 <emphasis>상태</emphasis>에 대해 항상 생각해야 하고,
+ SQL 문장들의 실행에 대해서는 필수적이지 않다. 이 부분은 Hibernate에 의해 처리되고 시스템의 퍼포먼스를 튜닝할 때
+ 어플리케이션 개발자와 유일하게 관련된다.
+ </para>
+
+ <sect1 id="objectstate-overview">
+ <title>Hibernate 객체 상태들</title>
+
+ <para>
+ Hibernate 다음 객체 상태들을 정의하고 지원한다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Transient</emphasis> - 만일 객체가 <literal>new</literal> 연산자를 사용하여 방금 초기화 되었다면
+ 객체는 transient이고, 그것은 Hibernate <literal>Session</literal>과 연관되어 있지 않다. 그것은 데이터베이스
+ 내에서 영속 표상을 갖지 않고 식별자 값이 할당되지 않았다. 만일 어플리케이션이 더 이상 참조를 소유하지 않을 경우
+ transient 인스턴스들은 쓰레기 수집기에 의해 파괴될 것이다. 객체를 영속화 시키는데
+ (그리고 이 전이(transition)에 대해 실행될 필요가 있는 SQL 문장들을 Hibernate로 하여금 처리하도록 하는데)
+ Hibernate <literal>Session</literal>을 사용하라.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Persistent</emphasis> - 하나의 영속 인스턴스는 데이터베이스 내에서 하나의 표상을 갖고 하나의 식별자 값을
+ 갖는다. 그것은 방금 저장되었거나 로드되었을 수 있지만, 정의상 그것은 <literal>Session</literal>의 범위 내에 있다.
+ Hibernate는 영속 상태에서 객체에 대해 행해진 임의의 변경들을 검출해낼 것이고 단위 작업이 완료될 때 그 상태를 데이터베이스와
+ 동기화 시킬 것이다. 개발자들은 하나의 객체가 transient로 되어야 할 때 <literal>UPDATE</literal> 문장들이나
+ <literal>DELETE</literal> 문장들을 수작업으로 실행하지 않는다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Detached</emphasis> - 하나의 detached 인스턴스는 영속화 되었지만, 그것의
+ <literal>Session</literal>이 닫혀진 객체이다. 물론 그 객체에 대한 참조는 여전히 유효하고,
+ 그 detached 인스턴스는 이 상태에서도 변경될 수도 있다. 하나의 detached 인스턴스는 나중에
+ 그것(과 모두 변경들)을 다시 영속화 시켜서 새로운 <literal>Session</literal>에 다시 첨부될 수 있다.
+ 이 특징은 사용자가 생각할 시간을 필요로 하는 장 기간 실행되는 작업 단위를 위한 프로그래밍 모형을 가능하게
+ 해준다. 우리는 그것들을 <emphasis>어플리케이션 트랜잭션들</emphasis>, 즉 사용자의 관점의 작업 단위라고
+ 부른다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 이제 우리는 상태들과 상태 전이(transition)들(그리고 전이를 트리거 시키는 Hibernate 메소드들)을 상세하게 논의할 것이다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-makingpersistent" revision="1">
+ <title>객체들을 영속화 시키기</title>
+
+ <para>
+ 하나의 영속 클래스의 새로이 초기화 된 인스턴스들은 Hibernate에 의해 <emphasis>transient</emphasis>로 간주된다.
+ 우리는 그것을 세션과 연관지어서 transient 인스턴스를 <emphasis>영속화</emphasis> 시킬 수 있다:
+ </para>
+
+ <programlisting><![CDATA[DomesticCat fritz = new DomesticCat();
+fritz.setColor(Color.GINGER);
+fritz.setSex('M');
+fritz.setName("Fritz");
+Long generatedId = (Long) sess.save(fritz);]]></programlisting>
+
+ <para>
+ 만일 <literal>Cat</literal>이 생성된 식별자를 가질 경우, <literal>save()</literal>가 호출될 때
+ 그 식별자가 생성되고 <literal>cat</literal>에 할당된다. 만일 <literal>Cat</literal>이 하나의
+ <literal>assigned</literal> 식별자나 하나의 composite key를 가질 경우, <literal>save()</literal>를
+ 호출하기 전에 그 식별자가<literal>cat</literal> 인스턴스에 할당될 것이다. 당신은 또한 EJB3 초기 드래프트에서
+ 정의된 의미로 <literal>save()</literal> 대신 <literal>persist()</literal>를 사용할 수도 있다.
+ </para>
+
+ <para>
+ 다른 방법으로, 당신은 <literal>save()</literal>의 오버로드된 버전을 사용하여 식별자를 할당할 수 있다.
+ </para>
+
+<programlisting><![CDATA[DomesticCat pk = new DomesticCat();
+pk.setColor(Color.TABBY);
+pk.setSex('F');
+pk.setName("PK");
+pk.setKittens( new HashSet() );
+pk.addKitten(fritz);
+sess.save( pk, new Long(1234) );]]></programlisting>
+
+ <para>
+ 만일 당신이 영속화 시키는 객체가 연관된 객체들(예를 들면. 앞의 예제에 있는 <literal>kittens</literal> 콜렉션)을 갖고 있다면,
+ 당신이 하나의 foreign 키 컬럼에 대해 하나의 <literal>NOT NULL</literal> 컨스트레인트를 갖지 않는 한,
+ 이들 객체들은 당신이 좋아하는 임의의 순서로 영속화 되었을 수도 있다. foreign 키 컨스트레인트들을 위배하는 위험성이
+ 결코 존재하지 않는다. 하지만 당신이 잘못된 순서로 그 객체들을 <literal>save()</literal> 시킬 경우 당신은
+ <literal>NOT NULL</literal> 컨스트레인트를 위배할 수도 있다.
+ </para>
+
+ <para>
+ 당신이 연관된 객체들을 자동적으로 저장시키는데 Hibernate의 <emphasis>transitive persistence(전이 영속)</emphasis>
+ 특징을 사용하는 것을 매우 좋아할 것이므로 대개 당신은 이 상세를 내버려둔다. 그때 <literal>NOT NULL</literal> 컨스트레인트
+ 위배들이 발생되지 않을지라도 - Hibernate는 모든 것을 처리할 것이다. Transitive persistence(전이 영속)은 이 장에서
+ 후반부에서 논의된다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-loading">
+ <title>객체를 로드시키기</title>
+
+ <para>
+ <literal>Session</literal>의 <literal>load()</literal> 메소드들은 만일 당신이 그것(영속 인스턴스)의 식별자들을
+ 이미 알고 있을 경우에 영속 인스턴스를 검색하는 방법을 당신에게 제공한다. <literal>load()</literal>는 하나의 클래스 객체를
+ 취하고 그 상태를 영속(persistent) 상태로 그 클래스의 새로이 초기화 된 인스턴스 속으로 로드시킬 것이다.
+ </para>
+
+ <programlisting><![CDATA[Cat fritz = (Cat) sess.load(Cat.class, generatedId);]]></programlisting>
+
+<programlisting><![CDATA[// you need to wrap primitive identifiers
+long id = 1234;
+DomesticCat pk = (DomesticCat) sess.load( DomesticCat.class, new Long(id) );]]></programlisting>
+
+ <para>
+ 다른 방법으로 당신은 주어진 인스턴스 속으로 상태를 로드시킬 수 있다:
+ </para>
+
+<programlisting><![CDATA[Cat cat = new DomesticCat();
+// load pk's state into cat
+sess.load( cat, new Long(pkId) );
+Set kittens = cat.getKittens();]]></programlisting>
+
+ <para>
+ 만일 일치하는 데이터베이스 행이 존재하지 않을 경우에 <literal>load()</literal>가 unrecoverable(복구 불가능한) 예외상황을
+ 던질 것임을 노트하라. 만일 클래스가 프락시를 갖도록 매핑된 경우, <literal>load()</literal>는 초기화 되지 않은 프락시를 단지
+ 반환하고 당신이 그 프락시의 메소드를 호출하기 전까지는 실제로 데이터베이스에 접속하지 않는다. 당신이 데이터베이스로부터
+ 객체에 대한 연관을 실제로 로드시키지 않고서 객체에 대한 연관을 생성시키고자 원할 경우에 이 특징이 매우 유용하다. 만일
+ <literal>batch-size</literal>가 class 매핑에 정의되는 경우 그것은 또한 다중 인스턴스들이 하나의 배치로서 로드되는 것을
+ 허용해준다.
+ </para>
+
+ <para>
+ 만일 당신이 하나의 일치하는 행이 존재하는지를 확신할 수 없을 경우, 당신은 <literal>get()</literal> 메소드를 사용해야 한다.
+ 그것(<literal>get()</literal> 메소드)는 데이터베이스에 즉시 접속하고 만일 일치하는 행이 없을 경우 null을 반환한다.
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) sess.get(Cat.class, id);
+if (cat==null) {
+ cat = new Cat();
+ sess.save(cat, id);
+}
+return cat;]]></programlisting>
+
+ <para>
+ 당신은 하나의 <literal>LockMode</literal>를 사용하는, <literal>SELECT ... FOR UPDATE</literal>를 사용하여
+ 하나의 객체를 로드시킬 수도 있다. 추가 정보는 API 문서를 보라.
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) sess.get(Cat.class, id, LockMode.UPGRADE);]]></programlisting>
+
+ <para>
+ 어떤 연관된 인스턴스들이나 포함된 콜렉션들은 당신이 그 연관에 대한 케스케이드 스타일로서 <literal>lock</literal> 또는
+ <literal>all</literal>을 지정하도록 결정하지 않는 한, <literal>FOR UPDATE</literal>로 선택되지 않음을 노트하라.
+ </para>
+
+ <para>
+ <literal>refresh()</literal> 메소드를 사용하여, 아무때나 하나의 객체와 모든 그것의 콜렉션들을 다시 로드시키는 것이
+ 가능하다. 데이터베이스 트리거들이 그 객체의 프로퍼티들 중 어떤 것을 초기화 시키는데 사용될 때 이것이 유용하다.
+ </para>
+
+ <programlisting><![CDATA[sess.save(cat);
+sess.flush(); //force the SQL INSERT
+sess.refresh(cat); //re-read the state (after the trigger executes)]]></programlisting>
+
+ <para>
+ 중요한 질문이 대개 이 지점에서 나타난다: Hibernate는 데이터베이로부터 그것을 얼마나 많이 로드시키고 그리고 얼마나 많은
+ SQL <literal>SELECT</literal>들이 그것을 사용할 것인가? 이것은 <emphasis>페칭 방도</emphasis>에 의존하고
+ <xref linkend="performance-fetching"/>에 설명되어 있다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-querying" revision="1">
+ <title>질의하기</title>
+
+ <para>
+ 만일 당신이 당신이 찾고 있는 객체들에 대한 식별자들을 모를 경우, 당신은 하나의 질의를 필요로 한다. Hibernate는 사용이 쉽지만
+ 강력한 객체 지향 질의 언어(HQL)를 지원한다. 프로그램 상의 질의 생성을 위해, Hibernate는 정교한 Criteria 및 Example 질의
+ 특징(QBC와 QBE)를 지원한다. 당신은 또한 객체들로의 결과 셋 변환을 위한 선택적인 Hibernate의 지원으로, 당신의 데이터베이스의
+ native SQL 속에 당신의 질의를 표현할 수도 있다.
+ </para>
+
+ <sect2 id="objectstate-querying-executing" revision="1">
+ <title>질의들을 실행하기</title>
+
+ <para>
+ HQL 질의와 native SQL 질의는 <literal>org.hibernate.Query</literal>의 인스턴스로 표현된다. 이 인터페이스는
+ 파라미터 바인딩, 결과셋 핸들링을 위한, 그리고 실제 질의의 실행을 위한 메소드들을 제공한다. 당신은 항상 현재
+ <literal>Session</literal>을 사용하여 하나의 <literal>Query</literal>를 얻는다:
+ </para>
+
+ <programlisting><![CDATA[List cats = session.createQuery(
+ "from Cat as cat where cat.birthdate < ?")
+ .setDate(0, date)
+ .list();
+
+List mothers = session.createQuery(
+ "select mother from Cat as cat join cat.mother as mother where cat.name = ?")
+ .setString(0, name)
+ .list();
+
+List kittens = session.createQuery(
+ "from Cat as cat where cat.mother = ?")
+ .setEntity(0, pk)
+ .list();
+
+Cat mother = (Cat) session.createQuery(
+ "select cat.mother from Cat as cat where cat = ?")
+ .setEntity(0, izi)
+ .uniqueResult();]]
+
+Query mothersWithKittens = (Cat) session.createQuery(
+ "select mother from Cat as mother left join fetch mother.kittens");
+Set uniqueMothers = new HashSet(mothersWithKittens.list());]]></programlisting>
+
+ <para>
+ 하나의 질의는 대개 <literal>list()</literal>를 호출하여 실행되고, 질의의 결과는 메모리 내에서 하나의 콜렉션 속으로
+ 전체적으로 로드될 것이다. 하나의 질의에 의해 검색된 엔티티 인스턴스들은 영속(persistent) 상태에 있다. 당신의 질의가
+ 하나의 객체를 오직 반환할 것임을 당신이 알고 있을 경우에 <literal>uniqueResult()</literal> 메소드는 단축을 제공한다.
+ 콜렉션들에 대해 eager 페칭을 사용하는 질의들은 대개 (그것들의 초기화된 콜렉션들을 가진) 루트 객체들에 대한 중복들을 대개
+ 반환한다. 당신은 <literal>Set</literal>을 통해 이들 중복들을 간단하게 필터링할 수 있다.
+ </para>
+
+ <sect3 id="objectstate-querying-executing-iterate">
+ <title>결과들을 반복하기</title>
+
+ <para>
+ 종종, 당신은 <literal>iterate()</literal> 메소드를 사용하여 질의를 실행함으로써 더 나은 퍼포먼스를 성취하는
+ 것이 가능할 수 있다. 이것은 오직 대개 질의에 의해 반환되는 실제 엔티티 인스턴스들이 이미 세션 내에 있거나
+ second-level 캐시 내에 있을 것임을 당신이 예상하는 경우일 것이다. 만일 그것들이 이미 캐시되지 않았다면,
+ <literal>iterate()</literal>는 <literal>list()</literal> 보다 더 느릴 것이고 간단한 질의에 대해
+ 많은 데이터베이스 접속들을, 대개 오직 식별자들을 반환하는 초기 select에 대해 <emphasis>1</emphasis>번의 접속과
+ 실제 인스턴스들을 초기화 시키는 추가적인 select들에 대해 <emphasis>n</emphasis> 번의 접속을 필요로 할 수 있다.
+ </para>
+
+ <programlisting><![CDATA[// fetch ids
+Iterator iter = sess.createQuery("from eg.Qux q order by q.likeliness").iterate();
+while ( iter.hasNext() ) {
+ Qux qux = (Qux) iter.next(); // fetch the object
+ // something we couldnt express in the query
+ if ( qux.calculateComplicatedAlgorithm() ) {
+ // delete the current instance
+ iter.remove();
+ // dont need to process the rest
+ break;
+ }
+}]]></programlisting>
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-tuples">
+ <title>튜플들을 반환하는 질의들</title>
+
+ <para>
+ Hibernate 질의들은 때때로 객체들의 튜플들을 반환하고, 그 경우에 각각의 튜플은 배열로서 반환된다:
+ </para>
+
+ <programlisting><![CDATA[Iterator kittensAndMothers = sess.createQuery(
+ "select kitten, mother from Cat kitten join kitten.mother mother")
+ .list()
+ .iterator();
+
+while ( kittensAndMothers.hasNext() ) {
+ Object[] tuple = (Object[]) kittensAndMothers.next();
+ Cat kitten = (Cat) tuple[0];
+ Cat mother = (Cat) tuple[1];
+ ....
+}]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-scalar" revision="1">
+ <title>스칼라 결과들</title>
+
+ <para>
+ 질의들은 <literal>select</literal> 절 내에 하나의 클래스에 대한 하나의 프로퍼티를 지정할 수 있다.
+ 그것들은 심지어 SQL 집계 함수들을 호출할 수도 있다. 프로퍼티들이나 aggregate들은
+ "스칼라" 결과들(그리고 영속 상태에 있는 엔티티들이 아닌 것으)로 간주된다.
+ </para>
+
+ <programlisting><![CDATA[Iterator results = sess.createQuery(
+ "select cat.color, min(cat.birthdate), count(cat) from Cat cat " +
+ "group by cat.color")
+ .list()
+ .iterator();
+
+while ( results.hasNext() ) {
+ Object[] row = (Object[]) results.next();
+ Color type = (Color) row[0];
+ Date oldest = (Date) row[1];
+ Integer count = (Integer) row[2];
+ .....
+}]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-parameters">
+ <title>바인드 프라미터들</title>
+
+ <para>
+ <literal>Query</literal> 상의 메소드들은 명명된 파라미터들 또는 JDBC-스타일의 <literal>?</literal>
+ 파라미터들에 바인딩 값들을 제공한다. <emphasis>JDBC와는 대조적으로, Hibernate 숫자 파라미터들은 0에서
+ 시작된다.</emphasis> 명명된 파라미터들은 질의 문자열 속에서 <literal>:name</literal> 형식의 식별자들이다.
+ 명명된 파라미터들의 장점들은 다음과 같다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 명명된 파라미터들은 그것들이 질의 문자열 내에 발생하는 순서에 관계없다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 그것들은 동일한 질의 내에서 여러 번 발생할 수 있다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 그것은 자기-설명적이다
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting><![CDATA[//named parameter (preferred)
+Query q = sess.createQuery("from DomesticCat cat where cat.name = :name");
+q.setString("name", "Fritz");
+Iterator cats = q.iterate();]]></programlisting>
+
+ <programlisting><![CDATA[//positional parameter
+Query q = sess.createQuery("from DomesticCat cat where cat.name = ?");
+q.setString(0, "Izi");
+Iterator cats = q.iterate();]]></programlisting>
+
+ <programlisting><![CDATA[//named parameter list
+List names = new ArrayList();
+names.add("Izi");
+names.add("Fritz");
+Query q = sess.createQuery("from DomesticCat cat where cat.name in (:namesList)");
+q.setParameterList("namesList", names);
+List cats = q.list();]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-pagination">
+ <title>쪽매김</title>
+
+ <para>
+ 만일 당신이 당신의 결과 셋에 경계(당신이 검색하고자 원하는 최대 개수 그리고/또는 당신이 검색하고자 원하는 첫 번째 행)을
+ 지정할 필요가 있다면 당신은 <literal>Query</literal> 인터페이스의 메소드들을 사용해야 한다:
+ </para>
+
+ <programlisting><![CDATA[Query q = sess.createQuery("from DomesticCat cat");
+q.setFirstResult(20);
+q.setMaxResults(10);
+List cats = q.list();]]></programlisting>
+
+ <para>
+ Hibernate는 이 limit 질의를 당신의 DBMS의 native SQL로 번역하는 방법을 알고 있다.
+ </para>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-scrolling">
+ <title>스크롤 가능한 iteration</title>
+
+ <para>
+ 당신의 JDBC 드라이버가 스크롤 가능한 <literal>ResultSet</literal>들을 지원할 경우,
+ <literal>Query</literal> 인터페이스는 <literal>ScrollableResults</literal> 객체를 얻는데
+ 사용될 수 있고, 그것은 질의 결과들에 대한 유연한 네비게이션을 허용해준다.
+ </para>
+
+ <programlisting><![CDATA[Query q = sess.createQuery("select cat.name, cat from DomesticCat cat " +
+ "order by cat.name");
+ScrollableResults cats = q.scroll();
+if ( cats.first() ) {
+
+ // find the first name on each page of an alphabetical list of cats by name
+ firstNamesOfPages = new ArrayList();
+ do {
+ String name = cats.getString(0);
+ firstNamesOfPages.add(name);
+ }
+ while ( cats.scroll(PAGE_SIZE) );
+
+ // Now get the first page of cats
+ pageOfCats = new ArrayList();
+ cats.beforeFirst();
+ int i=0;
+ while( ( PAGE_SIZE > i++ ) && cats.next() ) pageOfCats.add( cats.get(1) );
+
+}
+cats.close()]]></programlisting>
+
+ <para>
+ 열려진 데이터베이스 커넥션(과 커서)가 이 기능에 필요함을 노트하고, 만일 당신이 쪽매김 기능을 작동시킬 필요가 있다면
+ <literal>setMaxResult()</literal>/<literal>setFirstResult()</literal>를 사용하라.
+ </para>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-named" revision="1">
+ <title>명명된 질의들을 구체화 시키기</title>
+
+ <para>
+ 당신은 또한 매핑 문서 속에 명명된 질의들을 정의할 수 있다.(만일 당신의 질의가 마크업으로서 해석될 수 있는 문자들을
+ 포함할 경우에 <literal>CDATA</literal> 섹션을 사용하는 것을 기억하라))
+ </para>
+
+ <programlisting><![CDATA[<query name="ByNameAndMaximumWeight"><![CDATA[
+ from eg.DomesticCat as cat
+ where cat.name = ?
+ and cat.weight > ?
+] ]></query>]]></programlisting>
+
+ <para>
+ 파라미터 바인딩과 실행은 프로그램 상으로 행해진다:
+ </para>
+
+ <programlisting><![CDATA[Query q = sess.getNamedQuery("ByNameAndMaximumWeight");
+q.setString(0, name);
+q.setInt(1, minWeight);
+List cats = q.list();]]></programlisting>
+
+ <para>
+ 실제 프로그램 코드는 사용되는 질의 언어에 독립적이고, 당신은 또한 메타데이터로 native SQL 질의들을 정의할 수도 있거나
+ 그것들을 매핑 파일들 속에 기존 질의들을 위치지움으로써 기존 질의들을 Hibernate로 이전시킬 수도 있음을 노트하라.
+ </para>
+
+ <para>
+ 또한 <literal><hibernate-mapping></literal> 요소 내에서 하나의 질의 선언은 그 질의에 대한
+ 전역 유일 이름을 필요로 하고, 반면에 <literal><class></literal> 요소 내에서의 질의 선언은
+ 클래스 이름으로 수직된이름을 첨가하여 자동적으로 유일하게 만들어진다.
+ 예를 들어 <literal>eg.Cat.ByNameAndMaximumWeight</literal>.
+ </para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="objectstate-filtering" revision="1">
+ <title>콜렉션들을 필터링 하기</title>
+ <para>
+ 콜렉션 <emphasis>필터</emphasis>는 영속 콜렉션 또는 배열에 적용될 수 있는 질의의 특별한 타입이다. 질의 문자열은
+ 현재의 콜렉션 요소를 의미하는 <literal>this</literal>를 참조할 수 있다.
+ </para>
+
+ <programlisting><![CDATA[Collection blackKittens = session.createFilter(
+ pk.getKittens(),
+ "where this.color = ?")
+ .setParameter( Color.BLACK, Hibernate.custom(ColorUserType.class) )
+ .list()
+);]]></programlisting>
+
+ <para>
+ 반환되는 콜렉션은 하나의 bag으로 간주되고, 그것은 주어진 콜렉션에 대한 사본이다. 원래의 콜렉션은 변경되지 않는다
+ (이것은 이름 "filter"의 의미와는 정반대이지만, 예상되는 행위와 일치된다).
+ </para>
+
+ <para>
+ 필터들은 <literal>from</literal> 절을 필요로 하지 않음을 관찰하라(필요할 경우에 필터들이 한 개의 from 절을 가질 수
+ 있을지라도). 필터들은 콜렉션 요소들 자체들을 반환하는 것으로 한정되지 않는다.
+ </para>
+
+ <programlisting><![CDATA[Collection blackKittenMates = session.createFilter(
+ pk.getKittens(),
+ "select this.mate where this.color = eg.Color.BLACK.intValue")
+ .list();]]></programlisting>
+
+ <para>
+ 심지어 하나의 공백의 필터 질의도 예를 들어 거대한 콜렉션 내에 있는 요소들의 부분집합들을 로드시키는데 유용하다:
+ </para>
+
+ <programlisting><![CDATA[Collection tenKittens = session.createFilter(
+ mother.getKittens(), "")
+ .setFirstResult(0).setMaxResults(10)
+ .list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="objecstate-querying-criteria" revision="1">
+ <title>Criteria 질의들</title>
+
+ <para>
+ HQL은 극히 강력하지만 몇몇 개발자들은 질의 문자열들을 빌드하기 보다, 객체 지향 API를 사용하여 동적으로 질의들을 빌드시키는
+ 것을 선호한다. Hibernate는 이들 경우들을 위한 직관적인 <literal>Criteria</literal> query API를 제공한다:
+ </para>
+
+ <programlisting><![CDATA[Criteria crit = session.createCriteria(Cat.class);
+crit.add( Restrictions.eq( "color", eg.Color.BLACK ) );
+crit.setMaxResults(10);
+List cats = crit.list();]]></programlisting>
+
+ <para>
+ <literal>Criteria</literal>와 연관된 <literal>Example</literal> API 는
+ <xref linkend="querycriteria"/>에서 상세하게 논의된다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="objectstate-querying-nativesql" revision="2">
+ <title>native SQL에서 질의들</title>
+
+ <para>
+ 당신은 <literal>createSQLQuery()</literal>를 사용하여 SQL 속에 하나의 질의를 표현할 수 있고,
+ Hibernate로 하여금 결과 셋들로부터 객체들로의 매핑을 처리하도록 할수도 있다. 당신은 아무때나
+ <literal>session.connection()</literal>을 호출할 수 있고 직접 JDBC <literal>Connection</literal>을
+ 사용할 수 있음을 노트하라. 만일 당신이 Hibernate API를 사용하고자 선택한 경우에 , 당신은 SQL alias들을
+ 중괄호들 속에 포함시켜야 한다:
+ </para>
+
+ <programlisting><![CDATA[List cats = session.createSQLQuery("SELECT {cat.*} FROM CAT {cat} WHERE ROWNUM<10")
+ .addEntity("cat", Cat.class)
+.list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = session.createSQLQuery(
+ "SELECT {cat}.ID AS {cat.id}, {cat}.SEX AS {cat.sex}, " +
+ "{cat}.MATE AS {cat.mate}, {cat}.SUBCLASS AS {cat.class}, ... " +
+ "FROM CAT {cat} WHERE ROWNUM<10")
+ .addEntity("cat", Cat.class)
+.list()]]></programlisting>
+
+ <para>
+ SQL 질의들은 Hibernate 질의들처럼 명명된 파라미터들과 위치 파라미터들을 포함할 수도 있다. SQL 질의들에 대한
+ 추가 정보는 <xref linkend="querysql"/>에서 찾을 수 있다.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="objectstate-modifying" revision="1">
+ <title>영속 객체들을 변경하기</title>
+
+ <para>
+ <emphasis>트랜잭션 상의 영속 인스턴스들</emphasis> (예를들면. <literal>Session</literal>에 의해 로드되고,
+ 저장되고, 생성되거나 질의된 객체들)은 어플리케이션에 의해 처리될 수 있고 영속 상태에 대한 임의의 변경들은
+ <literal>Session</literal>이 <emphasis>flush될</emphasis> 때 영속화 될 것이다(이 장의 뒷 부분에서 논의됨).
+ 당신의 변경들을 영속화 시키기 위해 (다른 용도를 가진 <literal>update()</literal>와 같은) 특별한 메소드를 호출할
+ 필요가 없다. 따라서 객체의 상태를 업데이트 시키는 가장 간단한 방법은 <literal>Session</literal>이 열려 있는 동안,
+ 그것을 <literal>load()</literal>시키고 나서, 그것을 직접 처리하는 것이다:
+ </para>
+
+ <programlisting><![CDATA[DomesticCat cat = (DomesticCat) sess.load( Cat.class, new Long(69) );
+cat.setName("PK");
+sess.flush(); // changes to cat are automatically detected and persisted]]></programlisting>
+
+ <para>
+ 때때로 이 프로그래밍 모형은 불충분하다. 왜냐하면 그것은 동일한 세션 내에서 (객체를 로드시키는) SQL
+ <literal>SELECT</literal>와 (그것의 업데이트된 상태를 영속화 시키는) SQL <literal>UPDATE</literal>
+ 양자를 필요로 할 것이기 때문이다. 그러므로 Hibernate는 detached 인스턴스들을 사용하는 대안적인 접근법을 제공한다.
+ </para>
+
+ <para>
+ <emphasis>Hibernate는 <literal>UPDATE</literal> 문장 또는 <literal>DELETE</literal> 문장의 직접적인 실행을 위한
+ 그것 자신의 API를 제공하지 않음을 노트하라. Hibernate는 하나의 <emphasis>상태 관리</emphasis> 서비스이고, 당신은 그것을
+ 사용할 <emphasis>문장들</emphasis>을 생각하지 말아야 한다. JDBC는 SQL 문장들을 실행시키는 완전한 API이고, 당신은
+ <literal>session.connection()</literal>을 호출하여 아무때나 한 개의 JDBC <literal>Connection</literal>을
+ 얻을 수 있다. 게다가 대량 오퍼레이션의 개념은 온라인 트랜잭션 처리-지향적인 어플리케이션들을 위한 객체/관계형 매핑과 충돌한다.
+ 하지만 Hibernate의 장래 버전들은 특별한 대용량의 오퍼레이션 기능들을 제공할 수도 있다. 몇몇 가능한 배치 오퍼레이션 트릭들에
+ 대해서는 <xref linkend="batch"/>을 보라.</emphasis>
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-detached" revision="2">
+ <title>detached 객체들을 변경시키기</title>
+
+ <para>
+ 많은 어플리케이션들은 하나의 트랜잭션 내에서 하나의 객체를 검색하고, 처리를 위한 UI 계층으로 그것을 전송하고,
+ 그런 다음 새로운 트랜잭션 내에서 변경들을 저장할 필요가 있다. 고도의-동시성 환경에서 이런 종류의 접근법을 사용하는
+ 어플리케이션들은 대개 작업의 "긴" 단위를 확실히 격리시키기 위해 버전화 된 데이터를 사용한다.
+ </para>
+
+ <para>
+ Hibernate는 <literal>Session.update()</literal> 메소드 또는 <literal>Session.merge()</literal> 메소드를
+ 사용하여 detached 인스턴스들의 재첨부를 제공함으로써 이 모형을 지원한다:
+ </para>
+
+ <programlisting><![CDATA[// in the first session
+Cat cat = (Cat) firstSession.load(Cat.class, catId);
+Cat potentialMate = new Cat();
+firstSession.save(potentialMate);
+
+// in a higher layer of the application
+cat.setMate(potentialMate);
+
+// later, in a new session
+secondSession.update(cat); // update cat
+secondSession.update(mate); // update mate]]></programlisting>
+
+ <para>
+ 만일 <literal>catId</literal> 식별자를 가진 <literal>Cat</literal>이 <literal>secondSession</literal>에 의해
+ 이미 로드되었을 경우에 어플리케이션이 그것을 다시 재첨부하려고 시도할 때, 예외상황이 던져졌을 것이다.
+ </para>
+
+ <para>
+ 만일 그 세션이 동일한 식별자를 가진 영속 인스턴스를 이미 포함하지 않음을 당신이 확신하는 경우에는
+ <literal>update()</literal>를 사용하고, 만일 당신이 세션의 상태를 고려하지 않은채로 아무때나 당신의 변경을 병합시키고자
+ 원할 경우에는 <literal>merge()</literal>를 사용하라. 달리 말해, 당신의 detached 인스턴스들에 대한 재첨부가 실행되는
+ 첫 번째 오퍼레이션임을 확실히 함으로써, <literal>update()</literal>는 대개 갓 만들어진 세션에서 당신이 호출하게 될
+ 첫 번째 메소드이다.
+ </para>
+
+ <para>
+ 어플리케이션은 만일 그것이 detached 인스턴스들의 상태가 또한 업데이트 되는 것을 원할 경우에<emphasis>만</emphasis>
+ 주어진 detached 인스턴스로부터 도달 가능한 detached 인스턴스들을 개별적으로<literal>update()</literal> 시킬 것이다.
+ 이것은 물론 <emphasis>transitive persistence(전이 영속)</emphasis>을 사용하여 자동화 될 수 있고,
+ <xref linkend="objectstate-transitive"/>를 보라.
+ </para>
+
+ <para>
+ <literal>lock()</literal> 메소드는 또한 하나의 객체를 새로운 세션에 대해 다시 연관시키는것을 어플리케이션에게 허용해준다.
+ 하지만 detached 인스턴스는 변경되지 않아야 한다!
+ </para>
+
+ <programlisting><![CDATA[//just reassociate:
+sess.lock(fritz, LockMode.NONE);
+//do a version check, then reassociate:
+sess.lock(izi, LockMode.READ);
+//do a version check, using SELECT ... FOR UPDATE, then reassociate:
+sess.lock(pk, LockMode.UPGRADE);]]></programlisting>
+
+ <para>
+ <literal>lock()</literal>이 여러가지 <literal>LockMode</literal>들에 사용될 수 있음을 노트하고,
+ 상세한 것은 API 문서와 트랜잭션 처리에 관한 장을 보라. 재첨부는 <literal>lock()</literal>에 대한
+ 유일한 쓰임새는 아니다.
+ </para>
+
+ <para>
+ 긴 작업 단위에 대한 다른 모형들은 <xref linkend="transactions-optimistic"/>에서 논의된다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-saveorupdate">
+ <title>자동적인 상태 검출</title>
+
+ <para>
+ Hibernate 사용자들은 새로운 식별자를 생성시켜서 transient 인스턴스를 저장하거나
+ 그것의 현재 식별자와 연관된 detached 인스턴스들을 업데이트/재첨부 시키는 일반적인 용도의 메소드를 요청했다.
+ <literal>saveOrUpdate()</literal> 메소드는 이 기능을 구현한다.
+ </para>
+
+ <programlisting><![CDATA[// in the first session
+Cat cat = (Cat) firstSession.load(Cat.class, catID);
+
+// in a higher tier of the application
+Cat mate = new Cat();
+cat.setMate(mate);
+
+// later, in a new session
+secondSession.saveOrUpdate(cat); // update existing state (cat has a non-null id)
+secondSession.saveOrUpdate(mate); // save the new instance (mate has a null id)]]></programlisting>
+
+ <para>
+ <literal>saveOrUpdate()</literal>의 사용 예제와 의미는 초심자들에게는 혼동스러워 보인다. 먼저, 하나의 세션에서 온
+ 인스턴스를 또 다른 새로운 세션 내에서 사용하려고 시도하지 않는 한, 당신은 <literal>update()</literal>,
+ <literal>saveOrUpdate()</literal>, 또는 <literal>merge()</literal>를 사용할 필요는 없을 것이다.
+ 몇몇 전체 어플리케이션들은 이들 메소드들 중 어느 것도 결코 사용하지 않을 것이다.
+ </para>
+
+ <para>
+ 대개 <literal>update()</literal> 또는 <literal>saveOrUpdate()</literal>는 다음 시나리오에서 사용된다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 어플리케이션이 첫 번째 세션 내에 객체를 로드시킨다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 객체가 UI 티어로 전달된다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 몇몇 변경들이 그 객체에 행해진다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 객체가 비지니스 로직 티어로 전달된다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 어플리케이션은 두 번째 세션에서 <literal>update()</literal>를 호출함으로써 이들 변경들을 영속화 시킨다
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>saveOrUpdate()</literal>는 다음을 행한다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 만일 객체가 이 세션 내에서 이미 영속화 되어 있을 경우, 아무것도 행하지 않는다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 그 세션과 연관된 또 다른 객체가 동일한 식별자를 가질 경우, 예외상황을 던진다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 그 객체가 식별자 프로퍼티를 갖지 않을 경우, 그것을 <literal>save()</literal> 시킨다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 객체의 식별자가 새로이 초기화 된 객체에 할당된 값을 가질 경우, 그것을 <literal>save()</literal> 시킨다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 객체가 (<literal><version></literal> 또는 <literal><timestamp></literal>에 의해)
+ 버전화 되고, version 프로퍼티 값이 새로이 초기화 된 객체에 할당된 것과 동일한 값일 경우, 그것을 <literal>save()</literal>
+ 시킨다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 그 밖의 경우 그 객체를 <literal>update()</literal> 시킨다
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 그리고 <literal>merge()</literal>는 매우 다르다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 만일 세션과 현재 연관된 동일한 식별자를 가진 영속 인스턴스가 존재할 경우,
+ 주어진 객체의 상태를 영속 인스턴스 상으로 복사한다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 세션과 현재 연관된 영속 인스턴스가 존재하지 않을 경우, 데이터베이스로부터 그것을 로드시키려고 시도하거나
+ 새로운 영속 인스턴스를 생성시키려고 시도한다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 영속 인스턴스가 반환된다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 주어진 인스턴스는 세션과 연관되지 않고, 그것은 detached 상태에 머무른다
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 id="objectstate-deleting" revision="1">
+ <title>영속 객체들을 삭제하기</title>
+
+ <para>
+ <literal>Session.delete()</literal>는 데이터베이스로부터 객체의 상태를 제거할 것이다.
+ 물론 당신의 어플리케이션은 여전히 detached 객체에 대한 참조를 소유할 것이다. 영속 인스턴스를 transient로 만들 때
+ <literal>delete()</literal>를 생각하는 것이 최상이다.
+ </para>
+
+ <programlisting><![CDATA[sess.delete(cat);]]></programlisting>
+
+ <para>
+ 당신은 foreign 키 컨스트레인트 위배들에 대한 위험성 없이 당신이 좋아하는 어떤 순서로 객체들을 삭제할 수도 있다.
+ 잘못된 순서로 객체들을 삭제함으로써 foreign 키 컬럼에 대한 <literal>NOT NULL</literal> 컨스트레인트를 위배할 가능성이
+ 여전히 존재한다. 예를 들어, 당신이 부모를 삭제하지만, 그 자식들을 삭제하는 것을 잊은 경우.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-replicating" revision="1">
+ <title>두 개의 다른 데이터저장소들 사이에 객체들을 복제하기</title>
+
+ <para>
+ 영속 인스턴스들의 그래프를 취하고 식별자 값들을 다시 생성시키지 않고서 그것들을 다른 저장소 속에 영속화 시키는 것을 가능하도록
+ 만드는 것이 종종 유용하다.
+ </para>
+
+ <programlisting><![CDATA[//retrieve a cat from one database
+Session session1 = factory1.openSession();
+Transaction tx1 = session1.beginTransaction();
+Cat cat = session1.get(Cat.class, catId);
+tx1.commit();
+session1.close();
+
+//reconcile with a second database
+Session session2 = factory2.openSession();
+Transaction tx2 = session2.beginTransaction();
+session2.replicate(cat, ReplicationMode.LATEST_VERSION);
+tx2.commit();
+session2.close();]]></programlisting>
+
+ <para>
+ <literal>ReplicationMode</literal>는 <literal>replicate()</literal>가 데이터베이스 내에 있는 기존의
+ 행들과의 충돌을 처리하게될 방법을 결정한다.
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>ReplicationMode.IGNORE</literal> - 동일한 식별자를 가진 기존 데이터베이스 행이 존재할
+ 경우에 그 객체를 무시한다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.OVERWRITE</literal> - 동일한 식별자를 가진 어떤 기존의 데이터베이스 행을 덮어 쓴다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.EXCEPTION</literal> - 만일 동일한 식별자를 가진 기존 데이터베이스 행이 존재할 경우에
+ 예외상황을 던진다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.LATEST_VERSION</literal> - 행의 버전 번호가 객체의 버전 번호 보다 이전의 것이면 덮어쓰고,
+ 그 밖의 경우에 그 객체를 무시한다
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 이 특징의 쓰임새들은 다른 데이터베이스 인스턴스들 속으로 입력된 데이터 일치시키기, 제품 업그레이드 동안에 시스템 구성 정보
+ 업데이트 하기, non-ACID 트랜잭션들 동안에 행해진 변경들을 롤백시키기 등을 포함한다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-flushing">
+ <title>Session을 flush 시키기</title>
+
+ <para>
+ 시간이 지남에 따라 <literal>Session</literal>은 JDBC 커넥션의 상태와 메모리 내에 보관된 객체들의 상태를 동기화 시키는데
+ 필요한 SQL 문장들을 실행시킬 것이다. 이 프로세스 <emphasis>flush</emphasis>는 다음 시점들에서 디폴트로 발생한다
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 몇몇 질의들이 실행되기 전에
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>org.hibernate.Transaction.commit()</literal> 시점에서
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.flush()</literal> 시점에서
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ SQL 문장들이 다음 순서로 실행 명령이 내려진다
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+
+ 대응하는 객체들이 <literal>Session.save()</literal>를 사용하여 저장되었던 것과 같은 순서로, 모든 엔티티 삽입들
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 모든 엔티티 업데이트들
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 모든 콜렉션 삭제들
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 모든 콜렉션 요소 삭제들, 업데이트들 그리고 삽입들
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 모든 콜렉션 삽입들
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 대응하는 객체들이 <literal>Session.delete()</literal>를 사용하여 삭제되었던 것과 같은 순서로 모든 엔티티 삭제들.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ (한가지 예외는 객체들이 저장될 때 <literal>native</literal> ID 생성을 사용하는 객체들이 insert 되는 점이다.)
+ </para>
+
+ <para>
+ 당신이 명시적으로 <literal>flush()</literal> 시킬 때를 제외하면, <literal>Session</literal>이 JDBC 호출들을
+ 실행시키는 <emphasis>시점</emphasis>, 그것들이 실행되는 <emphasis>순서</emphasis>만을 절대적으로 보장하지는 않는다.
+ 하지만 Hibernate는 <literal>Query.list(..)</literal>가 실효성이 없는 데이터를 결코 반환하지 않을 것임을 보장하거나;
+ 그것들이 잘못된 데이터도 반환하지 않을 것임을 보장한다.
+ </para>
+
+ <para>
+ flush가 너무 자주 발생하지 않도록 디폴트 행위를 변경하는 것이 가능하다. <literal>FlushMode</literal> 클래스는 세 개의
+ 다른 모드들을 정의한다: 오직 커밋 시(그리고 Hibernate <literal>Transaction</literal> API가 사용될 때에만) flush 모드,
+ 설명된 루틴을 사용하는 자동적인 flush 모드, 또는 <literal>flush()</literal>가 명시적으로 호출되지 않는 한 flush 시키지
+ 않는 모드. 마지막 모드는 오래 동안 실행되는 작업 단위에 대해 유용하고, 여기서 <literal>Session</literal>은 열려진채로
+ 유지되고 오랜 시간 동안 연결이 해제된 채로 유지된다. (<xref linkend="transactions-optimistic-longsession"/>를 보라).
+ </para>
+
+ <programlisting><![CDATA[sess = sf.openSession();
+Transaction tx = sess.beginTransaction();
+sess.setFlushMode(FlushMode.COMMIT); // allow queries to return stale state
+
+Cat izi = (Cat) sess.load(Cat.class, id);
+izi.setName(iznizi);
+
+// might return stale data
+sess.find("from Cat as cat left outer join cat.kittens kitten");
+
+// change to izi is not flushed!
+...
+tx.commit(); // flush occurs
+sess.close();]]></programlisting>
+
+ <para>
+ flush 동안에, 하나의 예외상황이 발생할 수도 있다(예를 들면. 만일 DML 오퍼레이션이 컨스트레인트를 위반할 경우). 예외상황들을
+ 처리하는 것은 Hibernatem의 트랜잭션 특징에 관한 어떤 이해를 수반하며, 우리는 <xref linkend="transactions"/>에서 그것을
+ 논의한다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-transitive" revision="1">
+ <title>Transitive persistence(전이 영속)</title>
+
+ <para>
+ 특히 당신이 연관된 객체들의 그래프를 다룰 경우에, 특히 개별 객체들을 저장하고, 삭제하거나, 재첨부시키는 것이 꽤 번거롭다.
+ 공통된 경우는 하나의 부모/자식 관계이다. 다음 예제를 검토하자:
+ </para>
+
+ <para>
+ 만일 부모/자식 관계에서 자식들이 값(value) 타입(예를 들면. 주소들 또는 문자열들을 가진 하나의 콜렉션)일 경우, 그것들의 생명주기는
+ 부모에 의존할 것이고 상태 변경들에 대해 편리한 "케스케이딩"에 더 이상의 액션이 필요하지 않을 것이다. 만일 부모가 저장될 때,
+ 값(value)-타입의 자식 객체들도 마찬가지로 저장되고, 부모가 삭제될 때, 자식들이 삭제될 것이다. 이것은 심지어 콜렉션으로부터 하나의
+ 자식을 제거하는 그런 오퍼레이션들에 대해서도 동작한다; Hibernate는 이것을 검출하고, 값(value)-타입의 객체들은 참조를 공유할 수
+ 없으므로, 데이터베이스로부터 그 자식을 삭제시킨다.
+ </para>
+
+ <para>
+ 이제 값(value) 타입이 아닌, 엔티티들인 부모와 자식 객체들을 가진 동일한 시나리오를 검토하자(예를 들면. 카테고리들과 아이템들,
+ 또는 부모 고양이나 자식 고양이). 엔티티들은 그것들 자신의 생명주기를 갖고, 공유된 참조들을 지원하고 (따라서 콜렉션으로부터 하나의
+ 엔티티를 제거하는 것은 그것이 삭제될 수 있음을 의미하지 않는다), 그리고 디폴트로 하나의 엔티티로부터 어떤 다른 연관된 엔티티들로의
+ 상태의 케스케이딩은 존재하지 않는다. Hibernate는 디폴트로 <emphasis>도달가능성에 의한 영속성(persistence by reachability)</emphasis>을
+ 구현하지 않는다.
+ </para>
+
+ <para>
+ - <literal>persist(), merge(), saveOrUpdate(), delete(), lock(), refresh(), evict(), replicate()</literal>를
+ 포함하는- Hibernate 세션에 대한 각각의 기본 오퍼레이션에 대해서 하나의 대응하는 케스케이딩 스타일이 존재한다. 케스케이드 스타일들
+ 각각은 <literal>create, merge, save-update, delete, lock, refresh, evict, replicate</literal>로 명명된다.
+ 만일 당신이 하나의 오퍼레이션이 하나의 연관에 따라 케스케이딩되는 것을 원할 경우, 당신은 매핑 문서 내에 그것을 지시해야 한다.
+ 예를 들면:
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="person" cascade="persist"/>]]></programlisting>
+
+ <para>
+ 케스케이딩 스타일들이 결합될 수도 있다:
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="person" cascade="persist,delete,lock"/>]]></programlisting>
+
+ <para>
+ 당신은 <emphasis>모든</emphasis> 오퍼레이션들이 그 연관에 따라 케스케이드 되어야 함을 지정하는데
+ <literal>cascade="all"</literal>을 사용할 수도 있다. 디폴트<literal>cascade="none"</literal>은 오퍼레이션들이
+ 케스케이드 되지 않을 것임을 지정한다.
+ </para>
+
+ <para>
+ 특정한 케스케이드 스타일인, <literal>delete-orphan</literal>은 오직 one-to-many 연관들에만 적용되고,
+ <literal>delete()</literal> 오퍼레이션이 그 연관으로부터 제거되는 임의의 자식 객체에 적용되어야 함을 나타낸다.
+ </para>
+
+
+ <para>
+ 권장사항들 :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 하나의 <literal><many-to-one></literal> 또는 <literal><many-to-many></literal> 연관에
+ 대해 케스케이드를 가능하게 하는 것은 대개 의미가 없다. 케스케이드는 <literal><one-to-one></literal> 연관과
+ <literal><one-to-many></literal> 연관에 대해 종종 유용하다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 자식 객체의 수명이 그 부모 객체의 수명에 묶여져 있을 경우, <literal>cascade="all,delete-orphan"</literal>을
+ 지정함으로써 그것을 <emphasis>생명 주기 객체</emphasis>로 만들어라.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 그 밖의 경우, 당신은 케스케이드를 전혀 필요로 하지 않을 수 있다. 그러나 만일 당신이 동일한 트랜잭션 내에서 부모와 자식에
+ 대해 자주 함께 작업하게 될 것이라 생각되고, 당신 스스로 타이핑 하는 것을 절약하고자 원할 경우,
+ <literal>cascade="persist,merge,save-update"</literal>를 사용하는 것을 고려하라.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>cascade="all"</literal>을 가진 (단일 값 연관이든 하나의 콜렉션이든) 하나의 연관을 매핑시키는 것은
+ 그 연관을 부모의 저장/업데이트/삭제가 자식 또는 자식들의 저장/업데이트/삭제로 귀결되는 <emphasis>부모/자식</emphasis>
+ 스타일의 관계로 마크한다.
+ </para>
+ <para>
+ 게다가, 하나의 영속 부모로부터 하나의 자식에 대한 단순한 참조는 자식의 저장/업데이트로 귀결될 것이다. 하지만 이 메타포는 불완전하다.
+ 그것의 부모에 의해 참조 해제되는 자식은 <literal>cascade="delete-orphan"</literal>으로 매핑된 하나의
+ <literal><one-to-many></literal> 연관의 경우를 제외하면, 자동적으로 삭제되지 <emphasis>않는다</emphasis>.
+ 하나의 부모/자식 관계에 대한 케스케이딩 오퍼레이션의 정확한 의미는 다음과 같다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 만일 부모가 <literal>persist()</literal>에 전달될 경우, 모든 자식들이 <literal>persist()</literal>에 전달된다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 부모가 <literal>merge()</literal>에 전달될 경우, 모든 자식들이 <literal>merge()</literal>에 전달된다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 부모가 <literal>save()</literal>, <literal>update()</literal> 또는 <literal>saveOrUpdate()</literal>에
+ 전달될 경우, 모든 자식들이 <literal>saveOrUpdate()</literal>에 전달된다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 transient 또는 detached 자식이 영속 부모에 의해 참조될 경우, 그것은 <literal>saveOrUpdate()</literal>에 전달된다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 부모가 삭제될 경우, 모든 자식들이 <literal>delete()</literal>에 전달된다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 만일 자식이 영속 부모에 의해 참조 해제 될 경우, <literal>cascade="delete-orphan"</literal>이 아닌 한,
+ <emphasis>특별한 어떤 것도 발생하지 않는다</emphasis> - 어플리케이션은 필요한 경우에 자식을 명시적으로 삭제해야 한다 -,
+ <literal>cascade="delete-orphan"</literal>인 경우에 "orphaned(고아)"인 경우 자식이 삭제된다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <para>
+ 마지막으로 오퍼레이션들의 케스케이딩이 <emphasis>호출 시점</emphasis>에서 또는 <emphasis>flush 시점</emphasis>에서
+ 객체 그래프에 적용될 수 있음을 노트하라. 이용 가능할 경우에 모든 오퍼레이션들은 그 오퍼레이션이 실행될 때 도달 가능한 연관된
+ 엔티티들에 대해 케스케이드 된다. 하지만 <literal>save-upate</literal>와 <literal>delete-orphan</literal>은
+ <literal>Session</literal>의 flush 동안에 도달 가능한 모든 연관된 엔티티들에 대해 이행적(transitive)이다.
+ </para>
+
+ <sect1 id="objectstate-metadata">
+ <title>메타데이터 사용하기</title>
+
+ <para>
+ Hibernate는 모든 엔티티와 값(value) 타입들을 가진 매우 풍부한 메타-레벨 모형을 필요로 한다. 시간이 지남에 따라, 이 모형은
+ 어플리케이션 그 자체에 매우 유용하다. 예를 들어, 어플리케이션은 어느 객체들이 복사되어야 하는지(예를 들면 가변적인 값(value) 타입들)
+ 그리고 어느 것이 복사되지 말아야 하는지(예를 들면, 불변의 value 타입들과 가능한 연관된 엔티티들)를 인지하는 "스마트" deep-copy
+ 알고리즘을 구현하는데 Hibernate의 메타데이터를 사용할 수도 있다.
+ </para>
+ <para>
+ Hibernate는 <literal>ClassMetadata</literal> 인터페이스와 <literal>CollectionMetadata</literal> 인터페이스
+ 그리고 <literal>Type</literal> 계층구조를 통해 메타데이터를 노출시킨다. 메타데이터 인터페이스들의 인스턴스들은
+ <literal>SessionFactory</literal>로부터 얻어질 수도 있다.
+ </para>
+
+ <programlisting><![CDATA[Cat fritz = ......;
+ClassMetadata catMeta = sessionfactory.getClassMetadata(Cat.class);
+
+Object[] propertyValues = catMeta.getPropertyValues(fritz);
+String[] propertyNames = catMeta.getPropertyNames();
+Type[] propertyTypes = catMeta.getPropertyTypes();
+
+// get a Map of all properties which are not collections or associations
+Map namedValues = new HashMap();
+for ( int i=0; i<propertyNames.length; i++ ) {
+ if ( !propertyTypes[i].isEntityType() && !propertyTypes[i].isCollectionType() ) {
+ namedValues.put( propertyNames[i], propertyValues[i] );
+ }
+}]]></programlisting>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/toolset_guide.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/toolset_guide.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/toolset_guide.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/toolset_guide.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,588 @@
+<chapter id="toolsetguide" revision="2">
+ <title>도구셋 안내</title>
+
+ <para>
+ Hibernate에 대한 라운드트립 엔지니어링은 Eclipse 플러그인 세트, 명령라인 도구들, 뿐만 아니라 Ant 태스크들을 사용하여 가능하다.
+ </para>
+
+ <para>
+ <emphasis>Hibernate 도구들</emphasis>은 현재 기존 데이터베이스들에 대한 리버스 엔지니어링을 위해 Ant 태스크들 뿐만 아니라
+ Eclipse IDE용 플러그인들을 포함하고 있다:
+ </para>
+
+ <itemizedlist>
+ <listitem><para>
+ <emphasis>매핑 편집기:</emphasis> 자동 완성 기능과 구문 강조를 지원하는 Hibernate XML 매핑 파일들에 대한 편집기. 그것은 또한
+ 통상의 XML 편집기 보다 훨씬 더 융통성 있게 만들어서 클래스 이름들과 프로퍼티/필드 이름들에 대한 의미론적 자동 완성 기능을 지원한다.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>콘솔:</emphasis> 콘솔은 Eclipse에서 새로운 뷰이다. 당신의 콘솔 구성들에 대한 tree overview에 덧붙여, 당신은 또한
+ 당신의 영속 클래스들과 그것들의 관계들에 대한 상호작용 뷰를 얻는다. 콘솔은 당신의 데이터베이스에 대해 HQL 질의들을 실행하고 그 결과를
+ Eclipse 내에서 직접 브라우징 하도록 당신에게 허용해준다.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>개발 마법사들:</emphasis> 몇몇 마법사들이 Hibernate Eclipse 도구들에 제공된다; 당신은 Hibernate 구성
+ (cfg.xml) 파일들을 빠르게 생성시키는데 마법사를 사용하거나, 심지어 당신은 기존 데이터베이스 스키마를 POJO 소스 파일들과
+ Hibernate 매핑 파일들로 완전하게 리버스 엔지니어링할 수도 있다. 리버스 엔지니어링 마법사는 맞춤 가능한 템플릿들을 제공한다.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Ant 태스크들:</emphasis>
+ </para></listitem>
+
+ </itemizedlist>
+
+ <para>
+ 추가 정보는 <emphasis>Hibernate Tools</emphasis> 패키지와 그것의 문서를 참조하길 바란다.
+ </para>
+
+ <para>
+ 하지만 Hibernate 메인 패키지는 통합 도구에 번들화 되어 있다(그것은 심지어 플라이 상에서 Hibernate "내에서" 사용될 수 있다):
+ <emphasis>SchemaExport</emphasis> 별칭은 <literal>hbm2ddl</literal>.
+ </para>
+
+ <sect1 id="toolsetguide-s1" revision="2">
+ <title>자동적인 스키마 생성</title>
+
+ <para>
+ DDL은 Hibernate 유틸리티에 의해 당신의 매핑 파일들로부터 생성될 수 있다. 생성된 스키마는 엔티티 테이블과 콜렉션 테이블에 대한
+ 참조 무결성 컨스트레인트들(프라이머리 키와 foreign 키들)을 포함한다. 테이블들과 시퀀스들은 또한 페칭된 식별자 생성기들에 대해
+ 생성된다.
+ </para>
+
+ <para>
+ DDL이 매우 벤더에 특정하므로, 이 도구를 사용할 때 당신은 <literal>hibernate.dialect</literal> 프로퍼티를 통해 한 개의 SQL
+ <literal>Dialect</literal>를 지정<emphasis>해야 한다</emphasis>.
+ </para>
+
+ <para>
+ 먼저 생성된 스키마를 개선시키기 위해 당신의 매핑 파일들을 맞춤화 시켜라.
+ </para>
+
+ <sect2 id="toolsetguide-s1-2" revision="3">
+ <title>스키마 맞춤화 시키기</title>
+
+ <para>
+ 많은 Hibernate 매핑 요소들은 <literal>length</literal>로 명명된 옵션 속성을 정의한다. 당신은 이 속성으로 컬럼의 길이를
+ 설정할 수 있다.(또는 numeric/decimal 데이터 타입들, 배정도에 대해 ).
+ 많은 Hibernate 매칭 요소들은 <literal>length</literal>, <literal>precision</literal> 그리고
+ <literal>scale</literal>로 명명된 옵션 속성들을 정의하고 있다. 당신은 이 속성으로서 컬럼이 길이, 정밀도, 크기를 설정할 수 있다.
+
+ </para>
+
+ <programlisting><![CDATA[<property name="zip" length="5"/>]]></programlisting>
+ <programlisting><![CDATA[<property name="balance" precision="12" scale="2"/>]]></programlisting>
+
+ <para>
+ 몇몇 태그들은 또한 (테이블 컬럼들에 대한 <literal>NOT NULL</literal> 컨스트레인트를 생성시키는) <literal>not-null</literal>
+ 속성과 (테이블 컬럼들에 대한 <literal>UNIQUE</literal> 컨스트레인트를 생성시키는) <literal>unique</literal> 속성을 수용한다.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="bar" column="barId" not-null="true"/>]]></programlisting>
+
+ <programlisting><![CDATA[<element column="serialNumber" type="long" not-null="true" unique="true"/>]]></programlisting>
+
+ <para>
+ <literal>unique-key</literal> 속성은 하나의 유일 키 컨스트레인트로 컬럼들을 그룹지우는데 사용될 수도 있다. 현재
+ <literal>unique-key</literal> 속성의 지정된 값은 산출된 DDL내에서 컨스트레인트를 명명하는데 사용되지 <emphasis>않고</emphasis>,
+ 오직 매핑 파일 내에서 컬럼들을 그룹 지우는데 사용된다.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="org" column="orgId" unique-key="OrgEmployeeId"/>
+<property name="employeeId" unique-key="OrgEmployee"/>]]></programlisting>
+
+
+ <para>
+ <literal>index</literal> 속성은 매핑된 컬럼 또는 컬럼들을 사용하여 생성될 인덱스의 이름을 지정한다. 간단하게
+ 동일한 인덱스 이름을 지정함으로써 여러 컬럼들이 동일한 인덱스 내로 그룹지워질 수도 있다.
+ </para>
+
+ <programlisting><![CDATA[<property name="lastName" index="CustName"/>
+<property name="firstName" index="CustName"/>]]></programlisting>
+
+ <para>
+ <literal>foreign-key</literal> 속성은 임의의 산출된 foreign 키 컨스트레인트의 이름을
+ 오버라이드 시키는데 사용될 수 도 있다.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="bar" column="barId" foreign-key="FKFooBar"/>]]></programlisting>
+
+ <para>
+ 많은 매핑 요소들은 또한 하나의 자식 <literal><column></literal> 요소를 허용한다.
+ 이것은 특히 다중 컬럼 타입들을 매핑하는데 유용하다:
+ </para>
+
+ <programlisting><![CDATA[<property name="name" type="my.customtypes.Name"/>
+ <column name="last" not-null="true" index="bar_idx" length="30"/>
+ <column name="first" not-null="true" index="bar_idx" length="20"/>
+ <column name="initial"/>
+</property>]]></programlisting>
+
+ <para>
+ 다른 방법으로, 이들 요소들은 또한 자식 <literal><column></literal> 요소를 수용한다. 이것은 다중 컬럼 타입들에
+ 특히 유용하다:
+ <literal>default</literal> 속성은 당신으로 하여금 하나의 컬럼에 대한 디폴트 값을 설정하도록 한다(당신은 매핑된
+ 클래스의 새로운 인스턴스를 저장하기 전에 매핑된 프로퍼티에 동일한 값을 할당하게 될 것이다).
+ </para>
+
+ <programlisting><![CDATA[<property name="credits" type="integer" insert="false">
+ <column name="credits" default="10"/>
+</property>]]></programlisting>
+
+ <programlisting><![CDATA[<version name="version" type="integer" insert="false">
+ <column name="version" default="0"/>
+</property>]]></programlisting>
+
+ <para>
+ <literal>sql-type</literal> 속성은 SQL 데이터타입에 대한 Hibernate 타입의 디폴트 매핑을 오버라이드 시키는 것을
+ 사용자에게 허용해준다.
+ </para>
+
+ <programlisting><![CDATA[<property name="balance" type="float">
+ <column name="balance" sql-type="decimal(13,3)"/>
+</property>]]></programlisting>
+
+ <para>
+ <literal>check</literal> 속성은 check 컨스트레인트를 지정하는 것을 당신에게 허용해준다.
+ </para>
+
+ <programlisting><![CDATA[<property name="foo" type="integer">
+ <column name="foo" check="foo > 10"/>
+</property>]]></programlisting>
+
+ <programlisting><![CDATA[<class name="Foo" table="foos" check="bar < 100.0">
+ ...
+ <property name="bar" type="float"/>
+</class>]]></programlisting>
+
+
+ <table frame="topbot" id="schemattributes-summary" revision="2">
+ <title>요약</title>
+ <tgroup cols="3">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>속성</entry>
+ <entry>값들</entry>
+ <entry>해석</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>length</literal></entry>
+ <entry>number</entry>
+ <entry>컬럼 길이</entry>
+ </row>
+ <row>
+ <entry><literal>precision</literal></entry>
+ <entry>number</entry>
+ <entry>컬럼 decimal 정밀도</entry>
+ </row>
+ <row>
+ <entry><literal>scale</literal></entry>
+ <entry>number</entry>
+ <entry>컬럼 decimal 크기</entry>
+ </row>
+ <row>
+ <entry><literal>not-null</literal></entry>
+ <entry><literal>true|false</literal></entry>
+ <entry>컬럼이 null이 아니어야 함을 지정한다</entry>
+ </row>
+ <row>
+ <entry><literal>unique</literal></entry>
+ <entry><literal>true|false</literal></entry>
+ <entry>컬럼이 하나의 유일 컨스트레인트를 가져야함을 지정한다</entry>
+ </row>
+ <row>
+ <entry><literal>index</literal></entry>
+ <entry><literal>index_name</literal></entry>
+ <entry>(다중-컬럼) 인덱스의 이름을 지정한다 </entry>
+ </row>
+ <row>
+ <entry><literal>unique-key</literal></entry>
+ <entry><literal>unique_key_name</literal></entry>
+ <entry>다중-컬럼 유일 컨스트레인트의 이름을 지정한다</entry>
+ </row>
+ <row>
+ <entry><literal>foreign-key</literal></entry>
+ <entry><literal>foreign_key_name</literal></entry>
+ <entry>
+ 하나의 연관에 대해, <literal><one-to-one></literal>,
+ <literal><many-to-one></literal>,
+ <literal><key></literal>, 또는 <literal><many-to-many></literal>
+ 매핑 요소에 대해 foreign key 컨스트레인트의 이름을 지정한다.<literal>inverse="true"</literal>
+ 측들은 <literal>SchemaExport</literal>에 의해 고려되지 않을 것임을 노트하라.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>sql-type</literal></entry>
+ <entry><literal>SQL column type</literal></entry>
+ <entry>
+ 디폴트 컬럼 타입을 오버라이드 시킨다
+ (<literal><column></literal> 요소의 속성에만)
+ </entry>
+ </row>
+ <row>
+ <entry><literal>default</literal></entry>
+ <entry>SQL expression</entry>
+ <entry>
+ 컬럼에 대한 디폴트 값을 지정한다
+ </entry>
+ </row>
+ <row>
+ <entry><literal>check</literal></entry>
+ <entry>SQL expression</entry>
+ <entry>
+ 컬럼 또는 테이블에 대한 SQL check 컨스트레인트를 생성시킨다
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <literal><comment></literal> 요소는 생성된 스키마에 대한 주석들을 지정하는 것을 당신에게 허용해준다.
+ </para>
+
+ <programlisting><![CDATA[<class name="Customer" table="CurCust">
+ <comment>Current customers only</comment>
+ ...
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[<property name="balance">
+ <column name="bal">
+ <comment>Balance in USD</comment>
+ </column>
+</property>]]></programlisting>
+
+ <para>
+ 이것은 (지원되는 경우) 생성된 DDL에서 <literal>comment on table</literal> 또는
+ <literal>comment on column</literal> 문장으로 귀결된다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-3" revision="2">
+ <title>도구 실행하기</title>
+
+ <para>
+ <literal>SchemaExport</literal> 도구는 DDL 스크립트를 표준 출력으로 기록 하고/하거나 DDL 문장들을 실행시킨다.
+ </para>
+
+ <para>
+ <literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaExport</literal> <emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title><literal>SchemaExport</literal> 명령 라인 옵션들</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>옵션</entry>
+ <entry>설명</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>--quiet</literal></entry>
+ <entry>스크립트를 표준출력으로 출력하지 않는다</entry>
+ </row>
+ <row>
+ <entry><literal>--drop</literal></entry>
+ <entry>오직 테이블들을 드롭시킨다</entry>
+ </row>
+ <row>
+ <entry><literal>--create</literal></entry>
+ <entry>오직 테이블들을 생성시킨다</entry>
+ </row>
+ <row>
+ <entry><literal>--text</literal></entry>
+ <entry>데이터베이스로 내보내기 하지 않는다</entry>
+ </row>
+ <row>
+ <entry><literal>--output=my_schema.ddl</literal></entry>
+ <entry>ddl 스크립트를 파일로 출력한다</entry>
+ </row>
+ <row>
+ <entry><literal>--naming=eg.MyNamingStrategy</literal></entry>
+ <entry>하나의 <literal>NamingStrategy</literal>를 선택한다</entry>
+ </row>
+ <row>
+ <entry><literal>--config=hibernate.cfg.xml</literal></entry>
+ <entry>XML 파일로부터 Hibernate 구성을 읽어들인다</entry>
+ </row>
+ <row>
+ <entry><literal>--properties=hibernate.properties</literal></entry>
+ <entry>파일로부터 데이터베이스 프로퍼티들을 읽어들인다</entry>
+ </row>
+ <row>
+ <entry><literal>--format</literal></entry>
+ <entry>생성된 SQL을 스크립트 내에 좋게 형식지운다</entry>
+ </row>
+ <row>
+ <entry><literal>--delimiter=;</literal></entry>
+ <entry>스크립트를 위한 라인 경계의 끝을 설정한다 </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 당신은 당신의 어플리케이션 내에 <literal>SchemaExport</literal>를 삽입시킬 수도 있다:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaExport(cfg).create(false, true);]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-4">
+ <title>프로퍼티들</title>
+
+ <para>
+ 데이터베이스 프로퍼티들은 다음과 같이 지정될 수 있다
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>-D</literal><emphasis><property></emphasis>를 가진 시스템 프로퍼티로서</para>
+ </listitem>
+ <listitem>
+ <para><literal>hibernate.properties</literal> 내에서</para>
+ </listitem>
+ <listitem>
+ <para><literal>--properties</literal>를 가진 명명된 프로퍼티들 내에서</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 필요한 프로퍼티들은 다음과 같다:
+ </para>
+
+ <table frame="topbot">
+ <title>SchemaExport 커넥션 프로퍼티들</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>프로퍼티 이름</entry>
+ <entry>설명</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>hibernate.connection.driver_class</literal></entry>
+ <entry>jdbc 드라이버 클래스</entry>
+ </row>
+ <row>
+ <entry><literal>hibernate.connection.url</literal></entry>
+ <entry>jdbc url</entry>
+ </row>
+ <row>
+ <entry><literal>hibernate.connection.username</literal></entry>
+ <entry>데이터베이스 사용자</entry>
+ </row>
+ <row>
+ <entry><literal>hibernate.connection.password</literal></entry>
+ <entry>사용자 패스워드</entry>
+ </row>
+ <row>
+ <entry><literal>hibernate.dialect</literal></entry>
+ <entry>dialect</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-5">
+ <title>Ant 사용하기</title>
+
+ <para>
+ 당신은 당신의 Ant 빌드 스크립트에서 <literal>SchemaExport</literal>를 호출할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<target name="schemaexport">
+ <taskdef name="schemaexport"
+ classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
+ classpathref="class.path"/>
+
+ <schemaexport
+ properties="hibernate.properties"
+ quiet="no"
+ text="no"
+ drop="no"
+ delimiter=";"
+ output="schema-export.sql">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemaexport>
+</target>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-6" revision="2">
+ <title>점증하는 스키마 업데이트들</title>
+
+ <para>
+ <literal>SchemaUpdate</literal> 도구는 "점증하는" 변경들을 가진 기존 스키마를 변경시킬 것이다. <literal>SchemaUpdate</literal>는
+ JDBC 메타데이터 API에 무겁게 의존하여서, 그것은 모든 JDBC 드라이버들에 동작하지 않을 것임을 주목하라.
+ </para>
+
+ <para>
+ <literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaUpdate</literal> <emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title><literal>SchemaUpdate</literal> 명령 라인 옵션들</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>옵션</entry>
+ <entry>설명</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>--quiet</literal></entry>
+ <entry>스크립트를 표준출력으로 출력하지 않는다</entry>
+ </row>
+ <row>
+ <entry><literal>--text</literal></entry>
+ <entry>스크립트를 데이터베이스로 내보내기 하지 않는다</entry>
+ </row>
+ <row>
+ <entry><literal>--naming=eg.MyNamingStrategy</literal></entry>
+ <entry>하나의 <literal>NamingStrategy</literal>를 선택한다</entry>
+ </row>
+ <row>
+ <entry><literal>--properties=hibernate.properties</literal></entry>
+ <entry>파일로부터 데이터베이스 프로퍼티들을 읽어 들인다</entry>
+ </row>
+ <row>
+ <entry><literal>--config=hibernate.cfg.xml</literal></entry>
+ <entry><literal>.cfg.xml</literal> 파일을 지정한다</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 당신은 당신의 어플리케이션 내에 <literal>SchemaUpdate</literal>를 삽입시킬 수 있다:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaUpdate(cfg).execute(false);]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-7">
+ <title>점증하는 스키마 업데이트들에 Ant 사용하기</title>
+
+ <para>
+ 당신은 Ant 스크립트에서<literal>SchemaUpdate</literal>를 호출할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<target name="schemaupdate">
+ <taskdef name="schemaupdate"
+ classname="org.hibernate.tool.hbm2ddl.SchemaUpdateTask"
+ classpathref="class.path"/>
+
+ <schemaupdate
+ properties="hibernate.properties"
+ quiet="no">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemaupdate>
+</target>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-8" revision="1">
+ <title>스키마 유효성 검사</title>
+
+ <para>
+ <literal>SchemaValidator</literal> 도구는 기존의 데이터베이스 스키마가 당신의 매핑 문서들과 "일치하는지"를 유효성
+ 검사할 것이다. <literal>SchemaValidator</literal>가 JDBC 메타데이터 API에 무겁게 의존하므로 그것은 모든
+ JDBC 드라이버들에 대해 동작하지 않을 것이다. 이 도구는 테스팅에 극히 유용하다.
+ </para>
+
+ <para>
+ <literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaValidator</literal> <emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title><literal>SchemaValidator</literal> 명령 라인 옵션들</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>옵션</entry>
+ <entry>설명</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>--naming=eg.MyNamingStrategy</literal></entry>
+ <entry>하나의 <literal>NamingStrategy</literal>를 선택한다</entry>
+ </row>
+ <row>
+ <entry><literal>--properties=hibernate.properties</literal></entry>
+ <entry>파일로부터 데이터베이스 프로퍼티들을 읽어들인다</entry>
+ </row>
+ <row>
+ <entry><literal>--config=hibernate.cfg.xml</literal></entry>
+ <entry><literal>.cfg.xml</literal> 파일을 지정한다</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 당신은 당신의 어플리케이션 내에 <literal>SchemaValidator</literal>을 삽입시킬 수 도 있다:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaValidator(cfg).validate();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-9">
+ <title>스키마 유효성 검사를 위해 Ant 사용하기</title>
+
+ <para>
+ 당신은 Ant 스크립트에서 <literal>SchemaValidator</literal>를 호출할 수 있다:
+ </para>
+
+ <programlisting><![CDATA[<target name="schemavalidate">
+ <taskdef name="schemavalidator"
+ classname="org.hibernate.tool.hbm2ddl.SchemaValidatorTask"
+ classpathref="class.path"/>
+
+ <schemavalidator
+ properties="hibernate.properties">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemavalidator>
+</target>]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/transactions.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/transactions.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/transactions.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/transactions.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,1004 @@
+<chapter id="transactions" revision="2">
+ <title>트랜잭션들과 동시성</title>
+
+ <para>
+ Hibernate와 동시성 제어에 대한 가장 중요한 점은 이해하기가 매우 쉽다는 점이다. Hibernate는 어떤 추가적인 잠금 행위 없이
+ JDBC 커넥션들과 JTA 리소스들을 직접 사용한다. 우리는 당신의 데이터베이스 관리 시스템의 JDBC, ANSI, 그리고 트랜잭션 격리 명세에
+ 약간의 시간을 할애할 것을 매우 권장한다.
+ </para>
+
+ <para>
+ Hibernate는 메모리 내에서 객체들을 잠그지 않는다. 당신의 어플리케이션은 격리 레벨에 의해 정의된 대로 행위를 기대할 수 있다.
+ 또한 transaction-영역의 캐시인 <literal>Session</literal> 덕분에, Hibernate는 (스칼라 값들을 반환하는 질의들을 보고하지 않는)
+ 식별자와 엔티티 질의들에 의한 룩업을 위해 반복 가능한 읽기를 제공한다.
+ </para>
+
+ <para>
+ 자동적인 optimistic 동시성 제어를 위한 버전화에 덧붙여, Hibernate는 또한 <literal>SELECT FOR UPDATE</literal>
+ 구문을 사용하여 행들에 대한 pessimistic 잠금을 위한 하나의 (마이너)API를 제공한다. optimistic 동시성 제어와 이 API는
+ 이 장의 뒷부분에서 논의된다.
+ </para>
+
+ <para>
+ 우리는 <literal>Configuration</literal>, <literal>SessionFactory</literal>, <literal>Session</literal>,
+ 알갱이를 가진 Hibernate에서의 동시성 제어 뿐만 아니라 데이터베이스 트랜잭션과 장기간에 걸친 (컴퓨터와의)대화들에 대한 논의를 시작한다.
+ </para>
+
+ <sect1 id="transactions-basics" revision="1">
+ <title>세션 영역과 트랜잭션 영역</title>
+
+ <para>
+ <literal>SessionFactory</literal>는 모든 어플리케이션 쓰레드들에 의해 공유되도록 고안된 생성에 비용이 드는,
+ 쓰레드안전(threadsafe) 객체이다. 그것은 대개 어플리케이션 시작 시에 <literal>Configuration</literal> 인스턴스로부터
+ 한번 생성된다.
+ </para>
+
+ <para>
+ <literal>Session</literal>은 하나의 요청, 하나의 대화 , 하나의 작업 단위를 위해 한번만 사용되고 나서 폐기될 예정인,
+ 비용이 들지 않는, 쓰레드 안전하지 않은 객체이다. <literal>Session</literal>은 커넥션이 필요하지 않으면 하나의 JDBC
+ <literal>Connection</literal>(또는 <literal>Datasource</literal>)를 얻지 않을 것이므로, 사용될 때까지
+ 리소스들을 소비하지 않는다.
+ </para>
+
+ <para>
+ 이 그림을 완성하기 위해 당신은 또한 데이터베이스 트랜재션들에 대해 생각해야 한다. 데이터베이스 트랜잭션은 데이터베이스에서
+ 잠금 다툼을 줄이기 위해 가능한 짧아야 한다. 긴 데이터베이스 트랜잭션들은 당신의 어플리케이션이 고도의 동시성 로드로의 가용성을
+ 높이는 것을 방해할 것이다. 그러므로 사용자가 생각하는 시간 동안 단위 작업이 완료될 때까지 데이터베이스 트랜잭션을 열려진채로
+ 소유하는 것은 대개 결코 좋은 설계는 아니다.
+ </para>
+
+ <para>
+ 하나의 작업 단위의 영역은 무엇인가? 하나의 Hibernate <literal>Session</literal>은 몇몇 데이터베이스 트랜잭션들에
+ 걸칠 수 있는가 또는 이것은 영역들의 one-to-one 관계인가? 당신은 언제 <literal>Session</literal>을 열고 닫는가
+ 그리고 당신은 데이터베이스 트랜잭션 경계들을 어떻게 한정하는가?
+ </para>
+
+ <sect2 id="transactions-basics-uow" revision="1">
+ <title>작업 단위</title>
+
+ <para>
+ 첫번째로, <emphasis>session-per-operation</emphasis> anti-패턴을 사용하지 말라. 즉, 단일 쓰레드 내에서
+ 모든 간단한 데이터베이스 호출에 대해 <literal>Session</literal>을 열고 닫지 말라! 물론 같은 것이 데이터베이스
+ 트랜잭션들에 대해서도 참이다. 어플리케이션 내의 데이터베이스 호출들은 계획된 순서를사용하여 행해지며, 그것들은 원자
+ 작업 단위 속으로 그룹지워진다. (이것은 또한 모든 하나의 SQL 문장 뒤의 auto-commit(자동-커밋)이 어플리케이션 내에서
+ 무용지물임을 의미하고, 이 모드가 SQL 콘솔 작업을 돕도록 고안되었음을 노트하라. Hibernate는
+ 의미하고, 이 모드는 Hibernate는 즉시 자동-커밋 모드를 사용 불가능하게 하거나, 어플리케이션 서버가 그렇게 행하고,
+ 즉시 자동-커밋시키는 것을 사용불가능하게 하거나 ,그렇게 행하는 것을 기대한다.) 데이터베이스 트랜잭션들은 결코 옵션이 아니며,
+ 하나의 데이터베이스와의 모든 통신은 당신이 데이터를 읽든 쓰단간에 상관없이 하나의 트랜잭션 내에서 발생해야 한다.
+ 설명하였듯이, 데이터 읽기를 위한 auto-commit 특징을 피해야 할 것이며, 많은 작은 트랜잭션들은 하나의 명료하게 정의된
+ 작업 단위보다 더 좋게 수행될 것 같지 않다. 후자가 또한 훨씬 더 유지가능하고 확장적이다.
+ </para>
+
+ <para>
+ 다중 사용자 클라이언트/서버 어플리케이션에서 가장 공통된 패턴은 <emphasis>session-per-request</emphasis>이다.
+ 이 모형에서, 클라이언트로부터의 요청은 (Hibernate 영속 계층이 실행되는) 서버로 전송되고, 새로운 Hibernate
+ <literal>Session</literal>이 열려지고, 모든 데이터베이스 오퍼레이션들이 이 작업 단위 내에서 실행된다. 일단 그 작업이
+ 완료되었다면(그리고 클라이언트에 대한 응답이 준비되었다면), 그 세션은 flush 되고 닫혀진다. 당신은 또한 당신이
+ <literal>Session</literal>을 열고 닫을 때 그것을 시작하고 커밋시켜서 클라이언트 요청에 서비스하는데 한 개의 데이터베이스
+ 트랜잭션을 사용하게 될 것이다. 둘 사이의 관계는 일대일 대응이고 이 모형은 많은 어플리케이션들에서 완전하게 적합하다.
+ </para>
+
+ <para>
+ 난제는 구현에 놓여있다: Hibernate는 이 패턴을 단순화 시키기 위해 "현재 세션"에 관한 미리 빌드된 관리를 제공한다. 당신이
+ 행해야할 모든 것은 서버 요청이 처리되어야 할 때 트랜잭션을 시작하고, 그 응답이 클라이언트로 전송되기 전에 트랜잭션을 끝내는
+ 것이다. 당신은 당신이 좋아하는 임의의 방법으로 이것을 행할 수 있으며, 공통된 해결책들은 서비스 메소드들 상의 첨단, 또는
+ 하나의 프락시/인터셉션 컨테이너를 가진 APO 인터셉터인, <literal>ServletFilter</literal>이다. 하나의 EJB
+ 컨테이너는 CMT의 경우에 선언적으로 EJB session beans 상에 트랜잭션 경계구분과 같은 동시 대조 측면들을 구현하는
+ 표준 방법이다. 만일 당신이 프로그램 상의 트랜잭션 경계구분을 사용하고자 결정한다면, 사용의 용이성과 코드 이식성을 위해
+ 이 장의 뒷 부분에서 보여진 Hibernate <literal>Transaction</literal>을 선호하라.
+ </para>
+
+ <para>
+ 당신의 어플리케이션 코드는 어디서든 필요할 때 종종 <literal>sessionFactory.getCurrentSession()</literal>을
+ 간단히 호출함으로써 요청을 처리할 "현재 세션"에 접근할 수 있다. 당신은 현재 데이터베이스 트랜잭션으로 영역화된 하나의
+ <literal>Session</literal>을 항상 얻게 될 것이다. 이것은 resource-local 환경 또는 JTA 환경에 대해 구성되어야
+ 하며, <xref linkend="architecture-current-session"/>을 보라.
+ </para>
+
+ <para>
+ 때때로 "뷰가 렌더링될 때까지" 하나의 <literal>Session</literal> 과 데이터베이스 트랜잭션의 영역을 확장시키는 것이
+ 편리하다. 이것은 요청이 처리된 후에 하나의 별도의 렌더링 단계를 활용하는 서블릿 어플리케이션들에서 특히 유용하다.
+ 뷰 렌더링이 완료될 때까지 데이터베이스 트랜잭션을 확장하는 것은 당신이 당신 자신의 인터셉터를 구현하는 경우에 행하기가 쉽다.
+ 하지만 만일 당신이 컨테이너에 의해 관리되는 트랜잭션들을 가진 EJB들에 의존할 경우에, 하나의 EJB 메소드가 반환될 때
+ 임의의 뷰 렌더링이 시작될 수 있기 전에 하나의 트랜잭션이 완료되기 때문에, 행하는 것이 쉽지 않다. 이
+ <emphasis>Open Session in View</emphasis> 패턴을 둘러싼 팁들과 예제들은 Hibernate 웹 사이트와 포럼을 보라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-basics-apptx" revision="1">
+ <title>장기간의 대화</title>
+
+ <para>
+ session-per-request 패턴은 당신이 작업 단위들을 설계하는데 사용할 수 있는 유일한 유용한 개념이 아니다. 많은 비지니스
+ 프로세스들은 데이터베이스 접근들을 중재하는 사용자 사이의 전체 일련의 상호작용들을 필요로 한다. 웹과 엔터프라이즈
+ 어플리케이션에서 사용자 상호작용에 걸치는 것은 데이터베이스 트랜잭션에 허용되지 않는다. 다음 예제를 검토하자:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ 대화상자의 첫 번째 화면이 열리고, 사용자에게 보여진 데이터는 특정 <literal>Session</literal>과 데이터베이스
+ 트랜잭션 속에 로드되었다. 사용자가 객체들을 변경시키는 것이 자유롭다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+
+ 사용자는 5분 후에 "저장"을 클릭하고 그의 변경들이 영속화 되기를 기대한다; 그는 또한 그가 이 정보를 편집하는 유일한
+ 개인이고 변경 충돌이 발생하지 않기를 기대한다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 우리는 사용자의 관점에서, 이것을 작업 단위, 장기간 실행되는 <emphasis>대화</emphasis>
+ (또는 <emphasis>어플리케이션 트랜잭션</emphasis>)이라고 명명한다.
+ 당신이 당신의 어플리케이션에서 이것을 어떻게 구현할 수 있는 많은 방법들이 존재한다.
+ </para>
+
+ <para>
+ 첫 번째 naive 구현은 동시성 변경을 방지하고, 격리와 atomicity(원자 단위성)을 보장하기 위해 데이터베이스에 의해
+ 소유된 잠금으로 사용자가 생각하는동안 <literal>Session</literal>과 데이터베이스 트랜잭션을 유지할 수도 있다.
+ 이것은 물론 anti-패턴이다. 왜냐하면 잠금 다툼은 어플리케이션이 동시 사용자들의 가용 숫자를 높이는 것을 허용하지
+ 않을 것이기 때문이다.
+ </para>
+
+ <para>
+ 명료하게, 우리는 대화(<emphasis>어플리케이션 트랜잭션</emphasis>)를 구현하는데 몇몇 데이터베이스 트랜잭션들을
+ 사용해야 한다. 이 경우에, 비지니스 프로세스들의 격리를 유지하는 것은 어플리케이션 티어의 부분적인 책임이 된다.
+ 단일 대화는 대개 여러 개의 데이터베이스 트랜잭션들에 걸친다. 그것은 이들 데이터베이스 트랜잭션들 중
+ 오직 한 개(마지막 트랜잭션)가 업데이트된 데이터를 저장하고, 모든 다른 트랜잭션들이 단순히 데이터를 읽는 (예를 들면,
+ 몇몇 요청/응답 주기에 걸치는 마법사 스타일의 대화 상자에서) 경우에만 원자단위가 될 것이다. 특히 당신이 Hibernate의
+ 특징들을 사용할 경우에 , 이것은 들리는 것보다 구현하기가 더 쉽다:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>자동적인 버전화</emphasis> - Hibernate는 당신을 위해 자동적인 optimistic
+ 동시성 제어를 행할 수 있고, 그것은 사용자가 생각하는 시간 동안 동시적인 변경이 발생했는지를 자동적으로 검출할 수 있다.
+ 대개 우리는 오직 대화의 끝에서 체크한다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Detached 객체들</emphasis> - 만일 당신이 이미 논의된 <emphasis>session-per-request</emphasis>
+ 패턴을 사용하고자 결정하는 경우, 모든 로드된 인스턴스들은 사용자가 생각하는 시간 동안 detached 상태에 있을 것이다.
+ Hibernate는 그 객체들을 재첨부시키고 변경들을 영속화 시키는 것을 허용해주며, 그 패턴은
+ <emphasis>session-per-request-with-detached-objects(detached-객체들을 가진 요청 당 세션)</emphasis>으로 명명된다.
+ 자동적인 버전화는 동시성 변경들을 격리시키는데 사용된다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>확장된 (또는 Long) Session</emphasis> - Hibernate <emphasis>Session</emphasis>은 데이터베이스
+ 트랜잭션이 커밋된 후에 기본 JDBC 커넥션이 연결 해제될 수도 있고, 새로운 클라이언트 요청이 발생할 때 다시 연결될 수
+ 있다. 이 패턴은 <emphasis>session-per-conversation(대화 당 세션)</emphasis>으로
+ 알려져 있고 재첨부를 불필요하게 만든다. 자동적인 버전화는 동시성 변경들을 격리시키는데 사용되고 <literal>Session</literal>은
+ 자동적으로 flush되는 것이 허용되지 않지만 명시적으로 flush되는 것은 허용된다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <emphasis>session-per-request-with-detached-objects</emphasis>과
+ <emphasis>session-per-conversation</emphasis> 양자는 장점들과 단점들을 갖는데, 우리는 이 장의
+ 뒷 부분에서 optimistic 동시성 제어 단락에서 그것들을 논의한다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-basics-identity">
+ <title>객체 identity 고려하기</title>
+
+ <para>
+ 어플리케이션은 두 개의 다른 <literal>Session</literal>들 내에 있는 동일한 영속 상태에 동시에 접근할 수도 있다.
+ 하지만 영속 클래스의 인스턴스는 두 개의 <literal>Session</literal> 인스턴스들 사이에 결코 공유되지 않는다.
+ 그러므로 identity에 대한 두 개의 다른 개념들이 존재한다:
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>데이터베이스 Identity</term>
+ <listitem>
+ <para>
+ <literal>foo.getId().equals( bar.getId() )</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>JVM Identity</term>
+ <listitem>
+ <para>
+ <literal>foo==bar</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ 그때 (예를 들어 <literal>Session</literal> 영역에서) <emphasis>특정</emphasis> <literal>Session</literal>에
+ 첨부된 객체들의 경우 두 개의 개념들은 동등한 것이고, 데이터베이스 identity에 대한 JVM identity가 Hibernate에 의해 보장된다.
+ 하지만, 어플리케이션이 두 개의 다른 세션들에서 "동일한" (영속 identity) 비지니스 객체에 동시에 접근하는 동안, 두 개의 인스턴스들은
+ 실제로 "다르다"(JVM identity). 충돌들은 flush/커밋 시에 (자동적인 버전화)를 사용하여, optimistic 접근법을 사용하여 해결된다.
+ </para>
+
+ <para>
+ 이 접근법은 Hibernate와 데이터베이스가 동시성에 대해 걱정하지 않도록 해준다; 그것은 또한 최상의 scalability를 제공한다.
+ 왜냐하면 단일 쓰레드-작업 단위 내에서 identity 보장은 단지 비용이 드는 잠금이나 다른 동기화 수단들을 필요로 하지 않기 때문이다.
+ 어플리케이션은 그것이 <literal>Session</literal> 당 단일 쓰레드를 강제하는 한, 어떤 비지니스 객체에 대해 결코 동기화 시킬
+ 필요가 없다. 하나의 <literal>Session</literal> 내에서 어플리케이션은 객체들을 비교하는데 <literal>==</literal>를
+ 안전하게 사용할 수가 있다.
+ </para>
+
+ <para>
+ 하지만, 하나의 <literal>Session</literal> 외부에서 <literal>==</literal>를 사용하는 어플리케이션은 예기치 않은
+ 결과들을 보게 될 수도 있다. 이것은 어떤 예기치 않은 장소들에서, 예를 들어 당신이 두 개의 detached 인스턴스들을 동일한
+ <literal>Set</literal> 내에 집어넣을 경우에 발생할 수도 있다. 둘 다 동일한 데이터베이스 identity를 가질 수 있지만
+ (예를 들어 그것들은 동일한 행을 표현한다), JVM identity는 정의 상 detached 상태에 있는 인스턴스들을 보장하지 않는다.
+ 개발자는 영속 클래스들내에 <literal>equals()</literal> 메소드와 <literal>hashCode()</literal> 메소드를 오버라이드 시켜야 하고
+ 객체 equality에 대한 그 자신의 개념을 구현해야 한다. 하나의 경고가 존재한다: equality를 구현하는데 데이터베이스 identifier를 결코
+ 사용하지 말고, 하나의 비지니스 키, 유일한, 대개 불변인 속성들의 조합을 사용하라. 데이터베이스 식별자는 만일 transient 객체가 영속화되는
+ 경우에 변경될 것이다. 만일 transient 인스턴스가(대개 detached 인스턴스들과 함께) <literal>Set</literal> 내에 보관되는 경우에,
+ hashcode 변경은 <literal>Set</literal>의 계약을 파기시킨다. 비지니스 키들에 대한 속성들은 데이터베이스 프라이머리 키들 만큼
+ 안정적이어서는 안되며, 당신은 오직 객체들이 동일한 <literal>Set</literal> 내에 있는 한에서 안정성을 보장해야만 한다.
+ 이 쟁점에 관한 논의에 대한 더 많은 것을 Hibernate 웹 사이트를 보라. 또한 이것이 Hibernate 쟁점이 아니며, 단지 자바 객체
+ identity와 equality가 구현되어야 하는 방법임을 노트하라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-basics-issues">
+ <title>공통된 쟁점들</title>
+
+ <para>
+ 안티-패턴들 <emphasis>session-per-user-session</emphasis> 또는
+ <emphasis>session-per-application</emphasis>을 결코 사용하지 말라(물론 이 규칙에 대한 드문 예외상황들이 존재한다).
+ 다음 쟁점들 중 몇몇이 또한 권장되는 패턴들로 나타날 수 있음을 노트하고, 당신이 설계 결정을 내리기 전에 내포된 의미들을
+ 확실히 이해하라:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>Session</literal>은 쓰레드-안전하지 않다. HTTP 요청들, 세션 빈즈, 또는 Swing worker들처럼
+ 동시에 작업하는 것으로 가정되는 것들은 하나의 <literal>Session</literal> 인스턴스가 공유될 경우에 경쟁 조건들을
+ 발생시킬 것이다. 만일 당신이 당신의 <literal>HttpSession</literal> 내에 Hibernate
+ <literal>Session</literal>을 유지시키는 경우(나중에 논의됨), 당신은 당신의 Http 세션에 대한 접근을 동기화
+ 시키는 것을 고려해야 한다. 그 밖의 경우, 충분히 빠르게 reload를 클릭하는 사용자는 두 개의 동시적으로 실행되는
+ 쓰레드들 내에서 동일한 <literal>Session</literal>을 사용할 수도 있다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Hibernate에 의해 던져진 예외상황은 당신이 당신의 데이터베이스 트랜잭션을 롤백 시키고 즉시 <literal>Session</literal>을
+ 닫아야 함을 의미한다(나중에 상세히 논의됨). 만일 당신의 <literal>Session</literal>이 어플리케이션에 바인드 되어 있는 경우,
+ 당신은 어플리케이션을 중지시켜야 한다. 데이터베이스 트랜잭션 롤백은 당신의 비지니스 객체들을 그것들이 트랜잭션의 시작 시에
+ 머물렀던 상태로 되돌리지는 않는다. 이것은 데이터베이스 상태와 비지니스 객체들이 동기화를 벗어남을 의미한다. 대개 이것은 문제가 아니다.
+ 왜냐하면 예외상황들은 회복가능한 것이 아니고 당신이 어떻게든 롤백 후에 시작해야 하기 때문이다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session</literal>은 (Hibernate에 의해 dirty 상태로 관찰되었거나 체크된) 영속 상태에 있는
+ 모든 객체를 캐시 시킨다. 이것은 당신이 오랜 시간 동안 <literal>Session</literal>을 열어둔 채로 유지하거나
+ 단순하게 너무 많은 데이터를 로드시킬 경우에, 당신이 OutOfMemoryException을 얻기 전까지, 그것이 끝없이
+ 성장한다는 점을 의미한다. 이것에 대한 하나의 해결책은 <literal>Session</literal> 캐시를 관리하기 위해
+ <literal>clear()</literal>와 <literal>evict()</literal>를 호출하는 것이지만, 당신이 대용량 데이터
+ 오퍼레이션들을 필요로 하는 경우에 당신은 대개 내장 프로시저를 고려해야 할 것이다. 몇몇 해결책들이
+ <xref linkend="batch"/>에 보여져 있다. 사용자 세션 동안에 <literal>Session</literal>을 열려진 채로
+ 유지하는 것은 또한 실효성이 떨어진 데이터에 대한 높은 확률을 의미한다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="transactions-demarcation">
+ <title>데이터베이스 트랜잭션 경계 설정</title>
+
+ <para>
+ 데이터베이스 (또는 시스템) 트랜잭션 경계들은 항상 필수적이다. 데이터베이스와의 통신은 데이터베이스 트랜잭션의 외부에서 발생할 수
+ 없다(이것은 자동-커밋 모드로 사용되는 많은 개발자들에게는 혼동스러워 보인다). 항상 심지어 읽기 전용 오퍼레이션들에 대해서도 명료한
+ 트랜잭션 경계들을 사용하라. 당신의 격리 레벨과 데이터베이스 가용성들에 따라, 이것은 필요하지 않을 수 있지만, 만일 당신이 항상
+ 트랜잭션들을 명시적으로 경계 설정할 경우에는 하강하는 결점들이 존재하지 않는다. 확실히, 하나의 데이터베이스 트랜잭션은 심지어
+ 데이터 읽기조차도 많은 작은 트랜잭션들의 경우보다는 더 좋게 수행될 것이다.
+ </para>
+
+ <para>
+ Hibernate 어플리케이션은 관리되지 않는 환경(예를 들면. 스탠드얼론, 간단히 웹 어플리케이션들 또는 Swing 어플리케이션들)과
+ 관리되는 J2EE 환경에서 실행될 수 있다. 관리되지 않는 환경에서, Hibernate는 대개 그것 자신의 데이터베이스 커넥션 풀에 대한
+ 책임이 있다. 어플리케이션 개발자는 트랜잭션 경계들을 손수 설정해야 한다. 달리 말해, 개발자 스스로 데이터베이스 트랜잭션들을
+ 시작하고, 커밋시키거나 롤백시켜야 한다. 관리되는 환경은 대개 예를 들어 EJB 세션 빈즈의 배치 디스크립터 속에 선언적으로 정의된
+ 트랜잭션 어셈블리를 가진, 컨테이너에 의해-관리되는 트랜잭션들(CMT)을 제공한다. 그때 프로그램 상의 트랜잭션 경계 설정은 더 이상 필요하지
+ 않다.
+ </para>
+
+ <para>
+ 하지만, CMT 대신 BMT를 사용하는 JTA에 의존할 수 있는 시스템들, 그리고 관리되지 않는 resource-local 환경들 사이에서
+ 당신의 영속 계층에 이식성을 유지시키는 것이 자주 희망된다. 두 경우들에서 당신은 프로그램 상의 트랜잭션 경계설정을 사용할 것이다.
+ Hibernate는 당신의 배치 환경의 고유한 트랜잭션 시스템 속으로 변환되는 <literal>Transaction</literal>이라 명명되는
+ wrapper API 를 제공한다. 이 API는 실제로 옵션이지만 우리는 당신이 CMT session bean 속에 있지 않는 한 그것의 사용을
+ 강력하게 권장한다.
+ </para>
+
+ <para>
+ 대개 <literal>Session</literal> 종료는 네 개의 구분되는 단계들을 수반한다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ 세션을 flush 시킨다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 트랜잭션을 커밋 시킨다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 세션을 닫는다
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 예외상황들을 처리한다
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 세션을 flush 시키는 것은 앞서 논의되었고, 우리는 이제 관리되는 환경과 관리되지 않는 환경 양자에서 트랜잭션 경계 설정과 예외상황을
+ 더 자세히 살펴볼 것이다.
+ </para>
+
+
+ <sect2 id="transactions-demarcation-nonmanaged" revision="2">
+ <title>관리되지 않는 환경</title>
+
+ <para>
+ 만일 Hibernate 영속 계층이 관리되지 않는(non-managed) 환경에서 실행될 경우, 데이터베이스 커넥션들은 대개 Hibernate가
+ 필요로할 때 커넥션들을 획득하는 간단한 (예를 들면 DataSource가 아닌) 커넥션 풀(pool)들로부터 처리된다.
+ session/transaction 처리 관용구는 다음과 같다:
+ </para>
+
+ <programlisting><![CDATA[// Non-managed environment idiom
+Session sess = factory.openSession();
+Transaction tx = null;
+try {
+ tx = sess.beginTransaction();
+
+ // do some work
+ ...
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ if (tx != null) tx.rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>
+ 당신은 <literal>Session</literal>을 명시적으로 <literal>flush()</literal> 하지 말아야 한다 -
+ <literal>commit()</literal>에 대한 호출은 (그 세션에 대한
+ <xref linkend="objectstate-flushing">FlushMode</xref>에 따라)자동적으로 동기화를 트리거시킨다.
+ <literal>close()</literal>에 대한 호출은 세션의 끝을 마크한다. <literal>close()</literal>의
+ 주된 구현은 JDBC 커넥션이 그 세션에 의해 포기될 것이라는 점이다. 이 Java 코드는 관리되지 않는 환경과
+ JTA 환경 양자에서 이식성이 있고 실행된다.
+ </para>
+
+ <para>
+ 보다 더 유연한 해결책은 앞서 설명했듯이 Hibernate의 미리 빌드되어 있는 "현재 세션" 컨텍스트 관리이다:
+ </para>
+
+ <programlisting><![CDATA[// Non-managed environment idiom with getCurrentSession()
+try {
+ factory.getCurrentSession().beginTransaction();
+
+ // do some work
+ ...
+
+ factory.getCurrentSession().getTransaction().commit();
+}
+catch (RuntimeException e) {
+ factory.getCurrentSession().getTransaction().rollback();
+ throw e; // or display error message
+}]]></programlisting>
+
+ <para>
+ 당신은 통상의 어플리케이션에서 비지니스 코드 속에 이 관용구를 결코 보지 않을 것이다; 치명적인(시스템) 예외상황들은 항상
+ "상단"에서 잡혀야 한다. 달리 말해, (영속 계층에서) Hibernate 호출들을 실행시키는 코드와 <literal>RuntimeException</literal>을
+ 처리하(고 대개 오직 제거하고 빠져나갈 수 있는) 코드는 다른 계층들 속에 있다. Hibernate에 의한 현재 컨텍스트 관리는 이 설계를
+ 현격하게 단순화시켜서, 당신이 필요로 하는 모든 것은 <literal>SessionFactory</literal>에 대한 접근이다.예외상황
+ 처리는 이 장의 뒷부분에서 논의된다.
+ </para>
+
+ <para>
+ 당신은 (디폴트인) <literal>org.hibernate.transaction.JDBCTransactionFactory</literal>를 선택해야 하고,
+ 두번째 예제의 경우 당신의 <literal>hibernate.current_session_context_class</literal>를 선택해야 함을 노트하라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-jta" revision="3">
+ <title>JTA 사용하기</title>
+
+ <para>
+ 만일 당신의 영속 계층이 어플리케이션 서버에서(예를 들어, EJB 세션 빈즈 이면에서) 실행될 경우, Hibernate에 의해
+ 획득된 모든 데이터소스 커넥션은 자동적으로 전역 JTA 트랜잭션의 부분일 것이다. 당신은 또한 스탠드얼론 JTA 구현을
+ 설치할 수 있고 EJB 없이 그것을 사용할 수 있다. Hibernate는 JTA 통합을 위한 두 개의 방도들을 제공한다.
+ </para>
+
+ <para>
+ 만일 당신이 bean-managed transactions(BMT)를 사용할 경우 Hibernate는 당신이 <literal>Transaction</literal>
+ API를 사용할 경우에 BMT 트랜잭션을 시작하고 종료하도록 어플리케이션 서버에게 알려줄 것이다. 따라서 트랜잭션 관리 코드는
+ non-managed 환경과 동일하다.
+ </para>
+
+ <programlisting><![CDATA[// BMT idiom
+Session sess = factory.openSession();
+Transaction tx = null;
+try {
+ tx = sess.beginTransaction();
+
+ // do some work
+ ...
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ if (tx != null) tx.rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>
+ 만일 당신이 트랜잭션에 묶인 <literal>Session</literal>, 즉 쉬운 컨텍스트 보급을 위한
+ <literal>getCurrentSession()</literal> 기능을 사용하고자 원할 경우, 당신은
+ JTA <literal>UserTransaction</literal> API를 직접 사용해야 할 것이다:
+ </para>
+
+ <programlisting><![CDATA[// BMT idiom with getCurrentSession()
+try {
+ UserTransaction tx = (UserTransaction)new InitialContext()
+ .lookup("java:comp/UserTransaction");
+
+ tx.begin();
+
+ // Do some work on Session bound to transaction
+ factory.getCurrentSession().load(...);
+ factory.getCurrentSession().persist(...);
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ tx.rollback();
+ throw e; // or display error message
+}]]></programlisting>
+
+ <para>
+ CMT의 경우, 트랜잭션 관할[경계 설정]은 프로그램 상이 아닌, session bean 배치 디스크립터들 속에서 행해진다.
+ 그러므로 코드는 다음으로 감소된다:
+ </para>
+
+ <programlisting><![CDATA[// CMT idiom
+ Session sess = factory.getCurrentSession();
+
+ // do some work
+ ...
+]]></programlisting>
+
+ <para>
+ 왜냐하면 하나의 세션 빈 메소드에 의해 던져진 처리되지 않은 <literal>RuntimeException</literal>이
+ 글로벌 트랜잭션을 rollback으로 설정하도록 컨테이너에게 알려주기 때문에, CMT/EJB에서조차 롤백은 자동적으로 발생된다.
+ <emphasis>이것은 당신이 BMT 이든 CMT이든 모두에서 Hibernate <literal>Transaction</literal> API를 사용할 필요가
+ 없으며, 당신은 그 트랜잭션에 묶인 "현재" Session의 자동적인 보급(propagation)을 얻게 됨을 의미한다.</emphasis>
+ </para>
+
+ <para>
+ 당신이 Hibernate의 트랜잭션 팩토리를 구성할 때, 당신이 JTA를 직접 사용할 경우(BMT) 당신은
+ <literal>org.hibernate.transaction.JTATransactionFactory</literal>를 선택해야하고, CMT session bean에서는
+ <literal>org.hibernate.transaction.CMTTransactionFactory</literal>를 선택해야 함을 노트하라. 또한
+ <literal>org.hibernate.transaction.manager_lookup_class</literal>를 설정하는 것을 염두에 두라. 게다가
+ 반드시 당신의 <literal>hibernate.current_session_context_class</literal>이 설정되지 않도록 하거나(역호환성),
+ 또는 <literal>"jta"</literal>로 설정되도록 하라.
+ </para>
+
+ <para>
+ <literal>getCurrentSession()</literal> 오퍼레이션들은 JTA 환경에서 한 가지 단점을 갖고 있다.
+ 디폴트로 사용되는, <literal>after_statement</literal> 커넥션 해제 모드 사용에 대한 하나의 보류 통보가 존재한다.
+ JTA 명세서의 어리석은 제한으로 인해, Hibernate가 <literal>scroll()</literal> 또는 <literal>iterate()</literal>에
+ 의해 반환되는 임의의 닫혀지지 않은 <literal>ScrollableResults</literal> 또는 <literal>Iterator</literal>
+ 인스턴스들을 자동적으로 제거하는 것이 불가능하다. 당신은 <literal>finally</literal> 블록 내에서 명시적으로
+ <literal>ScrollableResults.close()</literal> 또는 <literal>Hibernate.close(Iterator)</literal>를
+ 호출하여 기본 데이터베이스 커서를 해제<emphasis>시켜야 한다</emphasis>.(물론 대부분의 어플리케이션들은 JTA 또는 CMT 코드에서
+ <literal>scroll()</literal>이나 <literal>iterate()</literal>를 사용하는 것을 쉽게 피할 수 있다.)
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-exceptions">
+ <title>예외상황 처리</title>
+
+ <para>
+ 만일<literal>Session</literal>이 (어떤 <literal>SQLException</literal>을 포함하는) 예외상황을 던질 경우,
+ 당신은 데이터베이스 트랜잭션을 즉시 롤백시키고, <literal>Session.close()</literal>를 호출하고
+ <literal>Session</literal> 인스턴스를 폐기시켜야한다. <literal>Session</literal>의 어떤 메소드들은
+ 그 세션을 일관된 상태로 남겨두지 <emphasis>않을</emphasis> 것이다. Hibernate에 의해 던져진 예외상황은 복구가능한
+ 것으로 취급될 수 없다. 그 <literal>Session</literal>이 <literal>finally</literal> 블록 내에서
+ <literal>close()</literal>를 호출하여 닫혀지도록 확실히 하라.
+ </para>
+
+ <para>
+ Hibernate 영속 계층에서 발생할 수 있는 대부분의 오류들을 포장하는, <literal>HibernateException</literal>은
+ 체크되지 않은 예외상황이다(그것은 Hibernate의 이전 버전에는 없었다). 우리의 의견으로, 우리는 낮은 계층에서 복구불가능한
+ 예외상황을 붙잡도록 어플리케이션 개발자에게 강제하지 않을 것이다. 대부분의 시스템들에서, 체크되지 않은 치명적인 예외상황들은
+ (예를 들어, 더 높은 계층에서) 메소드 호출 스택의 첫 번째 프레임들 중 하나 속에서 처리되고, 한 개의 오류 메시지가 어플리케이션
+ 사용자에게 표시된다(또는 어떤 다른 적절한 액션이 취해진다). Hibernate는 또한 <literal>HibernateException</literal>이
+ 아닌, 다른 체크되지 않은 예외상황들을 던질 수도 있음을 노트하라. 다시 이것들은 복구가능하지 않고 적절한 액션이 취해져야 한다.
+ </para>
+
+ <para>
+ Hibernate는 데이터베이스와 상호작용하는 동안에 던져진 <literal>SQLException</literal>들을 하나의
+ <literal>JDBCException</literal> 속에 포장한다. 사실, Hibernate는 그 예외상황을
+ <literal>JDBCException</literal>의 보다 의미있는 서브클래스로 변환하려고 시도할 것이다. 기본
+ <literal>SQLException</literal>은 <literal>JDBCException.getCause()</literal>를 통해 항상 이용 가능하다.
+ Hibernate는<literal>SessionFactory</literal>에 첨부된 <literal>SQLExceptionConverter</literal>를
+ 사용하여 <literal>SQLException</literal>을 적당한 하나의 <literal>JDBCException</literal> 서브클래스로
+ 변환시킨다. 디폴트로 <literal>SQLExceptionConverter</literal>는 구성된 dialect에 의해 정의된다; 하지만
+ 맞춤 구현 속에 플러그인 시키는 것이 또한 가능하다(상세한 것은 <literal>SQLExceptionConverterFactory</literal>
+ 클래스에 관한 javadocs를 보라). 표준 <literal>JDBCException</literal> 서브타입은 다음과 같다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>JDBCConnectionException</literal> - 기본 JDBC 통신에 대한 오류를 나타낸다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>SQLGrammarException</literal> - 생겨난 SQL에 대한 문법 또는 구문 문제점을 나타낸다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ConstraintViolationException</literal> - 무결성 제약 위반에 관한 어떤 형식을 나타낸다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockAcquisitionException</literal> - 요청된 오퍼레이션을 실행하는데 필수적인 잠금 레벨을
+ 획득하는 오류를 나타낸다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>GenericJDBCException</literal> - 다른 카테고리들 중 어떤 것으로 분류되지 않았던 일반적인 예외상황.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-timeout">
+ <title>트랜잭션 타임아웃</title>
+
+ <para>
+ 관리되지 않는 코드에 대해서는 결코 제공되지 않는 EJB와 같이 관리되는 환경에 의해 제공되는 한 가지 극히
+ 중요한 특징은 트랜잭션 타임아웃이다. 트랜잭션 타임아웃은 사용자에게 응답을 반환하지 않는 동안에
+ 무례한 행동을 행하는 트랜잭션이 자원들을 무한정 묶어둘 수 없음을 보증해준다. 관리되는 (JTA) 환경
+ 외부에서, Hibernate는 이 기능을 온전하게 제공할 수 없다. 하지만 Hibernate는 데이터베이스
+ 레벨 데드락들과 거대한 결과 셋들을 가진 질의들이 정의된 타임아웃에 의해 제약되는 것을 보장함으로써
+ 최소한 데이터 접근 오퍼레이션들을 제어할 수 있다. 관리되는 환경에서, Hibernate는 트랜잭션 타임아웃을
+ JTA에게 위임시킬 수 있다. 이 기능은 Hibernate <literal>Transaction</literal> 객체에 의해
+ 추상화 된다.
+ </para>
+
+ <programlisting><![CDATA[
+Session sess = factory.openSession();
+try {
+ //set transaction timeout to 3 seconds
+ sess.getTransaction().setTimeout(3);
+ sess.getTransaction().begin();
+
+ // do some work
+ ...
+
+ sess.getTransaction().commit()
+}
+catch (RuntimeException e) {
+ sess.getTransaction().rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>
+ <literal>setTimeout()</literal>은 CMT bean 내에서 호출도리 수 없음을 노트하라.
+ 여기서 트랜잭션 타임아웃들은 선언적으로 정의되어야 한다.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="transactions-optimistic">
+ <title>Optimistic 동시성 제어</title>
+
+ <para>
+ 고도의 동시성과 고도의 가용성을 일치시키는 유일한 접근법은 버전화를 가진 optimistic동시성 제어이다. 버전 체킹은 업데이트 충돌을
+ 검출하기 위해(그리고 업데이트 손실을 방지하기 위해) 버전 번호들 또는 timestamp들을 사용한다. Hibernate는 optimistic 동시성을
+ 사용하는 어플리케이션 코드 작성에 세 가지 가능한 접근법들을 제공한다. 우리가 보여주는 쓰임새들은 장시간의 대화의 상황
+ 속에 있지만, 버전 체킹 또한 단일 데이터베이스 트랜잭션들에서 업데이트 손실을 방지하는 이점을 갖고 있다.
+ </para>
+
+ <sect2 id="transactions-optimistic-manual">
+ <title>어플리케이션 버전 체킹</title>
+
+ <para>
+ 하나의 구현에서 Hibernate로부터 많은 도움이 없이, 데이터베이스에 대한 각각의 상호작용은 새로운 <literal>Session</literal>
+ 내에서 일어나고, 개발자는 영속 인스턴스들을 처리하기 전에 데이터베이스로부터 모든 영속 인스턴스들을 다시 로드시킬 책임이 있다.
+ 이 접근법은 대화 트랜잭션을 확실히 격리시키기 위해 그것 자신의 버전 체킹을 수행하도록 어플리케이션에게 강제시킨다.
+ </para>
+
+ <programlisting><![CDATA[// foo is an instance loaded by a previous Session
+session = factory.openSession();
+Transaction t = session.beginTransaction();
+
+int oldVersion = foo.getVersion();
+session.load( foo, foo.getKey() ); // load the current state
+if ( oldVersion != foo.getVersion() ) throw new StaleObjectStateException();
+foo.setProperty("bar");
+
+t.commit();
+session.close();]]></programlisting>
+
+ <para>
+ version 프로퍼티는 <literal><version></literal>을 사용하여 매핑되고, Hibernate는 만일 엔티티가 dirty일 경우
+ flush 동안에 그것을 자동적으로 증가시킬 것이다.
+ </para>
+
+ <para>
+ 물론, 당신이 낮은 데이터 동시성 환경에서 작업하고 있고 버전 체킹을 필요로 하지 않을 경우에, 당신은 이 접근법을 사용할 수 도 있고
+ 단지 버전 체크를 생략할 수도 있다. 그 경우에, <emphasis>마지막의 커밋 성공</emphasis>은 당신의 장시간의 대화에
+ 대한 디폴트 방도가 될 것이다. 이것이 어플리케이션의 사용자들을 혼동시킬 수 있음을 염두에 두라. 왜냐하면 사용자들은 오류 메시지들
+ 또는 충돌 변경들을 병합시킬 기회 없이 업데이트들 손실을 겪을 수도 있기 때문이다.
+ </para>
+
+ <para>
+ 명료하게 수작업 버전 체킹은 매우 사소한 환경들에서도 공포적이고 대부분의 어플리케이션들에 대해 실제적이지 않다. 흔히 단일
+ 인스턴스 뿐만 아니라 변경된 객체들의 전체 그래프들이 체크되어야 한다. Hibernate는 설계 패러다임으로서 하나의 확장된 <literal>Session</literal>
+ 또는 detached 인스턴스들에 대해 자동적인 버전 체킹을 제공한다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-longsession">
+ <title>확장된 세션과 자동적인 버전화</title>
+
+ <para>
+ 하나의 <literal>Session</literal> 인스턴스와 그것의 영속 인스턴스들은 전체 어플리케이션 트랜잭션에 사용된다. Hibernate는
+ flush 할 때 인스턴스 버전들을 체크하고 만일 동시성 변경이 검출될 경우에 예외상황을 던진다. 이 예외상황을 잡아내고 처리하는 것을
+ 개발자의 몫이다(공통된 옵션들은 변경들을 병합시키거나 또는 쓸모가 없지 않은 데이터로 비지니스 프로세스를 다시 시작하는 기회를
+ 사용자에게 주는 것이다).
+ 하나의 <literal>Session</literal> 인스턴스와 그것의 영속 인스턴스들은 <emphasis>session-per-conversation</emphasis>로
+ 알려진 전체 대화에 사용된다. Hibernate는 flush 시점에서 인스턴스 버전들을 체크하며, 만일 동시적인 변경이 검출될 경우에
+ 하나의 예외상황을 던진다. 이 예외상황을 포착하고 처리하는 것은 개발자의 몫이다(공통된 옵션들은 사용자가 변경들을 병합하거나
+ 손실되지 않은 데이터를 가지고 비지니스 대화를 재시작하는 기회이다).
+ </para>
+
+ <para>
+ <literal>Session</literal>은 사용자 상호작용을 기다릴 때 어떤 기본 JDBC 커넥션으로부터 연결해제된다. 이 접근법은
+ 데이터베이스 접근의 관점에서 보면 가장 효율적이다. 어플리케이션은 버전 체킹 또는 detached 인스턴스들을 재첨부하는 것에
+ 그 자체 관계할 필요가 없거나 그것은 모든 데이터베이스 트랜잭션에서 인스턴스들을 다시 로드시킬 필요가 없다.
+ </para>
+
+ <programlisting><![CDATA[// foo is an instance loaded earlier by the old session
+Transaction t = session.beginTransaction(); // Obtain a new JDBC connection, start transaction
+
+foo.setProperty("bar");
+
+session.flush(); // Only for last transaction in conversation
+t.commit(); // Also return JDBC connection
+session.close(); // Only for last transaction in conversation]]></programlisting>
+ <para>
+ <literal>foo</literal> 객체는 그것이 로드되었던 <literal>Session</literal>이 어느 것인지를 여전히 알고 있다.
+ 이전 세션 상에서 하나의 새로운 데이터베이스 트랜잭션을 시작하는 것은 하나의 새로운 커넥션을 획득하고 그 세션을 소비한다.
+ 데이터베이스 트랜잭션을 커밋(확약)시키는 것은 그 JDBC 커넥션으로부터 하나의 세션을 연결해제시키고 그 커넥션을 풀(pool)로
+ 반환시킬 것이다. 재연결 후에, 당신이 업데이트하고 있지 않은 데이터에 대한 버전 체크를 강제시키기 위해서, 당신은
+ 또 다른 트랜잭션에 의해 업데이트되었을 수도 있는 임의의 객체들에 대해 <literal>LockMode.READ</literal>로서
+ <literal>Session.lock()</literal>을 호출할 수도 있다. 당신은 당신이 업데이트 중인 임의의 데이터를 잠금할 필요가 없다.
+ 대개 당신은 마지막 데이터베이스 트랜잭션 주기만이 이 대화 내에서 행해진 모든 변경들을 실제로 영속화시키는 것이 허용되도록 하기 위해,
+ 하나의 확장된 <literal>Session</literal>에 대해 <literal>FlushMode.MANUAL</literal>를 설정할 것이다.
+ 그러므로 오직 이 마지막 데이터베이스 트랜잭션 만이 <literal>flush()</literal> 오퍼레이션을 포함할 것이고, 또한
+ 대화를 종료시키기 위해 세션을 <literal>close()</literal>할 것이다.
+ </para>
+
+ <para>
+ 만일 사용자가 생각하는시간 동안 <literal>Session</literal>이 저장되기에 너무 큰 경우 이 패턴은 문제성이 있다. 예를 들어
+ <literal>HttpSession</literal>은 가능한 작은 것으로 유지되어야 한다. 또한 <literal>Session</literal>은 (필수의)
+ 첫 번째 레벨 캐시이고 모든 로드된 객체들을 포함하기 때문에, 우리는 아마 적은 요청/응답 주기들에 대해서만 이 방도를 사용할 수 있다.
+ 당신은 하나의 대화에 대해서만 하나의 <literal>Session</literal>을 사용해야 한다. 왜냐하면 그것은 또한 곧 실없는 데이터가
+ 될 것이기 때문이다.
+ </para>
+
+ <para>
+ (초기의 Hibernate 버전들은 <literal>Session</literal>에 대한 명시적인 연결해제와 재연결을 필요로 했음을
+ 노트하라. 트랜잭션을 시작하고 끝내는 것이 동일한 효과를 가지므로, 이들 방법들은 진부하게 되었다.)
+ </para>
+
+ <para>
+ 또한 당신은 영속 계층에 대해 연결해제된 <literal>Session</literal>을 닫혀진채로 유지해야함을 노트하라. 달
+ 리말해, 하나의 3-tier 환경에서 <literal>Session</literal>을 소유하는데 EJB stateful session bean을
+ 사용하고, <literal>HttpSession</literal> 내에 그것을 저장하기 위해 그것을 웹 계층에 전송하지 말라
+ (또는 그것을 별도의 티어에 직렬화 시키지도 말라).
+ </para>
+
+ <para>
+ 확장된 세션 패턴, 또는 <emphasis>session-per-conversation</emphasis>은 자동적인 현재 세션 컨텍스트 관리에 대해
+ 구현하기가 더 어렵다. 당신은 이를 위해 당신 자신의 <literal>CurrentSessionContext</literal> 구현을 공급할 필요가
+ 있으며, 예제들은 Hibernate Wiki를 보라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-detached">
+ <title>Detached 객체들과 자동적인 버전화</title>
+
+ <para>
+ 영속 저장소에 대한 각각의 상호작용은 새로운 <literal>Session</literal>에서 일어난다. 하지만 동일한 영속 인스턴스들은
+ 데이터베이스와의 각각의 상호작용에 재사용된다. 어플리케이션은 원래 로드되었던 detached 인스턴스들의 상태를 또 다른
+ <literal>Session</literal> 내에서 처리하고 나서 <literal>Session.update()</literal>,
+ <literal>Session.saveOrUpdate()</literal>, <literal>Session.merge()</literal>를 사용하여 그것들을
+ 다시 첨부시킨다.
+ </para>
+
+ <programlisting><![CDATA[// foo is an instance loaded by a previous Session
+foo.setProperty("bar");
+session = factory.openSession();
+Transaction t = session.beginTransaction();
+session.saveOrUpdate(foo); // Use merge() if "foo" might have been loaded already
+t.commit();
+session.close();]]></programlisting>
+
+ <para>
+ 다시, Hibernate는 flush 동안에 인스턴스 버전들을 체크할 것이고 업데이트 충돌이 발생할 경우에 예외상황을 던질 것이다.
+ </para>
+
+ <para>
+ 당신은 또한 <literal>update()</literal>대신에 <literal>lock()</literal>을 호출할 수도 있고 만일 그 객체가
+ 변경되지 않았음을 당신이 확신하는 경우에 (버전 체킹을 수행하고 모든 캐시들을 무시하는) <literal>LockMode.READ</literal>를
+ 사용할 수 있다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-customizing">
+ <title>자동적인 버전화를 맞춤화 시키기</title>
+
+ <para>
+ 당신은 <literal>optimistic-lock</literal> 매핑 속성을 <literal>false</literal>로 설정함으로써 특정 프로퍼티들과
+ 콜렉션들에 대한 Hibernate의 자동적인 버전 증가를 불가능하도록 할 수도 있다. 그때 Hibernate는 그 프로퍼티가 dirty 일 경우에
+ 더 이상 버전을 증가시키지 않을 것이다.
+ </para>
+
+ <para>
+ 리거시 데이터베이스 스키마들은 자주 static이고 변경될 수 없다. 또는 다른 어플리케이션들은 또한 동일한 데이터베이스에 접근하고
+ 버전 번호들 또는 심지어 timestamp들을 처리하는 방법을 모를 수도 있다. 두 경우들에서, 버전화는 테이블 내의 특정 컬럼에 의지할 수
+ 없다. version 또는 timestamp 프로퍼티 매핑 없이 행 내의 모든 필드들에 대한 상태를 비교하여 버전 체크를 강제시키기 위해서,
+ <literal><class></literal> 매핑 속에 <literal>optimistic-lock="all"</literal>을 표시하라. 만일
+ Hibernate가 이전 상태와 새로운 상태를 비교할 수 있을 경우에, 예를 들면 당신이 하나의 긴 <literal>Session</literal>을
+ 사용하고 session-per-request-with-detached-objects을 사용하지 않을 경우 이것은 개념적으로만 동작함을 노트하라.
+ </para>
+
+ <para>
+ 때때로 행해졌던 변경들이 중첩되지 않는 한 동시적인 변경이 허용될 수 있다. 만일 <literal><class></literal>를
+ 매핑할 때 당신이 <literal>optimistic-lock="dirty"</literal>를 설정하면, Hibernate는 flush 동안에 dirty 필드들을
+ 비교만 할 것이다.
+ </para>
+
+ <para>
+ 두 경우들에서, 전용 version/timestamp 컬럼의 경우 또는 full/dirty 필드 비교의 경우, Hibernate는 법전 체크를 실행하고
+ 정보를 업데이트하는데 엔티티 당 (적절한 <literal>WHERE</literal> 절을 가진) 한 개의<literal>UPDATE</literal>
+ 문장을 사용한다. 만일 당신이 연관된 엔티티들에 대한 재첨부를 케스케이드 하는데 transitive 영속을 사용할 경우,
+ Hibernate는 불필요하게 업데이트들을 실행할 수도 있다. 이것은 대개 문제가 아니지만, 심지어 변경들이 detached 인스턴스들에
+ 대해 행해지지 않았을 때에도 데이터베이스 내에서 <emphasis>on update</emphasis> 트리거들이 실행될 수도 있다. 그 행을
+ 업데이트하기 전에 변경들이 실제로 일어났음을 확인하기 위해 인스턴스를 <literal>SELECT</literal>하는 것을 Hibernate에게
+ 강제시키는, <literal><class></literal> 매핑 속에 <literal>select-before-update="true"</literal>를
+ 설정함으로써 당신은 이 특징을 맞춤화 시킬 수 있다.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="transactions-locking">
+ <title>Pessimistic 잠금</title>
+
+ <para>
+ 사용자들은 잠금 방도에 대해 걱정하는데 많은 시간을 할애하하려고 생각하지 않는다. 대개 JDBC 커넥션들에 대한 격리 레벨을 지정하는
+ 것으로 충분하고 그런 다음 단순히 데이터베이스로 하여금 모든 작업을 행하도록 한다. 하지만 진일보한 사용자들은 때때로 배타적인
+ pessimistic 잠금들을 얻거나 또는 새로운 트랜잭션의 시작 시에 잠금들을 다시 얻고자 원할 수도 있다.
+ </para>
+
+ <para>
+ Hibernate는 결코 메모리 내에 있는 객체들이 아닌, 데이터베이스의 잠금 메커니즘을 항상 사용할 것이다!
+ </para>
+
+ <para>
+ <literal>LockMode</literal> 클래스는 Hibernate에 의해 획득될 수 있는 다른 잠금 레벨들을 정의한다. 잠금은 다음 메커니즘들에
+ 의해 얻어진다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>LockMode.WRITE</literal>는 Hibernate가 한 행을 업데이트 하거나 insert 할 때 자동적으로 획득된다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.UPGRADE</literal>는 <literal>SELECT ... FOR UPDATE</literal> 구문을 지원하는
+ 데이터베이스 상에서 <literal>SELECT ... FOR UPDATE</literal>를 사용하여 명시적인 사용자 요청 상에서
+ 얻어질 수 있다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.UPGRADE_NOWAIT</literal>는 오라클에서 <literal>SELECT ... FOR UPDATE NOWAIT</literal>를
+ 사용하여 명시적인 사용자 요청 상에서 얻어질 수도 있다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.READ</literal>는 Hibernate가 반복 가능한 읽기(Repeatable Read) 또는 Serialization
+ 격리 레벨에서 데이터를 읽어들일 때 자동적으로 얻어질 수도 있다. 명시적인 사용자 요청에 의해 다시 얻어질 수도 있다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.NONE</literal>은 잠금이 없음을 나타낸다. 모든 객체들은 <literal>Transaction</literal>의 끝에서
+ 이 잠금 모드로 전환된다. <literal>update()</literal> 또는 <literal>saveOrUpdate()</literal>에 대한 호출을 통해
+ 세션과 연관된 객체들이 또한 이 잠금 모드로 시작된다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ "명시적인 사용자 요청"은 다음 방법들 중 하나로 표현된다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>LockMode</literal>를 지정한 <literal>Session.load()</literal>에 대한 호출.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.lock()</literal>에 대한 호출.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Query.setLockMode()</literal>에 대한 호출.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 만일 <literal>Session.load()</literal>가 <literal>UPGRADE</literal> 또는 <literal>UPGRADE_NOWAIT</literal>
+ 모드로 호출되고 ,요청된 객체가 아직 이 세션에 의해 로드되지 않았다면, 그 객체는 <literal>SELECT ... FOR UPDATE</literal>를
+ 사용하여 로드된다. 만일 요청된 것이 아닌 다소 제한적인 잠금으로 이미 로드되어 있는 객체에 대해 <literal>load()</literal>가
+ 호출될 경우, Hibernate는 그 객체에 대해 <literal>lock()</literal>을 호출한다.
+ </para>
+
+ <para>
+ 만일 지정된 잠금 모드가 <literal>READ</literal>, <literal>UPGRADE</literal> 또는
+ <literal>UPGRADE_NOWAIT</literal> 일 경우에 <literal>Session.lock()</literal>은 버전 번호 체크를 수행한다.
+ (<literal>UPGRADE</literal> 또는 <literal>UPGRADE_NOWAIT</literal> 인 경우에,
+ <literal>SELECT ... FOR UPDATE</literal>가 사용된다.)
+ </para>
+
+ <para>
+ 만일 데이터베이스가 요청된 잠금 모드를 지원하지 않을 경우, (예외상황을 던지는 대신에) Hibernate는 적절한 대체 모드를 사용할 것이다.
+ 이것은 어플리케이션이 이식 가능할 것임을 확실히 해준다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="transactions-connection-release">
+ <title>연결 해제 모드들</title>
+
+ <para>
+ JDBC 커넥션 관리에 관한 Hibernate의 리거시(2.x) 특징은 그것이 처음으로 필요로 했을 때
+ 하나의 <literal>Session</literal>이 하나의 커넥션을 획득할 것이고, 그런 다음 그 커넥션은 그 세션이
+ 닫혀질때까지 보관된다는 것이었다.
+ Hibernate 3.x는 세션에게 그것의 JDBC 커넥션들을 처리하는 방법을 알려주기 위해 연결 해제 모드들에 관한
+ 개념을 도입했다. 다음 논의는 구성된 <literal>ConnectionProvider</literal>를 통해 제공되는 커넥션들에
+ 대해서만 적절하다는 점을 노트하라; 사용자가 제공하는 커넥션들은
+ <literal>org.hibernate.ConnectionReleaseMode</literal>의 열거된 값들에 의해 식별된다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>ON_CLOSE</literal> - 는 본질적으로 위에 설명된 리거시 특징이다. Hibernate 세션은 그것이
+ 어떤 JDBC 접근을 수행하고 세션이 닫혀질 때까지 그 커넥션을 보관할 필요가 있을 때 하나의 커넥션을 획득한다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>AFTER_TRANSACTION</literal> - 은 하나의
+ <literal>org.hibernate.Transaction</literal>이 완료된 후에 연결들을 해제하라고 말한다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>AFTER_STATEMENT</literal> (또한 적극적인 해제라고 언급됨) - 는 각각의 모든 문장 실행 후에
+ 커넥션들을 해제하라고 말한다. 이 적극적인 해제는 그 문장이 주어진 세션과 연관된 리소스들을 열려진채로 남겨둘
+ 경우에는 건너뛰게(skip) 된다; 현재 이것이 일어나는 유일한 상황은
+ <literal>org.hibernate.ScrollableResults</literal>의 사용을 통해서이다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 사용할 해제 모드를 지정하기 위해 구성 파라미터 <literal>hibernate.connection.release_mode</literal>가 사용된다.
+ 가능한 값들은 다음과 같다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>auto</literal> (디폴트) - 이 선택은
+ <literal>org.hibernate.transaction.TransactionFactory.getDefaultReleaseMode()</literal>
+ 메소드에 의해 반환된 해제 모드로 위임시킨다. JTATransactionFactory인 경우, 이것은
+ ConnectionReleaseMode.AFTER_STATEMENT를 반환한다; JDBCTransactionFactory인 경우, 이것은
+ ConnectionReleaseMode.AFTER_TRANSACTION을 반환한다. 이 설정의 값이 사용자 코드 내의 버그들 그리고/또는
+ 유효하지 않은 가정들을 가리키는 경향이 있음으로 인해 이 디폴트 특징을 실패로 변경하는 것은 거의 좋은 생각이 아니다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>on_close</literal> - 는 ConnectionReleaseMode.ON_CLOSE를 사용하라고 말한다. 이 설정은
+ 역호환성을 위해 남겨졌지만, 그것의 사용은 매우 권장되지 않는다.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>after_transaction</literal> - 은 ConnectionReleaseMode.AFTER_TRANSACTION을 사용하라고 말한다.
+ 이 설정은 JTA 환경들에서 사용되지 않을 것이다. 또한
+ ConnectionReleaseMode.AFTER_TRANSACTION인 경우에 만일 세션이 auto-commit 모드에 있도록 고려될 경우,
+ 커넥션들은 마치 해제 모드가 AFTER_STATEMENT인 것처럼 해제될 것임을 또한 노트하라.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>after_statement</literal> - 는 ConnectionReleaseMode.AFTER_STATEMENT를 사용하라고 말한다.
+ 추가적으로 구성된 <literal>ConnectionProvider</literal>는 그것이 이 설정
+ (<literal>supportsAggressiveRelease()</literal>)을 지원하는지 여부를 알기 위해 참고된다.
+ 만일 지원하지 않을 경우, 해제 모드는 ConnectionReleaseMode.AFTER_TRANSACTION으로 재설정된다. 이 설정은
+ 우리가 <literal>ConnectionProvider.getConnection()</literal>을 호출할 때마다 우리가 동일한 기본 JDBC
+ 커넥션을 다시 필요로 할 수 있는 환경들에서 또는 우리가 동일한 커넥션을 얻는 것에 상관없는 auto-commit 환경에서 오직
+ 안전하다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/tutorial.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/tutorial.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/tutorial.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/tutorial.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,1486 @@
+<chapter id="tutorial">
+ <title>Hibernate 개요</title>
+
+ <sect1 id="tutorial-intro" revision="1">
+ <title>머리말</title>
+
+ <para>
+ 이 장은 Hibernate 초심자를 위한 개론적인 튜토리얼이다. 우리는 메모리-내 데이터베이스를
+ 사용하는 간단한 명령 라인 어플리케이션으로 시작하고 단계들을 이해하도록 쉽게 그것을 개발한다.
+ </para>
+
+ <para>
+ 이 튜토리얼은 Hibernate 신규 사용자들을 의도하고 있지만 Java와 SQL 지식을 필요로 한다.
+ 그것은 Michael Gloegl이 작성한 튜토리얼에 기초하며, 우리가 명명하는 제 3의 라이브러리들은
+ JDK 1.4와 5.0 버전용이다. 당신은 JDK1.3에 대해 다른 라이브러리들을 필요로 할 수도 있다.
+ </para>
+
+ <para>
+ 튜토리얼용 소스는 <literal>doc/reference/tutorial/</literal> 디렉토리 내에 있는
+ 배포본 내에 포함되어 있다.
+ </para>
+
+ </sect1>
+
+ <sect1 id="tutorial-firstapp" revision="2">
+ <title>파트 1 - 첫 번째 Hibernate 어플리케이션</title>
+
+ <para>
+ 먼저, 우리는 한 개의 간단한 콘솔-기반 Hibernate 어플리케이션을 생성시킬 것이다. 우리는 메모리-내
+ 데이터베이스(HSQL DB)를 사용하므로, 우리는 어떤 데이터베이스 서버를 설치하지 않아도 된다.
+ </para>
+
+ <para>
+ 우리가 우리가 수반하고자 원하는 이벤트들을 저장할 수 있는 작은 데이터베이스 어플리케이션과 이들
+ 이벤트들의 호스트들에 대한 정보를 필요로 한다고 가정하자.
+ </para>
+
+ <para>
+ 우리가 행할 첫 번째 것은 우리의 개발 디렉토리를 설정하고, 우리가 필요로 하는 모든 Java 라이브러리들을
+ 그것 속에 집어 넣는 것이다. Hibernate 웹 사이트로부터 Hibernate 배포본을 내려 받아라. 패키지를
+ 추출해내고 <literal>/lib</literal> 속에서 발견되는 모든 필요한 라이브러리들을 당신의 새로운 개발 작업
+ 디렉토리의 <literal>/lib</literal> 디렉토리 속에 위치지워라. 그것은 다음과 같을 것이다:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ antlr.jar
+ cglib.jar
+ asm.jar
+ asm-attrs.jars
+ commons-collections.jar
+ commons-logging.jar
+ hibernate3.jar
+ jta.jar
+ dom4j.jar
+ log4j.jar ]]></programlisting>
+
+ <para>
+ 이것은 <emphasis>글의 작성 시점에서</emphasis> Hibernate에 필수적인 최소한의 세트이다(우리는
+ 또한 메인 아카이브인 hibernate3.jar를 복사했음을 노트하라). 당신이 사용 중인 Hibernate 배포본이
+ 더 많거나 보다 적은 라이브러리들을 필요로 할 수도 있다. 필수 라이브러리들과 선택적인 제3의 라이브러리들에 대한
+ 추가 정보는 Hibernate 배포본의 <literal>lib/</literal> 디렉토리 내에 있는 <literal>README.txt</literal>
+ 파일을 보라. (실제로, Log4j는 필수는 아니지만 많은 개발자들에 의해 선호된다.)
+ </para>
+
+ <para>
+ 다음으로 우리는 우리가 데이터베이스 속에 저장시키고자 원하는 이벤트를 표현하는 한 개의 클래스를 생성시킨다.
+ </para>
+
+ <sect2 id="tutorial-firstapp-firstclass" revision="1">
+ <title>첫 번째 클래스</title>
+
+ <para>
+ 우리의 첫 번째 영속 클래스는 몇몇 프로퍼티들을 가진 간단한 자바빈즈 클래스이다:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+import java.util.Date;
+
+public class Event {
+ private Long id;
+
+ private String title;
+ private Date date;
+
+ public Event() {}
+
+ public Long getId() {
+ return id;
+ }
+
+ private void setId(Long id) {
+ this.id = id;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}]]></programlisting>
+
+ <para>
+ 당신은 이 클래스가 프로퍼티 getter와 setter 메소드들에 대한 표준 자바빈즈 명명법들 뿐만 아니라 필드들에 대한
+ private 가시성을 사용하고 있음을 알 수 있다. 이것은 권장되는 설계이지만, 필수적이지는 않다. Hibernate는
+ 또한 필드들에 직접 접근할 수 있으며, accessor 메소드들의 이점은 강건한 리팩토링이다. 아규먼트 없는 생성자는
+ reflection을 통해 이 클래스의 객체를 초기화 시킬 필요가 있다.
+ </para>
+
+ <para>
+ <literal>id</literal> 프로퍼티는 특별한 이벤트를 위한 유일 식별자를 소유한다. 모든 영속 엔티티 클래스들
+ (보다 덜 중요한 종속 클래스들도 존재한다)은 우리가 Hibernate의 전체 특징 집합을 사용하고자 원할 경우에
+ 그런 식별자 프로퍼티를 필요로 할 것이다. 사실 대부분의 어플리케이션들(특히 웹 어플리케이션들)은 식별자에 의해
+ 객체들을 구분지을 필요가 있어서, 당신은 이것을 어떤 제약점이라기 보다는 하나의 특징으로 간주할 것이다. 하지만
+ 우리는 대개 객체의 항등(identity)를 처리하지 않으므로, setter 메소드는 private이어야 한다. 객체가 저장될 때,
+ Hibernate는 단지 식별자들을 할당할 것이다. 당신은 Hibernate가 public, private, protected 접근자 메소드들
+ 뿐만 아니라 (public, private, protected) 필드들에도 직접 접근할 수 있음을 알 수 있다. 선택은 당신에게 달려
+ 있으며, 당신은 당신의 어플리케이션 설계에 적합하도록 그것을 부합시킬 수 있다.
+ </para>
+
+ <para>
+ 아규먼트 없는 생성자는 모든 영속 클래스들에 대한 필요조건이다; Hibernate는 당신을 위해 Java Reflection을
+ 사용하여 객체들을 생성시켜야 한다. 하지만 생성자는 private 일 수 있고, 패키지 가시성은 런타임 프락시 생성과
+ 바이트코드 방편 없는 효율적인 데이터 검색에 필요하다.
+ </para>
+
+ <para>
+ 이 Java 소스 파일을 개발 폴더 내의 <literal>src</literal>로 명명된 디렉토리 속에 있는 위치지워라. 이제
+ 그 디렉토리는 다음과 같을 것이다:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java]]></programlisting>
+
+ <para>
+ 다음 단계에서, 우리는 Hiberante에게 이 영속 클래스에 대해 알려 준다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-mapping" revision="1">
+ <title>The mapping file</title>
+
+ <para>
+ Hibernate는 영속 크래스들에 대한 객체들을 로드시키고 저장시키는 방법을 알 필요가 있다.
+ 이곳은 Hibernate 매핑 파일이 역할을 행하는 곳이다. 매핑 파일은 Hibernate가 접근해야 하는
+ 데이터베이스 내의 테이블이 무엇인지, 그리고 그것이 사용해야 하는 그 테이블 내의 컬럼들이
+ 무엇인지를 Hibernate에게 알려준다.
+ </para>
+
+ <para>
+ 매핑 파일의 기본 구조는 다음과 같다:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping>
+[...]
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Hibernate DTD는 매우 정교하다. 당신은 당신의 편집기 또는 IDE 내에서 XML 매핑 요소들과 속성들에
+ 대한 자동 완성 기능을 위해 그것을 사용할 수 있다. 당신은 또한 당신의 텍스트 편집기 내에 DTD 파일을
+ 열 수 있을 것이다 - 그것은 모든 요소들과 속성들에 대한 전체상을 얻고 디폴트들 뿐만 아니라 몇몇 주석들을
+ 보는 가장 손쉬운 방법이다. Hibernate는 웹으로부터 DTD 파일을 로드시키지 않지만, 먼저 어플리케이션의
+ classpath 경로로부터 그것을 먼저 룩업할 것임을 노트하라. DTD 파일은 <literal>hibernate3.jar</literal>
+ 속에 포함되어 있을 뿐만 아니라 Hibernate 배포본의 <literal>src/</literal> 디렉토리 속에 포함되어
+ 있다.
+ </para>
+
+ <para>
+ 우리는 코드를 간략화 시키기 위해 장래의 예제에서 DTD 선언을 생략할 것이다. 그것은 물론 옵션이 아니다.
+ </para>
+
+ <para>
+ 두 개의 <literal>hibernate-mapping</literal> 태그들 사이에 <literal>class</literal> 요소를
+ 포함시켜라. 모든 영속 엔티티 클래스들(다시금 종속 클래스들일 수 있고, 그것은 첫번째-급의 엔티티들이 아니다)은
+ SQL 데이터베이스 내의 테이블에 대한 그런 매핑을 필요로 한다:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 지금까지 우리는 그 테이블 내에 있는 한 행에 의해 표현된 각각의 인스턴스인, 클래스의 객체를 영속화 시키고
+ 로드시키는 방법을 Hibernate에게 알려주었다. 이제 우린느 테이블 프라이머리 키에 대한 유일 식별자 프로퍼티 매핑을
+ 계속 행한다. 게다가 우리는 이 식별자를 처리하는 것에 주의를 기울이고자 원하지 않으므로, 우리는 대용 키 프라이머리 키
+ 컬럼에 대한 Hibernate의 식별자 생성 방도를 구성한다:
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+ <id name="id" column="EVENT_ID">
+ <generator class="native"/>
+ </id>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>id</literal> 요소는 식별자 프로퍼티의 선언이고, <literal>name="id"</literal>는
+ Java 프로퍼티의 이름을 선언한다 - Hibernate는 그 프로퍼티에 접근하는데 getter 및 setter 메소드들을
+ 사용할 것이다. column 속성은 우리가 <literal>EVENTS</literal> 테이블의 어느 컬럼을 이 프라이머리 키로
+ 사용하는지를 Hibernate에게 알려준다. 내포된 <literal>generator</literal> 요소는 식별자 생성 방도를
+ 지정하며, 이 경우에 우리는 <literal>increment</literal>를 사용했고, 그것은 대개 테스팅(과 튜토리얼들)에
+ 유용한 매우 간단한 메모리-내 숫자 증가 방법이다. Hibernate는 또한 전역적으로 유일한 데이터베이스에 의해 생성된
+ 식별자 뿐만 아니라 어플리케이션에 의해 할당된 식별자(또는 당신이 확장으로 작성한 어떤 방도)를 지원한다.
+ </para>
+
+ <para>
+ 마지막으로 우리는 매핑 파일 속에서 클래스의 영속 프로퍼티들에 대한 선언들을 포함한다. 디폴트로, 클래스의
+ 프로퍼티들은 영속적인 것으로 간주되지 않는다:
+ </para>
+
+ <programlisting><![CDATA[
+<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+ <id name="id" column="EVENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="date" type="timestamp" column="EVENT_DATE"/>
+ <property name="title"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>id</literal> 요소의 경우처럼, <literal>property</literal> 요소의 <literal>name</literal>
+ 속성은 사용할 getter 및 setter 메소드들이 어느 것인지를 Hibernate에게 알려준다. 따라서 이 경우에 Hibernate는
+ <literal>getDate()/setDate()</literal> 뿐만 아니라 <literal>getTitle()/setTitle()</literal>을
+ 찾게 될 것이다.
+ </para>
+
+ <para>
+ <literal>date</literal> 프로퍼티 매핑은 <literal>column</literal> 속성을 포함하는데,
+ 왜 <literal>title</literal>은 <literal>column</literal> 속성을 포함하지 않는가?
+ <literal>column</literal> 속성이 없을 경우 Hibernate는 디폴트로 컬럼 이름으로서 프로퍼티 이름을
+ 사용한다. 이것은 에 대해 잘 동작한다. 하지만 <literal>date</literal>는 대부분의 데이터베이스에서
+ 예약된 키워드이어서, 우리는 그것을 다른 이름으로 더 좋게 매핑 시킨다.
+ </para>
+
+ <para>
+ 다음 흥미로운 점은 <literal>title</literal> 매핑 또한 <literal>type</literal> 속성을 갖지 않는다.
+ 우리가 매핑파일들 속에서 선언하고 사용하는 타입들은 당신이 예상하는 Java 데이터 타입들이 아니다. 그것들은
+ 또한 SQL 데이터베이스 타입들도 아니다. 이들 타입들은 이른바 <emphasis>Hibernate 매핑 타입들</emphasis>,
+ 즉 Java 타입들로부터 SQL 타입들로 변환될 수 있고 반대로 SQL 타입들로부터 Java 타입들로 매핑될 수 있는 컨버터들이다.
+ 다시말해, <literal>type</literal> 속성이 매핑 속에 존재하지 않을 경우 Hibernate는 정확환 변환 및 매핑 타입
+ 그 자체를 결정하려고 시도할 것이다. 몇몇 경우들에서 (Java 클래스에 대한 Reflection을 사용하는) 이 자동적인 검출은
+ 당신이 예상하거나 필요로 하는 디폴트를 갖지 않을 수도 있다. 이것은 <literal>date</literal> 프로퍼티를 가진
+ 경우이다. Hibernate는 그 프로퍼티가 SQL <literal>date</literal> 컬럼, <literal>timestamp</literal>
+ 컬럼 또는 <literal>time</literal> 컬럼 중 어느 것으로 매핑되어야 하는지를 알 수가 없다. 우리는
+ <literal>timestamp</literal> 컨버터를 가진 프로퍼티를 매핑함으로써 전체 날짜와 시간 정보를 보존하고 싶다고
+ 선언한다.
+ </para>
+
+ <para>
+ 다음 매핑 파일은 <literal>Event</literal> Java 클래스 소스 파일과 같은 디렉토리 속에
+ <literal>Event.hbm.xml</literal>로서 저장될 것이다. 매핑 파일들에 대한 네이밍은 임의적일 수
+ 있지만, 접미사 <literal>hbm.xml</literal>은 Hibernate 개발자 공동체 내에서 컨벤션이 되었다.
+ 디렉토리 구조는 이제 다음과 같을 것이다:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java
+ Event.hbm.xml]]></programlisting>
+
+ <para>
+ 우리는 Hibernate의 메인 구성을 계속 행한다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-configuration" revision="2">
+ <title>Hibernate 구성</title>
+
+ <para>
+ 우리는 이제 적절한 곳에 한 개의 영속 클래스와 그것의 매핑 파일을 갖고 있다. Hibernate를 구성할 차례이다.
+ 우리가 이것을 행하기 전에, 우리는 데이터베이스를 필요로 할 것이다. 자바 기반의 메모리-내 SQL DBMS인
+ HSQL DB는 HSQL DB 웹 사이트에서 내려받을 수 있다. 실제로, 당신은 이 다운로드에서 오직 <literal>hsqldb.jar</literal>
+ 만을 필요로 한다. 개발 폴더의 <literal>lib/</literal> 디렉토리 속에 이 파일을 위치지워라.
+ </para>
+
+ <para>
+ 개발 디렉토리의 루트에 <literal>data</literal>로 명명된 디렉토리를 생성시켜라 - 이 디렉토리는
+ HSQL DB가 그것의 데이터 파일들을 저장하게 될 장소이다. 이제 이 데이터 디렉토리에서
+ <literal>java -classpath ../lib/hsqldb.jar org.hsqldb.Server</literal>를 실행시켜서
+ 데이터베이스를 시작시켜라. 당신은 그것이 시작되고 이것은 우리의 어플리케이션이 나중에 연결하게 될 장소인,
+ 하나의 TCP/IP 소켓에 바인드 되는 것을 볼 수 있다. 만일 이 튜토리얼 동안에 당신이 새 데이터베이스로
+ 시작하고자 원할 경우, HSQL DB를 셧다운시키고(왼도우에서 <literal>CTRL + C</literal>를 눌러라),
+ <literal>data/</literal> 디렉토리 내에 있는 모든 파일들을 삭제하고 다시 HSQL DB를 시작하라.
+ </para>
+
+ <para>
+ Hibernate는 당신의 어플리케이션 내에서 이 데이터베이스에 연결하는 계층이고, 따라서 그것은 커넥션 정보를
+ 필요로 한다. 커넥션들은 마찬가지로 구성되어야 하는 하나의 JDBC 커넥션 풀을 통해 행해진다. Hibernate
+ 배포본은 몇몇 오픈 소스 JDBC 커넥션 풀링 도구들을 포함하고 있지만, 이 튜토리얼에서는 Hibernate에 의해
+ 미리 빌드된 커넥션 풀링을 사용할 것이다. 당신이 필수 라이브러리를 당신의 classpath 속에 복사해야 하고
+ 만일 당신이 제품-특징의 제3의 JDBC 풀링 소프트웨어를 사용하고자 원할 경우에는 다른 커넥션 풀링 설정들을
+ 사용해야 함을 노트하라.
+ </para>
+
+ <para>
+ Hibernate의 구성을 위해, 우리는 한 개의 간단한 <literal>hibernate.properties</literal> 파일,
+ 한 개의 약간 더 세련된 <literal>hibernate.cfg.xml</literal> 파일, 또는 심지어 완전한 프로그램
+ 상의 설정을 사용할 수 있다. 대부분의 사용자들은 XMl 구성 파일을 선호한다:
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <session-factory>
+
+ <!-- Database connection settings -->
+ <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
+ <property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
+ <property name="connection.username">sa</property>
+ <property name="connection.password"></property>
+
+ <!-- JDBC connection pool (use the built-in) -->
+ <property name="connection.pool_size">1</property>
+
+ <!-- SQL dialect -->
+ <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
+
+ <!-- Enable Hibernate's automatic session context management -->
+ <property name="current_session_context_class">thread</property>
+
+ <!-- Disable the second-level cache -->
+ <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
+
+ <!-- Echo all executed SQL to stdout -->
+ <property name="show_sql">true</property>
+
+ <!-- Drop and re-create the database schema on startup -->
+ <property name="hbm2ddl.auto">create</property>
+
+ <mapping resource="events/Event.hbm.xml"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ 이 XML 구성이 다른 DTD를 사용함을 노트하라. 우리는 Hibernate의 <literal>SessionFactory</literal>
+ -특정 데이터베이스에 대해 책임이 있는 전역 팩토리-를 구성한다. 만일 당신이 여러 데이터베이스들을
+ 갖고 있다면, (보다 쉬운 시작을 위해) 몇 개의 구성 파일들 속에 여러 개의 <literal><session-factory></literal>
+ 구성들을 사용하라.
+ </para>
+
+ <para>
+ 처음 네 개의 <literal>property</literal> 요소들은 JDBC 커넥션을 위한 필수 구성을 포함한다.
+ dialect <literal>property</literal> 요소는 Hibernate가 발생시키는 특별한 SQL 이형(異形)을
+ 지정한다.
+ <literal>hbm2ddl.auto</literal> 옵션은 -직접 데이터베이스 속으로- 데이터베이스 스키마의 자동적인
+ 생성을 활성화 시킨다. 물론 이것은 (config 옵션을 제거함으로써) 비활성화 시킬 수 있거나
+ <literal>SchemaExport</literal> Ant 태스크의 도움으로 파일로 리다이렉트 될 수 있다. 마지막으로
+ 우리는 영속 클래스들을 위한 매핑 파일(들)을 추가시킨다.
+ </para>
+
+ <para>
+ 이 파일을 소스 디렉토리 속으로 복사하고, 따라서 그것은 classpath의 루트에서 끝날 것이다. Hibernate는
+ 시작 시에 classpath의 루트에서 <literal>hibernate.cfg.xml</literal>로 명명된 파일을 자동적으로
+ 찾는다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-ant" revision="1">
+ <title>Ant로 빌드하기</title>
+
+ <para>
+ 우리는 이제 Ant로 튜토리얼을 빌드할 것이다. 당신은 Ant를 설치할 필요가 있을 것이다 -
+ <ulink url="http://ant.apache.org/bindownload.cgi">Ant 내려받기 페이지</ulink>에서
+ Ant를 얻어라. Ant를 설치하는 방법은 여기서 다루지 않을 것이다. <ulink url="http://ant.apache.org/manual/index.html">Ant 매뉴얼</ulink>을
+ 참조하길 바란다. 당신이 Ant를 설치한 후에, 우리는 빌드파일 생성을 시작할 수 있다. 그것은 <literal>build.xml</literal>로
+ 명명되고 개발 디렉토리 속에 직접 위치될 것이다.
+ </para>
+
+ <para>
+ 기본 빌드 파일은 다음과 같다:
+ </para>
+
+ <programlisting><![CDATA[<project name="hibernate-tutorial" default="compile">
+
+ <property name="sourcedir" value="${basedir}/src"/>
+ <property name="targetdir" value="${basedir}/bin"/>
+ <property name="librarydir" value="${basedir}/lib"/>
+
+ <path id="libraries">
+ <fileset dir="${librarydir}">
+ <include name="*.jar"/>
+ </fileset>
+ </path>
+
+ <target name="clean">
+ <delete dir="${targetdir}"/>
+ <mkdir dir="${targetdir}"/>
+ </target>
+
+ <target name="compile" depends="clean, copy-resources">
+ <javac srcdir="${sourcedir}"
+ destdir="${targetdir}"
+ classpathref="libraries"/>
+ </target>
+
+ <target name="copy-resources">
+ <copy todir="${targetdir}">
+ <fileset dir="${sourcedir}">
+ <exclude name="**/*.java"/>
+ </fileset>
+ </copy>
+ </target>
+
+</project>]]></programlisting>
+
+ <para>
+ 이것은 <literal>.jar</literal>로 끝나는 lib 디렉토리 내에 있는 모든 파일들을 컴파일에 사용되는 classpath에
+ 추가하도록 Ant에게 알려줄 것이다. 그것은 또한 모든 비-Java 소스 파일들을 대상 디렉토리로 복사할 것이다. 예를 들면,
+ 구성 및 Hibernate 매핑 파일들. 만일 당신이 Ant를 이제 실행할 경우, 당신은 다음 출력을 얻게 될 것이다:
+ </para>
+
+ <programlisting><![CDATA[C:\hibernateTutorial\>ant
+Buildfile: build.xml
+
+copy-resources:
+ [copy] Copying 2 files to C:\hibernateTutorial\bin
+
+compile:
+ [javac] Compiling 1 source file to C:\hibernateTutorial\bin
+
+BUILD SUCCESSFUL
+Total time: 1 second ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-helpers" revision="3">
+ <title>시작과 helper들</title>
+
+ <para>
+ 몇몇 <literal>Event</literal> 객체들을 로드시키고 저장할 차례이지만, 먼저 우리는 어떤 인프라스트럭처
+ 코드로 설정을 완료해야 한다. 우리는 Hibernate를 시작해야 한다. 이 시작은 전역 <literal>SessionFactory</literal>
+ 객체를 빌드하고 어플리케이션 내에서 용이한 접근을 위해 그것을 어떤 곳에 저장하는 것을 포함한다.
+ <literal>SessionFactory</literal>는 새로운 <literal>Session</literal>들을 열 수 있다.
+ <literal>Session</literal>은 작업의 단일-쓰레드 단위를 표현하며, <literal>SessionFactory</literal>는
+ 한번 초기화 되는 하나의 thread-safe 전역 객체이다.
+ </para>
+
+ <para>
+ 우리는 시작을 처리하고 <literal>Session</literal> 처리를 편리하게 해주는 <literal>HibernateUtil</literal>
+ helper 클래스를 생성시킬 것이다. 이른바 <emphasis>ThreadLocal Session</emphasis> 패턴이 여기서
+ 유용하며, 우리는 현재의 작업 단위를 현재의 쓰레드와 연관지워 유지한다. 구현을 살펴보자:
+ </para>
+
+ <programlisting><![CDATA[package util;
+
+import org.hibernate.*;
+import org.hibernate.cfg.*;
+
+public class HibernateUtil {
+
+ private static final SessionFactory sessionFactory;
+
+ static {
+ try {
+ // Create the SessionFactory from hibernate.cfg.xml
+ sessionFactory = new Configuration().configure().buildSessionFactory();
+ } catch (Throwable ex) {
+ // Make sure you log the exception, as it might be swallowed
+ System.err.println("Initial SessionFactory creation failed." + ex);
+ throw new ExceptionInInitializerError(ex);
+ }
+ }
+
+ public static SessionFactory getSessionFactory() {
+ return sessionFactory;
+ }
+
+}]]></programlisting>
+
+ <para>
+ 이 클래스는 (클래스가 로드될 때 JVM에 의해 한번 호출되는) 그것의 static 초기자 내에 전역 <literal>SessionFactory</literal>를
+ 산출할 뿐만 아니라 또한 현재 쓰레드에 대한 <literal>Session</literal>을 소유하는 <literal>ThreadLocal</literal> 변수를
+ 갖는다. 당신이 <literal>HibernateUtil.getCurrentSession()</literal>을 호출하는 시점에는 문제가 없으며,
+ 그것은 항상 동일 쓰레드 내에 동일한 Hibernate 작업 단위를 반환할 것이다. <literal>HibernateUtil.closeSession()</literal>에
+ 대한 호출은 쓰레드와 현재 연관되어 있는 작업 단위를 종료시킨다.
+ </para>
+
+ <para>
+ 당신이 이 helper를 사용하기 전에 thread-local 변수들에 대한 Java 개념을 확실히 이해하도록 하라.
+ 보다 강력한 <literal>HibernateUtil</literal> helper는 http://caveatemptor.hibernate.org/에
+ 있는 <literal>CaveatEmptor</literal> 뿐만 아니라 "Java Persistence with Hibernate" 책에서 찾을 수 있다.
+ 당신이 J2EE 어플리케이션 서버 내에 Hibernate를 배치할 경우에 이 클래스는 필수적이지 않다: 하나의
+ <literal>Session</literal>은 현재의 JTA 트랜잭션에 자동적으로 바인드 될 것이고 당신은 JNDI를 통해
+ <literal>SessionFactory</literal>를 룩업할 수 있다. 만일 당신이 JBoss AS를 사용할 경우,
+ Hibernate는 관리되는 시스템 서비스로서 배치될 수 있고 <literal>SessionFactory</literal>를
+ JNDI 이름에 자동적으로 바인드시킬 수 있을 것이다.
+ </para>
+
+ <para>
+ 개발 소스 디렉토리 속에 <literal>HibernateUtil.java</literal> 를 위치지우고, 다음으로 <literal>Event.java</literal>를
+ 위치지워라:
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java
+ Event.hbm.xml
+ +util
+ HibernateUtil.java
+ hibernate.cfg.xml
++data
+build.xml]]></programlisting>
+
+ <para>
+ 이것은 문제 없이 다시 컴파일 될 것이다. 우리는 마지막으로 로깅 시스템을 구성할 필요가 있다 - Hibernate는
+ commons logging를 사용하고 Log4j와 JDK 1.4 사이의 선택은 당신의 몫으로 남겨둔다. 대부분의 개발자들은
+ Log4j를 선호한다: Hibernate 배포본에 있는 <literal>log4j.properties</literal>(이것은 디렉토리
+ <literal>etc/</literal> 내에 있다)를 <literal>src</literal> 디렉토리로 복사하고, 다음으로
+ <literal>hibernate.cfg.xml</literal>을 복사하라. 예제 구성을 살펴보고 당신이 더 많은 verbose 출력을
+ 원할 경우에 설정들을 변경하라. 디폴트로 Hibernate 시작 메시지는 stdout 상에 보여진다.
+ </para>
+
+ <para>
+ 튜토리얼 인프라스트럭처는 완전하다 - 그리고 우리는 Hibernate로 어떤 실제 작업을 행할 준비가 되어 있다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-workingpersistence" revision="5">
+ <title>객체 로딩과 객체 저장</title>
+
+ <para>
+ 마지막으로 우리는 객체들을 로드시키고 저장하는데 Hibernate를 사용할 수 있다. 우리는 한 개의 <literal>main()</literal>
+ 메소드를 가진 한 개의 <literal>EventManager</literal> 클래스를 작성한다:
+ </para>
+
+ <programlisting><![CDATA[package events;
+import org.hibernate.Session;
+
+import java.util.Date;
+
+import util.HibernateUtil;
+
+public class EventManager {
+
+ public static void main(String[] args) {
+ EventManager mgr = new EventManager();
+
+ if (args[0].equals("store")) {
+ mgr.createAndStoreEvent("My Event", new Date());
+ }
+
+ HibernateUtil.getSessionFactory().close();
+ }
+
+ private void createAndStoreEvent(String title, Date theDate) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+ session.beginTransaction();
+
+ Event theEvent = new Event();
+ theEvent.setTitle(title);
+ theEvent.setDate(theDate);
+
+ session.save(theEvent);
+
+ session.getTransaction().commit();
+ }
+
+}]]></programlisting>
+
+ <para>
+ 우리는 한 개의 새로운 <literal>Event</literal> 객체를 생성시키고, 그것을 Hibernate에게 건네준다.
+ Hibernate는 이제 SQL을 처리하고 데이터베이스 상에서 <literal>INSERT</literal>들을 실행시킨다.
+ -우리가 이것을 실행하기 전에 코드를 처리하는- <literal>Session</literal>과 <literal>Transaction</literal>을
+ 살펴보자.
+ </para>
+
+ <para>
+ <literal>Session</literal>은 한 개의 작업 단위이다. 지금부터 우리는 단숨함을 유지할 것이고
+ Hibernate <literal>Session</literal>과 데이터베이스 트랜잭션 사이의 일-대-일 과립형(granularity)을 가정할 것이다.
+ 실제 기반 트랜잭션 시스템으로부터 우리의 소스를 은폐시키기 위해(이 경우 통상의 JDBC이지만, 그것은 또한 JTA에도 실행된다)
+ 우리는 Hibernate <literal>Session</literal> 상에서 이용 가능한 <literal>Transaction</literal> API를
+ 사용한다.
+ </para>
+
+ <para>
+
+ <literal>sessionFactory.getCurrentSession()</literal>은 무엇을 행하는가? 먼저
+ 당신은 당신이 (<literal>HibernateUtil</literal> 덕분에 쉽게) <literal>SessionFactory</literal>을
+ 당신이 소유하고 있다면, 원하는 만큼 어디서든 여러번 그것을 호출할 수 있다.
+ <literal>getCurrentSession()</literal> 메소드는 항상 "현재의" 작업 단위를 반환한다. 우리가
+ <literal>hibernate.cfg.xml</literal> 내에서 이 매커니즘에 대한 구성 옵션을 "thread"로 전환시켰음을 기억하는가?
+ 그러므로 작업의 현재 단위는 우리의 어플리케이션을 실행시키는 현재 자바 쓰레드에 묶여 있다. 하지만
+ 이것은 전체 그림이 아니며, 당신은 또한 scope(영역), 작업 단위가 시작될 때와 작업 단위가 종료될 때를
+ 고려해야 한다.
+ </para>
+
+ <para>
+ <literal>Session</literal>은 그것이 처음으로 필요로 되고 <literal>getCurrentSession()</literal>에 대한
+ 첫 번째 호출이 이루어질 때 시작된다. 그때 그것은 Hibernate에 의해 현재의 쓰레드에 바인드 된다.
+ 커밋되든 롤백되든 간에 트랜잭션이 종료되고, Hibernate가 자동적으로 그 쓰레드로부터 <literal>Session</literal>을
+ 바인드 해제시키고 당신을 위해 세션을 닫는다. 만일 당신이 <literal>getCurrentSession()</literal>을 다시
+ 호출한다면, 당신은 새로운 <literal>Session</literal>을 얻고 새로운 작업단위를 시작할 수 있다.
+ 이 <emphasis>thread-bound</emphasis> 프로그래밍 모형은 Hibernate를 사용하는 가장 대중적인 방법이다.
+ 왜냐하면 그것은 당신의 코드를 유연하게 계층화시키는 것을 허용해주기 때문이다(트랜잭션 경계 분할 코드는
+ 데이트 접근 코드와 구별지워질 수 있는데, 우리는 이 튜토리얼의 뒷부분에서 이것을 다룰 것이다.).
+ </para>
+
+ <para>
+ 작업 영역의 단위와 관련하여, Hibernate <literal>Session</literal>은 하나 또는 여러 개의 데이터베이스
+ 오퍼레이션들을 실행시키는데 사용될 수 있는가? 위의 예제는 하나의 오퍼레이션에 한 개의 <literal>Session</literal>을
+ 사용하고 있다. 이것은 순진한 일치이며, 예제는 어떤 다른 접근법을 보여주기에는 충분히 복잡하지 않다.
+ Hibernate <literal>Session</literal>의 scope(영역)은 유연하지만 당신은 결코 <emphasis>모든</emphasis>
+ 데이터베이스 오퍼레이션 각각에 대해 새로운 Hibernate <literal>Session</literal>을 사용하도록
+ 당신의 어플리케이션을 설계할 수 없다. 따라서 심지어 당신이 다음의 (매우 사소한) 예제들에서 여러 번
+ 그것을 볼 수 있을지라도 <emphasis>session-per-operation</emphasis>을 하나의 안티-패턴으로 간주하라.
+ 실제 (웹) 어플리케이션은 이 튜토리얼의 뒷부분에 보여진다.
+ </para>
+
+ <para>
+ 트랜잭션 핸들링과 경계구분에 대한 추가 정보는 <xref linkend="transactions"/>을 살펴보라.
+ 우리는 또한 앞의 예제에서 임의의 오류 처리와 롤백을 생략했다.
+ </para>
+
+ <para>
+ 이 첫 번째 루틴을 실행하기 위해서 우리는 호출 가능한 대상을 Ant 빌드 파일에 추가해야 한다:
+ </para>
+
+ <programlisting><![CDATA[<target name="run" depends="compile">
+ <java fork="true" classname="events.EventManager" classpathref="libraries">
+ <classpath path="${targetdir}"/>
+ <arg value="${action}"/>
+ </java>
+</target>]]></programlisting>
+
+ <para>
+ <literal>action</literal> 아규먼트의 값은 대상을 호출할 때 명령 라인 상에서 설정된다:
+ </para>
+
+ <programlisting><![CDATA[C:\hibernateTutorial\>ant run -Daction=store]]></programlisting>
+
+ <para>
+ 컴파일, 구성에 따른 Hibernate 시작 후에, 당신은 많은 로그 출력을 보게 될 것이다. 끝에서 당신은
+ 다음 라인을 발견할 것이다:
+ </para>
+
+ <programlisting><![CDATA[[java] Hibernate: insert into EVENTS (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)]]></programlisting>
+
+ <para>
+ 이것은 Hibernate에 의해 실행된 <literal>INSERT</literal>이고, 물음표 기호는 JDBC 바인드
+ 파라미터들을 나타낸다. 아규먼트로서 바인드 된 값들을 보거나 장황한 로그를 줄이려면 당신의
+ <literal>log4j.properties</literal>를 체크하라.
+ </para>
+
+ <para>
+ 이제 우리는 마찬가지로 저장된 이벤트들을 열거하고자 원하며, 우리는 main 메소드에 한 개의 옵션을
+ 추가한다:
+ </para>
+
+ <programlisting><![CDATA[if (args[0].equals("store")) {
+ mgr.createAndStoreEvent("My Event", new Date());
+}
+else if (args[0].equals("list")) {
+ List events = mgr.listEvents();
+ for (int i = 0; i < events.size(); i++) {
+ Event theEvent = (Event) events.get(i);
+ System.out.println("Event: " + theEvent.getTitle() +
+ " Time: " + theEvent.getDate());
+ }
+}]]></programlisting>
+
+ <para>
+ 우리는 또한 새로운 <literal>listEvents() method</literal> 메소드를 추가 시킨다:
+ </para>
+
+ <programlisting><![CDATA[private List listEvents() {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+ session.beginTransaction();
+
+ List result = session.createQuery("from Event").list();
+
+ session.getTransaction().commit();
+
+ return result;
+}]]></programlisting>
+
+ <para>
+ 여기서 우리가 행할 것은 데이터베이스로부터 모든 존재하는 <literal>Event</literal> 객체들을 로드시키기
+ 위해 HQL (Hibernate Query Language) 질의를 사용하는 것이다. Hibernate는 적절한 SQL을 생성시킬
+ 것이고, 그것을 데이터베이스로 전송하고 데이터를 <literal>Event</literal> 객체들에 거주시킬 것이다.
+ 당신은 물론 HQL로서 보다 복잡한 질의들을 생성시킬 수 있다.
+ </para>
+
+ <para>
+ 이제 이 모든 것을 실행하고 테스트하기 위해, 다음 단계들을 따르라:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ 데이터베이스 속으로 어떤 것을 저장하고 물론 앞서 hbm2ddl을 통해 데이터베이스 스키마를 산출시키기 위해
+ <literal>ant run -Daction=store</literal>를 실행하라.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 이제 당신의 <literal>hibernate.cfg.xml</literal> 파일 속에서 그 프로퍼티를 주석처리함으로써 hbm2ddl을
+ 사용불가능하게 하라. 대개 당신은 지속되는 단위 테스팅에서는 그것을 사용 가능하게 내버려두어도 되지만, 또 다른
+ hbm2ddl의 실행은 당신이 저장했던 모든 것을 <emphasis>drop</emphasis>시킬 것이다 - <literal>create</literal>
+ 구성 설정은 실제로 "스키마로부터 모든 테이블들을 드롭시키고 나서, SessionFactory가 빌드될 때 모든 테이블들을
+ 다시 생성시키는 것"으로 변환된다.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 만일 당신이 지금 <literal>-Daction=list</literal>로 Ant를 호출할 경우, 당신은 당신이 지금까지 저장했던 이벤트들을
+ 보게 될 것이다. 물론 당신은 또한 여러 번 <literal>store</literal> 액션을 호출할 수 있다.
+ </para>
+
+ <para>
+ 노트 : 대부분의 Hibernate 사용자들은 이 지점에서 실패하고 우리는 정기적으로 <emphasis>Table not found</emphasis>
+ 오류 메시지들에 관한 질문을 받는다. 하지만 만일 당신이 위에 조명된 단게들을 따를 경우 당신은 이 문제를 겪지 않을 것이고,
+ hbm2ddl이 처음 실행 시에 데이터베이스 스키마를 생성시키므로, 차후의 어플리케이션 재시작은 이 스키마를 사용할 것이다.
+ 만일 당신이 매핑 그리고/또는 데이터베이스 스키마를 변경할 경우에, 당신은 다시 한번 더 hbm2ddl을 이용 가능하도록 해야 한다.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="tutorial-associations">
+ <title>파트 2 - 연관들을 매핑하기</title>
+
+ <para>
+ 우리는 한 개의 영속 엔티티 클래스를 한 개의 테이블로 매핑했다. 이것 위에서 빌드하고 몇몇 클래스 연관들을 추가시키자. 먼저
+ 우리는 우리의 어플리케이션에 사람들을 추가하고 그들이 참여하는 이벤트들의 목록을 저장할 것이다.
+ </para>
+
+ <sect2 id="tutorial-associations-mappinguser" revision="1">
+ <title>Person 클래스 매핑하기</title>
+
+ <para>
+ 클래스의 첫 번째 장면은 간단하다:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+public class Person {
+
+ private Long id;
+ private int age;
+ private String firstname;
+ private String lastname;
+
+ public Person() {}
+
+ // Accessor methods for all properties, private setter for 'id'
+
+}]]></programlisting>
+
+ <para>
+ <literal>Person.hbm.xml</literal>로 명명되는 새로운 매핑 파일을 생성시켜라
+ (맨위에 DTD 참조를 잊지말라):
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="native"/>
+ </id>
+ <property name="age"/>
+ <property name="firstname"/>
+ <property name="lastname"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ 마지막으로 새로운 매핑을 Hibernate의 구성에 추가하라:
+ </para>
+
+ <programlisting><![CDATA[<mapping resource="events/Event.hbm.xml"/>
+<mapping resource="events/Person.hbm.xml"/>]]></programlisting>
+
+ <para>
+ 이제 우리는 이들 두 개의 엔티티들 사이에 한 개의 연관을 생성시킬 것이다. 명백하게, 개인들은 이벤트들에
+ 참여할 수 있고, 이벤트들은 참여자들을 갖는다. 우리가 다루어야 하는 설계 질문들은 다음과 같다 :
+ 방향성(directionality), 다중성(multiplicity), 그리고 콜렉션 특징.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-unidirset" revision="3">
+ <title>단방향 Set-기반의 연관</title>
+
+ <para>
+ 우리는 <literal>Person</literal> 클래스에 이벤트들을 가진 한 개의 콜렉션을 추가할 것이다. 그 방법으로 우리는
+ 명시적인 질의-<literal>aPerson.getEvents()</literal>를 호출함으로써-를 실행시키지 않고서 특정 개인에 대한
+ 이벤트들을 쉽게 네비게이트할 수 있다. 우리는 하나의 Java 콜렉션, 하나의 <literal>Set</literal>를 사용한다. 왜냐하면
+ 그 콜렉션은 중복 요소들을 포함하기 않을 것이고 그 순서가 우리와 관련되어 있지 않기 때문이다.
+ </para>
+
+ <para>
+ 우리는 하나의 <literal>Set</literal>으로 구현된, 하나의 단방향, 다중값 연관들을 필요로 한다. Java 클래스들 내에
+ 이를 위한 코드를 작성하고 그런 다음 그것을 매핑시키자:
+ </para>
+
+ <programlisting><![CDATA[public class Person {
+
+ private Set events = new HashSet();
+
+ public Set getEvents() {
+ return events;
+ }
+
+ public void setEvents(Set events) {
+ this.events = events;
+ }
+}]]></programlisting>
+
+ <para>
+ 우리가 이 연관을 매핑하기 전에, 다른 측에 대해 생각하라. 명백하게 우리는 이것을 단지 단방향으로 유지시킬 수 있다.
+ 또는 우리가 그것을 양방향으로 네비게이트하는 것-예를 들어 <literal>anEvent.getParticipants()</literal>-이
+ 가능하도록 원할 경우에, <literal>Event</literal>측 상에 또 다른 콜렉션을 생성시킬 수 있다. 이것은 당신에게
+ 남겨진 설계 선택이지만, 이 논의에서 명료한 점은 연관의 다중성이다: 양 측 상에서 "다중" 값을 갖는 경우, 우리는 이것을
+ <emphasis>many-to-many</emphasis> 연관이라고 명명한다. 그러므로 우리는 Hibernate의 many-to-many 매핑을
+ 사용한다:
+ </para>
+
+ <programlisting><![CDATA[<class name="events.Person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="native"/>
+ </id>
+ <property name="age"/>
+ <property name="firstname"/>
+ <property name="lastname"/>
+
+ <set name="events" table="PERSON_EVENT">
+ <key column="PERSON_ID"/>
+ <many-to-many column="EVENT_ID" class="events.Event"/>
+ </set>
+
+</class>]]></programlisting>
+
+ <para>
+ Hibernate는 모든 종류의 콜렉션 매핑들, 가장 공통적인 <literal><set></literal>을 지원한다. many-to-many
+ 연관 (또는 <emphasis>n:m</emphasis> 엔티티 관계)의 경우, 한 개의 연관 테이블이 필요하다. 이 테이블 내에 있는 각각의
+ 행은 한 명의 개인과 한 개의 이벤트 사이의 링크를 표현한다. 테이블 이름은 <literal>set</literal> 요소의 <literal>table</literal>
+ 속성으로 구성된다. 연관 내의 식별자 컬럼 이름은 개인 측에 대해 <literal><key></literal> 요소로 정의되고
+ 이벤트 측에 대한 컬럼 이름은 <literal><many-to-many></literal>의 <literal>column</literal> 속성으로
+ 정의된다. 당신은 또한 당신의 콜렉션 내에 있는 객체들의 클래스(정확하게 : 참조들을 가진 콜렉션의 다른 측 상에 있는 클래스)를
+ Hibernate에게 알려주어야 한다.
+ </para>
+
+ <para>
+ 따라서 이 매핑을 위한 데이터베이스 스키마는 다음과 같다:
+ </para>
+
+ <programlisting><![CDATA[
+ _____________ __________________
+ | | | | _____________
+ | EVENTS | | PERSON_EVENT | | |
+ |_____________| |__________________| | PERSON |
+ | | | | |_____________|
+ | *EVENT_ID | <--> | *EVENT_ID | | |
+ | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID |
+ | TITLE | |__________________| | AGE |
+ |_____________| | FIRSTNAME |
+ | LASTNAME |
+ |_____________|
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-working" revision="2">
+ <title>연관들에 작업하기</title>
+
+ <para>
+ <literal>EventManager</literal> 속에 있는 한 개의 새로운 메소드 내에 몇몇 사람들과 이벤트들을 함께 가져오자:
+ </para>
+
+ <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session.load(Person.class, personId);
+ Event anEvent = (Event) session.load(Event.class, eventId);
+
+ aPerson.getEvents().add(anEvent);
+
+ session.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ <literal>Person</literal>과 <literal>Event</literal>를 로드시킨 후에, 정규 콜렉션 메소드들을 사용하여
+ 콜렉션을 간단하게 변경하라. 당신이 알 수 있듯이, <literal>update()</literal> 또는 <literal>save()</literal>에
+ 대한 명시적인 호출이 존재하지 않고, 변경되었고 저장할 필요가 있는 콜렉션을 Hibernate가 자동적으로 검출해낸다. 이것은
+ <emphasis>자동적인 dirty 체킹</emphasis>이라 불려지며, 당신은 또한 당신의 임의의 객체들에 대한 name 또는 date
+ 프로퍼티를 변경함으로써 그것을 시도할 수 있다. 그것들이 <emphasis>영속(persistent)</emphasis> 상태에 있는 동안, 즉 특정 Hibernate
+ <literal>Session</literal>에 바인드되어 있는 동안(예를 들면. 그것들은 작업 단위 속에 방금 로드되었거나 저장되었다),
+ Hibernate는 임의의 변경들을 모니터링하고 쓰기 이면의 형태로 SQL을 실행시킨다. 메모리 상태를 데이터베이스와 동기화 시키는
+ 과정은 대개 오직 작업 단위의 끝에서이고, <emphasis>flushing</emphasis>이라 명명된다. 우리의 코드에서, 작업 단위는
+ <literal>CurrentSessionContext</literal> 클래스에 대한 <literal>thread</literal> 구성 옵션에 의해 정의된
+ 대로 - 데이터베이스 트랜잭션의 커밋(또는 롤백)으로 끝이난다.
+ </para>
+
+ <para>
+ 물론 당신은 다른 작업 단위 속에 개인과 이벤트를 로드시킬 수 도 있다. 또는 당신은 하나의 객체그 영속 상태에 있지 않을 때
+ <literal>Session</literal>의 외부에서 객체를 변경시킬 수도 있다(만일 객체가 이전에 영속화 되었다면, 우리는 이 상태를
+ <emphasis>detached</emphasis>라고 부른다). (매우 사실적이지 않은) 코드 내에서 이것은 다음과 같을 수 있다:
+ </para>
+
+ <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session
+ .createQuery("select p from Person p left join fetch p.events where p.id = :pid")
+ .setParameter("pid", personId)
+ .uniqueResult(); // Eager fetch the collection so we can use it detached
+
+ Event anEvent = (Event) session.load(Event.class, eventId);
+
+ session.getTransaction().commit();
+
+ // End of first unit of work
+
+ aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached
+
+ // Begin second unit of work
+
+ Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
+ session2.beginTransaction();
+
+ session2.update(aPerson); // Reattachment of aPerson
+
+ session2.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ <literal>update</literal>에 대한 호출은 한 개의 detached 객체를 다시 영속화 시키고, 당신은 그것이 새로운 작업 단위에
+ 바인드된다고 말할 수 있고, 따라서 detached 동안에 당신이 그것에 대해 행한 임의의 변경들이 데이터베이스에 저장될 수 있다.
+ 이것은 당신이 그 엔티티 객체의 콜렉션에 대해 행했던 임의의 변경들(추가/삭제)를 포함한다.
+ </para>
+
+ <para>
+ 물론, 우리의 현재 상황에서 이것은 많이 사용되지 않지만, 그것은 당신이 당신 자신의 어플리케이션 내로 설계할 수 있는 중요한
+ 개념이다. 지금 <literal>EventManager</literal>의 main 메소드에 한 개의 새로운 액션을 추가하고 명령 라인에서 그것을
+ 호출하여 이 연습을 완료하라. 만일 당신이 한명의 개인과 한 개의 이벤트에 대한 식별자들을 필요로 할 경우 - <literal>save()</literal>
+ 메소드가 그것을 반환시킨다(당신은 그 식별자를 반환시키는 앞의 메소드들 중 몇몇을 변경시켜야 할 것이다):
+ </para>
+
+ <programlisting><![CDATA[else if (args[0].equals("addpersontoevent")) {
+ Long eventId = mgr.createAndStoreEvent("My Event", new Date());
+ Long personId = mgr.createAndStorePerson("Foo", "Bar");
+ mgr.addPersonToEvent(personId, eventId);
+ System.out.println("Added person " + personId + " to event " + eventId);
+}]]></programlisting>
+
+ <para>
+ 이것은 두 개의 동등하게 중요한 클래스들, 두 개의 엔티티들 사이에서 한 개의 연관에 관한 예제였다. 앞서 언급했듯이, 전형적인 모형 내에는
+ 다른 클래스들과 타이들이 존재하는데, 대개 "덜 중요하다". 당신은 이미 <literal>int</literal> 또는 <literal>String</literal>과
+ 같은 어떤 것을 이미 보았다. 우리는 이들 클래스들을 <emphasis>값 타입들(value types)</emphasis>이라 명명하고, 그들 인스턴스들은
+ 특정 엔티티에 <emphasis>의존한다(depend)</emphasis>. 이들 타입들을 가진 인스턴스들은 그것들 자신의 식별성(identity)를 갖지 않거나,
+ 그것들은 엔티티들 사이에서 공유되지도 않는다(두개의 person들은 심지어 그것들이 같은 첫 번째 이름을 갖는 경우에도 동일한 <literal>firstname</literal>을
+ 참조하지 않는다 ). 물론 값 타입들은 JDK 내에서 발견될 뿐만 아니라(사실, Hibernate 어플리케이션에서 모든 JDK 클래스들은 값 타입들로 간주된다),
+ 당신은 또한 당신 스스로 종속 클래스들, 예를 들면 <literal>Address</literal> 또는 <literal>MonetaryAmount</literal>을 작성할 수 있다.
+ </para>
+
+ <para>
+ 당신은 또한 값 타입들을 설계할 수 있다. 이것은 다른 엔티티들에 대한 참조들을 가진 콜렉션과는 개념적으로 매우 다르지만,
+ Java에서는 대개 동일한 것으로 보여진다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-valuecollections">
+ <title>값들을 가진 콜렉션</title>
+
+ <para>
+ 우리는 값 타입의 객체들을 가진 한 개의 콜렉션을 <literal>Person</literal> 엔티티에 추가시킨다. 우리는 email 주소를
+ 저장하고자 원하므로, 우리가 사용하는 타입은 <literal>String</literal>이고, 그 콜렉션은 다시 한 개의 <literal>Set</literal>이다:
+ </para>
+ <programlisting><![CDATA[private Set emailAddresses = new HashSet();
+
+public Set getEmailAddresses() {
+ return emailAddresses;
+}
+
+public void setEmailAddresses(Set emailAddresses) {
+ this.emailAddresses = emailAddresses;
+}]]></programlisting>
+
+ <para>
+ 이 <literal>Set</literal>에 대한 매핑은 다음과 같다:
+ </para>
+
+ <programlisting><![CDATA[<set name="emailAddresses" table="PERSON_EMAIL_ADDR">
+ <key column="PERSON_ID"/>
+ <element type="string" column="EMAIL_ADDR"/>
+</set>]]></programlisting>
+
+ <para>
+ 앞의 매핑과 비교한 차이점은 <literal>element</literal> 부분인데, 그것은 그 콜렉션이 또 다른 엔티티에 대한
+ 참조들을 포함하지 않을 것이지만 <literal>String</literal>(소문자 이름은 그것이 Hibernate 매핑 타입/변환자임을
+ 당신에게 말해준다) 타입의 요소들을 가진 한 개의 콜렉션을 포함할 것임을 Hibernate에게 알려준다. 일단 다시 <literal>set</literal>
+ 요소의 <literal>table</literal> 속성은 그 콜렉션에 대한 테이블 이름을 결정한다. <literal>key</literal> 요소는
+ 콜렉션 테이블 내에서 foreign-key 컬럼 이름을 정의한다. <literal>element</literal> 요소 내에 있는 <literal>column</literal>
+ 속성은 <literal>String</literal> 값들이 실제로 저장될 컬럼 이름을 정의한다.
+ </para>
+
+ <para>
+ 업데이트된 스키마를 살펴보라:
+ </para>
+
+ <programlisting><![CDATA[
+ _____________ __________________
+ | | | | _____________
+ | EVENTS | | PERSON_EVENT | | | ___________________
+ |_____________| |__________________| | PERSON | | |
+ | | | | |_____________| | PERSON_EMAIL_ADDR |
+ | *EVENT_ID | <--> | *EVENT_ID | | | |___________________|
+ | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID | <--> | *PERSON_ID |
+ | TITLE | |__________________| | AGE | | *EMAIL_ADDR |
+ |_____________| | FIRSTNAME | |___________________|
+ | LASTNAME |
+ |_____________|
+ ]]></programlisting>
+
+ <para>
+ 당신은 콜렉션 테이블의 프라이머리 키가 사실은 두 컬럼들을 사용하는 한 개의 합성 키(composite key)임을 알 수 있다.
+ 이것은 또한 개인에 대해 email 주소가 중복될 수 없음을 의미하며, 그것은 정확하게 우리가 Java에서 set을 필요로 하는
+ 의미론이다.
+ </para>
+
+ <para>
+ 마치 개인들과 이벤트들을 링크시켜서 이전에 우리가 행했던 것처럼 이제 당신은 요소들을 시도하고 이 콜렉션에 추가할 수 있다.
+ 그것은 Java에서 동일한 코드이다.
+ </para>
+
+ <programlisting><![CDATA[private void addEmailToPerson(Long personId, String emailAddress) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session.load(Person.class, personId);
+
+ // The getEmailAddresses() might trigger a lazy load of the collection
+ aPerson.getEmailAddresses().add(emailAddress);
+
+ session.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ 지금 우리는 콜렉션을 초기화 시키는데 <emphasis>fetch</emphasis> 질의를 사용하지 않았다.
+ 그러므로 콜렉션의 getter 메소드에 대한 호출은 콜렉션을 초기화 시키기 위해 추가적인 select를 트리거 시킬
+ 것이어서, 우리는 그것에 요소를 추가시킬 수 있다. SQL 로그를 관찰하고 이것을 eager fetch로 최적화 시키려고
+ 시도하라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-bidirectional" revision="1">
+ <title>Bi-directional associations</title>
+
+ <para>
+ 다음으로 우리는 양방향 연관을 매핑시킬 예정이다-개인과 이벤트 사이에 연관을 만드는 것은 Java에서 양 측들에서 동작한다.
+ 물론 데이터베이스 스키마는 변경되지 않고, 우리는 여전히 many-to-many 다중성을 갖는다. 관계형 데이터베이스는
+ 네트웍 프로그래밍 언어 보다 훨씬 더 유연하여서, 그것은 네비게이션 방향과 같은 어떤 것을 필요로 하지 않는다 - 데이터는
+ 어떤 가능한 바업ㅂ으로 보여질 수 있고 검색될 수 있다.
+ </para>
+
+ <para>
+ 먼저, 참여자들을 가진 한 개의 콜렉션을 <literal>Event</literal> Event 클래스에 추가시켜라:
+ </para>
+
+ <programlisting><![CDATA[private Set participants = new HashSet();
+
+public Set getParticipants() {
+ return participants;
+}
+
+public void setParticipants(Set participants) {
+ this.participants = participants;
+}]]></programlisting>
+
+ <para>
+ 이제 <literal>Event.hbm.xml</literal> 내에 연관의 이 쪽도 매핑하라.
+ </para>
+
+ <programlisting><![CDATA[<set name="participants" table="PERSON_EVENT" inverse="true">
+ <key column="EVENT_ID"/>
+ <many-to-many column="PERSON_ID" class="events.Person"/>
+</set>]]></programlisting>
+
+ <para>
+ 당신이 볼 수 있듯이, 이것들은 두 매핑 문서들 내에서 정규 <literal>set</literal> 매핑들이다. <literal>key</literal>와
+ <literal>many-to-many</literal>에서 컬럼 이름들은 두 매핑 문서들에서 바뀌어진다. 여기서 가장 중요한 부가물은
+ <literal>Event</literal>의 콜렉션 매핑에 관한 <literal>set</literal> 요소 내에 있는 <literal>inverse="true"</literal>
+ 속성이다.
+ </para>
+
+ <para>
+ 이것이 의미하는 바는 Hibernate가 둘 사이의 링크에 대한 정보를 알 필요가 있을 때 다른 측-<literal>Person</literal> 클래스-를 취할
+ 것이라는 점이다. 일단 당신이 우리의 두 엔티티들 사이에 양방향 링크가 생성되는 방법을 안다면 이것은 이해하기가 훨씬 더 쉬울 것이다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-usingbidir">
+ <title>양방향 링크들에 작업하기</title>
+
+ <para>
+ 첫 번째로 Hibernate가 정규 Java 의미론에 영향을 주지 않음을 염두에 두라. 우리는 단방향 예제에서 <literal>Person</literal>과
+ <literal>Event</literal> 사이에 어떻게 한 개의 링크를 생성시켰는가? 우리는 <literal>Event</literal> 타입의 인스턴스를
+ <literal>Person</literal> 타입의 이벤트 참조들을 가진 콜렉션에 추가시켰다. 따라서 명백하게 우리가 이 링크를 양방향으로
+ 동작하도록 만들고자 원한다면, 우리는 다른 측 상에서 -하나의 <literal>Person</literal> 참조를 하나의 <literal>Event</literal>
+ 내에 있는 콜렉션에 추가시킴으로써- 동일한 것을 행해야 한다. 이 "양 측 상에 링크 설정하기"는 절대적으로 필수적이고 당신은 그것을 행하는
+ 것을 결코 잊지 말아야 한다.
+ </para>
+
+ <para>
+ 많은 개발자들은 방비책을 프로그램하고 양 측들을 정확하게 설정하기 위한 하나의 링크 관리 메소드들을 생성시킨다. 예를 들면 <literal>Person</literal>에서 :
+ </para>
+
+ <programlisting><![CDATA[protected Set getEvents() {
+ return events;
+}
+
+protected void setEvents(Set events) {
+ this.events = events;
+}
+
+public void addToEvent(Event event) {
+ this.getEvents().add(event);
+ event.getParticipants().add(this);
+}
+
+public void removeFromEvent(Event event) {
+ this.getEvents().remove(event);
+ event.getParticipants().remove(this);
+}]]></programlisting>
+
+ <para>
+ 콜렉션에 대한 get 및 set 메소드드은 이제 protected임을 인지하라 - 이것은 동일한 패키지 내에 있는 클래스들과 서브클래스들이
+ 그 메소드들에 접근하는 것을 허용해주지만, 그 밖의 모든 것들이 그 콜렉션들을 (물론, 대개) 직접 만지는 것을 금지시킨다. 당신은
+ 다른 측 상에 있는 콜렉션에 대해 동일한 것을 행할 것이다.
+ </para>
+
+ <para>
+ <literal>inverse</literal> 매핑 속성은 무엇인가? 당신의 경우, 그리고 Java의 경우, 한 개의 양방향 링크는 단순히 양 측들에 대한
+ 참조들을 정확하게 설정하는 문제이다. 하지만 Hibernate는 (컨스트레인트 위배를 피하기 위해서) SQL <literal>INSERT</literal> 문장과
+ <literal>UPDATE</literal> 문장을 정확하게 마련하기에 충분한 정보를 갖고 있지 않으며, 양방향 연관들을 올바르게 처리하기 위해
+ 어떤 도움을 필요로 한다. 연관의 한 측을 <literal>inverse</literal>로 만드는 것은 기본적으로 그것을 무시하고 그것을 다른 측의
+ <emphasis>거울(mirror)</emphasis>로 간주하도록 Hibernate에게 알려준다. 그것은 Hibernate가 하나의 방향성 네비게이션 모형을
+ 한 개의 SQL 스키마로 변환시킬 때 모든 쟁점들을 잘 해결하는데 필수적인 모든 것이다. 당신이 염두에 두어야 하는 규칙들은 간단하다 :
+ 모든 양방향 연관들은 한 쪽이 <literal>inverse</literal>일 필요가 있다. one-to-many 연관에서 그것은 many-측이어야 하고,
+ many-to-many 연관에서 당신은 어느 측이든 선택할 수 있으며 차이점은 없다.
+ </para>
+
+ </sect2>
+
+ <para>
+ Let's turn this into a small web application.
+ </para>
+
+ </sect1>
+
+ <sect1 id="tutorial-webapp">
+ <title>파트 3 - EventManager 웹 어플리케이션</title>
+
+ <para>
+ Hibernate 웹 어플리케이션은 대부분의 스탠드얼론 어플리케이션과 같이 <literal>Session</literal>과
+ <literal>Transaction</literal>을 사용한다. 하지만 몇몇 공통 패턴들이 유용하다. 우리는 이제
+ <literal>EventManagerServlet</literal>를 작성한다. 이 서블릿은 데이터베이스 내에 저장된 모든 이벤트들을 나열할 수 있고,
+ 그것은 새로운 이벤트들을 입력하기 위한 HTML form을 제공한다.
+ </para>
+
+ <sect2 id="tutorial-webapp-servlet" revision="2">
+ <title>기본 서블릿 작성하기</title>
+
+ <para>
+ 다음 장에서 우리는 Hibernate를 Tomcat 및 WebWork와 통합시킨다. <literal>EventManager</literal>는 우리의 성장하는
+ 어플리케이션을 더이상 감당하지 못한다.
+ 당신의 소스 디렉토리에서 <literal>events</literal> 패키지 내에 새로운 클래스를 생성시켜라:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+// Imports
+
+public class EventManagerServlet extends HttpServlet {
+
+ // Servlet code
+}]]></programlisting>
+
+ <para>
+ 서블릿은 HTTP <literal>GET</literal> 요청들 만을 처리하므로, 우리가 구현하는 메소드는 <literal>doGet()</literal>이다:
+ </para>
+
+ <programlisting><![CDATA[protected void doGet(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+
+ SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");
+
+ try {
+ // Begin unit of work
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().beginTransaction();
+
+ // Process request and render page...
+
+ // End unit of work
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().getTransaction().commit();
+
+ } catch (Exception ex) {
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().getTransaction().rollback();
+ throw new ServletException(ex);
+ }
+
+}]]></programlisting>
+
+ <para>
+ 우리가 여기서 적용하는 패턴은 <emphasis>session-per-request</emphasis>이다. 하나의 요청이
+ 서블릿에 도달할 때, 하나의 새로운 Hibernate <literal>Session</literal>이
+ <literal>SessionFactory</literal> 상의 <literal>getCurrentSession()</literal>에 대한
+ 첫번째 호출을 통해 열린다. 그때 하나의 데이터베이스 트랜잭션이 시작되고, 모든 데이터 접근이 하나의 트랜잭션
+ 내에서 발생하는 한, 데이터가 읽혀지거나 기록되는데 문제가 없다(우리는 어플리케이션들 내에서 auto-commit 모드를
+ 사용하지 않는다).
+ </para>
+
+ <para>
+ 모든 데이터베이스 오퍼레이션 각각에 대해 새로운 Hibernate <literal>Session</literal>을 사용하지 <emphasis>말라</emphasis>.
+ 전체 요청에 대해 영역지워진 한 개의 Hibernate <literal>Session</literal>을 사용하라. 그것이 자동적으로 현재의 자바 쓰레드에 바인드되도록
+ <literal>getCurrentSession()</literal>을 사용하라.
+ </para>
+
+ <para>
+ 다음으로, 요청의 가능한 액션들이 처리되고 응답 HTML이 렌더링된다. 우리는 곧장 그부분으로 갈 것이다.
+ </para>
+
+ <para>
+ 마지막으로, 프로세싱과 렌더링이 완료될 때 작업 단위가 종료된다. 만일 어떤 문제가 프로세싱과 렌더링 동안에 발생될 경우,
+ 하나의 예외상황이 던져질 것이고 데이터베이스 트랜잭션은 롤백될 것이다. 이것은 <literal>session-per-request</literal>을
+ 완료시킨다. 모든 서블릿 내에 있는 트랜잭션 구획 코드 대신에 당신은 또한 서블릿 필터를 사용할 수 있다.
+ <emphasis>Open Session in View</emphasis>로 명명되는 이 패턴에 대한 추가 정보는 Hibernate 웹 사이트와 위키를 보라.
+ 당신은 서블릿 내에서가 아닌 JSP 내에 당신의 뷰를 렌더링하는 것을 고려할 때 그것을 필요로 할 것이다.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-webapp-processing" revision="1">
+ <title>프로세싱과 렌더링</title>
+
+ <para>
+ 요청의 처리와 페이지의 렌더링을 구현하자.
+ </para>
+
+<programlisting><![CDATA[// Write HTML header
+PrintWriter out = response.getWriter();
+out.println("<html><head><title>Event Manager</title></head><body>");
+
+// Handle actions
+if ( "store".equals(request.getParameter("action")) ) {
+
+ String eventTitle = request.getParameter("eventTitle");
+ String eventDate = request.getParameter("eventDate");
+
+ if ( "".equals(eventTitle) || "".equals(eventDate) ) {
+ out.println("<b><i>Please enter event title and date.</i></b>");
+ } else {
+ createAndStoreEvent(eventTitle, dateFormatter.parse(eventDate));
+ out.println("<b><i>Added event.</i></b>");
+ }
+}
+
+// Print page
+printEventForm(out);
+listEvents(out, dateFormatter);
+
+// Write HTML footer
+out.println("</body></html>");
+out.flush();
+out.close();]]></programlisting>
+
+ <para>
+ Java와 HTML이 혼합된 이 코딩이 보다 복잡한 어플리케이션에서 기준이 될 수 없다 할지라도, 우리는
+ 단지 이 튜토리얼 내에서 기본 Hibernate 개념들을 설명하고 있음을 염두에 두라. 코드는
+ 하나의 HTML 헤더와 하나의 footer를 프린트한다. 이 페이지 내에 이벤트 엔트리를 위한
+ 하나의 HTML form과 데이터베이스 내에 있는 모든 이벤트들의 목록이 프린트된다. 첫 번째 메소드는
+ 시행적이고 오직 HTML을 출력한다:
+ </para>
+
+ <programlisting><![CDATA[private void printEventForm(PrintWriter out) {
+ out.println("<h2>Add new event:</h2>");
+ out.println("<form>");
+ out.println("Title: <input name='eventTitle' length='50'/><br/>");
+ out.println("Date (e.g. 24.12.2009): <input name='eventDate' length='10'/><br/>");
+ out.println("<input type='submit' name='action' value='store'/>");
+ out.println("</form>");
+}]]></programlisting>
+
+ <para>
+ <literal>listEvents()</literal> 메소드는 하나의 질의를 실행하기 위해서 현재의
+ 쓰레드에 결합된 Hibernate <literal>Session</literal>을 사용한다:
+ </para>
+
+ <programlisting><![CDATA[private void listEvents(PrintWriter out, SimpleDateFormat dateFormatter) {
+
+ List result = HibernateUtil.getSessionFactory()
+ .getCurrentSession().createCriteria(Event.class).list();
+ if (result.size() > 0) {
+ out.println("<h2>Events in database:</h2>");
+ out.println("<table border='1'>");
+ out.println("<tr>");
+ out.println("<th>Event title</th>");
+ out.println("<th>Event date</th>");
+ out.println("</tr>");
+ for (Iterator it = result.iterator(); it.hasNext();) {
+ Event event = (Event) it.next();
+ out.println("<tr>");
+ out.println("<td>" + event.getTitle() + "</td>");
+ out.println("<td>" + dateFormatter.format(event.getDate()) + "</td>");
+ out.println("</tr>");
+ }
+ out.println("</table>");
+ }
+}]]></programlisting>
+
+ <para>
+ 마지막으로, <literal>store</literal> 액션은 <literal>createAndStoreEvent()</literal>
+ 메소드로 디스패치된다. 그것은 현재 쓰레드의 <literal>Session</literal>을 사용한다:
+ </para>
+
+ <programlisting><![CDATA[protected void createAndStoreEvent(String title, Date theDate) {
+ Event theEvent = new Event();
+ theEvent.setTitle(title);
+ theEvent.setDate(theDate);
+
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().save(theEvent);
+}]]></programlisting>
+
+ <para>
+ 즉 서블릿이 완성된다. 서블릿에 대한 요청은 하나의 단일 <literal>Session</literal>과
+ <literal>Transaction</literal> 내에서 처리될 것이다. 이전처럼 스탠드얼론 어플리케이션에서,
+ Hibernate는 이들 객체들을 실행 중인 현재 쓰레드에 자동적으로 바인드시킬 수 있다. 이것은 당신의 코드를
+ 계층화 시키고 당신이 좋아하는 임의의 방법으로 <literal>SessionFactory</literal>에 접근하는 자유를
+ 당신에게 부여한다. 대개 당신은 보다 세련된 설계를 사용할 것이고 데이터 접근 코드를 데이터 접근 객체들 내로
+ 이동시킬 것이다(DAO 패턴). 추가 예제들은 Hibernate 위키를 보라.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-webapp-deploy">
+ <title>배치하기 그리고 테스트하기</title>
+
+ <para>
+ 이 어플리케이션을 배치하기 위해서 당신은 하나의 웹 아카이브, WAR를 생성시켜야 한다. 다음 Ant target을
+ 당신의 <literal>build.xml</literal> 내에 추가하라:
+ </para>
+
+<programlisting><![CDATA[<target name="war" depends="compile">
+ <war destfile="hibernate-tutorial.war" webxml="web.xml">
+ <lib dir="${librarydir}">
+ <exclude name="jsdk*.jar"/>
+ </lib>
+
+ <classes dir="${targetdir}"/>
+ </war>
+</target>]]></programlisting>
+
+ <para>
+ 이 target은 당신의 프로젝트 디렉토리 내에 <literal>hibernate-tutorial.war</literal>로 명명된
+ 하나의 파일을 생성시킨다. 그것은 당신의 프로젝트의 기본 디렉토리 내에 기대되는 모든 라이브러리들과
+ <literal>web.xml</literal> 디스크립터를 패키징한다:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4"
+ xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+ <servlet>
+ <servlet-name>Event Manager</servlet-name>
+ <servlet-class>events.EventManagerServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Event Manager</servlet-name>
+ <url-pattern>/eventmanager</url-pattern>
+ </servlet-mapping>
+</web-app>]]></programlisting>
+
+ <para>
+ 당신이 웹 어플리케이션을 컴파일하고 배치하기 전에, 하나의 부가적인 라이브러리가 필요함을 노트하라:
+ <literal>jsdk.jar</literal>. 당신이 이미 이 라이브러리를 갖고 있지 않을 경우, 이것은 Java servlet
+ development kit이며, Sun 웹 사이트로부터 그것을 얻어서 그것을 당신의 라이브러리 디렉토리에 복사하라.
+ 하지만 그것은 오직 컴파일 시에만 사용될 것이고 WAR 패키지에서는 제외된다.
+ </para>
+
+ <para>
+ 빌드하고 배치하기 위해 당신의 프로젝트 디렉토리 내에서 <literal>ant war</literal>를 호출하고
+ <literal>hibernate-tutorial.war</literal> 파일을 당신의 Tomcat <literal>webapp</literal>
+ 디렉토리로 복사하라. 만일 당신이 Tomcat을 설치하지 않았다면, 그것을 내려받아 설치 지침들을 따르라. 당신은
+ 이 어플리케이션을 배치하기 위해 임의의 Tomcat 구성을 변경하지 않아야 한다.
+ </para>
+
+ <para>
+ 일단 배치했고 Tomcat이 실행중이면, <literal>http://localhost:8080/hibernate-tutorial/eventmanager</literal>로
+ 어플리케이션에 접근하라. 첫 번째 요청이 당신의 서블릿에 도달할 때 Hibernate가 초기화(<literal>HibernateUtil</literal>
+ 내에 있는 static initializer가 호출된다) 되는 것을 보기 위해 그리고 만일 어떤 예외상황들이 발생할 경우
+ 상세한 출력을 얻기 위해서 Tomcat 로그를 지켜보도록 하라.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="tutorial-summary" revision="1">
+ <title>요약</title>
+
+ <para>
+ 이 튜토리얼은 간단한 스탠드얼론 Hibernate 어플리케이션과 하나의 작은 웹 어플리케이션을 작성하는 기초를 다루었다.
+ </para>
+
+ <para>
+ 만일 당신이 이미 Hibernate에 자신이 있다고 느낀다면, 당신이 흥미를 찾는 주제들에 대한 참조 문서 목차를 계속 브라우징하라
+ - 가장 많이 요청되는 것은 트랜잭션 처리(<xref linkend="transactions"/>), 페치 퍼포먼스(<xref linkend="performance"/>),
+ 또는 API 사용법(<xref linkend="objectstate"/>), 그리고 질의 특징들(<xref linkend="objectstate-querying"/>)이다.
+ </para>
+
+ <para>
+ 더 많은(특화된) 튜토리얼들에 대해서는 Hibernate 웹 사이트를 체크하는 것을 잊지 말라.
+ </para>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/content/xml.xml (from rev 14078, core/trunk/documentation/manual/ko-KR/src/main/docbook/modules/xml.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/content/xml.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/content/xml.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,273 @@
+<chapter id="xml">
+ <title>XML 매핑</title>
+
+ <para><emphasis>
+ 이것은 Hibernate3.0에서 실험적인 특징이고 매우 활동적으로 개발 중에 있음을 노트하라.
+ </emphasis></para>
+
+ <sect1 id="xml-intro" revision="1">
+ <title>XML 데이터로 작업하기</title>
+
+ <para>
+ Hibernate는 당신이 영속 POJO들로 작업하는 것과 아주 동일한 방법으로 영속 XML 데이터에 작업하도록 해준다. 파싱된 XML 트리는
+ 단지 객체 레벨에서 관계형 데이터를 나타내는 또 다른 방법으로 간주될 수 있다. 하나의 파싱된 XML 트리는 POJO들 대신, 객체 레벨에서
+ 관계형 데이터를 표현하는 단지 또 다른 방법으로 간주될 수 있다.
+ </para>
+
+ <para>
+ Hibernate는 XML 트리들을 처리하는 API로서 dom4j를 지원한다. 당신은 데이터베이스로부터 dom4j 트리들을 검색하고 당신이 그 트리를
+ 데이터베이스와 자동적으로 동기화시키기 위해 어떤 변경을 행하도록 하는 질의들을 작성할 수 있다. 당신은 심지어 XML 문서를 취하고,
+ dom4j를 사용하여 그것을 파싱하고, Hibernate의 다음 기본적인 오퍼레이션들 중 어떤 것으로서 그것을 데이터베이스에 저장시킬 수 있다:
+ <literal>persist(), saveOrUpdate(), merge(), delete(), replicate()</literal>(merging(병합)은 아직 지원되지
+ 않는다).
+ </para>
+
+ <para>
+ 이 특징은 데이터 가져오기/내보내기,JMS 또는 SOAP 그리고 XSLT-기반의 레포팅을 통한 엔티티 데이터의 구체화를 포함하는 많은
+ 어플리케이션들을 갖는다.
+ </para>
+
+ <para>
+ 하나의 매핑은 클래스들의 프로퍼티들과 XML 문서의 노드들을 데이터베이스로 동시에 매핑시키는데 사용될 수 있거나, 만일 매핑할 클래스가
+ 존재하지 않을 경우, 그것은 단지 XML을 매핑시키는데 사용될 수도 있다.
+ </para>
+
+ <sect2 id="xml-intro-mapping">
+ <title>XML과 클래스 매핑을 함께 지정하기</title>
+
+ <para>
+ 다음은 POJO와 XML을 동시에 매핑시키는 예제이다 :
+ </para>
+
+ <programlisting><![CDATA[<class name="Account"
+ table="ACCOUNTS"
+ node="account">
+
+ <id name="accountId"
+ column="ACCOUNT_ID"
+ node="@id"/>
+
+ <many-to-one name="customer"
+ column="CUSTOMER_ID"
+ node="customer/@id"
+ embed-xml="false"/>
+
+ <property name="balance"
+ column="BALANCE"
+ node="balance"/>
+
+ ...
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="xml-onlyxml">
+ <title>XML 매핑만을 지정하기</title>
+
+ <para>
+ 다음은 POJO 클래스가 존재하지 않는 예제이다:
+ </para>
+
+ <programlisting><![CDATA[<class entity-name="Account"
+ table="ACCOUNTS"
+ node="account">
+
+ <id name="id"
+ column="ACCOUNT_ID"
+ node="@id"
+ type="string"/>
+
+ <many-to-one name="customerId"
+ column="CUSTOMER_ID"
+ node="customer/@id"
+ embed-xml="false"
+ entity-name="Customer"/>
+
+ <property name="balance"
+ column="BALANCE"
+ node="balance"
+ type="big_decimal"/>
+
+ ...
+
+</class>]]></programlisting>
+
+ <para>
+ 이 매핑은 dom4j 트리로서 또는 프로퍼티 name/value 쌍들(java <literal>Map</literal>들)의 그래프로서 데이터에
+ 접근하는 것을 당신에게 허용해준다. 프로퍼티 이름들은 HQL 질의들 내에서 참조될 수도 있는 순수하게 논리적인 구조체들이다.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="xml-mapping" revision="1">
+ <title>XML 매핑 메타데이터</title>
+
+ <para>
+ 많은 Hibernate 매핑 요소들은 <literal>node</literal> 속성을 수용한다. 이것은 당신이 프로퍼티 또는 엔티티 데이터를 소유하는
+ XML 속성이나 요소의 이름을 지정하도록 한다. <literal>node</literal> 속성의 포맷은 다음 중 하나이어야 한다:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>"element-name"</literal> - 명명된 XML 요소로 매핑시킨다</para>
+ </listitem>
+ <listitem>
+ <para><literal>"@attribute-name"</literal> - 명명된 XML 속성으로 매핑시킨다 </para>
+ </listitem>
+ <listitem>
+ <para><literal>"."</literal> - 부모 요소로 매핑 시킨다</para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>"element-name/@attribute-name"</literal> -
+ 명명된 요소의 명명된 속성으로 매핑시킨다
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 콜렉션들과 단일 값 콜렉션들의 경우, 추가적인 <literal>embed-xml</literal> 속성이 존재한다. 만일 <literal>embed-xml="true"</literal>
+ 일 경우, 연관된 엔티티(또는 value 타입을 가진 콜렉션)에 대한 디폴트 XML 트리는 그 연관을 소유하는 엔티티에 대한 XML 트리 속에
+ 직접 삽입될 것이다. 그 밖의 경우 <literal>embed-xml="false"</literal> 일 경우, 참조된 식별자 값 만이 단일 포인트 연관들에
+ 대해 나타날 것이고 콜렉션들은 단순히 전혀 나타나지 않을 것이다.
+ </para>
+
+ <para>
+ 당신은 너무 많은 연관들에 대해 <literal>embed-xml="true"</literal>로 남겨두지 말도록 주의해야 한다. 왜냐하면 XML이
+ 순환적으로 잘 처리하지 못하기 때문이다!
+ </para>
+
+ <programlisting><![CDATA[<class name="Customer"
+ table="CUSTOMER"
+ node="customer">
+
+ <id name="id"
+ column="CUST_ID"
+ node="@id"/>
+
+ <map name="accounts"
+ node="."
+ embed-xml="true">
+ <key column="CUSTOMER_ID"
+ not-null="true"/>
+ <map-key column="SHORT_DESC"
+ node="@short-desc"
+ type="string"/>
+ <one-to-many entity-name="Account"
+ embed-xml="false"
+ node="account"/>
+ </map>
+
+ <component name="name"
+ node="name">
+ <property name="firstName"
+ node="first-name"/>
+ <property name="initial"
+ node="initial"/>
+ <property name="lastName"
+ node="last-name"/>
+ </component>
+
+ ...
+
+</class>]]></programlisting>
+
+ <para>
+ 이 경우에, 우리는 실제 account 데이터가 아닌, account id들을 가진 콜렉션을 삽입시키기로 결정했다. 다음 HQL 질의:
+ </para>
+
+ <programlisting><![CDATA[from Customer c left join fetch c.accounts where c.lastName like :lastName]]></programlisting>
+
+ <para>
+ 는 다음과 같은 데이터셋들을 반환할 것이다:
+ </para>
+
+ <programlisting><![CDATA[<customer id="123456789">
+ <account short-desc="Savings">987632567</account>
+ <account short-desc="Credit Card">985612323</account>
+ <name>
+ <first-name>Gavin</first-name>
+ <initial>A</initial>
+ <last-name>King</last-name>
+ </name>
+ ...
+</customer>]]></programlisting>
+
+ <para>
+ 만일 당신이 <literal><one-to-many></literal> 매핑에 대해 <literal>embed-xml="true"</literal>를 설정할 경우,
+ 데이터는 다음과 같이 보일 수도 있다:
+ </para>
+
+ <programlisting><![CDATA[<customer id="123456789">
+ <account id="987632567" short-desc="Savings">
+ <customer id="123456789"/>
+ <balance>100.29</balance>
+ </account>
+ <account id="985612323" short-desc="Credit Card">
+ <customer id="123456789"/>
+ <balance>-2370.34</balance>
+ </account>
+ <name>
+ <first-name>Gavin</first-name>
+ <initial>A</initial>
+ <last-name>King</last-name>
+ </name>
+ ...
+</customer>]]></programlisting>
+
+ </sect1>
+
+
+ <sect1 id="xml-manipulation" revision="1">
+ <title>XML 데이터 처리하기</title>
+
+ <para>
+ 우리의 어플리케이션 내에서 XML 문서들을 다시 읽어들이고 업데이트 시키자. 우리는 dom4j 세션을 얻어서 이것을 행한다:
+ </para>
+
+ <programlisting><![CDATA[Document doc = ....;
+
+Session session = factory.openSession();
+Session dom4jSession = session.getSession(EntityMode.DOM4J);
+Transaction tx = session.beginTransaction();
+
+List results = dom4jSession
+ .createQuery("from Customer c left join fetch c.accounts where c.lastName like :lastName")
+ .list();
+for ( int i=0; i<results.size(); i++ ) {
+ //add the customer data to the XML document
+ Element customer = (Element) results.get(i);
+ doc.getRootElement().add(customer);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <programlisting><![CDATA[Session session = factory.openSession();
+Session dom4jSession = session.getSession(EntityMode.DOM4J);
+Transaction tx = session.beginTransaction();
+
+Element cust = (Element) dom4jSession.get("Customer", customerId);
+for ( int i=0; i<results.size(); i++ ) {
+ Element customer = (Element) results.get(i);
+ //change the customer name in the XML and database
+ Element name = customer.element("name");
+ name.element("first-name").setText(firstName);
+ name.element("initial").setText(initial);
+ name.element("last-name").setText(lastName);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ XML 기반의 데이터 가져오기/내보내기를 구현하는데 이 특징과 Hibernate의 <literal>replicate()</literal> 오퍼레이션을
+ 결합시키는 것이 매우 유용하다.
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/AuthorWork.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/AuthorWork.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/AuthorWork.zargo (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/AuthorWork.zargo)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/CustomerOrderProduct.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/CustomerOrderProduct.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/CustomerOrderProduct.zargo (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/CustomerOrderProduct.zargo)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/EmployerEmployee.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/EmployerEmployee.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/EmployerEmployee.zargo (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/EmployerEmployee.zargo)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/full_cream.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/full_cream.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/full_cream.svg (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/full_cream.svg)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/images/full_cream.svg (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/images/full_cream.svg 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,429 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="354.331"
+ height="336.614"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,5.25349)"
+ style="font-size:12;"
+ id="g659">
+ <rect
+ width="212.257"
+ height="57.2441"
+ x="17.9576"
+ y="100.132"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ transform="matrix(0.743454,0,0,0.482981,6.46949,52.2178)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <rect
+ width="325.86"
+ height="63.6537"
+ x="17.4083"
+ y="15.194"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="325.86"
+ height="63.6537"
+ x="13.6713"
+ y="12.4966"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ <g
+ transform="matrix(1.14345,0,0,0.729078,-1.67818,105.325)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <text
+ x="170.824753"
+ y="58.402939"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="170.824997"
+ y="58.402901"
+ id="tspan360">
+Application</tspan>
+ </text>
+ <text
+ x="178.076340"
+ y="364.281433"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="178.076004"
+ y="364.281006"
+ id="tspan421">
+Database</tspan>
+ </text>
+ <text
+ x="68.605331"
+ y="138.524582"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="68.605301"
+ y="138.524994"
+ id="tspan384">
+SessionFactory</tspan>
+ </text>
+ <rect
+ width="67.0014"
+ height="101.35"
+ x="196.927"
+ y="89.2389"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect387" />
+ <rect
+ width="67.0014"
+ height="101.35"
+ x="194.633"
+ y="86.4389"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect388" />
+ <text
+ x="249.108841"
+ y="173.885559"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text389">
+ <tspan
+ x="249.108994"
+ y="173.886002"
+ id="tspan392">
+Session</tspan>
+ </text>
+ <rect
+ width="73.0355"
+ height="101.35"
+ x="270.995"
+ y="90.0018"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect395" />
+ <rect
+ width="73.0355"
+ height="101.35"
+ x="267.869"
+ y="87.2018"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect396" />
+ <text
+ x="328.593658"
+ y="174.715622"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text397">
+ <tspan
+ x="328.593994"
+ y="174.716003"
+ id="tspan563">
+Transaction</tspan>
+ </text>
+ <g
+ transform="matrix(0.29544,0,0,0.397877,9.70533,103.96)"
+ style="font-size:12;"
+ id="g565">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect566" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect567" />
+ </g>
+ <text
+ x="25.592752"
+ y="204.497803"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:10;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text568">
+ <tspan
+ x="25.592800"
+ y="204.498001"
+ id="tspan662">
+TransactionFactory</tspan>
+ </text>
+ <g
+ transform="matrix(0.298082,0,0,0.397877,99.6898,103.96)"
+ style="font-size:12;"
+ id="g573">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect574" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect575" />
+ </g>
+ <text
+ x="134.030670"
+ y="205.532791"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:10;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text576">
+ <tspan
+ x="134.031006"
+ y="205.533005"
+ id="tspan664">
+ConnectionProvider</tspan>
+ </text>
+ <g
+ transform="matrix(1.14345,0,0,0.729078,-1.67818,38.9539)"
+ style="font-size:12;"
+ id="g587">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect588" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect589" />
+ </g>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="25.6196"
+ y="206.028"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect594" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="24.4229"
+ y="204.135"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect595" />
+ <text
+ x="85.575645"
+ y="282.300354"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text596">
+ <tspan
+ x="85.575600"
+ y="282.299988"
+ id="tspan607">
+JNDI</tspan>
+ </text>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="236.937"
+ y="206.791"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect610" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="235.741"
+ y="204.898"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect611" />
+ <text
+ x="342.093201"
+ y="283.226410"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text612">
+ <tspan
+ x="342.092987"
+ y="283.226013"
+ id="tspan621">
+JTA</tspan>
+ </text>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="130.134"
+ y="206.791"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect616" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="128.937"
+ y="204.898"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect617" />
+ <text
+ x="212.445343"
+ y="283.226410"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text618">
+ <tspan
+ x="212.445007"
+ y="283.226013"
+ id="tspan623">
+JDBC</tspan>
+ </text>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,6.19341)"
+ style="font-size:12;"
+ id="g637">
+ <g
+ transform="matrix(0.499515,0,0,0.415467,-0.237339,5.61339)"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="33.749969"
+ y="50.589706"
+ style="font-size:11;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="33.750000"
+ y="50.589699"
+ id="tspan635">
+Transient Objects</tspan>
+ </text>
+ </g>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,5.25349)"
+ style="font-size:12;"
+ id="g644">
+ <g
+ transform="matrix(0.297486,0,0,0.516482,230.251,36.9178)"
+ id="g364">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect365" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect366" />
+ </g>
+ <text
+ x="277.123230"
+ y="85.155571"
+ style="font-size:11;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text367">
+ <tspan
+ x="277.122986"
+ y="85.155602"
+ id="tspan631">
+Persistent</tspan>
+ <tspan
+ x="277.122986"
+ y="96.155602"
+ id="tspan633">
+Objects</tspan>
+ </text>
+ </g>
+</svg>
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/hibernate_logo_a.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/hibernate_logo_a.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/lite.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/lite.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/lite.svg (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/lite.svg)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/images/lite.svg (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/images/lite.svg 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,334 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="318.898"
+ height="248.031"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <rect
+ width="291.837"
+ height="57.0074"
+ x="17.3169"
+ y="18.646"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="291.837"
+ height="57.0074"
+ x="13.9703"
+ y="16.2302"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ <g
+ transform="matrix(0.326107,0,0,0.765831,9.59261,8.98517)"
+ style="font-size:12;"
+ id="g161">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <g
+ transform="matrix(1.02406,0,0,0.652953,0.223384,39.9254)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <g
+ transform="matrix(0.449834,0,0,0.338463,-3.15909,9.73319)"
+ style="font-size:12;"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="302.277679"
+ y="65.943230"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="302.277954"
+ y="65.943184"
+ id="tspan360">
+Application</tspan>
+ </text>
+ <text
+ x="36.235924"
+ y="63.796055"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:14;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="36.235950"
+ y="63.796051"
+ id="tspan427">
+Transient Objects</tspan>
+ </text>
+ <text
+ x="180.416245"
+ y="290.543701"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="180.415939"
+ y="290.543549"
+ id="tspan421">
+Database</tspan>
+ </text>
+ <text
+ x="25.037701"
+ y="179.154755"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="25.037655"
+ y="179.154648"
+ id="tspan384">
+SessionFactory</tspan>
+ </text>
+ <g
+ transform="matrix(0.252763,0,0,0.765831,109.104,8.98517)"
+ style="font-size:12;"
+ id="g386">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect387" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect388" />
+ </g>
+ <g
+ transform="matrix(0.297394,0,0,0.572692,101.502,21.6359)"
+ style="font-size:12;"
+ id="g364">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect365" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect366" />
+ </g>
+ <text
+ x="202.746506"
+ y="102.992203"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:14;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text367">
+ <tspan
+ x="202.746948"
+ y="102.992249"
+ id="tspan423">
+Persistent</tspan>
+ <tspan
+ x="202.746948"
+ y="116.992355"
+ id="tspan425">
+Objects</tspan>
+ </text>
+ <text
+ x="174.458496"
+ y="180.080795"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text389">
+ <tspan
+ x="174.458618"
+ y="180.080338"
+ id="tspan392">
+Session</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,188.675,8.98517)"
+ style="font-size:12;"
+ id="g394">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect395" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect396" />
+ </g>
+ <text
+ x="260.413269"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text397">
+ <tspan
+ x="260.412964"
+ y="179.154343"
+ id="tspan400">
+JDBC</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,229.156,8.98517)"
+ style="font-size:12;"
+ id="g405">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect406" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect407" />
+ </g>
+ <text
+ x="320.606903"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text408">
+ <tspan
+ x="320.606964"
+ y="179.154343"
+ id="tspan417">
+JNDI</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,269.281,8.98517)"
+ style="font-size:12;"
+ id="g411">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect412" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect413" />
+ </g>
+ <text
+ x="377.096313"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text414">
+ <tspan
+ x="377.096008"
+ y="179.154999"
+ id="tspan145">
+JTA</tspan>
+ </text>
+</svg>
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/overview.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/overview.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/images/overview.svg (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/overview.svg)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/images/overview.svg (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/images/overview.svg 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,250 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="248.031"
+ height="248.031"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,-3.02123)"
+ style="font-size:12;"
+ id="g158">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="17.3527"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="15.3883"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,3.04452)"
+ style="font-size:12;"
+ id="g161">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,8.0993)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.543505,2.59104,21.1103)"
+ style="font-size:12;"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="105.392174"
+ y="56.568123"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="105.392273"
+ y="56.568146"
+ id="tspan186">
+Application</tspan>
+ </text>
+ <text
+ x="81.820183"
+ y="103.149330"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:20;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="81.820213"
+ y="103.149727"
+ id="tspan206">
+Persistent Objects</tspan>
+ </text>
+ <text
+ x="111.548180"
+ y="278.927887"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="111.547874"
+ y="278.927551"
+ id="tspan200">
+Database</tspan>
+ </text>
+ <text
+ x="94.436180"
+ y="153.805740"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="94.436180"
+ y="153.805740"
+ id="tspan221">
+HIBERNATE</tspan>
+ </text>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,2.59083,1.02261)"
+ style="font-size:12;"
+ id="g254">
+ <g
+ transform="translate(4.58374,2.61928)"
+ id="g176">
+ <g
+ transform="matrix(0.571429,0,0,0.67347,-10.6174,117.093)"
+ id="g170">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect171" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect172" />
+ </g>
+ <g
+ transform="matrix(0.571429,0,0,0.67347,138.682,117.093)"
+ id="g173">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect174" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect175" />
+ </g>
+ </g>
+ <text
+ x="47.259438"
+ y="182.367538"
+ style="font-weight:bold;stroke-width:1pt;font-family:Courier;"
+ id="text191">
+ <tspan
+ x="47.259399"
+ y="182.367996"
+ id="tspan212">
+hibernate.</tspan>
+ <tspan
+ x="47.259399"
+ y="194.367996"
+ id="tspan214">
+properties</tspan>
+ </text>
+ <text
+ x="198.523010"
+ y="188.260941"
+ style="font-weight:normal;stroke-width:1pt;font-family:helvetica;"
+ id="text194">
+ <tspan
+ id="tspan195">
+XML Mapping</tspan>
+ </text>
+ </g>
+</svg>
Copied: core/trunk/documentation/manual/ko-KR/src/main/docbook/legal_notice.xml (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/legal_notice.xml)
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/legal_notice.xml (rev 0)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/legal_notice.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -0,0 +1,37 @@
+<?xml version='1.0'?>
+<!DOCTYPE legalnotice PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<legalnotice id="Legal_Notice">
+ <title>Legal Notice</title>
+ <para>
+ <address>
+ <street>1801 Varsity Drive</street>
+ <city>Raleigh</city>, <state>NC</state><postcode>27606-2072</postcode><country>USA</country>
+ <phone>Phone: +1 919 754 3700</phone>
+ <phone>Phone: 888 733 4281</phone>
+ <fax>Fax: +1 919 754 3701</fax>
+ <pob>PO Box 13588</pob><city>Research Triangle Park</city>, <state>NC</state><postcode>27709</postcode><country>USA</country>
+ </address>
+ </para>
+ <para>
+ Copyright <trademark class="copyright"></trademark> 2007 by Red Hat, Inc. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, V1.0 or later (the latest version is presently available at <ulink url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).
+ </para>
+ <para>
+ Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder.
+ </para>
+ <para>
+ Distribution of the work or derivative of the work in any standard (paper) book form for commercial purposes is prohibited unless prior permission is obtained from the copyright holder.
+ </para>
+ <para>
+ Red Hat and the Red Hat "Shadow Man" logo are registered trademarks of Red Hat, Inc. in the United States and other countries.
+ </para>
+ <para>
+ All other trademarks referenced herein are the property of their respective owners.
+ </para>
+ <para>
+ The GPG fingerprint of the security(a)redhat.com key is:
+ </para>
+ <para>
+ CA 20 86 86 2B D6 9D FC 65 F6 EC C4 21 91 80 CD DB 42 A6 0E
+ </para>
+</legalnotice>
\ No newline at end of file
Deleted: core/trunk/documentation/manual/ko-KR/src/main/docbook/master.xml
===================================================================
--- core/trunk/documentation/manual/ko-KR/src/main/docbook/master.xml 2007-10-09 19:05:51 UTC (rev 14078)
+++ core/trunk/documentation/manual/ko-KR/src/main/docbook/master.xml 2007-10-09 19:14:22 UTC (rev 14079)
@@ -1,184 +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 tutorial SYSTEM "modules/tutorial.xml">
-<!ENTITY architecture SYSTEM "modules/architecture.xml">
-<!ENTITY configuration SYSTEM "modules/configuration.xml">
-<!ENTITY persistent-classes SYSTEM "modules/persistent_classes.xml">
-<!ENTITY basic-mapping SYSTEM "modules/basic_mapping.xml">
-<!ENTITY collection-mapping SYSTEM "modules/collection_mapping.xml">
-<!ENTITY association-mapping SYSTEM "modules/association_mapping.xml">
-<!ENTITY component-mapping SYSTEM "modules/component_mapping.xml">
-<!ENTITY inheritance-mapping SYSTEM "modules/inheritance_mapping.xml">
-<!ENTITY session-api SYSTEM "modules/session_api.xml">
-<!ENTITY transactions SYSTEM "modules/transactions.xml">
-<!ENTITY events SYSTEM "modules/events.xml">
-<!ENTITY batch SYSTEM "modules/batch.xml">
-<!ENTITY query-hql SYSTEM "modules/query_hql.xml">
-<!ENTITY query-criteria SYSTEM "modules/query_criteria.xml">
-<!ENTITY query-sql SYSTEM "modules/query_sql.xml">
-<!ENTITY filters SYSTEM "modules/filters.xml">
-<!ENTITY xml SYSTEM "modules/xml.xml">
-<!ENTITY performance SYSTEM "modules/performance.xml">
-<!ENTITY toolset-guide SYSTEM "modules/toolset_guide.xml">
-<!ENTITY example-parentchild SYSTEM "modules/example_parentchild.xml">
-<!ENTITY example-weblog SYSTEM "modules/example_weblog.xml">
-<!ENTITY example-mappings SYSTEM "modules/example_mappings.xml">
-<!ENTITY best-practices SYSTEM "modules/best_practices.xml">
-]>
-
-<book lang="ko">
-
- <bookinfo lang="ko">
- <title>HIBERNATE - 개성있는 자바를 위한 관계 영속</title>
- <subtitle>하이버네이트 참조 문서</subtitle>
- <releaseinfo lang="ko">3.2 cr3</releaseinfo>
- </bookinfo>
-
- <toc lang="ko" />
-
- <preface id="preface" revision="2">
- <title>머리말</title>
-
- <para>
- 객체 지향 소프트웨어와 관계형 데이터베이스로 작업하는 것은 오늘날의 엔터프라이즈 환경들에서 성가시고 시간이
- 소비될 수 있다. Hibernate는 자바 환경들을 위한 객체/관계형 매핑 도구이다.
- object/relational mapping(ORM) 용어는 객체 모형으로부터 SQL-기반의 스키마를 가진
- 관계형 데이터 모형으로의 데이터 표상을 매핑하는 기술을 언급한다.
- </para>
-
- <para>
- Hibernate는 자바 클래스들로부터 데이터베이스로의 매핑(그리고 자바 데이터 타입들로부터 SQL 데이터
- 타입들로의 매핑)을 처리할 뿐만 아니라, 또한 데이터 질의와 검색 편의들을 제공하며, SQL과 JDBC로
- 수작업 데이터 핸들링에 소요되는 개발 시간을 현저하게 단축시켜줄 수 있다.
- </para>
-
- <para>
- Hibernate의 목적은 공통된 데이터 영속화 관련 프로그래밍 작업들의 95%를 덜어주는 것이다.
- Hibernate는 데이터베이스에서 비지니스 로직을 구현하는데 내장 프로시저들을 전용으로 사용하는 데이터
- 중심적 어플리케이션에 대한 최상의 솔루션이 아닐 수도 있지만, 그것은 자바 기반 미들-티어에서 객체 지향
- 도메인 모형들과 비지니스 로직에 가장 유용하다. 하지만 Hibernate는 벤더 지정적인 SQL 코드를
- 제거하거나 캡슐화 시키는 당신을 확실히 도와줄 수 있고 테이블 형식의 표현으로부터 객체들의 그래프로 결과
- 셋을 변환하는 공통된 태스크를 도와줄 것이다.
- </para>
-
- <para>
- 만일 당신이 Hibernate와 Object/Relational 매핑 또는 심지어 자바에 초심자라면, 다음
- 단계들을 따르기 바란다:
- </para>
-
- <orderedlist>
- <listitem>
- <para>
- 더 많은 단계적인 사용 설명서들을 가진 더 긴 튜토리얼은
- <xref linkend="tutorial"/>
- 을 읽어라. 튜토리얼을 위한 소스 코드는 <literal>doc/reference/tutorial/</literal>
- 디렉토리에 포함되어 있다.
- </para>
- </listitem>
- <listitem>
- <para>
- Hibernate가 사용될 수 있는 환경을 이해려면
- <xref linkend="architecture" />
- 를 읽어라.
- </para>
- </listitem>
- <listitem>
- <para>
- Hibernate 배포본 내의
- <literal>eg/</literal>
- 디렉토리를 살펴 보라. 이 디렉토리는 간단한 스탠드얼론 어플리케이션을 포함하고 있다. 당신의
- JDBC 드라이버를
- <literal>lib/</literal>
- 디렉토리에 복사하고 당신의 데이터베이스에 맞는 정확한 값을 지정하여
- <literal>etc/hibernate.properties</literal>
- 를 편집하라. 배보본 디렉토리에서 명령 라인 프롬프트에서 (Ant를 사용하여)
- <literal>ant eg</literal>
- 를 타이핑 하거나 , Windows 하에서
- <literal>build eg</literal>
- 를 타이프 하라.
- </para>
- </listitem>
- <listitem>
- <para>
- 당신의 주된 정보의 소스로서 이 참조 문서를 사용하라. 만일 어플리케이션 설계에 대해 더 많은
- 도움을 필요로 하거나 당신이 단계적인 튜토리얼을 선호한다면
- <emphasis>Java Persistence with Hibernate</emphasis>
- (http://www.manning.com/bauer2)을 읽는 것을 고려하라.또한
- http://caveatemptor.hibernate.org에 방문하여 Java Persistence
- with Hibernate용 예제 어플리케이션을 다운로드 하라.
- </para>
- </listitem>
- <listitem>
- <para>
- FAQ들은 Hibernate 웹 사이트 상에 답변되어 있다.
- </para>
- </listitem>
- <listitem>
- <para>
- 제 3의 데모들, 예제들, 그리고 튜토리얼들은 Hibernate 웹 사이트 상에 링크되어
- 있다.
- </para>
- </listitem>
- <listitem>
- <para>
- Hibernate 웹사이트 상의 공동체 영역은 설계 패턴과 다양한 통합 솔루션들(Tomcat,
- JBoss AS, Struts, EJB 등.)에 관한 좋은 리소스이다.
- </para>
- </listitem>
- </orderedlist>
-
- <para>
- 질문이 있다면, Hibernate 상에 링크되어 있는 사용자 포럼을 사용하라. 우리는 또한 버그 보고와 특징
- 요청들을 위한 JIRA 쟁점 추적 시스템을 제공한다. 당신이 Hibernate의 개발에 관심이 있다면,
- 개발자 메일링 리스트에 참여하라. 만일 당신이 이 문서를 당신의 언어로 번역하는 것에 관심이 있다면, 개발자
- 메일링 리스트에 접촉하라.
- </para>
-
- <para>
- Hibernate를 위한 상용 개발 지원, 제품 지원, 그리고 교육은 JBoss Inc를 통해 이용 가능하다
- (http://www.hibernate.org/SupportTraining/를 보라). Hibernate는
- JBoss Professional Open Source product 프로젝트이고 제품들에 대한 JBoss
- Enterprise Middleware System (JEMS) suite의 중대한 컴포넌트이다.
- </para>
-
- </preface>
-
- &tutorial;
-
- &architecture;
-
- &configuration;
-
- &persistent-classes;
-
- &basic-mapping;
- &collection-mapping;
- &association-mapping;
- &component-mapping;
- &inheritance-mapping;
-
- &session-api;
- &transactions;
- &events;
- &batch;
-
- &query-hql;
- &query-criteria;
- &query-sql;
- &filters;
- &xml;
-
- &performance;
-
- &toolset-guide;
-
- &example-parentchild;
- &example-weblog;
- &example-mappings;
-
- &best-practices;
-
-</book>
-
18 years, 6 months
Hibernate SVN: r14078 - core/trunk/documentation/manual/fr-FR/src/main/docbook/content.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2007-10-09 15:05:51 -0400 (Tue, 09 Oct 2007)
New Revision: 14078
Modified:
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/architecture.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_mappings.xml
Log:
fixed image extensions/types
Modified: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/architecture.xml
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/architecture.xml 2007-10-09 19:04:11 UTC (rev 14077)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/content/architecture.xml 2007-10-09 19:05:51 UTC (rev 14078)
@@ -30,7 +30,7 @@
<imagedata fileref="../images/overview.svg" format="SVG" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../images/overview.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/overview.png" format="PNG" align="center"/>
</imageobject>
</mediaobject>
@@ -53,7 +53,7 @@
<imagedata fileref="../images/lite.svg" format="SVG" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../images/lite.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/lite.png" format="PNG" align="center"/>
</imageobject>
</mediaobject>
@@ -67,7 +67,7 @@
<imagedata fileref="../images/full_cream.svg" format="SVG" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../images/full_cream.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/full_cream.png" format="PNG" align="center"/>
</imageobject>
</mediaobject>
Modified: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_mappings.xml
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_mappings.xml 2007-10-09 19:04:11 UTC (rev 14077)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_mappings.xml 2007-10-09 19:05:51 UTC (rev 14078)
@@ -34,10 +34,10 @@
<mediaobject>
<imageobject role="fo">
- <imagedata fileref="../images/EmployerEmployee.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/EmployerEmployee.png" format="PNG" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../images/EmployerEmployee.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/EmployerEmployee.png" format="PNG" align="center"/>
</imageobject>
</mediaobject>
@@ -148,10 +148,10 @@
<mediaobject>
<imageobject role="fo">
- <imagedata fileref="../images/AuthorWork.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/AuthorWork.png" format="PNG" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../images/AuthorWork.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/AuthorWork.png" format="PNG" align="center"/>
</imageobject>
</mediaobject>
@@ -272,10 +272,10 @@
<mediaobject>
<imageobject role="fo">
- <imagedata fileref="../images/CustomerOrderProduct.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/CustomerOrderProduct.png" format="PNG" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../images/CustomerOrderProduct.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/CustomerOrderProduct.png" format="PNG" align="center"/>
</imageobject>
</mediaobject>
18 years, 6 months
Hibernate SVN: r14077 - core/trunk/documentation/manual/es-ES/src/main/docbook/content.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2007-10-09 15:04:11 -0400 (Tue, 09 Oct 2007)
New Revision: 14077
Modified:
core/trunk/documentation/manual/es-ES/src/main/docbook/content/architecture.xml
core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_mappings.xml
Log:
fixed image extensions/types
Modified: core/trunk/documentation/manual/es-ES/src/main/docbook/content/architecture.xml
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/architecture.xml 2007-10-09 19:02:00 UTC (rev 14076)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/architecture.xml 2007-10-09 19:04:11 UTC (rev 14077)
@@ -14,7 +14,7 @@
<imagedata fileref="../images/overview.svg" format="SVG" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../images/overview.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/overview.png" format="PNG" align="center"/>
</imageobject>
</mediaobject>
@@ -37,7 +37,7 @@
<imagedata fileref="../images/lite.svg" format="SVG" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../images/lite.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/lite.png" format="PNG" align="center"/>
</imageobject>
</mediaobject>
@@ -51,7 +51,7 @@
<imagedata fileref="../images/full_cream.svg" format="SVG" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../images/full_cream.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/full_cream.png" format="PNG" align="center"/>
</imageobject>
</mediaobject>
Modified: core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_mappings.xml
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_mappings.xml 2007-10-09 19:02:00 UTC (rev 14076)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_mappings.xml 2007-10-09 19:04:11 UTC (rev 14077)
@@ -17,10 +17,10 @@
<mediaobject>
<imageobject role="fo">
- <imagedata fileref="../images/EmployerEmployee.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/EmployerEmployee.png" format="PNG" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../images/EmployerEmployee.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/EmployerEmployee.png" format="PNG" align="center"/>
</imageobject>
</mediaobject>
@@ -130,10 +130,10 @@
<mediaobject>
<imageobject role="fo">
- <imagedata fileref="../images/AuthorWork.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/AuthorWork.png" format="PNG" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../images/AuthorWork.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/AuthorWork.png" format="PNG" align="center"/>
</imageobject>
</mediaobject>
@@ -252,10 +252,10 @@
<mediaobject>
<imageobject role="fo">
- <imagedata fileref="../images/CustomerOrderProduct.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/CustomerOrderProduct.png" format="PNG" align="center"/>
</imageobject>
<imageobject role="html">
- <imagedata fileref="../images/CustomerOrderProduct.gif" format="GIF" align="center"/>
+ <imagedata fileref="../images/CustomerOrderProduct.png" format="PNG" align="center"/>
</imageobject>
</mediaobject>
18 years, 6 months
Hibernate SVN: r14076 - in core/trunk/documentation/manual/ja-JP/src/main: docbook and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2007-10-09 15:02:00 -0400 (Tue, 09 Oct 2007)
New Revision: 14076
Added:
core/trunk/documentation/manual/ja-JP/src/main/docbook/Hibernate_Reference.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/architecture.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/association_mapping.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/basic_mapping.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/batch.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/best_practices.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/collection_mapping.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/component_mapping.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/configuration.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/events.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/example_mappings.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/example_parentchild.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/example_weblog.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/filters.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/inheritance_mapping.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/performance.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/persistent_classes.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/preface.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/query_criteria.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/query_hql.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/query_sql.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/session_api.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/toolset_guide.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/transactions.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/tutorial.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/content/xml.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/AuthorWork.png
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/AuthorWork.zargo
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/CustomerOrderProduct.png
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/CustomerOrderProduct.zargo
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/EmployerEmployee.png
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/EmployerEmployee.zargo
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/full_cream.png
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/full_cream.svg
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/hibernate_logo_a.png
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/lite.png
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/lite.svg
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/overview.png
core/trunk/documentation/manual/ja-JP/src/main/docbook/images/overview.svg
core/trunk/documentation/manual/ja-JP/src/main/docbook/legal_notice.xml
Removed:
core/trunk/documentation/manual/ja-JP/src/main/docbook/master.xml
core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/
core/trunk/documentation/manual/ja-JP/src/main/resources/
Log:
new docbook layout (prep for translations migration to PO)
Added: core/trunk/documentation/manual/ja-JP/src/main/docbook/Hibernate_Reference.xml
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/Hibernate_Reference.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/Hibernate_Reference.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+ <!ENTITY versionNumber "3.3.0.alpha1">
+ <!ENTITY copyrightYear "2004">
+ <!ENTITY copyrightHolder "Red Hat Middleware, LLC.">
+]>
+
+<book>
+
+ <bookinfo>
+ <title>HIBERNATE - Relational Persistence for Idiomatic Java</title>
+ <subtitle>Hibernate Reference Documentation</subtitle>
+ <releaseinfo>&versionNumber;</releaseinfo>
+ <productnumber>&versionNumber;</productnumber>
+ <issuenum>1</issuenum>
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/hibernate_logo_a.png" align="center" />
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="images/hibernate_logo_a.png" depth="3cm" />
+ </imageobject>
+ </mediaobject>
+ <copyright>
+ <year>©rightYear;</year>
+ <holder>©rightHolder;</holder>
+ </copyright>
+ <!--
+ todo : figure out how best to include translator info...
+ <xi:include href="author_group.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ -->
+ <xi:include href="legal_notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </bookinfo>
+
+ <toc/>
+
+ <xi:include href="content/preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/tutorial.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/configuration.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/persistent_classes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/basic_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/collection_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/association_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/component_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/inheritance_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/session_api.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/transactions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/events.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/batch.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/query_hql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/query_criteria.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/query_sql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/filters.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/xml.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/performance.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/toolset_guide.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/example_parentchild.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/example_weblog.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/example_mappings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/best_practices.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+</book>
+
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/architecture.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/architecture.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/architecture.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/architecture.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,375 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="architecture">
+
+ <title>�A�[�L�e�N�`��</title>
+
+ <sect1 id="architecture-overview" revision="1">
+ <title>�T��</title>
+
+ <para>
+ Hibernate�A�[�L�e�N�`���́i���Ɂj�������x������̃r���[�F
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/overview.svg" format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/overview.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ ���̐}��Hibernate���A�A�v���P�[�V�����ɑ��ĉi�����T�[�r�X
+ �i�Ɖi���I�u�W�F�N�g�j����邽�߂ɁA�f�[�^�x�[�X�Ɛݒ�f�[�^��g�����Ƃ�
+ �����Ă��܂��B
+ </para>
+
+ <para>
+ �����Ŏ��s���A�[�L�e�N�`���̂��ڍׂȃr���[���������܂��傤�B
+ �����ɂ��AHibernate�͏_��ł���A���낢��ȃA�v���[�`��T�|�[�g���Ă��܂��B
+ �����ł́A2�̋ɒ[�ȗ���������܂��B
+ �u�y���v�A�[�L�e�N�`���ł́A�A�v���P�[�V���������O��JDBC�R�l�N�V������p�ӂ��A
+ �A�v���P�[�V�������g���g�����U�N�V������Ǘ����܂��B
+ ���̕��@�́AHibernate API�̍ŏ����̃T�u�Z�b�g��g���܂��F
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/lite.svg" format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/lite.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ �u�d���v�A�[�L�e�N�`���́A�A�v���P�[�V��������A���̉��Ɉʒu����JDBC��JTA��API��
+ ��蕥���Ē��ۉ����A���̏ڍׂ̖ʓ|��Hibernate�Ɍ������܂��B
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/full_cream.svg" format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/full_cream.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ �ȉ��́A��̐}�Ɋ܂܂��I�u�W�F�N�g�̒�`�ł��F
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>SessionFactory (<literal>org.hibernate.SessionFactory</literal>)</term>
+ <listitem>
+ <para>
+ 1�̃f�[�^�x�[�X�ɑ���R���p�C�����ꂽ�}�b�s���O��
+ �X���b�h�Z�[�t�ȁi�X�V�s�\�́j�L���b�V���B
+ <literal>Session</literal> �̃t�@�N�g���ł���A
+ <literal>ConnectionProvider</literal> �̃N���C�A���g�B
+ �I�v�V�����Ƃ��āA�v���Z�X�܂��̓N���X�^���x���ɂ����āA
+ �g�����U�N�V�����Ԃōė��p�\�ȃf�[�^�́i�j�L���b�V�������܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Session (<literal>org.hibernate.Session</literal>)</term>
+ <listitem>
+ <para>
+ �A�v���P�[�V�����Ɖi���X�g�A�Ƃ̑Θb��\���A
+ �V���O���X���b�h�ŒZ���̃I�u�W�F�N�g�B
+ JDBC�R�l�N�V�������b�v���܂��B
+ <literal>Transaction</literal> �̃t�@�N�g���ł��B
+ �i���I�u�W�F�N�g�̕K�{�́i�ꎟ�j�L���b�V����ێ����܂��B
+ ���̃L���b�V���̓I�u�W�F�N�g�O���t��i�r�Q�[�V�������鎞��A
+ ���ʎq�ŃI�u�W�F�N�g�������鎞�Ɏg���܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Persistent objects �� Collections</term>
+ <listitem>
+ <para>
+ �i������Ԃƃr�W�l�X���\�b�h���A�Z���ŃV���O���X���b�h�̃I�u�W�F�N�g�B
+ ����͒ʏ��JavaBeans/POJO�̂��Ƃ����܂����A�����I�Ȃ��Ƃ́A
+ ���̎��_�ł́i����1�́j <literal>Session</literal> �Ɗ֘A���Ă��邱�Ƃł��B
+ <literal>Session</literal> ���N���[�Y�����Ƃ����ɁA
+ �����͐藣����đ��̃A�v���P�[�V�����w���玩�R�Ɏg�����Ƃ��ł��܂��B
+ �i�Ⴆ�f�[�^�E�g�����X�t�@�E�I�u�W�F�N�g�Ƃ��āA
+ �v���[���e�[�V�����w����A�܂��̓v���[���e�[�V�����w�֒��ڎg�p�ł��܂��B�j
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Transient �� detached �� objects �� Collections</term>
+ <listitem>
+ <para>
+ �����_�ł� <literal>Session</literal> �Ɗ֘A���Ă��Ȃ��A
+ �i���N���X�̃C���X�^���X�B
+ ���łɃA�v���P�[�V�������ŃC���X�^���X������Ă��āA�܂��i��������Ă��Ȃ����A
+ �N���[�Y���ꂽ <literal>Session</literal> �ŃC���X�^���X�����ꂽ���̂ǂ��炩�ł��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Transaction (<literal>org.hibernate.Transaction</literal>)</term>
+ <listitem>
+ <para>
+ (�I�v�V����)���q������ƒP��(Unit of Work)��w�肷�邽�߂ɁA�A�v���P�[�V�������g�p����A
+ �V���O���X���b�h�ŒZ���ȃI�u�W�F�N�g�B
+ ���Ɉʒu����JDBC�AJTA�ACORBA�g�����U�N�V��������A�v���P�[�V�����𒊏ۉ����܂��B
+ <literal>Session</literal> �́A���ɂ�
+ �������� <literal>Transaction</literal> ��܂����邩�����܂���B
+ �������A���̑w��API��g���ɂ���A <literal>Transaction</literal> ��g���ɂ���A
+ �g�����U�N�V�������E��ݒ肷�邱�Ƃ́A�����ăI�v�V�����ł͂���܂���I�B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ConnectionProvider (<literal>org.hibernate.connection.ConnectionProvider</literal>)</term>
+ <listitem>
+ <para>
+ (�I�v�V����)JDBC�R�l�N�V�����i�Ƃ��̃v�[���j�̃t�@�N�g���B
+ ���̑w�Ɉʒu���� <literal>Datasource</literal> ��
+ <literal>DriverManager</literal> ����A�v���P�[�V�����𒊏ۉ����܂��B
+ �A�v���P�[�V�����ɂ͌��J����܂��A�J���҂��p���܂��͎������邱�Ƃ͉\�ł��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>TransactionFactory (<literal>org.hibernate.TransactionFactory</literal>)</term>
+ <listitem>
+ <para>
+ (�I�v�V����) <literal>Transaction</literal> �C���X�^���X�̃t�@�N�g���B
+ �A�v���P�[�V�����ɂ͌��J����܂��A�J���҂��p���܂��͎������邱�Ƃ͉\�ł��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis>Extension Interfaces</emphasis></term>
+ <listitem>
+ <para>
+ Hibernate�́A�i���w�̐U�镑����J�X�^�}�C�Y���邽�߂ɁA
+ �����̃I�v�V�����g���C���^�t�F�[�X��p�ӂ��Ă��܂��B
+ �ڍׂ�API�h�L�������g��Q�Ƃ��Ă��������B
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ �u�y���v�A�[�L�e�N�`���ł́A�A�v���P�[�V�����͒���JTA��JDBC�ƑΘb���邽�߂ɁA
+ <literal>Transaction</literal> �� <literal>TransactionFactory</literal> ��
+ <literal>ConnectionProvider</literal> ��o�C�p�X���܂��B
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-states" revision="1">
+ <title>�C���X�^���X�̏��</title>
+ <para>
+ �i���N���X�̃C���X�^���X�́A���̂R�̈قȂ��Ԃ̂ǂꂩ�ɂȂ�܂��B
+ ����́A <emphasis>�i���R���e�L�X�g</emphasis> �ɂ���Č��܂�܂��B
+ Hibernate�� <literal>Session</literal> �I�u�W�F�N�g���A�i���R���e�L�X�g�ɂȂ�܂��B
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>transient</term>
+ <listitem>
+ <para>
+ ���̏�Ԃ̃C���X�^���X�́A���݂�����ĉߋ��ɂ����Ă�A
+ �i���R���e�L�X�g�Ɋ֘A�Â��Ă��܂���B�܂��A�i��ID�i��L�[�̒l�j��
+ �����Ă��܂���B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>persistent</term>
+ <listitem>
+ <para>
+ ���̏�Ԃ̃C���X�^���X�́A���̎��_�ʼni���R���e�L�X�g�Ɋ֘A�Â��Ă��܂��B
+ �܂��A�i��ID�i��L�[�̒l�j�����A
+ �����Ă��̓f�[�^�x�[�X�ɑΉ�����s�����Ă���ł��傤�B
+ �X�̉i���R���e�L�X�g�̂Ȃ��ł́A�i��ID��
+ Java��ID�i�I�u�W�F�N�g�̃�������̈ʒu�j�Ɠ����ł��邱�Ƃ�
+ Hibernate�� <emphasis>�ۏ�</emphasis> ���܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>detached</term>
+ <listitem>
+ <para>
+ ���̏�Ԃ̃C���X�^���X�́A���ĉi���R���e�L�X�g�Ɋ֘A�Â���ꂽ���A
+ ���̃R���e�L�X�g���N���[�Y���ꂽ���A���邢�́A
+ ���̃v���Z�X�ɂ��̃C���X�^���X���V���A���C�Y���ꂽ���ł��B
+ ���̃C���X�^���X�́A�i��ID�����A�����Ă��̓f�[�^�x�[�X��
+ �Ή�����s�����Ă���ł��傤�B�����C���X�^���X�ɑ��ẮA
+ �i��ID��Java��ID�Ƃ̊֘A�́AHibernate���ۏ��܂���B
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 id="architecture-jmx" revision="1">
+ <title>JMX�Ƃ̓���</title>
+
+ <para>
+ JMX��Java�R���|�[�l���g�Ǘ���J2EE�W���ł��B
+ JMX�W���T�[�r�X��ʂ��āAHibernate�͊Ǘ�����܂��B
+ �f�B�X�g���r���[�V�����̒��� <literal>org.hibernate.jmx.HibernateService</literal> �Ƃ���
+ MBean������p�ӂ��Ă��܂��B
+ </para>
+
+ <para>
+ JBoss �A�v���P�[�V�����T�[�o�[���Hibernate��JMX�T�[�r�X�Ƃ��ăf�v���C������@�̗�Ƃ��ẮA
+ JBoss ���[�U�K�C�h��Q�Ƃ��Ă��������B JBoss �A�v���P�[�V�����T�[�o�[�ɂ����āA
+ JMX��g���ăf�v���C����ƁA���̃����b�g�������܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>�Z�b�V�����Ǘ�:</emphasis> Hibernate�� <literal>Session</literal> �̃��C�t�T�C�N���́A
+ �����I��JTA�g�����U�N�V�����̃X�R�[�v�Ɍ��т����܂��B����́A��͂�蓮��
+ <literal>Session</literal> ��I�[�v��������A�N���[�Y�����肷��K�v���Ȃ����Ƃ�Ӗ����܂��B
+ ����́AJBoss EJB �C���^�[�Z�v�^�̎d���ɂȂ�܂��B
+ �܂��A�R�[�h�̂ǂ��Ńg�����U�N�V�������E��ݒ肷�邩�ɂ��āA
+ ��͂�Y�ޕK�v������܂���i������ڐA�\�ȉi���w�������Ȃ��Ă����̂Ȃ�A
+ �I�v�V������Hibernate�� <literal>Transaction</literal> ��g�p�����������B�j
+ <literal>Session</literal> �ɃA�N�Z�X���邽�߂ɂ́A <literal>HibernateContext</literal> ��
+ �R�[�������������B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>HAR �f�v���C:</emphasis> �ʏ�A(EAR �܂��� SAR �t�@�C���ɂ���jJBoss �T�[�r�X
+ �f�v���C�����g�f�B�X�N���v�^��g���āAHibernate JMX �T�[�r�X��f�v���C���܂��B
+ ����́AHibernate�� <literal>SessionFactory</literal> �̑S�Ă̈�ʓI�Ȑݒ�I�v�V������
+ �T�|�[�g���܂��B�������ˑR�Ƃ��ăf�v���C�����g�f�B�X�N���v�^�̂Ȃ��ɂ��ׂẴ}�b�s���O�t�@�C����
+ ���O������K�v������܂��B
+ ����A�I�v�V������HAR�f�v���C�����g��g�����Ƃ��߂��Ȃ�A
+ JBoss�͎����I��HAR�t�@�C���̂Ȃ��̑S�Ẵ}�b�s���O�t�@�C�����o���܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ �����̃I�v�V�����ɂ��Ă̏ڍׂȏ��́AJBoss�A�v���P�[�V�����T�[�o���[�U�K�C�h��
+ �Q�l�ɂ��Ă��������B
+ </para>
+
+ <para>
+ JMX�T�[�r�X�Ƃ��ė��p�\�ȑ��̋@�\�ɁAHibernate���s�����v�����܂��B
+ <xref linkend="configuration-optional-statistics"/> �����������B
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-jca" revision="1">
+ <title>JCA �T�|�[�g</title>
+ <para>
+ Hibernate �� JCA �R�l�N�^�Ƃ��Ă�ݒ�ł��܂��B�ڍׂɂ��ẮAWeb�T�C�g���Ă��������B
+ Hibernate JCA �T�|�[�g�́A���̂Ƃ�������i�K�Ƃ��čl�����Ă��邱�Ƃɒ��ӂ��Ă��������B
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-current-session" revision="2">
+ <title>�R���e�L�X�g��̃Z�b�V����</title>
+ <para>
+ Hibernate ��g�����A�v���P�[�V�����́A�قƂ�ǁA�Ȃ�炩�̌`��"�R���e�L�X�g���"�Z�b�V�������K�v�ɂȂ�܂��B
+ �u�R���e�L�X�g��̃Z�b�V�����v�́A����̃R���e�L�X�g�̃X�R�[�v�̂Ȃ��ŗL���ȃZ�b�V�����̂��Ƃł��B
+ �������A�ʏ�A�v���P�[�V�������ƂɃR���e�L�X�g��\�������̂̒�`�͈قȂ�܂��B
+ ������A�قȂ镡���̃R���e�L�X�g�́A�����_�ɑ��ĈقȂ�X�R�[�v���`���܂��B
+ �o�[�W����3.0���O�� Hibernate �ł́A����� <literal>ThreadLocal</literal> �x�[�X�́u�R���e�L�X�g��̃Z�b�V�����v��
+ ���p���邩�A <literal>HibernateUtil</literal> �̂悤�ȃw���p�[�N���X�𗘗p���邩�A
+ proxy/interception �x�[�X�́u�R���e�L�X�g��̃Z�b�V�����v�����
+ �iSpring �� Pico �̂悤�ȁj�T�[�h�p�[�e�B�̃t���[�����[�N�𗘗p���邩�̂����ꂩ�ł����B
+ </para>
+
+ <para>
+ �o�[�W���� 3.0.1 ����AHibernate �ɂ� <literal>SessionFactory.getCurrentSession()</literal> ��
+ �����܂����B ����́A <literal>JTA</literal> �g�����U�N�V�����̎g�p��O��ɂ��Ă��܂��B
+ <literal>JTA</literal> �g�����U�N�V�����́A���݂̃Z�b�V�����̃X�R�[�v�ƃR���e�L�X�g�̗������`���܂��B
+ Hibernate �`�[���́A���̂��Ƃ�咣���܂��B
+ ����ȃX�^���h�A������ <literal>JTA TransactionManager</literal> ���������n������A
+ <literal>J2EE</literal> �R���e�i��Ƀf�v���C����邩�ǂ����ɂ�����炸�A
+ �قƂ�ǂ́i���ׂĂƂ͌���Ȃ����j�A�v���P�[�V�������A
+ <literal>JTA</literal> �g�����U�N�V�����Ǘ���g�p���ׂ��ł���ƁB
+ ���̍l���Ɋ�Â��ƁA <literal>JTA</literal> �x�[�X�́u�R���e�L�X�g��̃Z�b�V�����v��
+ �g�������Ȃ��ł��傤�B
+ </para>
+
+ <para>
+ �������A�o�[�W���� 3.1 ����́A <literal>SessionFactory.getCurrentSession()</literal> �̌�̏������A
+ �v���K�u���ɂȂ�܂����B
+ �����āA���݂̃Z�b�V�������`����X�R�[�v�ƃR���e�L�X�g�̃v���K�r���e�B��\�ɂ��邽�߂ɁA
+ �V�����g���C���^�t�F�[�X ( <literal>org.hibernate.context.CurrentSessionContext</literal> ) ��
+ �V�����\���p�����[�^ ( <literal>hibernate.current_session_context_class</literal> ) ���lj�����܂����B
+ </para>
+
+ <para>
+ <literal>org.hibernate.context.CurrentSessionContext</literal> �C���^�t�F�[�X�̋K��ɂ��Ă�
+ �ڍׂȓ�e�� Javadoc ��Q�Ƃ��Ă��������B
+ ����ɂ́A <literal>currentSession()</literal> �Ƃ���1�̃��\�b�h����`����Ă���A
+ ���̎����́A���݂́u�R���e�L�X�g��̃Z�b�V�����v��ǐՂ��邱�ƂɐӔC�����܂��B
+ ���̂܂g����悤�ɁAHibernate�͂��̃C���^�t�F�[�X�̎�����2���Ă��܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>org.hibernate.context.JTASessionContext</literal> -
+ <literal>JTA</literal> �g�����U�N�V�����ɂ���āA���݂̃Z�b�V�������ǐՂ���A
+ �X�R�[�v���߂��܂��B���̏����́A�Â�JTA�����̃A�v���[�`�Ƃ܂����������ł��B
+ �ڍׂ�Javadoc��Q�Ƃ��Ă��������B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>org.hibernate.context.ThreadLocalSessionContext</literal> -
+ �X���b�h�̎��s�ɂ���āA���݂̃Z�b�V�������ǐՂ���܂��B
+ �ڍׂ�Javadoc��Q�Ƃ��Ă��������B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>org.hibernate.context.ManagedSessionContext</literal> -
+ �X���b�h�̎��s�ɂ���āA���݂̃Z�b�V�������ǐՂ���܂��B
+ �������A���̃N���X��static���\�b�h�� <literal>Session</literal> �C���X�^���X��
+ �o�C���h/�A���o�C���h����ӔC�͂��Ȃ��ɂ���܂��B
+ ����͌����� <literal>Session</literal> ��I�[�v���A�t���b�V���A�N���[�Y���܂���B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ �n�߂�2�̎����́A"1�Z�b�V���� - 1�f�[�^�x�[�X�g�����U�N�V����" �v���O���~���O���f������܂��B
+ ����� <emphasis>���N�G�X�g���Ƃ̃Z�b�V�����isession-per-request�j</emphasis> �Ƃ��Ă�m���Ă���A�g���Ă��܂��B
+ Hibernate �Z�b�V�����̊J�n�ƏI���́A�f�[�^�x�[�X�g�����U�N�V�����̊��ԂŌ��܂�܂��B
+ JTA��g��Ȃ����ʂ�JSE�ŁA�v���O������̃g�����U�N�V�������E�ݒ��s���Ȃ�A
+ �R�[�h�����b�̃g�����U�N�V�����V�X�e����B�����邽�߂ɁA
+ Hibernate <literal>Transaction</literal> API��g���Ƃ悢�ł��傤�B
+ JTA��g���Ȃ�A�g�����U�N�V�����̋��E�ݒ�ɂ́AJTA�C���^�[�t�F�C�X��g���Ă��������B
+ CMT��T�|�[�g����EJB�R���e�i�Ŏ��s������Ȃ�A�g�����U�N�V�������E�͐錾�I�ɒ�`�ł��邽�߁A
+ �R�[�h��Ńg�����U�N�V������Z�b�V�����̋��E��ݒ肷��K�v�͂���܂���B
+ ����ɏڍׂȏ���R�[�h�̗�́A <xref linkend="transactions"/> ��Q�Ƃ��Ă��������B
+ </para>
+
+ <para>
+ <literal>hibernate.current_session_context_class</literal> �ݒ�p�����[�^�́A
+ <literal>org.hibernate.context.CurrentSessionContext</literal> �̂ǂ̎�����g������w�肵�܂��B
+ ���ʌ݊����̂��߁A���̃p�����[�^���ݒ肳�ꂸ
+ <literal>org.hibernate.transaction.TransactionManagerLookup</literal> ���ݒ肳��Ă����ꍇ�A
+ Hibernate�� <literal>org.hibernate.context.JTASessionContext</literal> ��g�����Ƃɒ��ӂ��Ă��������B
+ �ʏ킱�̃p�����[�^�̒l�ɂ́A3�̎����̒�����g�p��������N���X�̖��O�ڎw�肵�܂��B
+ �������A"jta", "thread", "managed"�Ƃ������ꂼ��̏ȗ�����p�ӂ���Ă��܂��B
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/association_mapping.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/association_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/association_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/association_mapping.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,620 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="associations">
+
+ <title>�֘A�}�b�s���O</title>
+
+ <sect1 id="assoc-intro" revision="1">
+ <title>�C���g���_�N�V����</title>
+
+ <para>
+ �֘A�}�b�s���O�͂����Η����ł�����̂ɂȂ�܂��B
+ ���̏͂ł́A��{�I�Ȉ��̃P�[�X�ɂ��ďq�ׂ܂��B
+ �P�����̃}�b�s���O����n�߁A���ꂩ��o�����̃P�[�X�ɂ��čl���Ă����܂��B
+ ��Ƃ��āA<literal>Person</literal> �� <literal>Address</literal> ��p���܂��B
+ </para>
+
+ <para>
+ �֘A�́A�����e�[�u�������邩���ǂ����ƁA
+ ���d�x�ɂ���ĕ��ނ��邱�Ƃɂ��܂��B
+ </para>
+
+ <para>
+ ���ׂĂ̗��not null�̊O���L�[��g�p���܂��B
+ �����Hibernate�̗v���ł͂���܂���B
+ not null�����O�����Ƃ��Ă�A�}�b�s���O�͖��Ȃ����삵�܂��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="assoc-unidirectional" revision="1">
+ <title>�P�����֘A</title>
+
+ <sect2 id="assoc-unidirectional-m21">
+ <title>���Έ�</title>
+
+ <para>
+ <emphasis>�P�������Έ�֘A</emphasis> �͒P�����֘A�̒��ōł��ʓI�Ȃ�̂ł��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-121">
+ <title>��Έ�</title>
+
+ <para>
+ <emphasis>�O���L�[�̒P������Έ�֘A</emphasis> �͂قƂ�Ǔ�����̂ł��B
+ �B��Ⴄ�̂́A�J�����̃��j�[�N�Ȑ���ł��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ unique="true"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ <emphasis>��L�[�̒P������Έ�֘A</emphasis> �͒ʏ�A���ʂ�ID�W�F�l���[�^��g���܂��B
+ �i���̗�ł͊֘A�̕������t�ɂȂ��Ă��邱�Ƃɒ��ӂ��Ă��������j
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+</class>
+
+<class name="Address">
+ <id name="id" column="personId">
+ <generator class="foreign">
+ <param name="property">person</param>
+ </generator>
+ </id>
+ <one-to-one name="person" constrained="true"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( personId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-12m">
+ <title>��Α�</title>
+
+ <para>
+ <emphasis>�O���L�[�̒P������Α��֘A</emphasis> �͂ƂĂ����ȃP�[�X�ŁA
+ ���܂萄������Ă��܂���B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses">
+ <key column="personId"
+ not-null="true"/>
+ <one-to-many class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( addressId bigint not null primary key, personId bigint not null )
+ ]]></programlisting>
+
+ <para>
+ ���̂悤�Ȋ֘A�̂��߂Ɍ����e�[�u����g�����Ƃ��E�߂��܂��B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-unidirectional-join" revision="1">
+ <title>�����e�[�u����g�����P�����֘A</title>
+
+ <sect2 id="assoc-unidirectional-join-12m">
+ <title>��Α�</title>
+
+ <para>
+ <emphasis>�����e�[�u����g�����P������Α��֘A</emphasis>
+ �͂��D�܂����ł��B
+ <literal>unique="true"</literal> �̎w��ɂ��A���d�x�����Α������Α�
+ �ɕς�������Ƃɒ��ӂ��ĉ������B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ unique="true"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId not null, addressId bigint not null primary key )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-m21">
+ <title>���Έ�</title>
+
+ <para>
+ <emphasis>�����e�[�u���̒P�������Έ�֘A</emphasis> ��
+ �֘A���C�ӂł���Ƃ��ɔ��Ɉ�ʓI�Ȃ�̂ł��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId" unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-121">
+ <title>��Έ�</title>
+
+ <para>
+ <emphasis>�����e�[�u���̒P������Έ�֘A</emphasis> �́A�{���ɓ���ł���
+ �s�\�ł͂���܂���B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId"
+ unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-m2m">
+ <title>���Α�</title>
+
+ <para>
+ �Ō�ɁA<emphasis>�P�������Α��֘A</emphasis> �����܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-bidirectional" revision="1">
+ <title>�o�����֘A</title>
+
+ <sect2 id="assoc-bidirectional-m21" revision="2">
+ <title>��Α�/���Έ�</title>
+
+ <para>
+ <emphasis>�o�������Έ�֘A</emphasis> �͍ł��ʓI�Ȋ֘A�ł��B
+ �i�W���I�Ȑe�q�W�ł��j
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <set name="people" inverse="true">
+ <key column="addressId"/>
+ <one-to-many class="Person"/>
+ </set>
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ <literal>List</literal> �i�܂��͑��̃C���f�b�N�X�t���̃R���N�V�����j��g���Ȃ�A
+ �O���L�[�� <literal>key</literal> �J������ <literal>not null</literal> �ɐݒ肵�A
+ �R���N�V���������e�v�f�̃C���f�b�N�X�����e�i���X����悤�ɁA
+ �֘A�����K�v������܂�
+ �i<literal>update="false"</literal> ���� <literal>insert="false"</literal>
+ �Ɛݒ肵�āA���Α����z�I��inverse�ɂ��܂��j�F
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id"/>
+ ...
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ insert="false"
+ update="false"/>
+</class>
+
+<class name="Address">
+ <id name="id"/>
+ ...
+ <list name="people">
+ <key column="addressId" not-null="true"/>
+ <list-index column="peopleIdx"/>
+ <one-to-many class="Person"/>
+ </list>
+</class>]]></programlisting>
+
+ <para>
+ ����O���L�[�J������ <literal>NOT NULL</literal> �ł���Ȃ�A
+ �R���N�V�����}�b�s���O�� <literal><key></literal> �v�f��
+ <literal>not-null="true"</literal> �ɂ��邱�Ƃ͏d�v�ł��B
+ ����q�ɂȂ��� <literal><column></literal> �v�f�����ł͂Ȃ��A
+ <literal><key></literal> �v�f�� <literal>not-null="true"</literal>
+ �ƒ�`���Ȃ��悤�ɂ��Ă��������B
+ </para>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-121">
+ <title>��Έ�</title>
+
+ <para>
+ <emphasis>�O���L�[�̑o������Έ�֘A</emphasis> �͔��Ɉ�ʓI�ł��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ unique="true"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <one-to-one name="person"
+ property-ref="address"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ <emphasis>��L�[�̑o������Έ�֘A</emphasis> �͓����ID�W�F�l���[�^��g���܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <one-to-one name="address"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="personId">
+ <generator class="foreign">
+ <param name="property">person</param>
+ </generator>
+ </id>
+ <one-to-one name="person"
+ constrained="true"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( personId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-bidirectional-join" revision="1">
+ <title>�����e�[�u����g�����o�����֘A</title>
+
+ <sect2 id="assoc-bidirectional-join-12m">
+ <title>��Α�/���Έ�</title>
+
+ <para>
+ <emphasis>�����e�[�u���̑o������Α��֘A</emphasis> �ł��B
+ <literal>inverse="true"</literal> ���֘A�[�A�R���N�V�����A�����̂����ꂩ��
+ �ݒ�ł��邱�Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses"
+ table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ unique="true"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ inverse="true"
+ optional="true">
+ <key column="addressId"/>
+ <many-to-one name="person"
+ column="personId"
+ not-null="true"/>
+ </join>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null primary key )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-join-121">
+ <title>��Έ�</title>
+
+ <para>
+ <emphasis>�����e�[�u���̑o������Έ�֘A</emphasis>
+ �͔��ɓ���ł����A�\�ł��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId"
+ unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true"
+ inverse="true">
+ <key column="addressId"
+ unique="true"/>
+ <many-to-one name="address"
+ column="personId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-join-m2m" revision="1">
+ <title>���Α�</title>
+
+ <para>
+ �Ō�ɁA<emphasis>�o�������Α��֘A</emphasis> �����܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <set name="people" inverse="true" table="PersonAddress">
+ <key column="addressId"/>
+ <many-to-many column="personId"
+ class="Person"/>
+ </set>
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-complex">
+ <title>��蕡�G�Ȋ֘A�}�b�s���O</title>
+
+ <para>
+ ��蕡�G�Ȋ֘A������ <emphasis>�ɂ߂�</emphasis> �H�ł��B
+ �}�b�s���O�h�L�������g��SQL���ߍ��ނ��ƂŁA
+ ����ɕ��G�ȏ������Ƃ��ł��܂��B
+ �Ⴆ�A<literal>accountNumber</literal>, <literal>effectiveEndDate</literal>,
+ <literal>effectiveStartDate</literal> �J��������account�i�����j���̗�������e�[�u���́A
+ �ȉ��̂悤�Ƀ}�b�s���O���܂��B
+ </para>
+
+ <programlisting><![CDATA[<properties name="currentAccountKey">
+ <property name="accountNumber" type="string" not-null="true"/>
+ <property name="currentAccount" type="boolean">
+ <formula>case when effectiveEndDate is null then 1 else 0 end</formula>
+ </property>
+</properties>
+<property name="effectiveEndDate" type="date"/>
+<property name="effectiveStateDate" type="date" not-null="true"/>]]></programlisting>
+
+ <para>
+ �����āA�֘A�� <emphasis>�����_��</emphasis> �C���X�^���X
+ �i<literal>effectiveEndDate</literal> ��null�ł����́j�Ƀ}�b�s���O���܂��B
+ �ȉ��̂悤�ɂȂ�܂��F
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="currentAccountInfo"
+ property-ref="currentAccountKey"
+ class="AccountInfo">
+ <column name="accountNumber"/>
+ <formula>'1'</formula>
+</many-to-one>]]></programlisting>
+
+ <para>
+ ����ɕ��G�ȗ�ł́A<literal>Employee�i�]�ƈ��j</literal> �� <literal>Organization�i�g�D�j</literal>
+ �Ԃ̊֘A�� <literal>Employment�i�ٗp�j</literal> �e�[�u���ŕێ������ꍇ��z�����Ă��������B
+ ���̃e�[�u���ɂ͌ٗp�f�[�^�̗������ׂĊ܂܂�܂��B
+ ����Ə]�ƈ��� <emphasis>�ł�ŋ߂�</emphasis> �ٗp�҂�\���֘A
+ �i�ł�ŋ߂� <literal>startDate</literal> ����́j�́A���̂悤�Ƀ}�b�s���O�ł��܂��F
+ </para>
+
+ <programlisting><![CDATA[<join>
+ <key column="employeeId"/>
+ <subselect>
+ select employeeId, orgId
+ from Employments
+ group by orgId
+ having startDate = max(startDate)
+ </subselect>
+ <many-to-one name="mostRecentEmployer"
+ class="Organization"
+ column="orgId"/>
+</join>]]></programlisting>
+
+ <para>
+ ���̋@�\�͔��ɋ��͂ł��B
+ ���������̂悤�ȏꍇ�A���ʂ�HQL��criteria�N�G����g�����������H�I�ł��B
+ </para>
+
+ </sect1>
+
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/basic_mapping.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/basic_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/basic_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/basic_mapping.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,3485 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+
+<chapter id="mapping">
+ <title>��{�I��O/R�}�b�s���O</title>
+
+ <sect1 id="mapping-declaration" revision="1">
+ <title>�}�b�s���O��`</title>
+
+ <para>
+ �I�u�W�F�N�g/�����[�V���i���}�b�s���O�͒ʏ�XML�h�L�������g�Œ�`���܂��B
+ �}�b�s���O�h�L�������g�́A�ǂ݂₷�����ƂŕҏW���₷���悤�Ƀf�U�C������Ă��܂��B
+ �}�b�s���O�����Java���S�A�܂�e�[�u����`�ł͂Ȃ��i���N���X�̒�`�Ɋ�Â��č\�z����Ă��܂��B
+ </para>
+
+ <para>
+ ������Hibernate���[�U��XML�}�b�s���O�̋L�q����Ƃōs���܂����A
+ XDoclet, Middlegen, AndroMDA�Ƃ����悤�ȃ}�b�s���O�h�L�������g������c�[����
+ ���������݂��܂��B
+ </para>
+
+ <para>
+ �T���v���̃}�b�s���O����n�߂܂��傤�F
+ </para>
+
+ <programlisting id="mapping-declaration-ex1" revision="1"><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class name="Cat"
+ table="cats"
+ discriminator-value="C">
+
+ <id name="id">
+ <generator class="native"/>
+ </id>
+
+ <discriminator column="subclass"
+ type="character"/>
+
+ <property name="weight"/>
+
+ <property name="birthdate"
+ type="date"
+ not-null="true"
+ update="false"/>
+
+ <property name="color"
+ type="eg.types.ColorUserType"
+ not-null="true"
+ update="false"/>
+
+ <property name="sex"
+ not-null="true"
+ update="false"/>
+
+ <property name="litterId"
+ column="litterId"
+ update="false"/>
+
+ <many-to-one name="mother"
+ column="mother_id"
+ update="false"/>
+
+ <set name="kittens"
+ inverse="true"
+ order-by="litter_id">
+ <key column="mother_id"/>
+ <one-to-many class="Cat"/>
+ </set>
+
+ <subclass name="DomesticCat"
+ discriminator-value="D">
+
+ <property name="name"
+ type="string"/>
+
+ </subclass>
+
+ </class>
+
+ <class name="Dog">
+ <!-- ������Dog�p�̃}�b�s���O�����܂� -->
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ �}�b�s���O�h�L�������g�̓�e�������܂��B�B
+ �������A�����ł�Hibernate�����s���Ɏg���h�L�������g�v�f�Ƒ����ɂ��Ă̂ݐ�����܂��B
+ �}�b�s���O�h�L�������g�́A�������̃I�v�V���������Ɨv�f��܂�ł��܂��i�Ⴆ�� <literal>not-null</literal> �����j�B
+ �����̓X�L�[�}�G�N�X�|�[�g�c�[�����o�͂���f�[�^�x�[�X�X�L�[�}�ɉe����^�����̂ł��B
+
+ </para>
+
+
+
+ <sect2 id="mapping-declaration-doctype" revision="3">
+ <title>Doctype</title>
+
+ <para>
+ XML�}�b�s���O�ł́A�����������悤�ȃh�L�������g�^��K����`���ׂ��ł��B
+ ���ۂ�DTD�́A��L��URL�� <literal>hibernate-x.x.x/src/org/hibernate</literal> �f�B���N�g���A �܂���
+ <literal>hibernate.jar</literal> ��ɂ���܂��B
+ Hibernate�͏�ɁA���̃N���X�p�X���DTD��T���n�߂܂��B
+ �C���^�[�l�b�g�ɂ���DTD�t�@�C����T�����Ƃ����Ȃ�A
+ �N���X�p�X�̓�e���āADTD�錾��m�F���Ă��������B
+ </para>
+
+
+
+ <sect3 id="mapping-declaration-entity-resolution">
+ <title>
+ �G���e�B�e�B�E���]���o
+ </title>
+ <para>
+ �O�q�����悤�ɁAHibernate�͂܂��N���X�p�X���DTD������悤�Ƃ��܂��B
+ <literal>org.xml.sax.EntityResolver</literal> �̃J�X�^��������
+ XML�t�@�C����ǂݍ��ނ��߂�SAXReader�ɓo�^���邱�Ƃɂ���āADTD������܂��B
+ ���̃J�X�^���� <literal>EntityResolver</literal> ��2�̈قȂ�V�X�e��ID���O��Ԃ�F�����܂��B
+
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>Hibernate���O���</literal> �́A���]���o��
+ <literal>http://hibernate.sourceforge.net/</literal> �Ŏn�܂�V�X�e��ID�ɓ��B�����Ƃ��ɁA
+ �F������܂��B
+ �����ă��]���o�́AHibernate�̃N���X���[�h�����N���X���[�_��p���āA
+ �����̃G���e�B�e�B������悤�Ƃ��܂��B
+
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>���[�U���O���</literal> �́A���]���o��
+ URL�v���g�R���� <literal>classpath://</literal> ��g�����V�X�e��ID�ɓ��B�����Ƃ��ɁA
+ �F������܂��B�����ă��]���o�́A(1)�J�����g�X���b�h�̃R���e�L�X�g�N���X���[�_�[�A
+ �܂���(2)Hibernate�̃N���X���[�h�����N���X���[�_��g���āA
+ �����̃G���e�B�e�B������悤�Ƃ��܂��B
+
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ ���L�́A���[�U���O��Ԃ�g������ł��F
+
+ </para>
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" [
+ <!ENTITY types SYSTEM "classpath://your/domain/types.xml">
+]>
+
+<hibernate-mapping package="your.domain">
+ <class name="MyEntity">
+ <id name="id" type="my-custom-id-type">
+ ...
+ </id>
+ <class>
+ &types;
+</hibernate-mapping>]]></programlisting>
+ <para>
+ ������ <literal>types.xml</literal> �� <literal>your.domain</literal> �p�b�P�[�W��̃��\�[�X�ł���A
+ �J�X�^�� <xref linkend="mapping-types-custom">typedef</xref> ��܂ނ܂��B
+ </para>
+ </sect3>
+
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-mapping" revision="3">
+ <title>hibernate-mapping</title>
+
+ <para>
+ ���̗v�f�ɂ͂������I�v�V��������������܂��B<literal>schema</literal> ������ <literal>catalog</literal> �����́A
+ ���̃}�b�s���O���Q�Ƃ���e�[�u�����A���̑����ɂ���Ďw�肳�ꂽ�X�L�[�}��(�܂���)�J�^���O�ɑ����邱�Ƃ�w�肵�܂��B
+ ���̑������w�肳���ƁA�e�[�u�����͗^����ꂽ�X�L�[�}���ƃJ�^���O���ŏC������܂��B�����̑������w�肳��Ă��Ȃ���A
+ �e�[�u�����͏C������܂���B<literal>default-cascade</literal> �����́A
+ <literal>cascade</literal> ������w�肵�Ă��Ȃ��v���p�e�B��R���N�V�����ɁA
+ �ǂ̃J�X�P�[�h�X�^�C�����蓖�Ă邩��w�肵�܂��B
+ <literal>auto-import</literal> �����́A
+ �N�G�������ŏC������Ă��Ȃ��N���X����A�f�t�H���g�Ŏg����悤�ɂ��܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="hm1" coords="2 55"/>
+ <area id="hm2" coords="3 55"/>
+ <area id="hm3" coords="4 55"/>
+ <area id="hm4" coords="5 55"/>
+ <area id="hm5" coords="6 55"/>
+ <area id="hm6" coords="7 55"/>
+ <area id="hm7" coords="8 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<hibernate-mapping
+ schema="schemaName"
+ catalog="catalogName"
+ default-cascade="cascade_style"
+ default-access="field|property|ClassName"
+ default-lazy="true|false"
+ auto-import="true|false"
+ package="package.name"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="hm1">
+ <para>
+ <literal>schema</literal>�i�I�v�V�����j�F�f�[�^�x�[�X�X�L�[�}�̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="hm2">
+ <para>
+ <literal>catalog</literal> �i�I�v�V�����j�F�f�[�^�x�[�X�J�^���O�̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="hm3">
+ <para>
+ <literal>default-cascade</literal> �i�I�v�V���� - �f�t�H���g�� <literal>none</literal>�j�F
+ �f�t�H���g�̃J�X�P�[�h�X�^�C���B
+ </para>
+ </callout>
+ <callout arearefs="hm4">
+ <para>
+ <literal>default-access</literal> (�I�v�V���� - �f�t�H���g�� <literal>property</literal> �j�F
+ Hibernate���v���p�e�B�ɃA�N�Z�X����ۂɍ̂�ׂ��헪�B <literal>PropertyAccessor</literal>
+ ��������邱�ƂŃJ�X�^�}�C�Y�\�B
+
+ </para>
+ </callout>
+ <callout arearefs="hm5">
+ <para>
+ <literal>default-lazy</literal> (�I�v�V���� - �f�t�H���g�� <literal>true</literal> )�F
+ <literal>lazy</literal> �������w�肳��Ă��Ȃ��N���X��R���N�V�����}�b�s���O�ɑ���f�t�H���g�l�B
+ </para>
+ </callout>
+ <callout arearefs="hm6">
+ <para>
+ <literal>auto-import</literal> �i�I�v�V���� - �f�t�H���g�� <literal>true</literal>�j�F
+ �N�G�������ŁA�i���̃}�b�s���O��̃N���X�́j�C������Ă��Ȃ��N���X����g���邩�ǂ�����w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="hm7">
+ <para>
+ <literal>package</literal> (�I�v�V����): �}�b�s���O�h�L�������g��ŏC������Ă��Ȃ��N���X���ɑ��Ċ��蓖�Ă�A
+ �p�b�P�[�W�̐ړ���(prefix)��w�肵�܂��B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ �i�C������Ă��Ȃ��j�������O�̉i���N���X��2����Ȃ�A
+ <literal>auto-import="false"</literal> ��ݒ肷�ׂ��ł��B
+ 2�̃N���X�Ɂh�C���|�[�g���ꂽ�h�������O���蓖�Ă悤�Ƃ���ƁAHibernate�͗�O�𓊂��܂��B
+ </para>
+
+ <para>
+ <literal>hibernate-mapping</literal> �v�f�́A�ŏ��̗�Ŏ������悤�ɂ������̉i�� <literal><class></literal>
+ �}�b�s���O��l�X�g�ł��܂��B
+ �������A�P�̃}�b�s���O�t�@�C���ł͂����ЂƂ̉i���N���X(�܂��͂ЂƂ̃N���X�K�w)�Ƀ}�b�s���O����悤�ɂ��A
+ ����ɉi���X�[�p�[�N���X�̌�Ŏw�肷��ׂ��ł��傤(�������̃c�[���͂��̂悤�ȃ}�b�s���O�t�@�C����z�肵�Ă��܂�)�B
+ �Ⴆ�Ύ��̂悤�ɂȂ�܂��B�F <literal>Cat.hbm.xml</literal> ,
+ <literal>Dog.hbm.xml</literal> , �܂��͌p����g���Ȃ� <literal>Animal.hbm.xml</literal> �B
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-class" revision="3">
+ <title>class</title>
+
+ <para>
+ <literal>class</literal> �v�f��g���āA�i���N���X��錾�ł��܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="class1" coords="2 55"/>
+ <area id="class2" coords="3 55" />
+ <area id="class3" coords="4 55"/>
+ <area id="class4" coords="5 55" />
+ <area id="class5" coords="6 55"/>
+ <area id="class6" coords="7 55" />
+ <area id="class7" coords="8 55"/>
+ <area id="class8" coords="9 55" />
+ <area id="class9" coords="10 55" />
+ <area id="class10" coords="11 55"/>
+ <area id="class11" coords="12 55"/>
+ <area id="class12" coords="13 55"/>
+ <area id="class13" coords="14 55"/>
+ <area id="class14" coords="15 55"/>
+ <area id="class15" coords="16 55"/>
+ <area id="class16" coords="17 55"/>
+ <area id="class17" coords="18 55"/>
+ <area id="class18" coords="19 55"/>
+ <area id="class19" coords="20 55"/>
+ <area id="class20" coords="21 55"/>
+ <area id="class21" coords="22 55"/>
+
+ </areaspec>
+ <programlisting><![CDATA[<class
+ name="ClassName"
+ table="tableName"
+ discriminator-value="discriminator_value"
+ mutable="true|false"
+ schema="owner"
+ catalog="catalog"
+ proxy="ProxyInterface"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ select-before-update="true|false"
+ polymorphism="implicit|explicit"
+ where="arbitrary sql where condition"
+ persister="PersisterClass"
+ batch-size="N"
+ optimistic-lock="none|version|dirty|all"
+ lazy="true|false"
+ entity-name="EntityName"
+ check="arbitrary sql check condition"
+ rowid="rowid"
+ subselect="SQL expression"
+ abstract="true|false"
+ entity-name="EntityName"
+ node="element-name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="class1">
+ <para>
+ <literal>name</literal> (�I�v�V����)�F�i���N���X�i�܂��̓C���^�[�t�F�C�X�j�̊��S�C��Java�N���X���B
+ ������̑�����w�肵�Ȃ���APOJO�ł͂Ȃ��G���e�B�e�B�ɑ���}�b�s���O�Ƃ��Ĉ����܂��B
+
+ </para>
+ </callout>
+ <callout arearefs="class2">
+ <para>
+ <literal>table</literal> (�I�v�V���� - �f�t�H���g�͏C������Ă��Ȃ��N���X��)�F�f�[�^�x�[�X�e�[�u���̖��O
+ </para>
+ </callout>
+ <callout arearefs="class3">
+ <para>
+ <literal>discriminator-value</literal> (�I�v�V���� - �f�t�H���g�̓N���X��)�F
+ �|�����[�t�B�b�N�ȐU�镑���Ɏg����X�̃T�u�N���X���ʂ��邽�߂̒l�B
+ �l�� <literal>null</literal> �� <literal>not null</literal> �̂����ꂩ����܂��B
+ </para>
+ </callout>
+ <callout arearefs="class4">
+ <para>
+ <literal>mutable</literal> (�I�v�V�����A �f�t�H���g�� <literal>true</literal> )�F
+ ���̃N���X�̃C���X�^���X���X�V�\�i�܂��͕s�\�j�ł��邱�Ƃ�w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="class5">
+ <para>
+ <literal>schema</literal> �i�I�v�V�����j�F
+ ���[�g�� <literal><hibernate-mapping></literal> �v�f�Ŏw�肳�ꂽ�X�L�[�}����I�[�o�[���C�h���܂��B
+ </para>
+ </callout>
+ <callout arearefs="class6">
+ <para>
+ <literal>catalog</literal> �i�I�v�V�����j�F���[�g�� <literal><hibernate-mapping></literal>
+ �v�f�Ŏw�肳�ꂽ�J�^���O����I�[�o�[���C�h���܂��B
+ </para>
+ </callout>
+ <callout arearefs="class7">
+ <para>
+ <literal>proxy</literal> �i�I�v�V�����j�F�x���������v���L�V�Ɏg���C���^�[�t�F�C�X��w�肵�܂��B
+ �i��������N���X�����̂�̂�w�肷�邱�Ƃ�\�ł��B
+ </para>
+ </callout>
+ <callout arearefs="class8">
+ <para>
+ <literal>dynamic-update</literal> �i�I�v�V�����A �f�t�H���g�� <literal>false</literal> �j�F
+ �l���ύX���ꂽ�J����������܂�SQL�� <literal>UPDATE</literal> ����A���s���ɐ������邱�Ƃ�w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="class9">
+ <para>
+ <literal>dynamic-insert</literal> �i�I�v�V����, �f�t�H���g�� <literal>false</literal> �j�F
+ �l��null�ł͂Ȃ��J����������܂�SQL�� <literal>INSERT</literal> ����A���s���ɐ������邱�Ƃ�w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="class10">
+ <para>
+ <literal>select-before-update</literal> (�I�v�V����, �f�t�H���g�� <literal>false</literal>):
+ �I�u�W�F�N�g���ύX���ꂽ�̂��m���łȂ��Ȃ�AHibernate��SQL�� <literal>UPDATE</literal> ��
+ <emphasis>�����Ď��s���Ȃ�</emphasis> ���Ƃ�w�肵�܂��B
+ �������̏ꍇ(���ۓI�ɂ́A�ꎞ�I�u�W�F�N�g�� <literal>update()</literal> ��g���A
+ �V�����Z�b�V�����Ɗ֘A�t����ꂽ������)�A<literal>UPDATE</literal> �����ۂɕK�v���ǂ������肷�邽�߂ɁA
+ Hibernate���]����SQL�� <literal>SELECT</literal> ������s���邱�Ƃ�Ӗ����܂��B
+ </para>
+ </callout>
+ <callout arearefs="class11">
+ <para>
+ (optional, �f�t�H���g�ł� <literal>implicit</literal> ): implicit�i�Öفj��explicit�i�����j�́A
+ �ǂ���̃N�G���|�����[�t�B�Y����g�������肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="class12">
+ <para>
+ <literal>where</literal> �i�I�v�V�����j�F
+ ���̃N���X�̃I�u�W�F�N�g��������Ƃ��Ɏg�p����A�C�ӂ�SQL�� <literal>WHERE</literal> ����w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="class13">
+ <para>
+ <literal>persister</literal> �i�I�v�V�����j�F�J�X�^�� <literal>ClassPersister</literal> ��w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="class14">
+ <para>
+ <literal>batch-size</literal> �i�I�v�V����, �f�t�H���g�� <literal>1</literal> �j�F
+ ���ʎq�ł��̃N���X�̃C���X�^���X������Ƃ��́u�o�b�`�T�C�Y�v��w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="class15">
+ <para>
+ <literal>optimistic-lock</literal> �i�I�v�V����,�f�t�H���g�� <literal>version</literal> �j�F
+ �y�σ��b�N�헪���肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="class16">
+ <para>
+ <literal>lazy</literal> �i�I�v�V�����j�F <literal>lazy="false"</literal> �Ɛݒ肷�邱�ƂŁA
+ �x���t�F�b�`���ł��Ȃ��Ȃ�܂��B
+ </para>
+ </callout>
+ <callout arearefs="class17">
+ <para>
+ <literal>entity-name</literal> �i�I�v�V�����A�f�t�H���g�̓N���X���j�F
+ Hibernate3�ł̓N���X��������}�b�s���O�ł��i�ꍇ�ɂ���Ă͈Ⴄ�e�[�u���ɑ��Ă�j�A
+ Java���x����Map��XML�ŕ\�������G���e�B�e�B�}�b�s���O���\�ł��B
+ �����̏ꍇ�A�G���e�B�e�B�ɑ��ĔC�ӂ̖��O��A�����I�ɕt���Ȃ��Ă͂Ȃ�܂���B
+ �ڂ����� <xref linkend="persistent-classes-dynamicmodels"/> �� <xref linkend="xml"/> ��Q�Ƃ��Ă��������B
+ </para>
+ </callout>
+ <callout arearefs="class18">
+ <para>
+ <literal>check</literal> �i�I�v�V�����j�F�����I�ɃX�L�[�}�����邽�߂ɁA
+ �����s�� <emphasis>check</emphasis> ���������SQL���B
+ </para>
+ </callout>
+ <callout arearefs="class19">
+ <para>
+ <literal>rowid</literal> �i�I�v�V�����j�FHibernate�́A�����T�|�[�g���Ă���f�[�^�x�[�X��ROWID��
+ �Ă���̂�g�����Ƃ��ł��܂��B
+ �Ⴆ��Oracle��g���Ă���Ƃ��A���̃I�v�V������ <literal>rowid</literal> ��ݒ肷��A
+ Hiberante��update���������邽�߂� <literal>rowid</literal> �Ƃ������ʂȃJ������g�����Ƃ��ł��܂��B
+ ROWID�͏ڍׂȎ����ł���A�ۑ����ꂽ�^�v���̕����I�Ȉʒu��\���Ă��܂��B
+ </para>
+ </callout>
+ <callout arearefs="class20">
+ <para>
+ <literal>subselect</literal> �i�I�v�V�����j�F�s�ς��ǂݎ���p�ł���G���e�B�e�B��
+ �f�[�^�x�[�X�̕��⍇���isubselect�j�Ƀ}�b�s���O���܂��B
+ ������̃e�[�u���̑���Ƀr���[����������ΗL�p�ł����A
+ �����łȂ��̂Ȃ�L�p�ł͂���܂���B���ڂ������͉��L��Q�Ƃ��Ă��������B
+ </para>
+ </callout>
+ <callout arearefs="class21">
+ <para>
+ <literal>abstract</literal> �i�I�v�V�����j�F
+ <literal><union-subclass></literal> �K�w��̒��ۃX�[�p�[�N���X�Ƀ}�[�N���邽�߂Ɏg���܂��B
+ </para>
+ </callout>
+
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ �i���N���X�̖��O�ɃC���^�[�t�F�C�X��w�肵�Ă�܂�������肠��܂���B
+ ���̂Ƃ��� <literal><subclass></literal> �v�f��g���āA
+ ���̃C���^�[�t�F�C�X���������N���X���`���Ă��������B
+ <emphasis>static</emphasis> �ȓ���N���X�ł�i�����ł��܂��B
+ ���̂Ƃ��͕W���`���A�Ⴆ�� <literal>eg.Foo$Bar</literal> ��g���ăN���X����w�肵�Ă��������B
+ </para>
+
+ <para>
+ <literal>mutable="false"</literal> �w������s�σN���X�́A
+ �A�v���P�[�V�����ɂ��X�V��폜���o���Ȃ����Ƃ�����܂��B
+ ����ɂ��AHibernate���p�t�H�[�}���X�������P���܂��B
+ </para>
+
+ <para>
+ �I�v�V������ <literal>proxy</literal> �����ɂ��A�N���X�̉i���C���X�^���X�̒x�����������\�ɂȂ�܂��B
+ Hibernate�͍ŏ��ɁA�w�肵���C���^�[�t�F�C�X���������CGLIB�v���L�V��Ԃ��܂��B
+ ���ۂ̉i���I�u�W�F�N�g�̓v���L�V�̃��\�b�h��Ăяo���Ƃ��Ƀ��[�h���܂��B
+ �ȉ��́u�x���������̂��߂̃v���L�V�v��Q�Ƃ��Ă��������B
+ </para>
+
+ <para>
+ <emphasis>�ÖٓI</emphasis> �|�����[�t�B�Y���Ƃ́A���̓��Ӗ����Ă��܂��B
+ ��̓N���X�̃C���X�^���X���A�X�[�p�[�N���X����������C���^�[�t�F�C�X�A�܂����̃N���X��w�肷��N�G���ɂ���ĕԂ���邱�ƂŁA
+ �����͂��̃N���X�̃T�u�N���X�̃C���X�^���X���A���̃N���X���g��w�肵���N�G���ɂ���ĕԂ���邱�Ƃł��B
+ �܂��A<emphasis>�����I</emphasis> �|�����[�t�B�Y���Ƃ́A���̓��Ӗ����Ă��܂��B
+ ��̓N���X�̃C���X�^���X���A���̃N���X���I�Ɏw�肵���N�G���ɂ���Ă̂ݕԂ���邱�ƂŁA
+ �����̓N���X��w�肵���N�G�����A<literal><class></literal> �v�f�̒��� <literal><subclass></literal> ��
+ <literal><joined-subclass></literal> �ƃ}�b�s���O����Ă���T�u�N���X�̃C���X�^���X������Ԃ����Ƃł��B
+ �قƂ�ǂ̗p�r�ł̓f�t�H���g�� <literal>polymorphism="implicit"</literal> ���K�ł��B
+ �����I�ȃ|�����[�t�B�Y���́A2�̈�����N���X�������e�[�u���Ƀ}�b�s���O����Ă���Ƃ��ɗL�p�ł�
+ �i����ɂ���ăe�[�u���J�����̃T�u�Z�b�g��܂ށA�u�y�ʂȁv�N���X���\�ɂȂ�܂��j�B
+ </para>
+
+ <para>
+ <literal>persister</literal> ������w�肷�邱�ƂŁA�N���X�̉i�����헪��J�X�^�}�C�Y�ł��܂��B
+ �Ⴆ�� <literal>org.hibernate.persister.EntityPersister</literal> ���g�̃T�u�N���X��w�肵����A
+ �܂��Ⴆ�X�g�A�h�v���V�[�W���R�[���A�t���b�g�t�@�C���փV���A���C�Y�A
+ LDAP�Ȃǂ�ʂ����i������������� <literal>org.hibernate.persister.ClassPersister</literal>
+ �C���^�[�t�F�C�X�̊��S�ɐV����������ł��܂��B�ȒP�ȗ�Ƃ��� <literal>org.hibernate.test.CustomPersister</literal>
+ ���Ă��������i����� <literal>Hashtable</literal> �́u�i�����v�ł��j�B
+
+ </para>
+
+ <para>
+ <literal>dynamic-update</literal> �� <literal>dynamic-insert</literal> �̐ݒ�̓T�u�N���X�Ɍp������܂���B
+ ���̂��� <literal><subclass></literal> �� <literal><joined-subclass></literal> �v�f��w�肷�邱�Ƃ�o���܂��B
+ �����̐ݒ�̓p�t�H�[�}���X����コ���鎖�����܂����A���Ƃ����Ƃ����܂��̂ŁA�T�d�Ɏg�p���Ă��������B
+ </para>
+
+ <para>
+ <literal>select-before-update</literal> �̎g�p�͒ʏ�p�t�H�[�}���X�𗎂Ƃ��܂��B
+ ��� <literal>Session</literal> �֕����C���X�^���X�̃O���t��Ēlj�����Ȃ�A
+ �f�[�^�x�[�X�X�V�̃g���K��s�K�v�ɌĂяo���̂����Ƃ����_�ŁA���ɗL�p�ł��B
+ </para>
+
+ <para>
+ <literal>dynamic-update</literal> ��L���ɂ���A�y�σ��b�N�헪��I�Ԃ��ƂɂȂ�܂��B
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>version</literal> �o�[�W����/�^�C���X�^���v�J������`�F�b�N���܂�
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>all</literal> ���ׂẴJ������`�F�b�N���܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>dirty</literal> �ύX�����J������`�F�b�N���A�����X�V�ł���悤�ɂ��܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>none</literal> �y�σ��b�N��g�p���܂���
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Hibernate�Ŋy�ϓI���b�N�헪��g���Ȃ�A�o�[�W����/�^�C���X�^���v�J������g�����Ƃ�
+ <emphasis> ����</emphasis> ���������߂��܂��B
+ �y�ϓI���b�N�̓p�t�H�[�}���X�̊ϓ_�����œK�ł���A����ɕ����C���X�^���X�ւ̏C��
+ �i�܂� <literal>Session.marge()</literal> ���g����Ƃ��j
+ �𐳊m�Ɉ������Ƃ̂ł���B��̐헪�ł����܂��B
+ </para>
+
+ <para>
+ Hibernate�̃}�b�s���O�ɂƂ��ăr���[�ƕ��ʂ̃e�[�u���̊ԂɈႢ�͂Ȃ��A
+ �f�[�^�x�[�X���x���ł͓��ߓI�ł�
+ �i�������r���[���S�ɂ̓T�|�[�g���Ă��Ȃ�DBMS�����܂��B
+ ���ɁA�X�V�̂���r���[�ɑ��Ă͂����ł��j�B
+ �r���[��g�������Ă�A�f�[�^�x�[�X�ō쐬�ł��Ȃ����Ƃ�����܂�
+ �i�Ⴆ�A���K�V�[�X�L�[�}�̏ꍇ�j�B
+ ���̏ꍇ�ɂ́A�s�ς��ǂݎ���p�̃G���e�B�e�B�ɗ^����ꂽSQL�̕��⍇������}�b�v�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Summary">
+ <subselect>
+ select item.name, max(bid.amount), count(*)
+ from item
+ join bid on bid.item_id = item.id
+ group by item.name
+ </subselect>
+ <synchronize table="item"/>
+ <synchronize table="bid"/>
+ <id name="name"/>
+ ...
+</class>]]></programlisting>
+
+ <para>
+ �e�[�u�����̃G���e�B�e�B�Ɠ�������悤�ɒ�`���Ă��������B
+ �I�[�g�t���b�V�����m���ɋN����悤�ɁA�܂����o�G���e�B�e�B�ɑ���N�G�����Â��f�[�^��
+ �Ԃ��Ȃ��悤�ɂ��邽�߂ł��B
+ <literal><subselect></literal> �͑����ƃl�X�g�����}�b�s���O�����̂ǂ���ł���p�ł��܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-id" revision="4">
+ <title>id</title>
+
+ <para>
+ �}�b�v���ꂽ�N���X�̓f�[�^�x�[�X�e�[�u���̎�L�[�J�������` <emphasis>���Ȃ���Ȃ�܂���</emphasis> �B
+ �قƂ�ǂ̃N���X�ɂ̓C���X�^���X�̃��j�[�N�Ȏ��ʎq��ێ�����JavaBeans�X�^�C���̃v���p�e�B�����܂��B
+ <literal><id></literal> �v�f�́A���̃v���p�e�B�����L�[�J�����ւ̃}�b�s���O���`���܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="id1" coords="2 70"/>
+ <area id="id2" coords="3 70" />
+ <area id="id3" coords="4 70"/>
+ <area id="id4" coords="5 70" />
+ <area id="id5" coords="6 70" />
+ </areaspec>
+ <programlisting><![CDATA[<id
+ name="propertyName"
+ type="typename"
+ column="column_name"
+ unsaved-value="null|any|none|undefined|id_value"
+ access="field|property|ClassName">
+ node="element-name|@attribute-name|element/@attribute|."
+
+ <generator class="generatorClass"/>
+</id>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="id1">
+ <para>
+ <literal>name</literal>�i�I�v�V�����j�F���ʎq�v���p�e�B�̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="id2">
+ <para>
+ <literal>type</literal>�i�I�v�V�����j�FHibernate�̌^�������O�B
+ </para>
+ </callout>
+ <callout arearefs="id3">
+ <para>
+ <literal>column</literal>�i�I�v�V���� - �f�t�H���g�̓v���p�e�B���j�F
+ ��L�[�J�����̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="id4">
+ <para>
+ <literal>unsaved-value</literal>�i�I�v�V���� - �f�t�H���g�̒l��sensible�j�F
+ �C���X�^���X���V�����C���X�^���X�����ꂽ
+ �i�Z�[�u����Ă��Ȃ��j���Ƃ����A���ʎq�v���p�e�B�̒l�B
+ �ȑO��Session�ŃZ�[�u�܂��̓��[�h���ꂽ�ꎞ�I�C���X�^���X�Ƌ�ʂ��邽�߂�
+ �g���܂��B
+ </para>
+ </callout>
+ <callout arearefs="id5">
+ <para>
+ <literal>access</literal>�i�I�v�V���� - �f�t�H���g�� <literal>property</literal> �j�F
+ �v���p�e�B�̒l�փA�N�Z�X���邽�߂�Hibernate���g���헪�ł��B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <literal>name</literal> �������Ȃ���A�N���X�ɂ͎��ʎq�v���p�e�B���Ȃ���̂Ƃ݂Ȃ���܂��B
+ </para>
+
+ <para>
+ <literal>unsaved-value</literal> ������Hibernate3�ł͂قƂ�ǂ̏ꍇ�A�K�v�ł͂���܂���B
+ </para>
+
+ <para>
+ �����L�[�����K�V�[�f�[�^�ɃA�N�Z�X�ł���悤�ɁA
+ <literal><composite-id></literal> �Ƃ�����ւ̃}�b�s���O��`������܂��B
+ ���������̗p�r�ւ̎g�p�͑S���������߂ł��܂���B
+ </para>
+
+ <sect3 id="mapping-declaration-id-generator" revision="2">
+ <title>�W�F�l���[�^</title>
+
+ <para>
+ �I�v�V������ <literal><generator></literal> �q�v�f�́A
+ �i���N���X�̃C���X�^���X�̃��j�[�N�Ȏ��ʎq�����邽�߂Ɏg���AJava�N���X��w�肵�܂��B
+ �W�F�l���[�^�C���X�^���X�̐ݒ�A������͏������Ƀp�����[�^���K�v�ł���A<literal><param></literal>
+ �v�f��g���ēn�����Ƃ��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+ <generator class="org.hibernate.id.TableHiLoGenerator">
+ <param name="table">uid_table</param>
+ <param name="column">next_hi_value_column</param>
+ </generator>
+</id>]]></programlisting>
+
+ <para>
+ ���ׂẴW�F�l���[�^�́A�C���^�[�t�F�C�X
+ <literal>org.hibernate.id.IdentifierGenerator</literal> ��������܂��B
+ ����͂ƂĂ�P���ȃC���^�[�t�F�C�X�Ȃ̂ŁA���ʂȎ�����Ǝ��ɗp�ӂ���A�v���P�[�V��������邩�����܂���B
+ ������Hibernate�͑g�ݍ��݂̎���������p�ӂ��Ă��܂��B
+ �g�ݍ��݂̃W�F�l���[�^�ɂ͈ȉ��̃V���[�g�J�b�g��������܂��F
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>increment</literal></term>
+ <listitem>
+ <para>
+ <literal>long</literal> , <literal>short</literal> ,
+ <literal>int</literal> �^�̎��ʎq�����܂��B
+ �����͑��̃v���Z�X�������e�[�u���Ƀf�[�^��}�����Ȃ��Ƃ��������j�[�N�ł��B
+ <emphasis>�N���X�^��ł͎g��Ȃ��ł�������</emphasis> �B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>identity</literal></term>
+ <listitem>
+ <para>
+ DB2, MySQL, MS SQL Server, Sybase, HypersonicSQL�̎��ʎq�J������
+ �T�|�[�g���܂��B
+ �Ԃ���鎯�ʎq�̌^�� <literal>long</literal> , <literal>short</literal> ,
+ <literal>int</literal> �̂����ꂩ�ł��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>sequence</literal></term>
+ <listitem>
+ <para>
+ DB2, PostgreSQL, Oracle, SAP DB, McKoi�̃V�[�P���X��AInterbase�̃W�F�l���[�^��g�p���܂��B
+ �Ԃ���鎯�ʎq�̌^�� <literal>long</literal> , <literal>short</literal> ,
+ <literal>int</literal> �̂����ꂩ�ł��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>hilo</literal></term>
+ <listitem>
+ <para id="mapping-declaration-id-hilodescription" revision="1">
+ <literal>long</literal> , <literal>short</literal> ,
+ <literal>int</literal> �^�̎��ʎq������I�ɐ�������hi/lo�A���S���Y����g���܂��B
+ hi�l�̃\�[�X�Ƃ��āA�e�[�u���ƃJ������^���܂�(�f�t�H���g�ł͂��ꂼ�� <literal>hibernate_unique_key</literal> ��
+ <literal>next_hi</literal> )�B
+
+ hi/lo�A���S���Y���͓���̃f�[�^�x�[�X�ɑ��Ă̂݃��j�[�N�Ȏ��ʎq�����܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>seqhilo</literal></term>
+ <listitem>
+ <para>
+ <literal>long</literal> , <literal>short</literal> ,
+ <literal>int</literal> �^�̎��ʎq������I�ɐ�������hi/lo�A���S���Y����g���܂��B
+ �w�肳�ꂽ�f�[�^�x�[�X�V�[�P���X��^���܂��B
+
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>uuid</literal></term>
+ <listitem>
+ <para>
+ (IP�A�h���X���g�p�����)�l�b�g���[�N��Ń��j�[�N�ȕ�����^�̎��ʎq�����邽�߂ɁA
+ 128�r�b�g��UUID�A���S���Y����g�p���܂��BUUID�͒���32��16�i�����̕�����Ƃ��ăG���R�[�h����܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>guid</literal></term>
+ <listitem>
+ <para>
+ MS SQL�T�[�o��MySQL�Ńf�[�^�x�[�X����������GUID�������g�p���܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>native</literal></term>
+ <listitem>
+ <para>
+ �g�p����f�[�^�x�[�X�̐��\�ɂ�� <literal>identity</literal> , <literal>sequence</literal> ,
+ <literal>hilo</literal> �̂����ꂩ���I��܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>assigned</literal></term>
+ <listitem>
+ <para>
+ <literal>save()</literal> ���Ă��O�ɁA
+ �A�v���P�[�V�������I�u�W�F�N�g�Ɏ��ʎq�����ł���悤�ɂ��܂��B
+ <literal><generator></literal> ���w�肳��Ă��Ȃ���A���ꂪ�f�t�H���g�̐헪�ɂȂ�܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>select</literal></term>
+ <listitem>
+ <para>
+ ���郆�j�[�N�L�[�ɂ��s�̑I��Ǝ�L�[�̒l�̕����ɂ��A
+ �f�[�^�x�[�X�g���K�����蓖�Ă���L�[��擾���܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>foreign</literal></term>
+ <listitem>
+ <para>
+ ���̊֘A�I�u�W�F�N�g�̎��ʎq��g���܂��B
+ ���ʂ́A<literal><one-to-one></literal> ��L�[�֘A�Ƒg�ݍ��킹�Ďg���܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-hilo" revision="1">
+ <title>Hi/lo �A���S���Y��</title>
+ <para>
+ <literal>hilo</literal> �� <literal>seqhilo</literal> �W�F�l���[�^�́A
+ ���ʎq�����̑�\�I�ȃA�v���[�`�ł���hi/lo�A���S���Y����2�̑�֎�������܂��B
+
+ 1�Ԗڂ̎����́A����ɗ��p�����"hi"�l��ێ�����u���ʂȁv�f�[�^�x�[�X�e�[�u����
+ �K�v�Ƃ��܂��B
+ 2�Ԗڂ̎����́AOracle�X�^�C���̃V�[�P���X��g���܂��i�T�|�[�g����Ă���ꍇ�j�B
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+ <generator class="hilo">
+ <param name="table">hi_value</param>
+ <param name="column">next_value</param>
+ <param name="max_lo">100</param>
+ </generator>
+</id>]]></programlisting>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+ <generator class="seqhilo">
+ <param name="sequence">hi_value</param>
+ <param name="max_lo">100</param>
+ </generator>
+</id>]]></programlisting>
+
+ <para>
+ �c�O�Ȃ���Hibernate�ւ̓Ǝ��� <literal>Connection</literal> �����Ƃ��ɂ́A<literal>hilo</literal> ��g���܂���B
+ Hibernate��JTA�Ń��X�g����Ă���ڑ���擾���邽�߂ɃA�v���P�[�V�����T�[�o�[�̃f�[�^�\�[�X��g�p���Ă���Ƃ��ɂ́A
+ <literal>hibernate.transaction.manager_lookup_class</literal> ��K�ɐݒ肵�Ȃ���Ȃ�܂���B
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-uuid">
+ <title>UUID �A���S���Y��</title>
+ <para>
+ UUID�ɂ͈ȉ��̂�̂��܂܂�܂��F
+ IP�A�h���X�AJVM�̃X�^�[�g�A�b�v�^�C���i4����1�b�̐��m���j�A
+ �V�X�e�����ԁA�iJVM�ɑ��ă��j�[�N�ȁj�J�E���^�l�B
+ Java�R�[�h����MAC�A�h���X������A�h���X��擾���邱�Ƃ͂ł��Ȃ��̂ŁA
+ JNI���g���Ȃ��Ƃ��̍ŗǂ̕��@�ł��B
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-sequences">
+ <title>���ʎq�J�����ƃV�[�P���X</title>
+ <para>
+ ���ʎq�J������T�|�[�g���Ă���f�[�^�x�[�X�iDB2, MySQL, Sybase, MS SQL�j�ł́A
+ <literal>identity</literal> �L�[������g���܂��B
+ �V�[�P���X��T�|�[�g����f�[�^�x�[�X�iDB2, Oracle, PostgreSQL, Interbase, McKoi, SAP DB�j�ł́A
+ <literal>sequence</literal> �X�^�C���̃L�[������g���܂��B
+ �ǂ���̐헪��A�V�����I�u�W�F�N�g��}�����邽�߂ɁASQL�N�G����2�K�v�Ƃ��܂��B
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="person_id">
+ <generator class="sequence">
+ <param name="sequence">person_id_sequence</param>
+ </generator>
+</id>]]></programlisting>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="person_id" unsaved-value="0">
+ <generator class="identity"/>
+</id>]]></programlisting>
+
+ <para>
+ �N���X�v���b�g�t�H�[���̊J���ł́A<literal>native</literal> �헪��
+ <literal>identity</literal> , <literal>sequence</literal> ,
+ <literal>hilo</literal> �헪�̒�����1��I���܂����A
+ ����͎g�p���Ă���f�[�^�x�[�X�̔\�͂Ɉˑ����܂��B
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-assigned">
+ <title>���ʎq�̊��蓖��</title>
+ <para>
+ �A�v���P�[�V�����Ɏ��ʎq���蓖�Ă��������̂ł����(Hibernate�����������̂ł͂Ȃ��j�A
+ <literal>assigned</literal> �W�F�l���[�^��g�����Ƃ��ł��܂��B
+ ���̓��ʂȃW�F�l���[�^�́A���łɃI�u�W�F�N�g�̎��ʎq�v���p�e�B�ɑ�����ꂽ�l��
+ ���ʎq�Ɏg���܂��B���̃W�F�l���[�^�͎�L�[���㗝�L�[�̑���Ɏ��R�L�[�ł���ꍇ�Ɏg�p���܂��B
+ <literal><generator></literal> �v�f��w�肵�Ȃ��ꍇ�̃f�t�H���g�̓���ɂȂ�܂��B
+ </para>
+
+ <para>
+ <literal>assigned</literal> �W�F�l���[�^��I����ƁA
+ Hibernate�� <literal>unsaved-value="undefined"</literal> ��g�p���܂��B
+ �����āA�o�[�W������^�C���X�^���v�̃v���p�e�B���Ȃ��ꍇ�� <literal>Interceptor.isUnsaved()</literal>
+ ���`���Ȃ������ꍇ�ɂ́A�C���X�^���X���ꎞ�I(transient)�Ȃ�̂ł���̂��A
+ �܂��̓Z�b�V�������番��(detached)������̂��ǂ������߂邽�߂ɁA�f�[�^�x�[�X�ׂ܂��B
+ </para>
+ </sect3>
+
+ <sect3 id="mapping-declaration-id-select">
+ <title>�g���K�ɂ�芄�蓖�Ă�ꂽ��L�[</title>
+ <para>
+ ���K�V�[�X�L�[�}�̂��߂ɂ̂ݎw�肵�܂�(Hibernate�̓g���K��g����DDL�����܂���)�B
+ </para>
+
+ <programlisting><![CDATA[<id name="id" type="long" column="person_id">
+ <generator class="select">
+ <param name="key">socialSecurityNumber</param>
+ </generator>
+</id>]]></programlisting>
+
+ <para>
+ ��̗�̒��ŁA�N���X�Ŏ��R�L�[�Ƃ��Ē�`���ꂽ
+ <literal>socialSecurityNumber</literal> �Ƃ������O�̃��j�[�N�Ȓl�̃v���p�e�B�ƁA
+ �l���g���K�ɂ�萶������� <literal>person_id</literal> �Ƃ������O�̑㗝�L�[������܂��B
+ </para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-compositeid" revision="3">
+ <title>composite-id</title>
+
+ <programlisting><![CDATA[<composite-id
+ name="propertyName"
+ class="ClassName"
+ mapped="true|false"
+ access="field|property|ClassName">
+ node="element-name|."
+
+ <key-property name="propertyName" type="typename" column="column_name"/>
+ <key-many-to-one name="propertyName class="ClassName" column="column_name"/>
+ ......
+</composite-id>]]></programlisting>
+
+ <para>
+ �����L�[�̂���e�[�u���ɑ��A
+ ���ʎq�v���p�e�B�Ƃ��ăN���X�̕����̃v���p�e�B��}�b�s���O���邱�Ƃ��ł��܂��B
+ <literal><composite-id></literal> �v�f�́A�q�v�f�Ƃ���
+ <literal><key-property></literal> �v���p�e�B�}�b�s���O��
+ <literal><key-many-to-one></literal> �}�b�s���O�����܂��B
+ </para>
+
+ <programlisting><![CDATA[<composite-id>
+ <key-property name="medicareNumber"/>
+ <key-property name="dependent"/>
+</composite-id>]]></programlisting>
+
+ <para>
+ �������ʎq�̓�������������邽�߂ɂ́A�i���N���X�� <literal>equals()</literal> ��
+ <literal>hashCode()</literal> ��I�[�o�[���C�h <emphasis>���Ȃ���Ȃ�܂���</emphasis> �B
+ �܂� <literal>Serializable</literal> ��������Ȃ�������܂���B
+ </para>
+
+ <para>
+ �c�O�Ȃ��畡�����ʎq�̂��߂̂��̕��@�́A
+ �i���I�u�W�F�N�g�����g�̎��ʎq�ł��邱�Ƃ�Ӗ����Ă��܂��B
+ �I�u�W�F�N�g���g���ʎq�Ƃ���ȏ�֗̕��ȁu�������v�͂���܂���B
+ �����L�[�Ɋ֘A�����i����Ԃ� <literal>load()</literal> �o����悤�ɂȂ�O�ɁA
+ �i���N���X���g��C���X�^���X�����A���ʎq�v���p�e�B��ݒ肵�Ȃ���Ȃ�܂���B
+ <emphasis> �g�ݍ��݂�</emphasis> �������ʎq�ƌĂ�邱�̃A�v���[�`�́A
+ �{�i�I�ȃA�v���P�[�V�����ɂ͌����Ă��܂���B
+
+
+ </para>
+
+ <para>
+ 2�ڂ̕��@�� <emphasis> �}�b�v���ꂽ</emphasis> �������ʎq�ƌĂ���̂ŁA
+ <literal><composite-id></literal>�G�������g��Ŏw�肵�����ʃv���p�e�B��
+ �i���N���X�ƕ����������ʎq�N���X�̗����ɏd�����đ��݂��܂��B
+ </para>
+
+ <programlisting><![CDATA[<composite-id class="MedicareId" mapped="true">
+ <key-property name="medicareNumber"/>
+ <key-property name="dependent"/>
+</composite-id>]]></programlisting>
+
+ <para>
+ ���̗�ł́A�������ʎq�N���X�i <literal>MedicareId</literal> �j�ƃG���e�B�e�B�N���X���g�̗������A
+ <literal>medicareNumber</literal> �� <literal>dependent</literal> �Ƃ������O�̃v���p�e�B�����܂��B
+ ���ʎq�N���X�́A<literal>equals()</literal> �� <literal>hashCode()</literal> ��I�[�o���C�h���A
+ <literal>Serializable</literal> ��������Ȃ��Ă͂Ȃ�܂���B
+ ���̕��@�ɂ́A���炩�ɃR�[�h���d������Ƃ����s�s��������܂��B
+ </para>
+
+ <para>
+ ���̑����̓}�b�s���O�����������ʎq��w�肷�邽�߂Ɏg�p���܂��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>mapped</literal> (�I�v�V�����A�f�t�H���g�� <literal>false</literal> ):
+ �}�b�s���O�����������ʎq���g�p����邱�ƂƁA��܂��ꂽ�v���p�e�B�̃}�b�s���O���A
+ �G���e�B�e�B�N���X�ƕ������ʎq�N���X�̗�����Q�Ƃ��邱�Ƃ����܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>class</literal> (�I�v�V����,�������}�b�s���O�����������ʎq�ɂ͕K�{):
+ �������ʎq�Ƃ��Ďg�p����N���X�B
+
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ 3�ڂ̂���ɕ֗��ȕ��@�́A�������ʎq��<xref linkend="components-compositeid"/>���
+ �R���|�[�l���g�N���X�Ƃ��Ď������邱�Ƃł��B
+ ���ŋL�q���Ă��鑮���́A���̑�֕��@�ɂ̂ݓK�p����܂��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>name</literal> (�I�v�V����, ���̃A�v���[�`�ł͕K�{):
+ �������ʎq��ێ�����R���|�[�l���g�^�C�v�̃v���p�e�B(9�͂�Q�Ƃ��Ă�������).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>access</literal> (�I�v�V���� - �f�t�H���g�� <literal>property</literal> ):
+ Hibernate���v���p�e�B�̒l�ɃA�N�Z�X���邽�߂Ɏg�p���ׂ��헪�B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>class</literal>
+ �i�I�v�V���� - �f�t�H���g�̓��t���N�V�����ɂ�茈�肳���v���p�e�B�̌^�j�F
+ �������ʎq�Ƃ��Ďg����R���|�[�l���g�̃N���X�i���̐߂��Ă��������j�B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ����3�ڂ̕��@�� <emphasis> ���ʎq�R���|�[�l���g</emphasis> �ƌĂсA
+ �قƂ�ǂ��ׂẴA�v���P�[�V�����ɑ��Đ���������@�ł��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-discriminator" revision="3">
+ <title>discriminator</title>
+
+ <para>
+ <literal><discriminator></literal> �v�f�́A
+ table-per-class-hierarchy�}�b�s���O�헪��g���|�����[�t�B�b�N�ȉi�����ɕK�v�ł���A
+ �e�[�u���̎��ʃJ�������`���܂��B
+ ���ʃJ�����́A����s�ɑ��ĉi���w���ǂ̃T�u�N���X��C���X�^���X�����邩��
+ �`����}�[�J�[�l��܂�ł��܂��B
+ �ȉ��̂悤�Ȍ^�ɐ�������܂��F <literal>string</literal> , <literal>character</literal> ,
+ <literal>integer</literal>,
+ <literal>byte</literal> , <literal>short</literal> , <literal>boolean</literal> ,
+ <literal>yes_no</literal> , <literal>true_false</literal>.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="discriminator1" coords="2 60"/>
+ <area id="discriminator2" coords="3 60" />
+ <area id="discriminator3" coords="4 60" />
+ <area id="discriminator4" coords="5 60" />
+ <area id="discriminator5" coords="6 60" />
+ </areaspec>
+ <programlisting><![CDATA[<discriminator
+ column="discriminator_column"
+ type="discriminator_type"
+ force="true|false"
+ insert="true|false"
+ formula="arbitrary sql expression"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="discriminator1">
+ <para>
+ <literal>column</literal>�i�I�v�V���� - �f�t�H���g�� <literal>class</literal> �j�F
+ ���ʃJ�����̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="discriminator2">
+ <para>
+ <literal>type</literal>
+ �i�I�v�V���� - �f�t�H���g�� <literal>string</literal> �j�FHibernate�̌^�������O�B
+ </para>
+ </callout>
+ <callout arearefs="discriminator3">
+ <para>
+ <literal>force</literal>
+ �i�I�v�V���� - �f�t�H���g�� <literal>false</literal> �j�F
+ ���[�g�N���X�̂��ׂẴC���X�^���X��������ꍇ�ł����Ă�A
+ Hibernate���g�p�ł��鎯�ʃJ�����̎w���u�����v���܂��B
+ </para>
+ </callout>
+ <callout arearefs="discriminator4">
+ <para>
+ <literal>insert</literal>
+ �i�I�v�V���� - �f�t�H���g�� <literal>true</literal> �j�F
+ ������ʃJ�������}�b�s���O���镡�����ʎq�̈ꕔ�Ȃ�A<literal>false</literal> �Ɛݒ肵�Ă��������B
+ (Hibernate��SQL�� <literal>INSERT</literal> �ɂ͊܂܂�Ȃ����Ƃ�m�点��)
+
+ </para>
+ </callout>
+ <callout arearefs="discriminator5">
+ <para>
+ <literal>formula</literal> (�I�v�V����)�^���]�������Ƃ��Ɏ��s�����C�ӂ�SQL���B
+ �R���e���c�x�[�X�̎��ʂ�\�ɂ��܂��B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ ���ʃJ�����̎��ۂ̒l�́A <literal><class></literal> ��
+ <literal><subclass></literal> �v�f��
+ <literal>discriminator-value</literal> �����Ŏw�肳��܂��B
+ </para>
+
+ <para>
+ �i���N���X�փ}�b�s���O����Ȃ���]���ȁv���ʒl���s��
+ �e�[�u���ɂ���A�i���̂Ƃ��Ɍ���j<literal>force</literal> �����͗L���ł��B
+ �������A���ʂ͂����������Ƃ͂���܂���B
+ </para>
+
+ <para>
+ <literal>formula</literal> ������g���ƁA�s�̌^��]�����邽�߂ɔC�ӂ�SQL����錾�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<discriminator
+ formula="case when CLASS_TYPE in ('a', 'b', 'c') then 0 else 1 end"
+ type="integer"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-version" revision="4">
+ <title>version�i�I�v�V�����j</title>
+
+ <para>
+ <literal><version></literal> �v�f�̓I�v�V�����ł���A
+ �e�[�u�����o�[�W�����f�[�^��܂ނ��Ƃ����܂��B
+ ����� <emphasis>�����O�g�����U�N�V����</emphasis>
+ ��g�����Ȃ�A���ɖ𗧂��܂��i�ȉ����Ă��������j�B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="version1" coords="2 70"/>
+ <area id="version2" coords="3 70"/>
+ <area id="version3" coords="4 70"/>
+ <area id="version4" coords="5 70"/>
+ <area id="version5" coords="6 70"/>
+ <area id="version6" coords="7 70"/>
+ <area id="version7" coords="8 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<version
+ column="version_column"
+ name="propertyName"
+ type="typename"
+ access="field|property|ClassName"
+ unsaved-value="null|negative|undefined"
+ generated="never|always"
+ insert="true|false"
+ node="element-name|@attribute-name|element/@attribute|."
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="version1">
+ <para>
+ <literal>column</literal>�i�I�v�V���� - �f�t�H���g�̓v���p�e�B���j:
+ �o�[�W�����ԍ���ێ�����J�����̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="version2">
+ <para>
+ <literal>name</literal> �F�i���N���X�̃v���p�e�B�̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="version3">
+ <para>
+ <literal>type</literal>
+ �i�I�v�V���� - �f�t�H���g�� <literal>integer</literal> �j�F�o�[�W�����ԍ��̌^�B
+ </para>
+ </callout>
+ <callout arearefs="version4">
+ <para>
+ <literal>access</literal>
+ �i�I�v�V���� - �f�t�H���g�� <literal>property</literal> �j�F
+ �v���p�e�B�̒l�ւ̃A�N�Z�X��Hibernate���g���헪�B
+ </para>
+ </callout>
+ <callout arearefs="version5">
+ <para>
+ <literal>unsaved-value</literal>
+ �i�I�v�V���� - �f�t�H���g�� <literal>undefined</literal> �j�F
+ �C���X�^���X���V�����C���X�^���X�����ꂽ���Ƃ���
+ �i�Z�[�u����Ă��Ȃ����Ƃ����j�o�[�W�����v���p�e�B�̒l�B
+ �ȑO��Session�ŃZ�[�u�܂��̓��[�h���ꂽ�ꎞ�I�ȃC���X�^���X�Ƌ�ʂ��邽�߂�
+ �g���܂��B
+ �i <literal>undefined</literal> �͎��ʎq�v���p�e�B�̒l���g���邱�Ƃ�w�肵�܂��B�j
+ </para>
+ </callout>
+
+ <callout arearefs="version6">
+ <para>
+ <literal>generated</literal> (�I�v�V���� - �f�t�H���g�� <literal>never</literal> ):
+ ���̃o�[�W�����̃v���p�e�B�̒l���A�f�[�^�x�[�X�ɂ���Đ������ꂽ���Ƃ�w�肵�܂��B
+ <xref linkend="mapping-generated">�����v���p�e�B</xref> �̋c�_���Ă��������B
+ </para>
+ </callout>
+ <callout arearefs="version7">
+ <para>
+ <literal>insert</literal> (�I�v�V���� - �f�t�H���g�� <literal>true</literal> ):
+ SQL��insert���Ƀo�[�W�����E�J������܂߂�ׂ����ǂ�����w�肵�܂��B
+ ����f�[�^�x�[�X�E�J�����̃f�t�H���g�l�� <literal>0</literal> �ƒ�`�����Ƃ��ɂ́A
+ <literal>false</literal> �ɐݒ肷��Ɨǂ��ł��傤�B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ �o�[�W�����ԍ��� Hibernate�� <literal>long</literal> , <literal>integer</literal> ,
+ <literal>short</literal> , <literal>timestamp</literal> ,
+ <literal>calendar</literal> �^�̂����ꂩ�ł��B
+ </para>
+
+ <para>
+ �o�[�W������^�C���X�^���v�̃v���p�e�B�́A�������ꂽ�C���X�^���X�ɑ���null�ł����Ă͂Ȃ�܂���B
+ ���̂��߂ǂ̂悤�� <literal>unsaved-value</literal> �헪���w�肳��Ă�A
+ Hibernate��null�̃o�[�W������^�C���X�^���v���������ׂẴC���X�^���X��A
+ �ꎞ�I�Ȃ�̂ł���Ɣ��f���܂��B
+
+ <emphasis> null���e����o�[�W������^�C���X�^���v�̃v���p�e�B���`���邱�Ƃ́A
+ �ߓn�I�Ɉꎞ�I�u�W�F�N�g�Ƃ��邱�Ƃ�h���ȒP�ȕ��@�ł��B
+ ���Ɏ��ʎq�̊��蓖�Ă╡���L�[��g�p���Ă���Ƃ��ɂ͓��ɗL�p�ł��B</emphasis>
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-declaration-timestamp" revision="4">
+ <title>timestamp�i�I�v�V�����j</title>
+
+ <para>
+ �I�v�V������ <literal><timestamp></literal> �v�f�́A
+ �e�[�u�����^�C���X�^���v�f�[�^��܂ނ��Ƃ����܂��B
+ ����̓o�[�W�����t���̑���̕��@�Ƃ��ėp�ӂ���Ă��܂��B
+ �^�C���X�^���v�͂�Ƃ�Ɗy�ϓI���b�N�ɂ�������S���̒Ⴂ�����ł��B
+ �������A�v���P�[�V�����͈قȂ�p�r�Ŏg�����Ƃ���邩�����܂���B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="timestamp1" coords="2 70"/>
+ <area id="timestamp2" coords="3 70" />
+ <area id="timestamp3" coords="4 70" />
+ <area id="timestamp4" coords="5 70" />
+ <area id="timestamp5" coords="6 70" />
+ <area id="timestamp6" coords="7 70" />
+ </areaspec>
+ <programlisting><![CDATA[<timestamp
+ column="timestamp_column"
+ name="propertyName"
+ access="field|property|ClassName"
+ unsaved-value="null|undefined"
+ source="vm|db"
+ generated="never|always"
+ node="element-name|@attribute-name|element/@attribute|."
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="timestamp1">
+ <para>
+ <literal>column</literal>�i�I�v�V���� - �f�t�H���g�̓v���p�e�B���j�F
+ �^�C���X�^���v��ێ�����J�����̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="timestamp2">
+ <para>
+ <literal>name</literal> �F
+ �i���N���X�ł���Java �� <literal>Date</literal >�^ �܂���
+ <literal>Timestamp</literal> �^ �́AJavaBeans�X�^�C���v���p�e�B�̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="timestamp3">
+ <para>
+ <literal>access</literal>
+ �i�I�v�V���� - �f�t�H���g�� <literal>property</literal> �j�F
+ �v���p�e�B�̒l�ւ̃A�N�Z�X��Hibernate���g���헪�B
+ </para>
+ </callout>
+ <callout arearefs="timestamp4">
+ <para>
+ <literal>unsaved-value</literal>
+ �i�I�v�V���� - �f�t�H���g�� <literal>null</literal> �j�F
+ �C���X�^���X���V�����C���X�^���X�����ꂽ
+ �i�Z�[�u����Ă��Ȃ��j���Ƃ����o�[�W�����v���p�e�B�̒l�B
+ �ȑO��Session�ŃZ�[�u�܂��̓��[�h���ꂽ�ꎞ�I�ȃC���X�^���X��
+ ��ʂ��邽�߂Ɏg���܂��B
+ �i <literal>undefined</literal> �Ǝw�肷��ƁA
+ ���ʎq�v���p�e�B�̒l���g���܂��B�j
+ </para>
+ </callout>
+
+ <callout arearefs="timestamp5">
+ <para>
+ <literal>source</literal> (�I�v�V���� - �f�t�H���g�� <literal>vm</literal> ):
+ Hibernate�͂ǂ�����^�C���X�^���v�̒l��擾����ׂ��ł��傤���H
+ �f�[�^�x�[�X����ł��傤���A���݂�JVM����ł��傤���H
+ �f�[�^�x�[�X�ɂ��^�C���X�^���v�́AHibernate��"���̒l"���肷�邽�߂�
+ �f�[�^�x�[�X��q�b�g���Ȃ���Ȃ�Ȃ����߁A�I�[�o�w�b�h�����܂��B
+ �������N���X�^���ł�JVM����擾��������S�ł��B
+ �f�[�^�x�[�X�̌��݂̃^�C���X�^���v�̎擾��T�|�[�g����
+ ���ׂĂ� <literal>�f�[�^�x�[�X����</literal> ���m���Ă���킯�ł͂Ȃ����Ƃ�
+ ���ӂ��Ă��������B�܂�����ŁA�������������߂ɁA
+ ���b�N�Ŏg�p����ɂ͈��S�łȂ���̂����܂�(�Ⴆ��Oracle 8)�B
+ </para>
+ </callout>
+ <callout arearefs="timestamp6">
+ <para>
+ <literal>generated</literal> (�I�v�V���� - �f�t�H���g�� <literal>never</literal> ):
+ ���̃^�C���X�^���v�E�v���p�e�B�̒l���A�f�[�^�x�[�X�ɂ���Đ�������邱�Ƃ�w�肵�܂��B
+ <xref linkend="mapping-generated">�����v���p�e�B</xref> ��Q�Ƃ��Ă��������B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <literal><timestamp></literal> ��
+ <literal><version type="timestamp"></literal> �Ɠ����ł��邱�Ƃɒ��ӂ��Ă��������B
+ <literal><timestamp source="db"></literal> ��
+ <literal><version type="dbtimestamp"></literal> �Ɠ����ł��邱�Ƃɒ��ӂ��Ă��������B
+ </para>
+ </sect2>
+
+ <sect2 id="mapping-declaration-property" revision="4">
+ <title>property</title>
+
+ <para>
+ <literal><property></literal> �v�f�́A�N���X�̉i���I��JavaBean�X�^�C���̃v���p�e�B���`���܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="property1" coords="2 70"/>
+ <area id="property2" coords="3 70"/>
+ <area id="property3" coords="4 70"/>
+ <areaset id="property4-5" coords="">
+ <area id="property4" coords='5 70'/>
+ <area id="property5" coords='6 70'/>
+ </areaset>
+ <area id="property6" coords="7 70"/>
+ <area id="property7" coords="8 70"/>
+ <area id="property8" coords="9 70"/>
+ <area id="property9" coords="10 70"/>
+ <area id="property10" coords="11 70"/>
+ <area id="property11" coords="12 70"/>
+ <area id="property12" coords="13 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<property
+ name="propertyName"
+ column="column_name"
+ type="typename"
+ update="true|false"
+ insert="true|false"
+ formula="arbitrary SQL expression"
+ access="field|property|ClassName"
+ lazy="true|false"
+ unique="true|false"
+ not-null="true|false"
+ optimistic-lock="true|false"
+ generated="never|insert|always"
+ node="element-name|@attribute-name|element/@attribute|."
+ index="index_name"
+ unique_key="unique_key_id"
+ length="L"
+ precision="P"
+ scale="S"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="property1">
+ <para>
+ <literal>name</literal>�F�������Ŏn�܂�v���p�e�B���B
+ </para>
+ </callout>
+ <callout arearefs="property2">
+ <para>
+ <literal>column</literal>�i�I�v�V���� - �f�t�H���g�̓v���p�e�B���j�F
+ �}�b�s���O���ꂽ�f�[�^�x�[�X�e�[�u���̃J�����̖��O�B
+ �l�X�g���� <literal><column></literal> �v�f�ł�w��ł��܂��B
+ </para>
+ </callout>
+ <callout arearefs="property3">
+ <para>
+ <literal>type</literal>�i�I�v�V�����j�FHibernate�̌^�������O�B
+ </para>
+ </callout>
+ <callout arearefs="property4-5">
+ <para>
+ <literal>update, insert</literal>
+ �i�I�v�V���� - �f�t�H���g�� <literal>true</literal> �j�F
+ �}�b�s���O���ꂽ�J������SQL��
+ <literal>UPDATE</literal> �� <literal>INSERT</literal> �Ɋ܂܂�邱�Ƃ�w�肵�܂��B
+ �����Ƃ� <literal>false</literal> �ɐݒ肷��ƁA
+ �����J�����Ƀ}�b�s���O���ꂽ���̃v���p�e�B��g���K��
+ ���̃A�v���P�[�V�����ɂ���ď��������ꂽ�����ȁu���o�v�v���p�e�B���\�ɂȂ�܂��B
+ </para>
+ </callout>
+ <callout arearefs="property6">
+ <para>
+ <literal>formula</literal>�i�I�v�V�����j�F
+ <emphasis>�v�Z</emphasis> �v���p�e�B�̂��߂̒l���`����SQL���B
+ �v�Z���ꂽ�v���p�e�B�͎��g�̃J�����ւ̃}�b�s���O������܂���B
+ </para>
+ </callout>
+ <callout arearefs="property7">
+ <para>
+ <literal>access</literal>�i�I�v�V���� - �f�t�H���g�� <literal>property</literal> �j�F
+ �v���p�e�B�̒l�ւ̃A�N�Z�X��Hibernate���g���헪�B
+ </para>
+ </callout>
+ <callout arearefs="property8">
+ <para>
+ <literal>lazy</literal> (optional - �f�t�H���g�� <literal>false</literal> ):
+ �C���X�^���X�ϐ��ɍŏ��ɃA�N�Z�X�����Ƃ��ɁA�v���p�e�B��x�����Ď擾����悤�w�肵�܂��B
+ (�o�C�g�R�[�h������쐬���鎞�Ԃ��K�v�ɂȂ�܂�)�B
+ </para>
+ </callout>
+ <callout arearefs="property9">
+ <para>
+ <literal>unique</literal> (�I�v�V����):�J�����Ƀ��j�[�N��������DDL�̐�����\�ɂ��܂��B
+ �܂��A<literal>property-ref</literal> �̃^�[�Q�b�g�Ƃ��邱�Ƃ�ł��܂��B
+ </para>
+ </callout>
+ <callout arearefs="property10">
+ <para>
+ <literal>not-null</literal> (�I�v�V����):�J������null�l������DDL�̐�����\�ɂ��܂��B
+ </para>
+ </callout>
+ <callout arearefs="property11">
+ <para>
+ <literal>optimistic-lock</literal> (�I�v�V���� - �f�t�H���g�� <literal>true</literal> ):
+ ���̃v���p�e�B�̍X�V�Ɋy�σ��b�N�̎擾��v�����邩�ǂ�����w�肵�܂��B
+ ����������A���̃v���p�e�B���_�[�e�B�ł���Ƃ��Ƀo�[�W�����𑝂₷�ׂ������肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="property12">
+ <para>
+ <literal>generated</literal> (�I�v�V���� - �f�t�H���g�� <literal>never</literal> ):
+ �v���p�e�B�̒l���A�f�[�^�x�[�X�ɂ���Đ������ꂽ���Ƃ�w�肵�܂��B
+ <xref linkend="mapping-generated">�����v���p�e�B</xref> ��Q�Ƃ��Ă��������B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <emphasis>typename</emphasis> �ɂ͈ȉ��̒l���\�ł��F
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ Hibernate�̊�{�^�̖��O�i�� <literal>integer, string, character,
+ date, timestamp, float, binary, serializable, object, blob</literal> �j�B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �f�t�H���g�̊�{�^��Java�N���X�� �i�� <literal>int, float,
+ char, java.lang.String, java.util.Date, java.lang.Integer, java.sql.Clob</literal> �j�B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �V���A���C�Y�\��Java�N���X�̖��O�B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �J�X�^���^�̃N���X���i�� <literal>com.illflow.type.MyCustomType</literal> �j�B
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ �^��w�肵�Ȃ���AHibernate�͐�����Hibernate�̌^�𐄑����邽�߂ɁA
+ �w�肳�ꂽ�v���p�e�B�ɑ��ă��t���N�V������g���܂��B
+ Hibernate�̓��[��2, 3, 4���̏����Ɏg���A
+ getter�v���p�e�B�̕Ԃ�l�̃N���X�̖��O���߂��悤�Ƃ��܂��B
+ ����������ŏ�ɏ\���ł���Ƃ͌���܂���B
+ �ꍇ�ɂ���ẮA<literal>type</literal> �������K�v�ȏꍇ������܂��B
+ �i�Ⴆ�� <literal>Hibernate.DATE</literal> �� <literal>Hibernate.TIMESTAMP</literal> ���ʂ��邽�߁A
+ �܂��̓J�X�^���^��w�肷�邽�߂Ȃǂł��B�j
+ </para>
+
+ <para>
+ <literal>access</literal> �����ŁA
+ ���s����Hibernate���ǂ̂悤�Ƀv���p�e�B�ɃA�N�Z�X���邩�𐧌�ł��܂��B
+ �f�t�H���g�ł�Hibernate�̓v���p�e�B��get/set�̃y�A��R�[�����܂��B
+ <literal>access="field"</literal> �Ǝw�肷��A
+ Hibernate�̓��t���N�V������g��get/set�̃y�A�����ɁA���ڃt�B�[���h�ɃA�N�Z�X���܂��B
+ �C���^�[�t�F�C�X <literal>org.hibernate.property.PropertyAccessor</literal> ��
+ ��������N���X��w�肷�邱�ƂŁA�v���p�e�B�ւ̃A�N�Z�X�ɓƎ��̐헪��w�肷�邱�Ƃ��ł��܂��B
+ </para>
+
+ <para>
+ ���ɋ��͂ȓ����͐����v���p�e�B�ł��B
+ �����̃v���p�e�B�͓��R�ǂݎ���p�ł���A�v���p�e�B�̒l�̓��[�h���Ɍv�Z����܂��B
+ �v�Z��SQL���Ƃ��Đ錾����ƁA���̃v���p�e�B��
+ �C���X�^���X���[�h����SQL�N�G���� <literal>SELECT</literal> ��̃T�u�N�G���ɕϊ�����܂��B
+ </para>
+
+ <programlisting><![CDATA[
+<property name="totalPrice"
+ formula="( SELECT SUM (li.quantity*p.price) FROM LineItem li, Product p
+ WHERE li.productId = p.productId
+ AND li.customerId = customerId
+ AND li.orderNumber = orderNumber )"/>]]></programlisting>
+
+ <para>
+ ����̃J����(��ł� <literal>customerId</literal> ������ɂ�����܂�)�̃G�C���A�X��錾���邱�ƂȂ��A
+ �G���e�B�e�B���g�̃e�[�u����Q�Ƃł��邱�Ƃɒ��ӂ��Ă��������B
+ ���������g�p�������Ȃ���A
+ �l�X�g���� <literal><formula></literal> �}�b�s���O�v�f��g���邱�Ƃɂ���ӂ��Ă��������B
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-manytoone" revision="5">
+ <title>many-to-one</title>
+
+ <para>
+ ���̉i���N���X�ւ̒ʏ�̊֘A�� <literal>many-to-one</literal> �v�f��g���Ē�`���܂��B
+ �����[�V���i�����f���͑��Έ�֘A�ł��B
+ �܂肠��e�[�u���̊O���L�[�́A�^�[�Q�b�g�ƂȂ�e�[�u���̎�L�[�J������Q�Ƃ��Ă��܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="manytoone1" coords="2 70"/>
+ <area id="manytoone2" coords="3 70"/>
+ <area id="manytoone3" coords="4 70"/>
+ <area id="manytoone4" coords="5 70"/>
+ <area id="manytoone5" coords="6 70"/>
+ <areaset id="manytoone6-7" coords="">
+ <area id="manytoone6" coords='7 70'/>
+ <area id="manytoone7" coords='8 70'/>
+ </areaset>
+ <area id="manytoone8" coords="9 70"/>
+ <area id="manytoone9" coords="10 70"/>
+ <area id="manytoone10" coords="11 70"/>
+ <area id="manytoone11" coords="12 70"/>
+ <area id="manytoone12" coords="13 70"/>
+ <area id="manytoone13" coords="14 70"/>
+ <area id="manytoone14" coords="15 70"/>
+ <area id="manytoone15" coords="16 70"/>
+ <area id="manytoone16" coords="17 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<many-to-one
+ name="propertyName"
+ column="column_name"
+ class="ClassName"
+ cascade="cascade_style"
+ fetch="join|select"
+ update="true|false"
+ insert="true|false"
+ property-ref="propertyNameFromAssociatedClass"
+ access="field|property|ClassName"
+ unique="true|false"
+ not-null="true|false"
+ optimistic-lock="true|false"
+ lazy="proxy|no-proxy|false"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ formula="arbitrary SQL expression"
+ node="element-name|@attribute-name|element/@attribute|."
+ embed-xml="true|false"
+ index="index_name"
+ unique_key="unique_key_id"
+ foreign-key="foreign_key_name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="manytoone1">
+ <para>
+ <literal>name</literal>�F�v���p�e�B���B
+ </para>
+ </callout>
+ <callout arearefs="manytoone2">
+ <para>
+ <literal>column</literal> (�I�v�V����):�O���L�[�J�����̖��O�B
+ �l�X�g���� <literal><column></literal> �v�f�ł�w��ł��܂��B
+ </para>
+ </callout>
+ <callout arearefs="manytoone3">
+ <para>
+ <literal>class</literal>�i�I�v�V���� - �f�t�H���g�́A
+ ���t���N�V�����ɂ�茈�肳���v���p�e�B�̌^�j�F�֘A�N���X�̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="manytoone4">
+ <para>
+ <literal>cascade</literal>�i�I�v�V�����j�F
+ �ǂ̑����A�e�I�u�W�F�N�g����֘A�I�u�W�F�N�g�ւƃJ�X�P�[�h�����邩��w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="manytoone5">
+ <para>
+ <literal>fetch</literal> (�I�v�V���� - �f�t�H���g�� <literal>select</literal> ):
+ �O�������t�F�b�`�������I��t�F�b�`�isequential select fetch�j��I���܂��B
+ </para>
+ </callout>
+ <callout arearefs="manytoone6-7">
+ <para>
+ <literal>update, insert</literal>�i�I�v�V���� - �f�t�H���g�� <literal>true</literal> �j�F
+ �}�b�s���O���ꂽ�J������SQL�� <literal>UPDATE</literal> �܂���
+ <literal>INSERT</literal> ���Ɋ܂܂�邱�Ƃ�w�肵�܂��B
+ �����Ƃ� <literal>false</literal> �ɐݒ肷��ƁA
+ ���̒l�������J�����Ƀ}�b�s���O���ꂽ���̃v���p�e�B��g���K��
+ ���̃A�v���P�[�V�����ɂ���ď��������ꂽ�����ȁu���o�v�v���p�e�B���\�ɂȂ�܂��B
+ </para>
+ </callout>
+ <callout arearefs="manytoone8">
+ <para>
+ <literal>property-ref</literal>�i�I�v�V�����j�F
+ ���̊O���L�[�Ɍ������ꂽ�֘A�N���X�̃v���p�e�B���B
+ ����w�肵�Ȃ���A�֘A�N���X�̎�L�[���g���܂��B
+ </para>
+ </callout>
+ <callout arearefs="manytoone9">
+ <para>
+ <literal>access</literal>�i�I�v�V���� - �f�t�H���g�� <literal>property</literal> �j�F
+ �v���p�e�B�̒l�ւ̃A�N�Z�X��Hibernate���g���헪�B
+ </para>
+ </callout>
+ <callout arearefs="manytoone10">
+ <para>
+ <literal>unique</literal>�i�I�v�V�����j�F
+ �O���L�[�J�����ɑ��ă��j�[�N��������DDL�̐�����\�ɂ��܂��B
+ �܂��A<literal>property-ref</literal> �̃^�[�Q�b�g�ɂ��邱�Ƃ�ł��܂��B
+ ����ɂ��֘A�̑��d�x����ʓI�Ɉ�Έ�ɂ��܂��B
+ </para>
+ </callout>
+ <callout arearefs="manytoone11">
+ <para>
+ <literal>not-null</literal> (�I�v�V����):�O���L�[�J�����ɑ��āA
+ null�l������DDL�̐�����\�ɂ��܂�
+ </para>
+ </callout>
+ <callout arearefs="manytoone12">
+ <para>
+ <literal>optimistic-lock</literal> (�I�v�V���� - �f�t�H���g�� <literal>true</literal> ):
+ ���̃v���p�e�B�̍X�V�Ɋy�ϓI���b�N�̎擾��v�����邩�ǂ�����w�肵�܂��B
+ ����������A���̃v���p�e�B���_�[�e�B�ł���Ƃ��Ƀo�[�W�����𑝂₷�ׂ������肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="manytoone13">
+ <para>
+ <literal>lazy</literal> (�I�v�V���� - �f�t�H���g�� <literal>proxy</literal> ):
+ �f�t�H���g�ł́A���d�x�P�̊֘A���v���L�V�ƂȂ�܂��B
+ <literal>lazy="no-proxy"</literal> �́A�C���X�^���X�ϐ��ɍŏ��ɃA�N�Z�X�����Ƃ��ɁA
+ �v���p�e�B��x���t�F�b�`����悤�w�肵�܂�
+ (�r���h���Ƀo�C�g�R�[�h�������K�v�ɂȂ�܂�)�B
+ <literal>lazy="false"</literal> �͊֘A���ɑ����Ƀt�F�b�`����悤�w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="manytoone14">
+ <para>
+ <literal>not-found</literal> (�I�v�V���� - �f�t�H���g�� <literal>exception</literal> ):
+ ���������s��Q�Ƃ���O���L�[��ǂ̂悤�Ɉ�������w�肵�܂��B
+ <literal>ignore</literal> �͌��������s��null�֘A�Ƃ��Ĉ����܂��B
+ </para>
+ </callout>
+ <callout arearefs="manytoone15">
+ <para>
+ <literal>entity-name</literal> (�I�v�V����):�֘A�����N���X�̃G���e�B�e�B���B
+ </para>
+ </callout>
+ </calloutlist>
+ <callout arearefs="manytoone16">
+ <para>
+ <literal>formula</literal> (�I�v�V����):
+ <emphasis> �v�Z���ꂽ</emphasis> �O���L�[�ɑ��Ēl���`����SQL��
+ </para>
+ </callout>
+ </programlistingco>
+
+ <para>
+ <literal>cascade</literal> ������ <literal>none</literal> �ȊO�̈Ӗ��̂���l���ݒ肷��ƁA
+ �֘A�I�u�W�F�N�g�ւ��鑀�삪�`�d���邱�ƂɂȂ�܂��B
+ �Ӗ��̂���l�Ƃ�Hibernate�̊�{����̖��O�̂��ƂŁA
+ <literal>delete-orphan</literal> �� <literal>all</literal> �A���얼��J���}�ŋ�����g�ݍ��킹
+ �i�Ⴆ�� <literal>cascade="persist,merge,evict"</literal> ��
+ <literal>cascade="all,delete-orphan"</literal>�j�A
+ �܂����ꂾ���łȂ� <literal>persist, merge, delete, save-update, evict, replicate, lock,
+ refresh</literal> �̂��Ƃ�w���܂��B
+ �ڂ�������� <xref linkend="objectstate-transitive"/> ���Ă��������B
+ �l����̊֘A(many-to-one��one-to-one�֘A)�́A
+ �P�Ƃł̍폜�iorphan delete)��T�|�[�g���Ă��Ȃ����Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ �T�^�I�� <literal>many-to-one</literal> �錾�͎��̂悤�ɃV���v���ł��B�F
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="product" class="Product" column="PRODUCT_ID"/>]]></programlisting>
+
+ <para>
+ <literal>property-ref</literal> �����́A�O���L�[���֘A�t����ꂽ�e�[�u���́A��L�[�łȂ�
+ ���j�[�N�L�[��Q�Ƃ��Ă��郌�K�V�[�f�[�^��}�b�v���邽�߂ɂ����g���ׂ��ł��B
+ ����͏X�������[�V���i�����f���ł��B
+ �Ⴆ�� <literal>Product</literal> �N���X���A
+ ��L�[�łȂ����j�[�N�ȃV���A���i���o�[�����Ă���Ɖ��肵�Ă݂Ă��������B
+ �i <literal>unique</literal> ������SchemaExport�c�[����g����Hibernate��DDL�����𐧌䂵�܂��B�j
+ </para>
+
+ <programlisting><![CDATA[<property name="serialNumber" unique="true" type="string" column="SERIAL_NUMBER"/>]]></programlisting>
+
+ <para>
+ �ȉ��̂悤�� <literal>OrderItem</literal> �ɑ��ă}�b�s���O��g���܂��F
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="product" property-ref="serialNumber" column="PRODUCT_SERIAL_NUMBER"/>]]></programlisting>
+
+ <para>
+ �������A����͌����Đ����ł��܂���B
+ </para>
+
+ <para>
+ �Q�Ƃ������j�[�N�L�[���A�֘A����G���e�B�e�B�̑����̃v���p�e�B����\�������ꍇ�A
+ �w�肵�� <literal><properties></literal> �v�f��ŁA�Q�Ƃ���v���p�e�B��}�b�s���O����ׂ��ł��B
+ </para>
+
+ <para>
+ ����Q�Ƃ������j�[�N�L�[���R���|�[�l���g�̃v���p�e�B�ł���ꍇ�́A�v���p�e�B�̃p�X��w��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="owner" property-ref="identity.ssn" column="OWNER_SSN"/>]]></programlisting>
+
+
+ </sect2>
+
+
+ <sect2 id="mapping-declaration-onetoone" revision="3">
+ <title>one-to-one</title>
+
+ <para>
+ ���̉i���N���X�ւ̈�Έ�֘A�́A<literal>one-to-one</literal> �v�f�Œ�`���܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="onetoone1" coords="2 70"/>
+ <area id="onetoone2" coords="3 70"/>
+ <area id="onetoone3" coords="4 70"/>
+ <area id="onetoone4" coords="5 70"/>
+ <area id="onetoone5" coords="6 70"/>
+ <area id="onetoone6" coords="7 70"/>
+ <area id="onetoone7" coords="8 70"/>
+ <area id="onetoone8" coords="9 70"/>
+ <area id="onetoone9" coords="10 70"/>
+ <area id="onetoone10" coords="11 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<one-to-one
+ name="propertyName"
+ class="ClassName"
+ cascade="cascade_style"
+ constrained="true|false"
+ fetch="join|select"
+ property-ref="propertyNameFromAssociatedClass"
+ access="field|property|ClassName"
+ formula="any SQL expression"
+ lazy="proxy|no-proxy|false"
+ entity-name="EntityName"
+ node="element-name|@attribute-name|element/@attribute|."
+ embed-xml="true|false"
+ foreign-key="foreign_key_name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="onetoone1">
+ <para>
+ <literal>name</literal>�F�v���p�e�B���B
+ </para>
+ </callout>
+ <callout arearefs="onetoone2">
+ <para>
+ <literal>class</literal>�i�I�v�V���� -
+ �f�t�H���g�̓��t���N�V�����ɂ�茈�肳���v���p�e�B�̌^�j�F
+ �֘A�N���X�̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="onetoone3">
+ <para>
+ <literal>cascade</literal>�i�I�v�V�����j�F
+ �e�I�u�W�F�N�g����֘A�I�u�W�F�N�g�ցA�ǂ̑����J�X�P�[�h���邩��w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="onetoone4">
+ <para>
+ <literal>constrained</literal>�i�I�v�V�����j�F
+ �}�b�s���O���ꂽ�e�[�u���̎�L�[�ɑ���O���L�[���A
+ �֘A�N���X�̃e�[�u����Q�Ƃ��邱�Ƃ�w�肵�܂��B
+ ���̃I�v�V������ <literal>save()</literal> ��
+ <literal>delete()</literal> ���J�X�P�[�h����鏇���ɉe�����A
+ �����Ċ֘A���v���L�V����邩�ǂ����ɂ�e�����܂�
+ �i�����ăX�L�[�}�G�N�X�|�[�g�c�[���ɂ�g���܂��j�B
+ </para>
+ </callout>
+ <callout arearefs="onetoone5">
+ <para>
+ <literal>fetch</literal>�i�I�v�V���� - �f�t�H���g�� <literal>select</literal> �j�F
+ �O�������t�F�b�`�Ə����I��t�F�b�`�isequential select fetch�j�̂ǂ��炩��I���܂��B
+ </para>
+ </callout>
+ <callout arearefs="onetoone6">
+ <para>
+ <literal>property-ref</literal>�i�I�v�V�����j�F
+ ���̃N���X�̎�L�[�Ɍ������ꂽ�֘A�N���X�̃v���p�e�B���B
+ �w�肳��Ȃ���A�֘A�N���X�̎�L�[���g���܂��B
+ </para>
+ </callout>
+ <callout arearefs="onetoone7">
+ <para>
+ <literal>access</literal>�i�I�v�V���� - �f�t�H���g�� <literal>property</literal> �j�F
+ �v���p�e�B�̒l�ւ̃A�N�Z�X��Hibernate���g���헪�B
+ </para>
+ </callout>
+ <callout arearefs="onetoone8">
+ <para>
+ <literal>formula</literal> (�I�v�V����):
+ �قƂ�ǂ��ׂĂ̈�Έ�֘A�̓I�[�i�[�̃G���e�B�e�B�̎�L�[�ւƃ}�b�s���O����܂��B
+ ����ȊO�̋H�ȏꍇ�́A
+ ���̃J������A�����̃J�����ASQL�\����g�����������邽�߂̎���w��ł��܂��B
+ �i��� <literal>org.hibernate.test.onetooneformula</literal> ��Q�Ƃ��Ă��������B�j
+ </para>
+ </callout>
+ <callout arearefs="onetoone9">
+ <para>
+ <literal>lazy</literal> (�I�v�V���� - �f�t�H���g�� <literal>proxy</literal> ):
+ �f�t�H���g�ł́A���d�x�P�̊֘A���v���L�V�ƂȂ�܂��B
+ <literal>lazy="no-proxy"</literal> �́A�C���X�^���X�ϐ��ɍŏ��ɃA�N�Z�X�����Ƃ��ɁA
+ �v���p�e�B��x���t�F�b�`����悤�w�肵�܂�
+ (�r���h���Ƀo�C�g�R�[�h�������K�v�ɂȂ�܂�)�B
+ <literal>lazy="false"</literal> �͊֘A���ɑ����Ƀt�F�b�`����悤�w�肵�܂��B
+ <emphasis>��� <literal>constrained="false"</literal> �Ȃ�A
+ �v���L�V�͎g�p�s�\�ƂȂ�A�֘A���Ƀt�F�b�`���邱�Ƃɒ��ӂ��Ă��������I</emphasis>
+
+ </para>
+ </callout>
+ <callout arearefs="onetoone10">
+ <para>
+ <literal>entity-name</literal> (�I�v�V����):�֘A�N���X�̃G���e�B�e�B��
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ ��Έ�֘A�ɂ�2��ނ���܂��F
+ </para>
+ <itemizedlist>
+ <listitem><para>
+ ��L�[�֘A
+ </para></listitem>
+ <listitem><para>
+ ���j�[�N�O���L�[�֘A
+ </para></listitem>
+ </itemizedlist>
+
+ <para>
+ ��L�[�֘A�ɂ́A���ʂȃe�[�u���J�����͕K�v����܂���B
+ ���2�̍s���֘A�ɂ��W���Ă���A2�̃e�[�u���͓�����L�[�̒l���L���܂��B
+ ���̂���2�̃I�u�W�F�N�g���L�[�֘A�ɂ���Ċ֘A�t�������̂ł���A
+ �m���ɓ������ʎq�̒l�������Ȃ���Ȃ�܂���B
+ </para>
+
+ <para>
+ ��L�[�֘A��s�����߂ɂ́A�ȉ��̃}�b�s���O�� <literal>Employee</literal> ��
+ <literal>Person</literal> �̂��ꂼ��ɒlj����Ă��������B
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="person" class="Person"/>]]></programlisting>
+ <programlisting><![CDATA[<one-to-one name="employee" class="Employee" constrained="true"/>]]></programlisting>
+
+ <para>
+ �����ŁAPERSON��EMPLOYEE�e�[�u���̊W����s�̎�L�[�������ł��邱�Ƃ�m���ɂ��Ȃ�������܂���B
+ �����ł́A<literal>foreign</literal> �Ƃ��������Hibernate���ʎq�����헪��g���܂��F
+ </para>
+
+ <programlisting><![CDATA[<class name="person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="foreign">
+ <param name="property">employee</param>
+ </generator>
+ </id>
+ ...
+ <one-to-one name="employee"
+ class="Employee"
+ constrained="true"/>
+</class>]]></programlisting>
+
+ <para>
+ <literal>Employee</literal> �C���X�^���X���A<literal>Person</literal> ��
+ <literal>employee</literal> �v���p�e�B�ŎQ�Ƃ����悤�ɁA
+ �V�����Z�[�u���ꂽ <literal>Person</literal> �̃C���X�^���X�ɂ͓�����L�[�̒l���������܂��B
+
+ �V�����Z�[�u���� <literal>Person</literal> �C���X�^���X�́A
+ ���� <literal>Person</literal> �� <literal>employee</literal> �v���p�e�B���Q�Ƃ���
+ <literal>Employee</literal> �C���X�^���X�Ƃ��ē�����L�[�����蓖�Ă��܂��B
+ </para>
+
+ <para>
+ ���1�̕��@�Ƃ��āA<literal>Employee</literal> ���� <literal>Person</literal> �ւ�
+ ���j�[�N�����g�����O���L�[�֘A�͈ȉ��̂悤�ɕ\������܂��F
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="person" class="Person" column="PERSON_ID" unique="true"/>]]></programlisting>
+
+ <para>
+ �����Ă��̊֘A�́A
+ �ȉ��̋L�q�� <literal>Person</literal> �̃}�b�s���O�ɒlj����邱�Ƃőo�����ɂ��邱�Ƃ��ł��܂��F
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="employee" class="Employee" property-ref="person"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-naturalid">
+ <title>natural-id</title>
+
+ <programlisting><![CDATA[<natural-id mutable="true|false"/>
+ <property ... />
+ <many-to-one ... />
+ ......
+</natural-id>]]></programlisting>
+
+ <para>
+ ��L�[�Ƃ��đ㗝�L�[�̎g�p�𐄏����܂����A
+ ���ׂẴG���e�B�e�B�ɑ��Ď��R�L�[���ʂ���悤�ɂ��ׂ��ł��B
+ ���R�L�[�̓��j�[�N����null�Ȉ�̃v���p�e�B�A�܂��̓v���p�e�B�̘A���ł��B
+ �s�ςł������ɗǂ��ł��B
+ <literal><natural-id></literal> �v�f��Ŏ��R�L�[�̃v���p�e�B��}�b�s���O���܂��B
+ Hibernate�͕K�R�I�Ƀ��j�[�N����null�l�����鐧������A
+ �������ă}�b�s���O�͂�莩�ȋL�q�I�ɂȂ�܂��B
+ </para>
+
+ <para>
+ �G���e�B�e�B�̎��R�L�[�v���p�e�B�̔�r�ɂ́A
+ <literal>equals()</literal> �� <literal>hashCode()</literal> �̎������������߂��܂��B
+ </para>
+
+ <para>
+ ���̃}�b�s���O�͎��R��L�[��g�����G���e�B�e�B�ł̎g�p��Ӑ}���Ă��܂���B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>mutable</literal> (�I�v�V����, �f�t�H���g�� <literal>false</literal> ):
+ �f�t�H���g�ł́A���R���ʎq�v���p�e�B�͕s��(�萔)�Ƒz�肳��Ă��܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-component" revision="2">
+ <title>component, dynamic-component</title>
+
+ <para>
+ <literal><component></literal> �v�f�́A
+ �q�I�u�W�F�N�g�̃v���p�e�B��e�N���X�̃e�[�u���̃J�����փ}�b�s���O���܂��B
+ �R���|�[�l���g�͎����̃v���p�e�B�A�R���|�[�l���g�A�R���N�V�����̏��ɒ�`�ł��܂��B
+ �ȉ��́u�R���|�[�l���g�v���Ă��������B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="component1" coords="2 45"/>
+ <area id="component2" coords="3 45"/>
+ <area id="component3" coords="4 45"/>
+ <area id="component4" coords="5 45"/>
+ <area id="component5" coords="6 45"/>
+ <area id="component6" coords="7 45"/>
+ <area id="component7" coords="8 45"/>
+ <area id="component8" coords="9 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<component
+ name="propertyName"
+ class="className"
+ insert="true|false"
+ update="true|false"
+ access="field|property|ClassName"
+ lazy="true|false"
+ optimistic-lock="true|false"
+ unique="true|false"
+ node="element-name|."
+>
+
+ <property ...../>
+ <many-to-one .... />
+ ........
+</component>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="component1">
+ <para>
+ <literal>name</literal>�F�v���p�e�B���B
+ </para>
+ </callout>
+ <callout arearefs="component2">
+ <para>
+ <literal>class</literal>
+ �i�I�v�V���� - �f�t�H���g�̓��t���N�V�����ɂ�茈�肳���v���p�e�B�̌^�j�F
+ �R���|�[�l���g�i�q�j�N���X�̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="component3">
+ <para>
+ <literal>insert</literal> �F�}�b�s���O���ꂽ�J������SQL��
+ <literal>INSERT</literal> �Ɍ����悤�ɂ���ǂ�����w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="component4">
+ <para>
+ <literal>update</literal> : �}�b�s���O���ꂽ�J������SQL ��
+ <literal>UPDATE</literal> �Ɍ����悤�ɂ��邩�ǂ�����w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="component5">
+ <para>
+ <literal>access</literal> �i�I�v�V���� - �f�t�H���g�� <literal>property</literal> �j�F
+ �v���p�e�B�̒l�ւ̃A�N�Z�X��Hibernate���g���헪�B
+ </para>
+ </callout>
+ <callout arearefs="component6">
+ <para>
+ <literal>lazy</literal> (optional - �f�t�H���g�� <literal>false</literal> ):
+ �C���X�^���X�ϐ��ɍŏ��ɃA�N�Z�X�����Ƃ��ɁA
+ �R���|�[�l���g��x�����ăt�F�b�`����悤�w�肵�܂��B
+ (�o�C�g�R�[�h������쐬���鎞�Ԃ��K�v�ɂȂ�܂�)
+ </para>
+ </callout>
+ <callout arearefs="component7">
+ <para>
+ <literal>optimistic-lock</literal> (�I�v�V���� - �f�t�H���g�� <literal>true</literal> ):
+ ���̃v���p�e�B�̍X�V�ɁA�y�σ��b�N�̎擾��v�����邩�ǂ�����w�肵�܂��B
+ ����������A���̃v���p�e�B���_�[�e�B�ł���Ƃ��Ƀo�[�W�����𑝂₷�ׂ������肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="component8">
+ <para>
+ <literal>unique</literal> (�I�v�V���� - �f�t�H���g�� <literal>false</literal> ):
+ �R���|�[�l���g�̂��ׂẴ}�b�s���O����J�����ɁA���j�[�N�����݂��邩��w�肵�܂��B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ �q�� <literal><property></literal> �^�O�ŁA
+ �q�̃N���X�̃v���p�e�B��e�[�u���J�����Ƀ}�b�s���O���܂��B
+ </para>
+
+ <para>
+ <literal><component></literal> �v�f�́A�e�G���e�B�e�B�֖߂�Q�ƂƂ��āA
+ �R���|�[�l���g�̃N���X�̃v���p�e�B��}�b�s���O���� <literal><parent></literal> �T�u�v�f�����܂��B
+ </para>
+
+ <para>
+ <literal><dynamic-component></literal> �v�f�́A
+ <literal>Map</literal> ���R���|�[�l���g�Ƃ��ă}�b�s���O����邱�Ƃ�\�ɂ��܂��B
+ �v���p�e�B����map�̃L�[��Q�Ƃ��܂��B<xref linkend="components-dynamic"/> ��Q�Ƃ��Ă��������B
+
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-properties" revision="2">
+ <title>properties</title>
+
+ <para>
+ <literal><properties></literal> �v�f�̓N���X�̃v���p�e�B�̎w�肳�ꂽ�A
+ �_���I�ȃO���[�s���O��\�ɂ��܂��B
+ ���̍\���̍ł�d�v�Ȏg�p���@�́A
+ <literal>property-ref</literal> �̃^�[�Q�b�g�ɂȂ�v���p�e�B�̌��������邱�Ƃł��B
+ ����͂܂��A�����J�����̃��j�[�N������`����ȒP�ȕ��@�ł����܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="properties1" coords="2 45"/>
+ <area id="properties2" coords="3 45"/>
+ <area id="properties3" coords="4 45"/>
+ <area id="properties4" coords="5 45"/>
+ <area id="properties5" coords="6 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<properties
+ name="logicalName"
+ insert="true|false"
+ update="true|false"
+ optimistic-lock="true|false"
+ unique="true|false"
+>
+
+ <property ...../>
+ <many-to-one .... />
+ ........
+</properties>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="properties1">
+ <para>
+ <literal>name</literal> : �O���[�s���O�̘_�����B
+ ���ۂ̃v���p�e�B���ł� <emphasis>����܂���</emphasis> �B
+ </para>
+ </callout>
+ <callout arearefs="properties2">
+ <para>
+ <literal>insert</literal>�F�}�b�s���O���ꂽ�J������SQL��
+ <literal>INSERT</literal> �Ɍ����悤�ɂ��邩�ǂ�����w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="properties3">
+ <para>
+ <literal>update</literal>�F�}�b�s���O���ꂽ�J������SQL��
+ <literal>UPDATE</literal> �Ɍ����悤�ɂ��邩�ǂ�����w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="properties4">
+ <para>
+ <literal>optimistic-lock</literal> (�I�v�V���� - �f�t�H���g�� <literal>true</literal> ):
+ �����̃v���p�e�B�̍X�V�Ɋy�ϓI���b�N�̎擾��v�����邩�ǂ�����w�肵�܂��B
+ ����������A���̃v���p�e�B���_�[�e�B�ł���Ƃ��Ƀo�[�W�����𑝂₷�ׂ������肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="properties5">
+ <para>
+ <literal>unique</literal> (�I�v�V���� - �f�t�H���g�� <literal>false</literal> ):
+ �R���|�[�l���g�̂��ׂẴ}�b�s���O����J�����ɁA���j�[�N�����݂��邩��w�肵�܂��B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ �Ⴆ�A����ȉ��̂悤�� <literal><properties></literal> �}�b�s���O���������ꍇ�F
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="personNumber"/>
+ ...
+ <properties name="name"
+ unique="true" update="false">
+ <property name="firstName"/>
+ <property name="initial"/>
+ <property name="lastName"/>
+ </properties>
+</class>]]></programlisting>
+
+ <para>
+ ��L�[�̑���� <literal>Person</literal> �e�[�u���̃��j�[�N�L�[�ւ̎Q�Ƃ��A
+ ���K�V�[�f�[�^�̊֘A���������܂���B�F
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="person"
+ class="Person" property-ref="name">
+ <column name="firstName"/>
+ <column name="initial"/>
+ <column name="lastName"/>
+</many-to-one>]]></programlisting>
+
+ <para>
+ �������A���̂悤�ȃ��K�V�[�f�[�^�}�b�s���O�̃R���e�L�X�g�O�ւ̎g�p�͐������܂���B
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-subclass" revision="4">
+ <title>subclass</title>
+
+ <para>
+ �Ō�Ƀ|�����[�t�B�b�N�ȉi�����ɂ́A���[�g�̉i���N���X�̊e�T�u�N���X�̒�`���K�v�ł��B
+ table-per-class-hierarchy�}�b�s���O�헪�ł́A
+ <literal><subclass></literal> ��`���g���܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="subclass1" coords="2 55"/>
+ <area id="subclass2" coords="3 55"/>
+ <area id="subclass3" coords="4 55"/>
+ <area id="subclass4" coords="5 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<subclass
+ name="ClassName"
+ discriminator-value="discriminator_value"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ entity-name="EntityName"
+ node="element-name"
+ extends="SuperclassName">
+
+ <property .... />
+ .....
+</subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="subclass1">
+ <para>
+ <literal>name</literal>�F�T�u�N���X�̊��S�C�����ꂽ�N���X���B
+ </para>
+ </callout>
+ <callout arearefs="subclass2">
+ <para>
+ <literal>discriminator-value</literal>�i�I�v�V���� - �f�t�H���g�̓N���X���j�F
+ �X�̃T�u�N���X���ʂ��邽�߂̒l�B
+ </para>
+ </callout>
+ <callout arearefs="subclass3">
+ <para>
+ <literal>proxy</literal>�i�I�v�V�����j�F
+ �x���������v���L�V�Ɏg���N���X��C���^�[�t�F�C�X��w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="subclass4">
+ <para>
+ <literal>lazy</literal>�i�I�v�V����, �f�t�H���g�� <literal>true</literal> �j�F
+ <literal>lazy="false"</literal> �Ɛݒ肷��ƁA�x���t�F�b�`���g�p�ł��܂���B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ �e�T�u�N���X�ł́A�i���v���p�e�B�ƃT�u�N���X���`���܂��B
+ <literal><version></literal> �� <literal><id></literal> �v���p�e�B�́A
+ ���[�g�N���X����p�������Ɖ��肳��܂��B
+ �K�w�\���ɂ�����T�u�N���X�́A
+ ���j�[�N�� <literal>discriminator-value</literal> ���`���Ȃ���Ȃ�܂���B
+ none���w�肳���ƁA���S�C�����ꂽJava�N���X�����g���܂��B
+ </para>
+
+<!--
+ <para>
+ It is possible to define <literal>subclass</literal>, <literal>union-subclass</literal>,
+ and <literal>joined-subclass</literal> mappings in separate mapping documents, directly beneath
+ <literal>hibernate-mapping</literal>. This allows you to extend a class hierachy just by adding
+ a new mapping file. You must specify an <literal>extends</literal> attribute in the subclass mapping,
+ naming a previously mapped superclass. Note: Previously this feature made the ordering of the mapping
+ documents important. Since Hibernate3, the ordering of mapping files does not matter when using the
+ extends keyword. The ordering inside a single mapping file still needs to be defined as superclasses
+ before subclasses.
+
+ <literal>subclass</literal> �A<literal>union-subclass</literal> �A
+ <literal>joined-subclass</literal> �}�b�s���O��
+ <literal>hibernate-mapping</literal> �����̕ʂ̃}�b�s���O�h�L�������g��Ő錾�ł��܂��B
+ ����ɂ��A�V�����}�b�s���O�t�@�C����lj����邾���ŃN���X�K�w��g�����邱�Ƃ��ł��܂��B
+ ���炩���߃}�b�s���O����X�[�p�[�N���X��w�肵���T�u�N���X�}�b�s���O��ŁA
+ <literal>extends</literal> ������w�肵�Ȃ���Ȃ�܂���B
+ ���ӁF���̓����̓}�b�s���O�h�L�������g�̏��ԕt�����d�v�ɂȂ�܂��B
+ Hibernate3�ł́A�g���L�[���[�h��g���Ƃ��ɂ́A�}�b�s���O�t�@�C���̏����t���͖��ɂȂ�܂���B
+ ��̃}�b�s���O�t�@�C����ł̏����t���͖����ɁA�T�u�N���X�̑O�ɃX�[�p�[�N���X�Ƃ��Ē�`����K�v������܂��B
+ </para>
+
+
+ <programlisting><![CDATA[
+<hibernate-mapping>
+ <subclass name="DomesticCat" extends="Cat" discriminator-value="D">
+ <property name="name" type="string"/>
+ </subclass>
+</hibernate-mapping>]]></programlisting>
+-->
+
+ <para>
+ �p���̃}�b�s���O�Ɋւ������ <xref linkend="inheritance"/> ���Ă��������B
+ </para>
+
+ </sect2>
+
+
+ <sect2 id="mapping-declaration-joinedsubclass" revision="3">
+ <title>joined-subclass</title>
+
+ <para>
+ ���1�̕��@�Ƃ��āA�e�T�u�N���X���g�̃e�[�u���փ}�b�s���O���邱�Ƃ��ł��܂�
+ (table-per-subclass mapping strategy)�B
+ �p��������Ԃ̓X�[�p�[�N���X�̃e�[�u����g���������Ō������܂��B
+ <literal><joined-subclass></literal> �v�f��g�p���܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="joinedsubclass1" coords="2 45"/>
+ <area id="joinedsubclass2" coords="3 45"/>
+ <area id="joinedsubclass3" coords="4 45"/>
+ <area id="joinedsubclass4" coords="5 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<joined-subclass
+ name="ClassName"
+ table="tablename"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ schema="schema"
+ catalog="catalog"
+ extends="SuperclassName"
+ persister="ClassName"
+ subselect="SQL expression"
+ entity-name="EntityName"
+ node="element-name">
+
+ <key .... >
+
+ <property .... />
+ .....
+</joined-subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="joinedsubclass1">
+ <para>
+ <literal>name</literal>�F�T�u�N���X�̊��S�C�����ꂽ�N���X���B
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass2">
+ <para>
+ <literal>table</literal> :�T�u�N���X�e�[�u���̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass3">
+ <para>
+ <literal>proxy</literal> (�I�v�V����):
+ �x���������v���L�V�Ɏg�p����N���X��C���^�[�t�F�C�X��w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass4">
+ <para>
+ <literal>lazy</literal> (�I�v�V����, �f�t�H���g�� <literal>true</literal> ):
+ <literal>lazy="false"</literal> �Ƃ���ƁA�x���t�F�b�`���g�p�ł��܂���B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ ���̃}�b�s���O�헪�ɂ́A���ʃJ�����͕K�v����܂���B
+ �������e�T�u�N���X�� <literal><key></literal> �v�f��g���A
+ �I�u�W�F�N�g���ʎq��ێ�����e�[�u���J�������`���Ȃ���Ȃ�܂���B
+ ���̏͂̏��߂̃}�b�s���O�͈ȉ��̂悤�ɏ��������܂��F
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class name="Cat" table="CATS">
+ <id name="id" column="uid" type="long">
+ <generator class="hilo"/>
+ </id>
+ <property name="birthdate" type="date"/>
+ <property name="color" not-null="true"/>
+ <property name="sex" not-null="true"/>
+ <property name="weight"/>
+ <many-to-one name="mate"/>
+ <set name="kittens">
+ <key column="MOTHER"/>
+ <one-to-many class="Cat"/>
+ </set>
+ <joined-subclass name="DomesticCat" table="DOMESTIC_CATS">
+ <key column="CAT"/>
+ <property name="name" type="string"/>
+ </joined-subclass>
+ </class>
+
+ <class name="eg.Dog">
+ <!-- ������Dog�̃}�b�s���O�����܂� -->
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ �p���̃}�b�s���O�Ɋւ������ <xref linkend="inheritance"/> ���Ă��������B
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-unionsubclass" revision="2">
+ <title>union-subclass</title>
+
+ <para>
+ 3�ڂ̑I���́A�p���K�w�̋�ۃN���X�݂̂�e�[�u���Ƀ}�b�s���O���邱�Ƃł�
+ (the table-per-concrete-class�헪)�B
+ ���ꂼ��̃e�[�u���͌p���̏�Ԃ�܂߂��ׂẴN���X�̉i����Ԃ��`���܂��B
+ Hibernate�ł͂��̗l�Ȍp���K�w���K������K�v�ł͂���܂���B
+ �P���ɂ��ꂼ��̃N���X��A
+ �ʁX�� <literal><class></literal> �錾��g���ă}�b�s���O���邱�Ƃ��ł��܂��B
+ �������|�����[�t�B�b�N�Ȋ֘A(�Ⴆ�� �K�w�̃X�[�p�[�N���X�ւ̊֘A)��g�������Ȃ�A
+ <literal><union-subclass></literal> �}�b�s���O��g���K�v������܂��B
+
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="unionsubclass1" coords="2 45"/>
+ <area id="unionsubclass2" coords="3 45"/>
+ <area id="unionsubclass3" coords="4 45"/>
+ <area id="unionsubclass4" coords="5 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<union-subclass
+ name="ClassName"
+ table="tablename"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ schema="schema"
+ catalog="catalog"
+ extends="SuperclassName"
+ abstract="true|false"
+ persister="ClassName"
+ subselect="SQL expression"
+ entity-name="EntityName"
+ node="element-name">
+
+ <property .... />
+ .....
+</union-subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="unionsubclass1">
+ <para>
+ <literal>name</literal>�F�T�u�N���X�̊��S�C�����ꂽ�N���X���B
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass2">
+ <para>
+ <literal>table</literal> :�T�u�N���X�e�[�u���̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass3">
+ <para>
+ <literal>proxy</literal> (�I�v�V����):
+ �x���������v���L�V�Ɏg�p����N���X��C���^�[�t�F�C�X��w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass4">
+ <para>
+ <literal>lazy</literal> (�I�v�V����, �f�t�H���g�� <literal>true</literal> ):
+ <literal>lazy="false"</literal> �Ƃ���ƁA�x���t�F�b�`���g�p�ł��܂���B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ ���̃}�b�s���O�헪�ł͎��ʃJ������L�[�J�����͕K�v����܂���B
+ </para>
+
+ <para>
+ �p���̃}�b�s���O�Ɋւ������ <xref linkend="inheritance"/> ���Ă��������B
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-join" revision="3">
+ <title>join</title>
+
+ <para>
+ <literal><join></literal> �v�f��g�����ƂŁA
+ �P�̃N���X�̃v���p�e�B������̃e�[�u���Ƀ}�b�s���O���邱�Ƃ��ł��܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="join1" coords="2 50"/>
+ <area id="join2" coords="3 50"/>
+ <area id="join3" coords="4 50"/>
+ <area id="join4" coords="5 50"/>
+ <area id="join5" coords="6 50"/>
+ <area id="join6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<join
+ table="tablename"
+ schema="owner"
+ catalog="catalog"
+ fetch="join|select"
+ inverse="true|false"
+ optional="true|false">
+
+ <key ... />
+
+ <property ... />
+ ...
+</join>]]></programlisting>
+
+ <calloutlist>
+ <callout arearefs="join1">
+ <para>
+ <literal>table</literal> :���������e�[�u���̖��O
+ </para>
+ </callout>
+ <callout arearefs="join2">
+ <para>
+ <literal>schema</literal> (�I�v�V����):
+ ���[�g�� <literal><hibernate-mapping></literal> �v�f�Ŏw�肵���X�L�[�}����
+ �I�[�o�[���C�h���܂��B
+ </para>
+ </callout>
+ <callout arearefs="join3">
+ <para>
+ <literal>catalog</literal> (�I�v�V����):
+ ���[�g�� <literal><hibernate-mapping></literal> �v�f�Ŏw�肵���J�^���O����
+ �I�[�o�[���C�h���܂��B
+ </para>
+ </callout>
+ <callout arearefs="join4">
+ <para>
+ <literal>fetch</literal> (�I�v�V���� - �f�t�H���g�� <literal>join</literal> ):
+ <literal>join</literal> ��ݒ肵���ꍇ�A
+ Hibernate�̓f�t�H���g�ŁA�N���X��X�[�p�[�N���X�Œ�`���ꂽ <literal><join></literal>
+ ��������̂ɓ��������g���A�T�u�N���X�Œ�`���ꂽ <literal><join></literal>
+ ��������̂ɊO��������g���܂��B
+ <literal>select</literal> ��ݒ肵���ꍇ�ɂ́A
+ Hibernate�̓T�u�N���X�Œ�`���ꂽ <literal><join></literal>
+ �̑I��ɏ����I���g���܂��B���̏ꍇ�A
+ �s���T�u�N���X�̃C���X�^���X���\���邱�Ƃ��킩�����ꍇ�ɂ̂ݔ��s����܂��B
+ ��������̓N���X�₻�̃X�[�p�[�N���X�Œ�`���ꂽ <literal><join></literal> ����
+ ���邽�߂Ɏg�p���܂��B
+ </para>
+ </callout>
+ <callout arearefs="join5">
+ <para>
+ <literal>inverse</literal> (�I�v�V���� - �f�t�H���g�� <literal>false</literal> ):
+ ����\�ł���AHibernate�͂��̌����Œ�`����Ă���v���p�e�B�ɑ�
+ �}����X�V��s���܂���B
+ </para>
+ </callout>
+ <callout arearefs="join6">
+ <para>
+ <literal>optional</literal> (�I�v�V���� - �f�t�H���g�� <literal>false</literal> ):
+ ����\�ł���AHibernate�͂��̌����Œ�`���ꂽ�v���p�e�B��null�łȂ��ꍇ�ɂ̂�
+ �s��}�����A���̃v���p�e�B�̌����ɂ͏�ɊO��������g�p���܂��B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ �Ⴆ�ΐl�̃A�h���X�̏��������e�[�u���Ƀ}�b�s���O���邱�Ƃ��\�ł�
+ (���ׂẴv���p�e�B�ɑ��Ēl�^�̃Z�}���e�B�N�X��ێ����܂�)�B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person"
+ table="PERSON">
+
+ <id name="id" column="PERSON_ID">...</id>
+
+ <join table="ADDRESS">
+ <key column="ADDRESS_ID"/>
+ <property name="address"/>
+ <property name="zip"/>
+ <property name="country"/>
+ </join>
+ ...]]></programlisting>
+
+ <para>
+ ���̓����͂������K�V�[�f�[�^���f���ɑ��Ă̂ݗL�p�ł����A
+ �N���X������Ȃ��e�[�u���ƁA���߂ׂ̍����h���C�����f���𐄏����܂��B
+ ��������Ő������悤�ɁA�P�̃N���X�K�w�Ōp���̃}�b�s���O�헪���ւ��鎞�ɂ͗L�p�ł��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-key">
+ <title>key</title>
+
+ <para>
+ ���܂ʼn��x�� <literal><key></literal> �v�f���o�Ă��܂����B
+ ���̗v�f�͐V�����e�[�u���ւ̌������`������A
+ �����e�[�u���ŊO���L�[���`�����肷��e�v�f�̂ǂ��ɂł����A
+ �I���W�i���e�[�u���̎�L�[��Q�Ƃ��܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="key1" coords="2 50"/>
+ <area id="key2" coords="3 50"/>
+ <area id="key3" coords="4 50"/>
+ <area id="key4" coords="5 50"/>
+ <area id="key5" coords="6 50"/>
+ <area id="key6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<key
+ column="columnname"
+ on-delete="noaction|cascade"
+ property-ref="propertyName"
+ not-null="true|false"
+ update="true|false"
+ unique="true|false"
+/>]]></programlisting>
+
+ <calloutlist>
+ <callout arearefs="key1">
+ <para>
+ <literal>column</literal> (�I�v�V����):�O���L�[�J�����̖��O�B
+ �l�X�g���� <literal><column></literal> �J�����ɂ���Ă�w�肳��܂��B
+ </para>
+ </callout>
+ <callout arearefs="key2">
+ <para>
+ <literal>on-delete</literal> (�I�v�V����, �f�t�H���g�� <literal>noaction</literal>):
+ �O���L�[���f�[�^�x�[�X���x���ŃJ�X�P�[�h�폜���\���ǂ�����w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="key3">
+ <para>
+ <literal>property-ref</literal> (�I�v�V����):
+ �I���W�i���e�[�u���̎�L�[�ł͂Ȃ��J������Q�Ƃ���O���L�[��w�肵�܂�
+ (���K�V�[�f�[�^�ɑ��Ē���܂�)�B
+ </para>
+ </callout>
+ <callout arearefs="key4">
+ <para>
+ <literal>not-null</literal> (�I�v�V����):
+ �O���L�[�J������null�l���e���Ȃ����Ƃ�w�肵�܂�
+ (���̂��Ƃ͊O���L�[����L�[�̈ꕔ�ł��邱�Ƃ�ÖٓI�Ɏ����܂�)�B
+ </para>
+ </callout>
+ <callout arearefs="key5">
+ <para>
+ <literal>update</literal> (�I�v�V����):
+ �O���L�[�����čX�V���Ă͂Ȃ�Ȃ����Ƃ�w�肵�܂�
+ (���̂��Ƃ͊O���L�[����L�[�̈ꕔ�ł��邱�Ƃ�ÖٓI�Ɏ����܂�)�B
+
+ </para>
+ </callout>
+ <callout arearefs="key6">
+ <para>
+ <literal>unique</literal> (�I�v�V����):
+ �O���L�[�����j�[�N������ׂ��ł��邱�Ƃ�w�肵�܂�
+ (���̂��Ƃ͊O���L�[����L�[�̈ꕔ�ł��邱�Ƃ�ÖٓI�Ɏ����܂�)�B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ �폜�̃p�t�H�[�}���X���d�v�ł���V�X�e���ɂ́A
+ ���ׂẴL�[�� <literal>on-delete="cascade"</literal> �ƒ�`���邱�Ƃ𐄏����܂��B
+ �������邱�Ƃ�Hibernate�́A<literal>DELETE</literal> ���s�������ɁA
+ �f�[�^�x�[�X���x���� <literal>ON CASCADE DELETE</literal> �����g�p���܂��B
+ ���̓����̓o�[�W�����t����ꂽ�f�[�^�ɑ���Hibernate�̒ʏ�̊y�ϓI���b�N�헪��
+ ��������Ƃ������Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ <literal>not-null</literal> �� <literal>update</literal> �����́A�P������Α��֘A�̎��ɂ͗L�p�ł��B
+ �P������Α��֘A��null���e���Ȃ��O���L�[�Ƀ}�b�s���O����Ƃ��́A
+ <literal><key not-null="true"></literal> ��g���ăL�[�J������錾
+ <emphasis> ���Ȃ��Ă͂Ȃ�܂���</emphasis> �B
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-column" revision="4">
+ <title>column �� formula �v�f</title>
+ <para>
+ <literal>column</literal> ������L�q�ł���C�ӂ̃}�b�s���O�v�f�͂܂��A
+ <literal><column></literal> �T�u�v�f��L�q�ł��܂��B
+ ���l�� <literal><formula></literal> �� <literal>formula</literal> �����̑�֎�i�ł��B
+ </para>
+
+ <programlisting><![CDATA[<column
+ name="column_name"
+ length="N"
+ precision="N"
+ scale="N"
+ not-null="true|false"
+ unique="true|false"
+ unique-key="multicolumn_unique_key_name"
+ index="index_name"
+ sql-type="sql_type_name"
+ check="SQL expression"
+ default="SQL expression"/>]]></programlisting>
+
+ <programlisting><![CDATA[<formula>SQL expression</formula>]]></programlisting>
+
+ <para>
+ �����v���p�e�B��֘A�̃}�b�s���O�̒��ŁA
+ <literal>column</literal> �� <literal>formula</literal> ������g�ݍ��킹�邱�Ƃ��ł��܂��B
+ �Ⴆ�A����Ȍ������Ȃǂł��B
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="homeAddress" class="Address"
+ insert="false" update="false">
+ <column name="person_id" not-null="true" length="10"/>
+ <formula>'MAILING'</formula>
+</many-to-one>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="mapping-declaration-import">
+ <title>import</title>
+
+ <para>
+ �A�v���P�[�V�����ɓ������O��2�̉i���N���X������A
+ Hibernate�N�G���Ŋ��S�C�����ꂽ�i�p�b�P�[�W�́j���O��w�肵�����Ȃ��Ɖ��肵�܂��B
+ ���̂悤�ȏꍇ�� <literal>auto-import="true"</literal> �ɗ��炸�A
+ �N���X���u�C���|�[�g�v���ꂽ��̂ł���Ɩ����ł��܂��B
+ �����I�Ƀ}�b�s���O����Ă��Ȃ��N���X��C���^�[�t�F�C�X�ł�����C���|�[�g�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<import class="java.lang.Object" rename="Universe"/>]]></programlisting>
+
+ <programlistingco>
+ <areaspec>
+ <area id="import1" coords="2 40"/>
+ <area id="import2" coords="3 40"/>
+ </areaspec>
+ <programlisting><![CDATA[<import
+ class="ClassName"
+ rename="ShortName"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="import1">
+ <para>
+ <literal>class</literal>�FJava�N���X�̊��S�C�����ꂽ�N���X���B
+ </para>
+ </callout>
+ <callout arearefs="import2">
+ <para>
+ <literal>rename</literal>�i�I�v�V���� - �f�t�H���g�͏C������Ă��Ȃ��N���X���j�F
+ �N�G������Ŏg���閼�O�B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ </sect2>
+
+ <sect2 id="mapping-types-anymapping" revision="2">
+ <title>any</title>
+
+ <para>
+ �v���p�e�B�}�b�s���O�ɂ͂���ɂ��1�̌^������܂��B
+ <literal><any></literal> �}�b�s���O�v�f�́A
+ �����̃e�[�u������N���X�ւ̃|�����[�t�B�b�N�Ȋ֘A���`���܂��B
+ ���̌^�̃}�b�s���O�ɂ͕K�������̃J�������K�v�ł��B1�Ԗڂ̃J�����͊֘A�G���e�B�e�B�̌^��ێ����܂��B
+ �c��̃J�����͎��ʎq��ێ����܂��B���̎�ނ̊֘A�ɂ͊O���L�[�����w�肷�邱�Ƃ͂ł��܂���B
+ ���̂��߂���͍ł�g���邱�Ƃ̂Ȃ��i�|�����[�t�B�b�N�ȁj�֘A�̃}�b�s���O���@�ł��B
+ ���ɓ��ʂȏꍇ�i�Ⴆ�A�������O��[�U�Z�b�V�����f�[�^�Ȃ�)�Ɍ����āA�����g���ׂ��ł��B
+ </para>
+
+ <para>
+ <literal>meta-type</literal> �ɂ��A
+ �A�v���P�[�V�����̓J�X�^���^��w��ł��܂��B���̃J�X�^���^��
+ �f�[�^�x�[�X�J�����̒l��A<literal>id-type</literal> �Ŏw�肵���^��
+ ���ʎq�v���p�e�B�������i���N���X�փ}�b�s���O���܂��B
+ meta-type�̒l����N���X���ւ̃}�b�s���O��w�肵�Ȃ���Ȃ�܂���B
+ </para>
+
+ <programlisting><![CDATA[<any name="being" id-type="long" meta-type="string">
+ <meta-value value="TBL_ANIMAL" class="Animal"/>
+ <meta-value value="TBL_HUMAN" class="Human"/>
+ <meta-value value="TBL_ALIEN" class="Alien"/>
+ <column name="table_name"/>
+ <column name="id"/>
+</any>]]></programlisting>
+
+ <programlistingco>
+ <areaspec>
+ <area id="any1" coords="2 50"/>
+ <area id="any2" coords="3 50"/>
+ <area id="any3" coords="4 50"/>
+ <area id="any4" coords="5 50"/>
+ <area id="any5" coords="6 50"/>
+ <area id="any6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<any
+ name="propertyName"
+ id-type="idtypename"
+ meta-type="metatypename"
+ cascade="cascade_style"
+ access="field|property|ClassName"
+ optimistic-lock="true|false"
+>
+ <meta-value ... />
+ <meta-value ... />
+ .....
+ <column .... />
+ <column .... />
+ .....
+</any>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="any1">
+ <para>
+ <literal>name</literal>�F�v���p�e�B���B
+ </para>
+ </callout>
+ <callout arearefs="any2">
+ <para>
+ <literal>id-type</literal>�F���ʎq�̌^�B
+ </para>
+ </callout>
+ <callout arearefs="any3">
+ <para>
+ <literal>meta-type</literal>�i�I�v�V���� - �f�t�H���g�� <literal>string</literal> �j�F
+ �f�B�X�N���~�l�[�^�}�b�s���O�ŋ����ꂽ�^
+ </para>
+ </callout>
+ <callout arearefs="any4">
+ <para>
+ <literal>cascade</literal>�i�I�v�V���� - �f�t�H���g�� <literal>none</literal> �j�F
+ �J�X�P�[�h�̃X�^�C���B
+ </para>
+ </callout>
+ <callout arearefs="any5">
+ <para>
+ <literal>access</literal>�i�I�v�V���� - �f�t�H���g�� <literal>property</literal> �j�F
+ �v���p�e�B�̒l�ւ̃A�N�Z�X��Hibernate���g���헪�B
+ </para>
+ </callout>
+ <callout arearefs="any6">
+ <para>
+ <literal>optimistic-lock</literal> (�I�v�V���� - �f�t�H���g�� <literal>true</literal> ):
+ ���̃v���p�e�B�̍X�V�Ɋy�σ��b�N�̎擾��v�����邩�ǂ�����w�肵�܂��B
+ ����������A���̃v���p�e�B���_�[�e�B�ł���Ƃ��Ƀo�[�W�����𑝂₷�ׂ������`���܂��B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="mapping-types">
+ <title>Hibernate�̌^</title>
+
+ <sect2 id="mapping-types-entitiesvalues" revision="1">
+ <title>�G���e�B�e�B�ƒl</title>
+
+ <para>
+ �i���T�[�r�X�Ɋւ��l�X��Java���ꃌ�x���̃I�u�W�F�N�g�̐U�镑���𗝉��邽�߂ɂ́A
+ �I�u�W�F�N�g��2�̃O���[�v�ɕ�����K�v������܂��F
+ </para>
+
+ <para>
+ <emphasis> �G���e�B�e�B</emphasis> �̓G���e�B�e�B�ւ̎Q�Ƃ�ێ�����A
+ ���̂��ׂẴI�u�W�F�N�g����Ɨ����đ��݂��܂��B
+ �Q�Ƃ���Ȃ��I�u�W�F�N�g���K�x�[�W�R���N�g����Ă��܂��������ʏ��Java���f���ƁA
+ ������ׂĂ݂Ă��������B
+ �i�e�G���e�B�e�B����q�ցA�Z�[�u�ƍ폜�� <emphasis>�J�X�P�[�h</emphasis> ���ꂤ�邱�Ƃ����āj
+ �G���e�B�e�B�͖����I�ɃZ�[�u�܂��͍폜����Ȃ���Ȃ�܂���B
+ ����͓��B�\���ɂ��I�u�W�F�N�g�i������ODMG���f���Ƃ͈قȂ��Ă��܂��B
+ ��K�͂ȃV�X�e���ŃA�v���P�[�V�����I�u�W�F�N�g�����ʂǂ̂悤�Ɏg���邩�ɂ�薧�ڂɑΉ����܂��B
+ �G���e�B�e�B�͏z�ƎQ�Ƃ̋��L��T�|�[�g���܂��B
+ �܂������̓o�[�W�����t�����邱�Ƃ�ł��܂��B
+
+ </para>
+
+ <para>
+ �G���e�B�e�B�̉i����Ԃ͑��̃G���e�B�e�B�� <emphasis>�l</emphasis> �^��
+ �C���X�^���X�ւ̎Q�Ƃ���\������܂��B
+ �l�̓v���~�e�B�u�A�R���N�V����(�R���N�V�����̓���ł͂Ȃ�)�A
+ �R���|�[�l���g�A�s�σI�u�W�F�N�g�ł��B
+ �G���e�B�e�B�Ƃ͈Ⴂ�A�l�́i���ɃR���N�V�����ƃR���|�[�l���g�ɂ����āj�A
+ ���B�\���ɂ��i������폜�� <emphasis>�s���܂�</emphasis> �B
+ �l�I�u�W�F�N�g�i�ƃv���~�e�B�u�j�́A��܂���G���e�B�e�B�ƈꏏ�ɉi������폜���s����̂ŁA
+ ������Ɨ��Ƀo�[�W�����t�����邱�Ƃ͂ł��܂���B
+ �l�ɂ͓Ɨ������A�C�f���e�B�e�B���Ȃ��̂ŁA
+ �����̃G���e�B�e�B��R���N�V������������L���邱�Ƃ͂ł��܂���B
+ </para>
+
+ <para>
+ ����܂Łu�i���N���X�v�Ƃ������t��G���e�B�e�B�̈Ӗ��Ŏg���Ă��܂����B
+ ���ꂩ���������Ă����܂��B
+ �����Ɍ����ƁA�i����Ԃ����[�U��`�̃N���X�̂��ׂĂ�
+ �G���e�B�e�B�Ƃ����킯�ł͂���܂���B
+ <emphasis>�R���|�[�l���g</emphasis> �͒l�̃Z�}���e�B�N�X�����[�U��`�N���X�ł��B
+ <literal>java.lang.String</literal> �^�̃v���p�e�B��܂��l�̃Z�}���e�B�N�X�����܂��B
+ ��`����Ȃ�AJDK�Œ���Ă��邷�ׂĂ�Java�̌^(�N���X)���l�̃Z�}���e�B�N�X���Ƃ����܂��B
+ ������[�U��`�^�́A�G���e�B�e�B��l�^�̃Z�}���e�B�N�X�ƂƂ�Ƀ}�b�s���O�ł��܂��B
+ ���̌���̓A�v���P�[�V�����J���Ҏ���ł��B
+ ���̃N���X�̂P�̃C���X�^���X�ւ̋��L�Q�Ƃ́A
+ �h���C�����f����̃G���e�B�e�B�N���X�ɑ���ǂ��q���g�ɂȂ�܂��B
+ ��������W���W��́A�ʏ�l�^�֕ϊ�����܂��B
+
+ </para>
+
+ <para>
+ �{�h�L�������g��ʂ��āA���x����̊T�O����グ�܂��B
+ </para>
+
+ <para>
+ Java�^�̃V�X�e��(������͊J���҂���`�����G���e�B�e�B�ƒl�^)��
+ SQL/�f�[�^�x�[�X�^�̃V�X�e���Ƀ}�b�s���O���邱�Ƃ͓���ł��B
+ Hibernate�͂Q�̃V�X�e���̉˂�������܂��B
+ �G���e�B�e�B�ɑ��Ă�
+ <literal><class></literal> �� <literal><subclass></literal> �Ȃǂ�g�p���܂��B
+ �l�^�ɑ��Ă� <literal><property></literal> ��
+ <literal><component></literal> �Ȃǂ�A�ʏ� <literal>type</literal> �ƂƂ�Ɏg���܂��B
+ ���̑����̒l��Hibernate�� <emphasis>�}�b�s���O�^</emphasis> �̖��O�ł��B
+ Hibernate��(�W��JDK�̒l�^�ɑ���)�����̎��R�ȃ}�b�s���O����܂��B
+ ��Ō���悤�ɁA���g�̃}�b�s���O�^��L�q���A���l�ɃJ�X�^���̕ϊ��헪��������邱�Ƃ��ł��܂��B
+ </para>
+
+ <para>
+ �R���N�V���������g�ݍ��݂�Hibernate�̌^�͂��ׂāAnull�Z�}���e�B�N�X��T�|�[�g���܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-types-basictypes" revision="3">
+ <title>��{�I�Ȍ^</title>
+
+ <para>
+ �g�ݍ��݂� <emphasis>��{�I�ȃ}�b�s���O�^</emphasis> �͑�܂��Ɉȉ��̂悤�ɕ������܂��B
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>integer, long, short, float, double, character, byte,
+ boolean, yes_no, true_false</literal></term>
+ <listitem>
+ <para>
+ Java�̃v���~�e�B�u��b�p�[�N���X����K�ȁi�x���_�[�ŗL�́j
+ SQL�J�����^�ւ̌^�}�b�s���O�B
+ <literal>boolean, yes_no</literal> �� <literal>true_false</literal> �́A
+ ���ׂ�Java�� <literal>boolean</literal>
+ �܂��� <literal>java.lang.Boolean</literal> �̑�փG���R�[�h�ł��B
+
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>string</literal></term>
+ <listitem>
+ <para>
+ <literal>java.lang.String</literal> ���� <literal>VARCHAR</literal>
+ �i�܂���Oracle�� <literal>VARCHAR2</literal> �j�ւ̌^�}�b�s���O�B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>date, time, timestamp</literal></term>
+ <listitem>
+ <para>
+ <literal>java.util.Date</literal> �Ƃ��̃T�u�N���X����SQL�^�� <literal>DATE</literal>,
+ <literal>TIME</literal> , <literal>TIMESTAMP</literal> �i�܂��͂����Ɠ����Ȃ�́j
+ �ւ̌^�}�b�s���O�B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>calendar, calendar_date</literal></term>
+ <listitem>
+ <para>
+ <literal>java.util.Calendar</literal> ����SQL�^ �́u <literal>TIMESTAMP</literal> ,
+ <literal>DATE</literal> (�܂��͂����Ɠ����Ȃ�́j�ւ̌^�}�b�s���O�B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>big_decimal, big_integer</literal></term>
+ <listitem>
+ <para>
+ <literal>java.math.BigDecimal</literal> �� <literal>java.math.BigInteger</literal>
+ ���� <literal>NUMERIC</literal>�i�܂���Oracle�� <literal>NUMBER</literal> �j�ւ̌^�}�b�s���O�B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>locale, timezone, currency</literal></term>
+ <listitem>
+ <para>
+ <literal>java.util.Locale</literal> , <literal>java.util.TimeZone</literal> ,
+ <literal>java.util.Currency</literal> ���� <literal>VARCHAR</literal>
+ �i�܂���Oracle�� <literal>VARCHAR2</literal> �j�ւ̌^�}�b�s���O�B
+ <literal>Locale</literal> �� <literal>Currency</literal> �̃C���X�^���X�́A
+ ������ISO�R�[�h�Ƀ}�b�s���O����܂��B
+ <literal>TimeZone</literal> �̃C���X�^���X�́A
+ ������ <literal>ID</literal> �Ƀ}�b�s���O����܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>class</literal></term>
+ <listitem>
+ <para>
+ <literal>java.lang.Class</literal> ���� <literal>VARCHAR</literal>
+ �i�܂���Oracle�� <literal>VARCHAR2</literal> �j�ւ̌^�}�b�s���O�B
+ <literal>Class</literal> �͂��̊��S�C�����ꂽ���O�Ƀ}�b�s���O����܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>binary</literal></term>
+ <listitem>
+ <para>
+ �o�C�g�z��́A�K��SQL�̃o�C�i���^�Ƀ}�b�s���O����܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>text</literal></term>
+ <listitem>
+ <para>
+ ����Java������́ASQL�� <literal>CLOB</literal> �܂���
+ <literal>TEXT</literal> �^�Ƀ}�b�s���O����܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>serializable</literal></term>
+ <listitem>
+ <para>
+ �V���A���C�Y�\��Java�^�́A�K��SQL�̃o�C�i���^�Ƀ}�b�s���O����܂��B
+ �f�t�H���g�Ŋ�{�^�ł͂Ȃ��V���A���C�Y�\��Java�N���X��
+ �C���^�[�t�F�C�X�̖��O��w�肷�邱�ƂŁA
+ Hibernate�̌^�� <literal>serializable</literal> �Ƃ��邱�Ƃ�ł��܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>clob, blob</literal></term>
+ <listitem>
+ <para>
+ JDBC�N���X <literal>java.sql.Clob</literal> �� <literal>java.sql.Blob</literal>
+ �ɑ���^�}�b�s���O�B
+ blob��clob�I�u�W�F�N�g�̓g�����U�N�V�����̊O�ł͍ė��p�ł��Ȃ����߁A
+ �A�v���P�[�V�����ɂ���Ă͕s�ւ������܂���B
+ �i����ɂ̓h���C�o�T�|�[�g����т��Ă��܂���B�j
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>imm_date, imm_time, imm_timestamp, imm_calendar, imm_calendar_date,
+ imm_serializable, imm_binary</literal>
+ </term>
+ <listitem>
+ <para>
+ �قƂ�ǂ̏ꍇ�ɉςł���Java�̌^�ɑ���^�}�b�s���O�B
+ Hibernate�͕s�ς�Java�̌^�ɑ��Ă͍œK����s���A
+ �A�v���P�[�V�����͂����s�σI�u�W�F�N�g�Ƃ��Ĉ����܂��B
+ �Ⴆ�� <literal>imm_timestamp</literal> �Ƃ��ă}�b�v�����C���X�^���X�ɑ��āA
+ <literal>Date.setTime()</literal> ��Ăяo���Ă͂Ȃ�܂���B
+ �v���p�e�B�̒l��ύX�����̕ύX��i�������邽�߂ɂ́A
+ �A�v���P�[�V�����̓v���p�e�B�ɑ��ĐV����(����łȂ�)�I�u�W�F�N�g���蓖�ĂȂ���Ȃ�܂���B
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+
+ <para>
+ �G���e�B�e�B�ƃR���N�V�����̃��j�[�N�Ȏ��ʎq�́A<literal>binary</literal> , <literal>blob</literal> ,
+ <literal>clob</literal> �����A�ǂ�Ȋ�{�^�ł�\���܂���B
+ �i�������ʎq�ł�\���܂���B�ȉ����Ă��������B�j
+ </para>
+
+ <para>
+ ��{�I�Ȓl�^�ɂ́A<literal>org.hibernate.Hibernate</literal> �Œ�`���ꂽ
+ <literal>Type</literal> �萔�����ꂼ�ꂠ��܂��B
+ �Ⴆ�A<literal>Hibernate.STRING</literal> �� <literal>string</literal> �^��\�����Ă��܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-types-custom" revision="2">
+ <title>�J�X�^���^</title>
+
+ <para>
+ �J���҂��Ǝ��̒l�^��쐬���邱�Ƃ́A��r�I�ȒP�ł��B
+ �Ⴆ�A<literal>java.lang.BigInteger</literal> �^�̃v���p�e�B��
+ <literal>VARCHAR</literal> �J�����ɉi�����������������܂���B
+ Hibernate�͂��̂��߂̑g�ݍ��^��p�ӂ��Ă��܂���B
+ �������J�X�^���^�́A�v���p�e�B�i�܂��̓R���N�V�����̗v�f�j��1�̃e�[�u���J������
+ �}�b�s���O����̂ɐ����͂���܂���B
+ ���̂��ߗႦ�A<literal>java.lang.String</literal> �^��
+ <literal>getName()</literal> / <literal>setName()</literal>
+ Java�v���p�e�B�� <literal>FIRST_NAME</literal> , <literal>INITIAL</literal>, <literal>SURNAME</literal>
+ �J�����ɉi�����ł��܂��B
+ </para>
+
+ <para>
+ �J�X�^���^���������ɂ́A<literal>org.hibernate.UserType</literal> �܂���
+ <literal>org.hibernate.CompositeUserType</literal> ��������A
+ �^�̊��S�C�����ꂽ���O��g���ăv���p�e�B���`���܂��B
+ �ǂ̂悤�Ȏ�ނ̂�̂��\���ׂ�ɂ́A
+ <literal>org.hibernate.test.DoubleStringType</literal> ��m�F�����������B
+ </para>
+
+ <programlisting><![CDATA[<property name="twoStrings" type="org.hibernate.test.DoubleStringType">
+ <column name="first_string"/>
+ <column name="second_string"/>
+</property>]]></programlisting>
+
+ <para>
+ <literal><column></literal> �^�O�ŁA
+ �v���p�e�B���̃J�����փ}�b�s���O�ł��邱�Ƃɒ��ڂ��Ă��������B
+ </para>
+
+ <para>
+ <literal>CompositeUserType</literal> , <literal>EnhancedUserType</literal> ,
+ <literal>UserCollectionType</literal> , <literal>UserVersionType</literal>
+ �C���^�[�t�F�C�X�́A������Ȏg�p�@�ɑ��ẴT�|�[�g����܂��B
+ </para>
+
+ <para>
+ �}�b�s���O�t�@�C����� <literal>UserType</literal> �փp�����[�^��ł��܂��B
+ ���̂��߂ɂ́A<literal>UserType</literal> ��
+ <literal>org.hibernate.usertype.ParameterizedType</literal> ��������Ȃ��Ă͂Ȃ�܂���B
+ �J�X�^���^�p�����[�^����邽�߂ɁA
+ �}�b�s���O�t�@�C����� <literal><type></literal> �v�f��g�p�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<property name="priority">
+ <type name="com.mycompany.usertypes.DefaultValueIntegerType">
+ <param name="default">0</param>
+ </type>
+</property>]]></programlisting>
+
+ <para>
+ <literal>UserType</literal> �́A
+ �����Ƃ��ēn���ꂽ <literal>Properties</literal> �I�u�W�F�N�g����A
+ <literal>default</literal> �Ŏw�肵���p�����[�^�ɑ���l�������邱�Ƃ��ł��܂��B
+ </para>
+
+ <para>
+ ����� <literal>UserType</literal> ��p�ɂɎg�p����Ȃ�A�Z�����O���`����ƕ֗��ɂȂ�ł��傤�B
+ <literal><typedef></literal> �v�f��g���Ă��̂悤�Ȃ��Ƃ��s���܂��B
+ Typedefs�̓J�X�^���^�ɖ��O���蓖�Ă܂��B
+ ���̌^���p�����[�^���Ȃ�A
+ �p�����[�^�̃f�t�H���g�l�̃��X�g��܂ނ��Ƃ�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<typedef class="com.mycompany.usertypes.DefaultValueIntegerType" name="default_zero">
+ <param name="default">0</param>
+</typedef>]]></programlisting>
+
+ <programlisting><![CDATA[<property name="priority" type="default_zero"/>]]></programlisting>
+
+ <para>
+ �v���p�e�B�̃}�b�s���O�Ō^�p�����[�^��g�����ƂŁA
+ typedef�Œ��ꂽ�p�����[�^���̓s�x�I�[�o�[���C�h���邱�Ƃ��\�ł��B
+
+ </para>
+
+ <para>
+ Hibernate�̕��L���g�ݍ��^�ƃR���|�[�l���g�ɑ���T�|�[�g�́A
+ �J�X�^���^��߂����� <emphasis>�g��Ȃ�</emphasis> �Ƃ������Ƃ�Ӗ����܂��B
+ ����ł�Ȃ��A�A�v���P�[�V�����ŕp�o����(�G���e�B�e�B�ł͂Ȃ�)�N���X�ɑ���J�X�^���^�̎g�p�́A
+ �悢�����ł���Ƃ݂Ȃ���܂��B
+ �Ⴆ�� <literal>MonetaryAmount</literal> �N���X�̓R���|�[�l���g�Ƃ��ĊȒP�Ƀ}�b�s���O�ł��܂����A
+ <literal>CompositeUserType</literal> �̗ǂ����ł��B
+ �J�X�^���^��g�p���铮�@��1�͒��ۉ��ł��B
+ �J�X�^���^��g�����ƂŁA�ʉ݂�ǂ̂悤�ɕ\�����悤�Ƃ�
+ �}�b�s���O�h�L�������g�͋N���肤��ω��ɑΉ��ł��܂��B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+
+ <sect1 id="mapping-entityname">
+ <title>�P�̃N���X�ɂP�ȏ�̃}�b�s���O</title>
+ <para>
+ ����i���N���X�ɁA��ȏ�̃}�b�s���O����邱�Ƃ��o���܂��B
+ ���̏ꍇ�A�}�b�s���O����Q�̃G���e�B�e�B�̃C���X�^���X�m�ɂ��邽�߂ɁA
+ <emphasis>�G���e�B�e�B��</emphasis> ��w�肵�Ȃ���Ȃ�܂���
+ (�f�t�H���g�ł̓G���e�B�e�B���̓N���X���Ɠ����ł��B)�B
+ �i���I�u�W�F�N�g�����Ƃ��A�N�G���������ނƂ��A
+ �w�肳�ꂽ�G���e�B�e�B�ւ̊֘A��}�b�s���O����Ƃ��ɂ́A
+ Hibernate�ł̓G���e�B�e�B����w�肵�Ȃ���Ȃ�܂���B
+ </para>
+
+ <programlisting><![CDATA[<class name="Contract" table="Contracts"
+ entity-name="CurrentContract">
+ ...
+ <set name="history" inverse="true"
+ order-by="effectiveEndDate desc">
+ <key column="currentContractId"/>
+ <one-to-many entity-name="HistoricalContract"/>
+ </set>
+</class>
+
+<class name="Contract" table="ContractHistory"
+ entity-name="HistoricalContract">
+ ...
+ <many-to-one name="currentContract"
+ column="currentContractId"
+ entity-name="CurrentContract"/>
+</class>]]></programlisting>
+
+ <para>
+ �֘A��<literal>class</literal> �̑���� <literal>entity-name</literal> ��g���āA
+ �ǂ̂悤�Ɏw�肳���̂��ɒ��ڂ��Ă��������B
+ </para>
+
+ </sect1>
+
+ <sect1 id="mapping-quotedidentifiers">
+ <title>�o�b�N�N�H�[�g�ň͂� SQL ���ʎq</title>
+ <para>
+ �}�b�s���O�h�L�������g�Ńe�[�u����J�����̖��O��o�b�N�N�H�[�g�ň͂ނ��ƂŁA
+ Hibernate�Ő������ꂽSQL���̎��ʎq����p�����邱�Ƃ��ł��܂��B
+ Hibernate��SQL�� <literal>Dialect</literal> �ɑΉ�����A���������p�X�^�C����g���܂�
+ �i���ʂ̓_�u���N�H�[�g�ł����ASQL Server�ł͂������ʁAMySQL�ł̓o�b�N�N�H�[�g�ł��j�B
+ </para>
+
+ <programlisting><![CDATA[<class name="LineItem" table="`Line Item`">
+ <id name="id" column="`Item Id`"/><generator class="assigned"/></id>
+ <property name="itemNumber" column="`Item #`"/>
+ ...
+</class>]]></programlisting>
+
+ </sect1>
+
+
+ <sect1 id="mapping-alternatives">
+ <title>���^�f�[�^�̑�֎�i</title>
+
+ <para>
+ XML�̋L�q�ȊO�ɁA
+ Hibernate�ł�O/R�}�b�s���O�̃��^�f�[�^���`�����֕��@������܂��B
+ </para>
+
+ <sect2 id="mapping-xdoclet">
+ <title>XDoclet �}�[�N�A�b�v�̎g�p</title>
+
+ <para>
+ ������Hibernate���[�U��XDoclet�� <literal>@hibernate.tags</literal> ��g���āA
+ �\�[�X�R�[�h��ɒ��ڃ}�b�s���O���ߍ��ނ��Ƃ�D�݂܂��B
+ ����͌����Ɍ�����XDoclet�̕���Ȃ̂ŁA�{�h�L�������g�ł͂��̕��@��ΏۂƂ͂��܂���B
+ ������XDoclet��g�����ȉ��� <literal>Cat</literal> �}�b�s���O�̗�����܂��B
+ </para>
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+import java.util.Date;
+
+/**
+ * @hibernate.class
+ * table="CATS"
+ */
+public class Cat {
+ private Long id; // identifier
+ private Date birthdate;
+ private Cat mother;
+ private Set kittens
+ private Color color;
+ private char sex;
+ private float weight;
+
+ /*
+ * @hibernate.id
+ * generator-class="native"
+ * column="CAT_ID"
+ */
+ public Long getId() {
+ return id;
+ }
+ private void setId(Long id) {
+ this.id=id;
+ }
+
+ /**
+ * @hibernate.many-to-one
+ * column="PARENT_ID"
+ */
+ public Cat getMother() {
+ return mother;
+ }
+ void setMother(Cat mother) {
+ this.mother = mother;
+ }
+
+ /**
+ * @hibernate.property
+ * column="BIRTH_DATE"
+ */
+ public Date getBirthdate() {
+ return birthdate;
+ }
+ void setBirthdate(Date date) {
+ birthdate = date;
+ }
+ /**
+ * @hibernate.property
+ * column="WEIGHT"
+ */
+ public float getWeight() {
+ return weight;
+ }
+ void setWeight(float weight) {
+ this.weight = weight;
+ }
+
+ /**
+ * @hibernate.property
+ * column="COLOR"
+ * not-null="true"
+ */
+ public Color getColor() {
+ return color;
+ }
+ void setColor(Color color) {
+ this.color = color;
+ }
+ /**
+ * @hibernate.set
+ * inverse="true"
+ * order-by="BIRTH_DATE"
+ * @hibernate.collection-key
+ * column="PARENT_ID"
+ * @hibernate.collection-one-to-many
+ */
+ public Set getKittens() {
+ return kittens;
+ }
+ void setKittens(Set kittens) {
+ this.kittens = kittens;
+ }
+ // addKitten not needed by Hibernate
+ public void addKitten(Cat kitten) {
+ kittens.add(kitten);
+ }
+
+ /**
+ * @hibernate.property
+ * column="SEX"
+ * not-null="true"
+ * update="false"
+ */
+ public char getSex() {
+ return sex;
+ }
+ void setSex(char sex) {
+ this.sex=sex;
+ }
+}]]></programlisting>
+
+ <para>
+ Hibernate�̃E�F�u�T�C�g�ɂ́AXDoclet��Hibernate�Ɋւ���T���v������������܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="mapping-annotations" revision="2">
+ <title>JDK 5.0 �A�m�e�[�V�����̎g�p</title>
+
+ <para>
+ JDK5.0�ł̓^�C�v�Z�[�t���R���p�C�����Ƀ`�F�b�N�ł���A
+ ���ꃌ�x����XDoclet�X�^�C���̃A�m�e�[�V���������܂����B
+ ���̃��J�j�Y����XDoclet�̃A�m�e�[�V����������͂ŁA�c�[����IDE��������T�|�[�g���Ă��܂��B
+ �Ⴆ��IntelliJ IDEA�́AJDK5.0�ɃA�m�e�[�V�����̎����⊮�ƍ\���̋����\����T�|�[�g���Ă��܂��B
+ EJB�d�l (JSR-220)�̐V�����o�[�W�����ł́A�G���e�B�e�B�r�[���ɑ����v�ȃ��^�f�[�^���J�j�Y���Ƃ���
+ JDK5.0�̃A�m�e�[�V������g�p���Ă��܂��B
+ Hibernate3�ł�JSR-220 (�i����API)�� <literal>EntityManager</literal> ��������A
+ ���^�f�[�^�}�b�s���O�ɑ���T�|�[�g�́A
+ �ʃ_�E�����[�h�� <emphasis>Hibernate Annotations</emphasis> �p�b�P�[�W�ɂ�藘�p�\�ł��B
+ �����EJB3(JSR-220)��Hibernate3�̃��^�f�[�^��ǂ����T�|�[�g���Ă��܂��B
+
+ </para>
+
+ <para>
+ �ȉ���EJB�̃G���e�B�e�B�r�[���Ƃ��Ē��߂��ꂽPOJO�N���X�̗�ł��B
+ </para>
+
+ <programlisting><![CDATA[@Entity(access = AccessType.FIELD)
+public class Customer implements Serializable {
+
+ @Id;
+ Long id;
+
+ String firstName;
+ String lastName;
+ Date birthday;
+
+ @Transient
+ Integer age;
+
+ @Embedded
+ private Address homeAddress;
+
+ @OneToMany(cascade=CascadeType.ALL)
+ @JoinColumn(name="CUSTOMER_ID")
+ Set<Order> orders;
+
+ // Getter/setter and business methods
+}]]></programlisting>
+
+ <para>
+ JDK5.0�̃A�m�e�[�V����(��JSR-220)�̃T�|�[�g�͐i�s���̍�Ƃł���A���S�ł͂Ȃ����Ƃɒ��ӂ��Ă��������B
+ ����ɏڂ�������Hibernate�̃A�m�e�[�V�����E���W���[����Q�Ƃ��Ă��������B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+
+ <sect1 id="mapping-generated" revision="1">
+ <title>�����v���p�e�B</title>
+ <para>
+ �����v���p�e�B�Ƃ́A�f�[�^�x�[�X�ɂ���Đ������ꂽ�l���v���p�e�B�ł��B
+ �ʏ�AHibernate�A�v���P�[�V�����́A�f�[�^�x�[�X���l�������v���p�e�B��܂ރI�u�W�F�N�g��
+ <literal>���t���b�V��</literal> ����K�v������܂����B
+ �������A�v���p�e�B���������ꂽ�Ƃ������Ƃ�}�[�N���邱�ƂŁA
+ �A�v���P�[�V�����̓��t���b�V���̐ӔC��Hibernate�ɈϏ����܂��B
+
+ ��{�I�ɁA�����v���p�e�B���ƒ�`�����G���e�B�e�B�ɑ���
+ Hibernate��INSERT��UPDATE��SQL�s�����シ���ɁA
+ �������ꂽ�l��ǂݍ��ނ��߂� SELECT SQL �����s����܂��B
+ </para>
+ <para>
+ �����v���p�e�B�́A�}���s�\���X�V�s�\�łȂ���Ȃ�܂���B
+ <xref linkend="mapping-declaration-version">versions</xref> �A
+ <xref linkend="mapping-declaration-timestamp">timestamps</xref> �A
+ <xref linkend="mapping-declaration-property">simple properties</xref> �������������ꂽ�ƃ}�[�N�ł��܂��B
+ </para>
+ <para>
+ <literal>never</literal> (�f�t�H���g) - �^����ꂽ�v���p�e�B�̒l�́A
+ �f�[�^�x�[�X���琶������Ȃ����Ƃ�Ӗ����܂��B
+ </para>
+ <para>
+ <literal>insert</literal> - �^����ꂽ�v���p�e�B�̒l�͑}�����ɐ�������邪�A
+ �����ċN����X�V���ɂ͐�������Ȃ����Ǝ����܂��B
+ �쐬���ꂽ���t�Ȃǂ́A���̃J�e�S���ɕ��ނ���܂��B
+ <xref linkend="mapping-declaration-version">version</xref> ��
+ <xref linkend="mapping-declaration-timestamp">timestamp</xref> ��
+ �v���p�e�B�͐������ꂽ�ƃ}�[�N�ł��܂����A���̃I�v�V�����͗��p�ł��Ȃ����Ƃɒ��ӂ��Ă��������B
+ </para>
+ <para>
+ <literal>always</literal> - �}������X�V����v���p�e�B�̒l����������邱�Ƃ����܂��B
+ </para>
+ </sect1>
+
+ <sect1 id="mapping-database-object" revision="0">
+ <title>�⏕�I�ȃf�[�^�x�[�X�E�I�u�W�F�N�g</title>
+ <para>
+ Hibernate�̃X�L�[�}�E�G�{�����[�V�����c�[���ƘA�����邱�ƂŁA
+ �C�ӂ̃f�[�^�x�[�X�E�I�u�W�F�N�g�i�g���K�[��X�g�A�h�v���V�[�W���Ȃǁj��CREATE��DROP�ɂ��A
+ Hibernate�̃}�b�s���O�t�@�C����̃��[�U�E�X�L�[�}���ׂĒ�`���邱�Ƃ��o���܂��B
+ ��Ƀg���K��X�g�A�h�v���V�[�W���̂悤�ȃf�[�^�x�[�X�E�I�u�W�F�N�g����폜���邱�Ƃ�Ӑ}���Ă��܂����A
+ ���ۂɂ� <literal>java.sql.Statement.execute()</literal> ���\�b�h�ɂ���Ď��s�ł���
+ �C�ӂ�SQL�R�}���h�iALTER�AINSERT�Ȃǁj�����s�ł��܂��B
+ �⏕�I�ȃf�[�^�x�[�X�E�I�u�W�F�N�g���`���邽�߂́A2�̊�{�I�ȕ��@������܂��B
+ </para>
+ <para>
+ 1�ڂ̕��@�́ACREATE��DROP�R�}���h��}�b�s���O�t�@�C���̊O�ɁA�����I�ɋL�ڂ��邱�Ƃł��B
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <create>CREATE TRIGGER my_trigger ...</create>
+ <drop>DROP TRIGGER my_trigger</drop>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ <para>
+ 2�ڂ̕��@�́ACREATE��DROP�R�}���h�̑g�ݗ��ĕ���m���Ă���J�X�^���N���X����邱�Ƃł��B
+ ���̃J�X�^���N���X�� <literal>org.hibernate.mapping.AuxiliaryDatabaseObject</literal> �C���^�t�F�[�X��
+ �������Ȃ���Ȃ�܂���B
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <definition class="MyTriggerDefinition"/>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ <para>
+ ����ɁA����f�[�^�x�[�X�������g�p����鎞�ɂ����K�p����Ƃ������悤�ɁA
+ �f�[�^�x�[�X�E�I�u�W�F�N�g���g����P�[�X�����ł��܂��B
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <definition class="MyTriggerDefinition"/>
+ <dialect-scope name="org.hibernate.dialect.Oracle9Dialect"/>
+ <dialect-scope name="org.hibernate.dialect.OracleDialect"/>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/batch.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/batch.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/batch.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/batch.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,386 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="batch">
+ <title>�o�b�`����</title>
+
+ <para>
+ Hibernate��g���ăf�[�^�x�[�X��100,000�s��}������ȕ��@�́A���̂悤�Ȃ�̂ł��F
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+for ( int i=0; i<100000; i++ ) {
+ Customer customer = new Customer(.....);
+ session.save(customer);
+}
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ �����50,000�Ԗڂ̍s�̂������ <literal>OutOfMemoryException</literal> �Ŏ��s����ł��傤�B
+ Hibernate���Z�b�V�������x���L���b�V���ŁA
+ �V�����}�����ꂽ���ׂĂ� <literal>Customer</literal>
+ �C���X�^���X��L���b�V�����邩��ł��B
+ </para>
+
+ <para>
+ ���̏͂ł́A���̖���������@��Љ�܂��B
+ �������o�b�`��������Ȃ�AJDBC�o�b�`���g�p�\�ł��邱�Ƃ����ɏd�v�ł��B
+ �����łȂ���Ύ荠�ȃp�t�H�[�}���X�������܂���B
+ JDBC�o�b�`�T�C�Y��荠�Ȑ��l�i�Ⴆ�A10����50�j�ɐݒ肵�Ă��������F
+ </para>
+
+<programlisting><![CDATA[hibernate.jdbc.batch_size 20]]></programlisting>
+
+ <para>
+ �܂��L���b�V�����S�������Ȃ��v���Z�X�ŁA
+ ���̂悤�ȍ�Ƃ������Ǝv���������܂���F
+ </para>
+
+<programlisting><![CDATA[hibernate.cache.use_second_level_cache false]]></programlisting>
+
+ <para>
+ �������A����͐�ɕK�v�Ƃ����킯�ł͂���܂���B
+ �Ȃ��Ȃ疾���I�� <literal>CacheMode</literal> ��ݒ肵�āA
+ �L���b�V���Ƃ̑��ݍ�p���ɂ��邱�Ƃ��ł��邩��ł��B
+
+ </para>
+
+ <sect1 id="batch-inserts">
+ <title>�o�b�`�}��</title>
+
+ <para>
+ �V�����I�u�W�F�N�g��i��������Ƃ��A�ꎟ�L���b�V���̃T�C�Y�𐧌����邽�߁A
+ �Z�b�V������ <literal>flush()</literal> ���� <literal>clear()</literal>
+ ���Ȃ���Ȃ�܂���B
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+for ( int i=0; i<100000; i++ ) {
+ Customer customer = new Customer(.....);
+ session.save(customer);
+ if ( i % 20 == 0 ) { //20, same as the JDBC batch size
+ //flush a batch of inserts and release memory:
+ session.flush();
+ session.clear();
+ }
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="batch-update" >
+ <title>�o�b�`�X�V</title>
+
+ <para>
+ �f�[�^��������X�V�����肷��ɂ͓����A�C�f�B�A��K�p���܂��B
+ ����ɉ����āA�f�[�^�̍s�𑽂��Ԃ��N�G���ɑ��ėL����
+ �T�[�o�[�T�C�h�̃J�[�\���̗��_�����������
+ <literal>scroll()</literal> ��g���K�v������܂��B
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+ScrollableResults customers = session.getNamedQuery("GetCustomers")
+ .setCacheMode(CacheMode.IGNORE)
+ .scroll(ScrollMode.FORWARD_ONLY);
+int count=0;
+while ( customers.next() ) {
+ Customer customer = (Customer) customers.get(0);
+ customer.updateStuff(...);
+ if ( ++count % 20 == 0 ) {
+ //flush a batch of updates and release memory:
+ session.flush();
+ session.clear();
+ }
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="batch-statelesssession">
+ <title>
+ StatelessSession�C���^�[�t�F�C�X
+ </title>
+
+ <para>
+ �܂��ʂ̕��@�Ƃ��āAHibernate�̓R�}���h�w����API��p�ӂ��Ă��܂��B
+ ����͕����I�u�W�F�N�g�̌`�ŁA
+ �f�[�^�x�[�X�Ƃ̃f�[�^�X�g���[���̂����Ɏg�����Ƃ��ł��܂��B
+ <literal>StatelessSession</literal> �͊֘A����i���R���e�L�X�g�������A
+ �����x���̃��C�t�T�C�N���Z�}���e�B�N�X�̑�������܂���B
+ ���ɃX�e�[�g���X�Z�b�V�����́A�ꎞ�L���b�V������������A
+ �܂��ǂ̂悤�ȓL���b�V����N�G���L���b�V���Ƃ���ݍ�p���܂���B
+ �g�����U�N�V���i����write-behind�⎩���_�[�e�B�`�F�b�N��������܂���B
+ �X�e�[�g���X�Z�b�V������g���čs���鑀�삪�A
+ �֘A����C���X�^���X�փJ�X�P�[�h����邱�Ƃ͌����Ă���܂���B
+ �R���N�V�����́A�X�e�[�g���X�Z�b�V��������͖�������܂��B
+ �X�e�[�g���X�Z�b�V������ʂ��čs���鑀��́A
+ Hibernate�̃C�x���g���f����C���^�[�Z�v�^�̉e����܂���B
+ �ꎞ�L���b�V�������Ȃ����߁A
+ �X�e�[�g���X�Z�b�V�����͕ʖ����f�[�^�ɏ�肭�Ώ��ł��܂���B
+ �X�e�[�g���X�Z�b�V�����͒�x���̒��ۉ��ł���AJDBC�ɔ��ɂ悭���Ă��܂��B
+
+ </para>
+
+<programlisting><![CDATA[StatelessSession session = sessionFactory.openStatelessSession();
+Transaction tx = session.beginTransaction();
+
+ScrollableResults customers = session.getNamedQuery("GetCustomers")
+ .scroll(ScrollMode.FORWARD_ONLY);
+while ( customers.next() ) {
+ Customer customer = (Customer) customers.get(0);
+ customer.updateStuff(...);
+ session.update(customer);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ ���̃R�[�h��ł́A�N�G�����Ԃ� <literal>Customer</literal>
+ �C���X�^���X�͑����Ɂi�Z�b�V��������j��������邱�Ƃɒ��ӂ��Ă��������B
+ ����́A�ǂ̂悤�ȉi���R���e�L�X�g�Ƃ�����Ċ֘A���܂���B
+
+ </para>
+
+ <para>
+ <literal>StatelessSession</literal> �C���^�[�t�F�C�X�Œ�`����Ă���
+ <literal>insert(), update(), delete()</literal> �́A
+ ��x���̒��ړI�ȃf�[�^�x�[�X����ƍl�����܂��B
+ ���ʂƂ��āASQL�� <literal>INSERT, UPDATE, DELETE</literal> �����ꂼ�ꑦ���Ɏ��s����܂��B
+ ���̂悤�ɁA������ <literal>Session</literal> �C���^�[�t�F�C�X�Œ�`����Ă���
+ <literal>save(), saveOrUpdate(), delete()</literal>
+ �Ƃ͔��ɈقȂ�Ӗ������܂��B
+
+ </para>
+
+ </sect1>
+
+ <sect1 id="batch-direct" revision="3">
+ <title>
+ DML�X�^�C���̑���
+ </title>
+
+ <para>
+ ���łɋc�_�����悤�ɁA�����I�����ߓI�ȃI�u�W�F�N�g/�����[�V���i���}�b�s���O�́A
+ �I�u�W�F�N�g�̏�Ԃ̊Ǘ��ł���ƍl�����܂��B
+ ����̓�������̃I�u�W�F�N�g�̏�Ԃ𗘗p�ł���Ƃ������Ƃł��B
+ ���̂��߁iSQL�� <literal>�f�[�^���쌾��</literal> (DML) ���F
+ <literal>INSERT</literal>, <literal>UPDATE</literal>, <literal>DELETE</literal>
+ ��g���āj�f�[�^�x�[�X��̃f�[�^�ڑ��삵�Ă�A
+ ��������̏�Ԃɂ͉e����^���܂���B
+ ������Hibernate�́A�o���NSQL�X�^�C����DML�����s�ɑΉ����郁�\�b�h��p�ӂ��Ă��܂��B
+ �����Hibernate�N�G������i<xref linkend="queryhql">HQL</xref>�j
+ ��ʂ��Ď��s����܂��B
+
+ </para>
+
+ <para>
+ <literal>UPDATE</literal> �� <literal>DELETE</literal> ���̋^���\���́F
+ <literal>( UPDATE | DELETE ) FROM? �G���e�B�e�B�� (WHERE ����)?</literal> �ł��B
+ ���ӂ��ׂ��_������������܂��F
+
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ from�߂ɂ����āAFROM�L�[���[�h�̓I�v�V�����ł��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ from�߂ł͒P��̃G���e�B�e�B���������\�ŁA
+ �C�ӂŕʖ���t���邱�Ƃ��ł��܂��B
+ �G���e�B�e�B���ɕʖ����^������ƁA�ǂ̂悤�ȃv���p�e�B�Q�Ƃ�A
+ ���̕ʖ���g���ďC�����Ȃ���Ȃ�܂���B
+ ����G���e�B�e�B���ɕʖ����^�����Ȃ���A
+ �ǂ̂悤�ȃv���p�e�B�Q�Ƃ�C�����Ă͂Ȃ�܂���B
+
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �i�ÖٓI�ł��ꖾ���I�ł���j<xref linkend="queryhql-joins-forms">����</xref>
+ ��o���NHQL�N�G����Ŏw�肷�邱�Ƃ͂ł��܂���B
+ �T�u�N�G����where�߂Ŏg�����Ƃ��ł��܂�
+ �T�u�N�G�����̂�̂́A������܂߂��܂��B
+
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ where�߂̓I�v�V�����ł��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ��Ƃ��āAHQL�� <literal>UPDATE</literal> ����s����ɂ́A
+ <literal>Query.executeUpdate()</literal> ���\�b�h��g�����������B
+ �i���̃��\�b�h�͂��Ȃ��݂�JDBC <literal>PreparedStatement.executeUpdate()</literal>
+ ���疼�t�����܂����j�F
+ d
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName";
+// or String hqlUpdate = "update Customer set name = :newName where name = :oldName";
+int updatedEntities = s.createQuery( hqlUpdate )
+ .setString( "newName", newName )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ HQL�� <literal>UPDATE</literal> ���́A�f�t�H���g�ł́A��p����G���e�B�e�B��
+ <xref linkend="mapping-declaration-version">version</xref> ��
+ <xref linkend="mapping-declaration-timestamp">timestamp</xref>
+ �v���p�e�B�̒l�ɂ͉e�����܂���B
+ �����EJB3�̎d�l�ɂ�p����Ă��܂��B
+ ������ <literal>versioned update</literal> ��g���āA
+ <literal>version</literal> �� <literal>timestamp</literal>
+ �v���p�e�B�̒l�����I�Ƀ��Z�b�g�����邱�Ƃ��ł��܂��B
+ ����� <literal>UPDATE</literal> �L�[���[�h�̌�� <literal>VERSIONED</literal>
+ �L�[���[�h��lj����邱�Ƃōs���܂��B
+
+ </para>
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+String hqlVersionedUpdate = "update versioned Customer set name = :newName where name = :oldName";
+int updatedEntities = s.createQuery( hqlUpdate )
+ .setString( "newName", newName )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ �J�X�^���o�[�W�����^�i<literal>org.hibernate.usertype.UserVersionType</literal>�j
+ �� <literal>update versioned</literal> ���ƈꏏ�Ɏg���Ȃ����Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ HQL�� <literal>DELETE</literal> ����s����ɂ́A
+ ���� <literal>Query.executeUpdate()</literal> ���\�b�h��g�����������F
+
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlDelete = "delete Customer c where c.name = :oldName";
+// or String hqlDelete = "delete Customer where name = :oldName";
+int deletedEntities = s.createQuery( hqlDelete )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ <literal>Query.executeUpdate()</literal> ���\�b�h���Ԃ� <literal>int</literal>
+ �̒l�́A���̑��삪�e����y�ڂ����G���e�B�e�B�̐��ł��B
+ ���ꂪ�e������f�[�^�x�[�X��̍s���ƁA���݂ɊW���邩�ǂ�����l���Ă݂Ă��������B
+ HQL�o���N����́A���ʂƂ��āA���ۂ�SQL�����������s����邱�ƂɂȂ�܂��B
+ �Ⴆ��joined-subclass�ł��B
+ �Ԃ���鐔�́A���̕��ɂ���ĉe�����ꂽ���ۂ̃G���e�B�e�B�̐������܂��B
+ joined-subclass�̗�ɖ߂�ƁA�T�u�N���X�̈�ɑ���폜�́A
+ ���̃T�u�N���X���}�b�s���O���ꂽ�e�[�u�������ł͂Ȃ��A
+ �u���[�g�v�e�[�u���ƌp���K�w����ɉ�����joined-subclass�̃e�[�u���̍폜�ɂȂ�܂��B
+ </para>
+
+ <para>
+ <literal>INSERT</literal> ���̋^���\���́F
+ <literal>INSERT INTO �G���e�B�e�B�� �v���p�e�B���X�g select��</literal> �ł��B
+ ���ӂ��ׂ��_������������܂��F
+
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ INSERT INTO ... SELECT ... �̌`���������T�|�[�g����Ă��܂��B
+ INSERT INTO ... VALUES ... �̌`���̓T�|�[�g����Ă��܂���B
+ </para>
+ <para>
+ �v���p�e�B���X�g�́ASQL�� <literal>INSERT</literal> ���ɂ����� <literal>�J�����̎d�l</literal>
+ �ɗގ����Ă��܂��B
+ �p���̃}�b�s���O�Ɋ܂܂��G���e�B�e�B�ɑ��āA
+ �N���X���x���Œ��ڒ�`���ꂽ�v���p�e�B�������A�v���p�e�B���X�g�Ɏg���܂��B
+ �X�[�p�[�N���X�̃v���p�e�B�͔F�߂�ꂸ�A�T�u�N���X�̃v���p�e�B�͌��ʂ�����܂���B
+ ����������� <literal>INSERT</literal> ���́A�{���I�Ƀ|�����[�t�B�b�N�ł͂���܂���B
+
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ select���̕Ԃ�l�̌^��insert�������҂���^�ƃ}�b�`���Ă���A
+ ����select���͑Ó���HQL select�N�G���ƂȂ肦�܂��B
+ ���݂��̃`�F�b�N��f�[�^�x�[�X�֔C����̂ł͂Ȃ��A�N�G���̃R���p�C�����Ƀ`�F�b�N���܂��B
+ ���̂��Ƃ́A<emphasis>equal</emphasis>�Ƃ͈Ⴂ�A
+ Hibernate�� <literal>Type</literal> �Ԃ� <emphasis>equivalent</emphasis> �Ɋւ���
+ ��������N�������Ƃɒ��ӂ��Ă��������B
+ ����� <literal>org.hibernate.type.DataType</literal> �Ƃ��Ē�`���ꂽ�v���p�e�B�ƁA
+ <literal>org.hibernate.type.TimestampType</literal>
+ �Ƃ��Ē�`���ꂽ�v���p�e�B�̊Ԃ̃~�X�}�b�`�̖�������N�����܂��B
+ �f�[�^�x�[�X���������ʂł��Ȃ��Ă�A�ϊ����邱�Ƃ��ł��Ă�A���̖��͔������܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ id�v���p�e�B�ɑ��āAinsert���ɂ͓�̑I��������܂��B
+ �v���p�e�B���X�g�Ŗ����I��id�v���p�e�B��w�肷�邩
+ �i���̏ꍇ�A�Ή�����select������l������܂��j�A
+ �v���p�e�B���X�g���珜�O���邩
+ �i���̏ꍇ�A���������l���g���܂��j�̂����ꂩ�ł��B
+ ��҂̑I���́A�f�[�^�x�[�X��𑀍삷��id�W�F�l���[�^��g���Ƃ��̂݁A���p�\�ł��B
+ ���̑I����̂�ꍇ�A�u�C���������v�^�̃W�F�l���[�^��g���ƁA�\����͎��ɗ�O���������܂��B
+ ���̋c�_�ł́A�C���f�[�^�x�[�X�^�W�F�l���[�^�� <literal>org.hibernate.id.SequenceGenerator</literal>
+ �i�Ƃ��̃T�u�N���X�j�ƁA<literal>org.hibernate.id.PostInsertIdentifierGenerator</literal>
+ �̎����ł���ƍl���Ă��܂��B
+ �����ōł���ӂ��ׂ���O�́A<literal>org.hibernate.id.TableHiLoGenerator</literal> �ł��B
+ �l��擾����I��\�ȕ��@���Ȃ����߁A���̃W�F�l���[�^��g�����Ƃ͂ł��܂���B
+
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>version</literal> �� <literal>timestamp</literal> �Ƃ��ă}�b�s���O�����v���p�e�B�ɑ��āA
+ insert���ɂ͓�̑I��������܂��B
+ �v���p�e�B���X�g�Ŗ����I�Ƀv���p�e�B��w�肷�邩
+ �i���̏ꍇ�A�Ή�����select������l������܂��j�A
+ �v���p�e�B���X�g���珜�O���邩
+ �i���̏ꍇ�A<literal>org.hibernate.type.VersionType</literal> �Œ�`���ꂽ
+ <literal>�V�[�h�l</literal> ���g���܂��j�̂����ꂩ�ł��B
+
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ HQL�� <literal>INSERT</literal> ���̎��s��ł��F
+
+ </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlInsert = "insert into DelinquentAccount (id, name) select c.id, c.name from Customer c where ...";
+int createdEntities = s.createQuery( hqlInsert )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/best_practices.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/best_practices.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/best_practices.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/best_practices.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="best-practices" revision="3">
+ <title>�x�X�g�v���N�e�B�X</title>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>
+ �N���X�ׂ͍������x�ŏ��� <literal><component></literal> �Ń}�b�s���O���܂��傤�B</term>
+ <listitem>
+ <para>
+ <literal>street</literal>�i�ʂ�j, <literal>suburb</literal>
+ �i�s�s�j, <literal>state</literal>�i�B�j, <literal>postcode</literal>
+ �i�X�֔ԍ��j��J�v�Z�������� <literal>Address</literal>�i�Z���j�N���X��g���܂��傤�B
+ ��������R�[�h���ė��p���₷���Ȃ�A���t�@�N�^�����O��ȒP�ɂȂ�܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ �i���N���X�ɂ͎��ʎq�v���p�e�B���`���܂��傤�B</term>
+ <listitem>
+ <para>
+ Hibernate�ł͎��ʎq�v���p�e�B�̓I�v�V�����ł����A
+ �g�p���ׂ����R����������܂��B
+ ���ʎq�́u�l�H�I�v�i�������ꂽ�A�Ɩ��I�ȈӖ������Ȃ��j
+ �Ȃ�̂ɂ��邱�Ƃ������߂��܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>���R�L�[�����܂��傤�B</term>
+ <listitem>
+ <para>
+ ���ׂẴG���e�B�e�B�ɑ��Ď��R�L�[�����āA
+ <literal><natural-id></literal> �Ń}�b�s���O���܂��傤�B
+ ���R�L�[��\������v���p�e�B���r���邽�߂ɁA
+ <literal>equals()</literal> �� <literal>hashCode()</literal> ��������܂��傤�B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>�N���X�̃}�b�s���O�͂��ꂼ��̃N���X��p�̃t�@�C���ɏ����܂��傤�B</term>
+ <listitem>
+ <para>
+ �P��̋���ȃ}�b�s���O�h�L�������g��g�p���Ȃ��ł��������B
+ <literal>com.eg.Foo</literal> �N���X�Ȃ�
+ <literal>com/eg/Foo.hbm.xml</literal> �t�@�C���Ƀ}�b�s���O���܂��傤�B
+ ���̂��Ƃ́A���Ƀ`�[���ł̊J���ɈӖ�������܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>���\�[�X�Ƃ��ă}�b�s���O���[�h���܂��傤�B</term>
+ <listitem>
+ <para>
+ �}�b�s���O��A����炪�}�b�s���O���邷��N���X�ƈꏏ�ɔz�u���܂��傤�B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>�N�G���������O���ɒu�����Ƃ�l���܂��傤</term>
+ <listitem>
+ <para>
+ �N�G����ANSI�W���łȂ�SQL����Ă�ł���Ȃ�A����͂悢�v���N�e�B�X�ł��B
+ �N�G���������}�b�s���O�t�@�C���֊O�o������A�v���P�[�V�������|�[�^�u���ɂȂ�܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>�o�C���h�ϐ���g���܂��傤�B</term>
+ <listitem>
+ <para>
+ JDBC�̏ꍇ�Ɠ����悤�ɁA�萔�łȂ��l�͕K��"?"�Œu�������܂��傤�B
+ �萔�łȂ��l��o�C���h���邽�߂ɁA�N�G���ŕ������g���Ă͂����܂���B
+ ���O�t���̃p�����[�^��g���悤�ɂ���Ƃ���ɗǂ��ł��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>JDBC�R�l�N�V������Ǘ����Ă͂����܂���B</term>
+ <listitem>
+ <para>
+ Hibernate�ł̓A�v���P�[�V������JDBC�R�l�N�V������Ǘ����邱�Ƃ�������Ă��܂��B
+ ����������͍ŏI��i���Ǝv���Ă��������B
+ �g�ݍ��݂̃R�l�N�V�����v���o�C�_��g�����Ƃ��ł��Ȃ���A
+ <literal>org.hibernate.connection.ConnectionProvider</literal> ��������邱�Ƃ�l���Ă��������B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>�J�X�^���^�̎g�p��l���܂��傤�B</term>
+ <listitem>
+ <para>
+ ���郉�C�u�������玝���Ă���Java�^��i��������K�v������Ƃ��܂��傤�B
+ ���������̌^�ɂ́A�R���|�[�l���g�Ƃ��ă}�b�s���O���邽�߂ɕK�v�ȃA�N�Z�T���Ȃ��Ƃ��܂��B
+ ���̂悤�ȏꍇ�� <literal>org.hibernate.UserType</literal> �̎�����l����ׂ��ł��B
+ ���������Hibernate�^�Ƃ̎����ϊ���S�z�����ɃA�v���P�[�V�����̃R�[�h�����܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>�{�g���l�b�N��������ɂ�JDBC��n���h�R�[�h���܂��傤�B</term>
+ <listitem>
+ <para>
+ �V�X�e���̃p�t�H�[�}���X�N���e�B�J���ȗ̈�ł́A
+ �����̑����JDBC�ڎg���Ɨǂ��������܂���B
+ �����������{�g���l�b�N�ɂȂ��Ă��邩 <emphasis>�͂����肷��</emphasis> �܂ł͑҂��Ă��������B
+ �܂�JDBC�ڎg������Ƃ����āA�K����������Ȃ�Ƃ͌���Ȃ����Ƃ�����Ă��������B
+ JDBC�ڎg���K�v������AHibernate�� <literal>Session</literal> ��I�[�v�����āA
+ JDBC�R�l�N�V������g���Ɨǂ��������܂���B
+ �ˑR�Ƃ��ē����g�����U�N�V�����헪�ƃR�l�N�V�����v���o�C�_���g���邩��ł��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>Session</literal> �̃t���b�V���𗝉��܂��傤�B</term>
+ <listitem>
+ <para>
+ Session���i����Ԃ�f�[�^�x�[�X�Ɠ��������邱�Ƃ��Ƃ��ǂ�����܂��B
+ ���������ꂪ���܂�ɕp�ɂɋN����悤���ƁA�p�t�H�[�}���X�ɉe�����o�Ă��܂��B
+ �����t���b�V�����ɂ�����A����̃g�����U�N�V�����̃N�G���⑀��̏��Ԃ�ύX���邱�ƂŁA
+ �s�K�v�ȃt���b�V����ŏ����ɂł��܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>3�w�A�[�L�e�N�`���ł͕����I�u�W�F�N�g�̎g�p��l���܂��傤�B</term>
+ <listitem>
+ <para>
+ �T�[�u���b�g / �Z�b�V�����r�[���A�[�L�e�N�`����g���Ƃ��A
+ �T�[�u���b�g�w / JSP�w�ԂŃZ�b�V�����r�[���Ń��[�h�����i���I�u�W�F�N�g������ł��܂��B
+ ���̍ۃ��N�G�X�g���ƂɐV����Session��g���Ă��������B
+ �܂� <literal>Session.merge()</literal> �� <literal>Session.saveOrUpdate()</literal>
+ ��g���āA�I�u�W�F�N�g�ƃf�[�^�x�[�X�������Ă��������B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>2�w�A�[�L�e�N�`���ł͒����i���R���e�L�X�g�̎g�p��l���܂��傤�B</term>
+ <listitem>
+ <para>
+ �ō��̃X�P�[���r���e�B��ɂ́A
+ �f�[�^�x�[�X�g�����U�N�V������ł��邾���Z�����Ȃ���Ȃ�܂���B
+ �����������Ԏ��s���� <emphasis>�A�v���P�[�V�����g�����U�N�V����</emphasis>
+ �̎������K�v�Ȃ��Ƃ͂����ł��B
+ ����̓��[�U�̎��_�����1�̍�ƒP�ʁiunit of work�j�ɂȂ�܂��B
+ �A�v���P�[�V�����g�����U�N�V�����͂������̃N���C�A���g�̃��N�G�X�g/���X�|���X�T�C�N���ɂ܂�����܂��B
+ �A�v���P�[�V�����g�����U�N�V�����̎����ɕ����I�u�W�F�N�g��g���͈̂�ʓI�ł��B
+
+ �����łȂ���A2�w�A�[�L�e�N�`���̏ꍇ�͓��ɓK�Ȃ��Ƃł����A
+ �A�v���P�[�V�����g�����U�N�V�����̃��C�t�T�C�N���S�̂ɑ���
+ �P��̃I�[�v���ȉi�����R���e�L�X�g�i�Z�b�V�����j��ێ����Ă��������B
+ �����ĒP���Ƀ��N�G�X�g�̍Ō��JDBC�R�l�N�V��������ؒf���A
+ ���̃��N�G�X�g�̍ŏ��ɍĐڑ����܂��B
+
+ �����ĕ����̃A�v���P�[�V�����g�����U�N�V�������[�X�P�[�X�ɓn����
+ 1��Session��g���Ȃ��ł��������B
+ �����łȂ���A�Â��f�[�^�ō�Ƃ��邱�ƂɂȂ�܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>��O�A�\�Ȃ�̂Ƃ��Ĉ����Ă͂����܂���B</term>
+ <listitem>
+ <para>
+ ����́u�x�X�g�v�v���N�e�B�X�ȏ�́A�K�{�̃v���N�e�B�X�ł��B
+ ��O�����������Ƃ��� <literal>Transaction</literal> ���[���o�b�N���āA
+ <literal>Session</literal> ��N���[�Y�����������B
+ �������Ȃ���Hibernate�̓������̏�Ԃ��i����Ԃ𐳊m�ɕ\�����Ă��邱�Ƃ�ۏł��܂���B
+ ���̓��ʂȏꍇ�Ƃ��āA�^����ꂽ���ʎq���C���X�^���X���f�[�^�x�[�X�ɑ��݂��邩�ǂ����肷�邽�߂ɁA
+ <literal>Session.load()</literal> ��g�����Ƃ͂�߂Ă��������B
+ ���̑���� <literal>Session.get()</literal> ���N�G����g���Ă��������B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>�֘A�ɂ͂Ȃ�ׂ��x���t�F�b�`��g���܂��傤�B</term>
+ <listitem>
+ <para>
+ �����t�F�b�`�͍T���߂ɂ��܂��傤�B
+ �L���b�V���ɂ͊��S�ɕێ�����Ȃ��悤�ȃN���X�̊֘A�ɂ́A
+ �v���L�V�ƒx���R���N�V������g���Ă��������B
+ �L���b�V�������N���X�̊֘A�A�܂�L���b�V�����q�b�g����\�������ɍ����֘A�́A
+ <literal>lazy="false"</literal> �ŐϋɓI�ȃt�F�b�`���I�ɖ����ɂ��Ă��������B
+ �����t�F�b�`���K�ȓ���̃��[�X�P�[�X�ɂ́A
+ �N�G���� <literal>left join fetch</literal> ��g�����������B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ �t�F�b�`����Ă��Ȃ��f�[�^�Ɋւ�������邽�߂ɁA
+ <emphasis>�r���[�̒��ŃI�[�v���Z�b�V������g��(open session in view)</emphasis>
+ �p�^�[�����A�������ꂽ <emphasis>�g�ݗ��ăt�F�[�Y(assembly phase)</emphasis> ��g���܂��傤�B
+ </term>
+ <listitem>
+ <para>
+ Hibernate�� <emphasis>Data Transfer Objects</emphasis> (DTO)�����ދ��ȍ�Ƃ���J���҂������܂��B
+ �`���I��EJB�A�[�L�e�N�`���ł�DTO�͓�ړI������܂��F
+ 1�ڂ́A�G���e�B�e�B�r�[�����V���A���C�Y����Ȃ����ւ̑�ł��B
+ 2�ڂ́A�v���[���e�[�V�����w�ɐ��䂪�߂�O�ɁA
+ �r���[�Ɏg���邷�ׂẴf�[�^���t�F�b�`����āADTO�ɕ��������悤�ȑg�ݗ��ăt�F�[�Y��ÖٓI�ɒ�`���܂��B
+ Hibernate�ł�1�ڂ̖ړI���s�v�ɂȂ�܂��B
+ �������r���[�̃����_�����O�����̊ԁA�i���R���e�L�X�g�i�Z�b�V�����j��I�[�v���ɂ����܂܂ɂ��Ȃ���A
+ �g�ݗ��ăt�F�[�Y�͂܂��K�v�ł��i�����I�u�W�F�N�g�̒��̂ǂ̃f�[�^�����p�\���ɂ��āA
+ �v���[���e�[�V�����w�ƌ����Ȏ�茈�߂��Ă���r�W�l�X���\�b�h��l���Ă݂Ă��������j�B
+ �����Hibernate���̖��ł͂���܂���B
+ �g�����U�N�V������ň��S�Ƀf�[�^�A�N�Z�X���邽�߂̊�{�I�ȗv���ł��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Hibernate����r�W�l�X���W�b�N�𒊏ۉ����邱�Ƃ�l���܂��傤�B</term>
+ <listitem>
+ <para>
+ �C���^�[�t�F�C�X�ŁiHibernate�́j�f�[�^�A�N�Z�X�R�[�h��B�����܂��傤�B
+ <emphasis>DAO</emphasis> �� <emphasis>Thread Local Session</emphasis> �p�^�[����g�ݍ��킹�܂��傤�B
+ <literal>UserType</literal> ��Hibernate�Ɋ֘A�t����ƁA
+ �n���h�R�[�h����JDBC�ʼni��������N���X�����Ƃ�ł��܂��B
+ �i���̃A�h�o�C�X�́u�\���傫�ȁv�A�v���P�[�V�����ɑ��Ă̂�̂ł��B
+ �e�[�u����5�����Ȃ��悤�ȃA�v���P�[�V�����ɂ͓��Ă͂܂�܂���B�j
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>�������֘A�}�b�s���O�͎g��Ȃ��悤�ɂ��܂��傤�B</term>
+ <listitem>
+ <para>
+ �悢���[�X�P�[�X�ɖ{���̑��Α��֘A�����邱�Ƃ͋H�i�܂�j�ł��B
+ �قƂ�ǂ̏ꍇ�u�����N�e�[�u���v�̕t���I�ȏ�K�v�ɂȂ�܂��B
+ ���̏ꍇ�A�����N�N���X��2��1�Α��֘A��g�����������Ɨǂ��ł��B
+ ���ۂقƂ�ǂ̏ꍇ�֘A��1�Α��Ƒ���1�Ȃ̂ŁA
+ ���̃X�^�C���̊֘A��g���Ƃ��͖{���ɕK�v���ǂ�����l���Ă݂Ă��������B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>�Ȃ�ׂ��o�����֘A�ɂ��܂��傤�B</term>
+ <listitem>
+ <para>
+ �P�����֘A�͑o�����ɔ�ׂČ���������Ȃ�܂��B
+ �傫�ȃA�v���P�[�V�����ł́A
+ �قƂ�ǂ��ׂĂ̊֘A���o�����Ƀi�r�Q�[�V�����ł��Ȃ���Ȃ�܂���B
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/collection_mapping.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/collection_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/collection_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/collection_mapping.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,1226 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="collections">
+ <title>�R���N�V�����̃}�b�s���O</title>
+
+ <sect1 id="collections-persistent" revision="3">
+ <title>�R���N�V�����̉i����</title>
+
+ <para>
+ �R���N�V�����^�̃t�B�[���h��i��������ɂ́A
+ ���̃R���N�V�����^���C���^�[�t�F�C�X�^�ł���K�v������܂��B
+ �Ⴆ�A
+ </para>
+
+ <programlisting><![CDATA[public class Product {
+ private String serialNumber;
+ private Set parts = new HashSet();
+
+ public Set getParts() { return parts; }
+ void setParts(Set parts) { this.parts = parts; }
+ public String getSerialNumber() { return serialNumber; }
+ void setSerialNumber(String sn) { serialNumber = sn; }
+}]]></programlisting>
+
+ <para>
+ ���݂���C���^�[�t�F�C�X�ɂ� <literal>java.util.Set</literal>�A
+ <literal>java.util.Collection</literal>�A<literal>java.util.List</literal>�A
+ <literal>java.util.Map</literal>�A<literal>java.util.SortedSet</literal>�A
+ <literal>java.util.SortedMap</literal> �Ȃǂ�����܂��B
+ �܂��́A�C�ӂ̃C���^�[�t�F�C�X���g���܂��I
+ �i�������A�C�ӂ̃C���^�[�t�F�C�X��g�p����ꍇ�́A
+ <literal>org.hibernate.usertype.UserCollectionType</literal>
+ �̎����N���X��쐬����K�v������܂��B�j
+ </para>
+
+ <para>
+ <literal>HashSet</literal> �̃C���X�^���X���C���X�^���X�ϐ���
+ �ǂ̂悤�ɏ���������邩�ɒ��ڂ��Ă݂܂��傤�B
+ ����͐V���ɐ������ꂽ�i�i��������Ă��Ȃ��j�R���N�V�����^�̃v���p�e�B��
+ ����������œK�ȕ��@�ł��B
+ �i�Ⴆ�� <literal>persist()</literal> �ɂ��j�C���X�^���X��i�������悤�Ƃ����Ƃ��A
+ Hibernate�� <literal>HashSet</literal> ��Hibernate�Ǝ��� <literal>Set</literal>
+ �̎����N���X�ɒu�������܂��B
+ ���̂��߁A���̂悤�ȃG���[�ɂ͒��ӂ��K�v�ł��B
+ </para>
+
+ <programlisting><![CDATA[Cat cat = new DomesticCat();
+Cat kitten = new DomesticCat();
+....
+Set kittens = new HashSet();
+kittens.add(kitten);
+cat.setKittens(kittens);
+session.persist(cat);
+kittens = cat.getKittens(); // Okay, kittens collection is a Set
+(HashSet) cat.getKittens(); // Error!]]></programlisting>
+
+ <para>
+ Hibernate�ɂ�蒍�����ꂽ�i�����R���N�V�����́A�C���^�[�t�F�C�X�^�ɉ����āA
+ <literal>HashMap</literal> �� <literal>HashSet</literal>�A
+ <literal>TreeMap</literal>�A <literal>TreeSet</literal>�A
+ <literal>ArrayList</literal> �̂悤�ɐU�����܂��B
+ </para>
+
+ <para>
+ �R���N�V�����C���X�^���X�́A�l�^�Ƃ��ĕ��ʂɐU�����܂��B
+ �i�����I�u�W�F�N�g�ɎQ�Ƃ��ꂽ�Ƃ��Ɏ����I�ɉi��������A
+ �Q�Ƃ��Ȃ��Ȃ����Ƃ��Ɏ����I�ɍ폜����܂��B
+ �������i�����I�u�W�F�N�g����ʂ̉i�����I�u�W�F�N�g�ɓn���ꂽ��A
+ ���̗v�f�͌��݂̃e�[�u������ʂ̃e�[�u���Ɉړ����邩�����܂���B
+ �Q�̃G���e�B�e�B�������R���N�V�����C���X�^���X���L���Ă͂����܂���B
+ �����[�V���i�����f����x�[�X�ɂ��Ă��邽�߁A�R���N�V�����^�̃v���p�e�B��
+ null�l�������Ă�Ӗ�������܂���B
+ �܂�Hibernate�͎Q�Ɛ�̂Ȃ��R���N�V�����Ƌ�̃R���N�V�������ʂ��܂���B
+ </para>
+
+ <para>
+ ����������قǐS�z���Ȃ��Ă�\���܂���B
+ ���i�g���Ă���Java�̃R���N�V�����Ɠ����悤�ɁA�i�����R���N�V������g���Ă��������B
+ �o�����֘A�̈Ӗ��𗝉���悢�̂ł��i����͌�قǐ�����܂��j�B
+ </para>
+
+ </sect1>
+
+ <sect1 id="collections-mapping" revision="4">
+ <title>�R���N�V�����̃}�b�s���O</title>
+
+ <para>
+ �R���N�V������}�b�s���O���邽�߂̃}�b�s���O�v�f�́A�C���^�[�t�F�C�X�̌^�Ɉˑ����܂��B
+ �Ⴆ�A<literal><set></literal> �v�f�� <literal>Set</literal> �^��
+ �}�b�s���O���邽�߂Ɏg���܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Product">
+ <id name="serialNumber" column="productSerialNumber"/>
+ <set name="parts">
+ <key column="productSerialNumber" not-null="true"/>
+ <one-to-many class="Part"/>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ �}�b�s���O�v�f�ɂ� <literal><set></literal> �̑��� <literal><list></literal>�A
+ <literal><map></literal>�A<literal><bag></literal>�A
+ <literal><array></literal>�A<literal><primitive-array></literal> ������܂��B
+ ��\�Ƃ��āA<literal><map></literal> �v�f���L�Ɏ����܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="mappingcollection1" coords="2 65"/>
+ <area id="mappingcollection2" coords="3 65"/>
+ <area id="mappingcollection3" coords="4 65"/>
+ <area id="mappingcollection4" coords="5 65"/>
+ <area id="mappingcollection5" coords="6 65"/>
+ <area id="mappingcollection6" coords="7 65"/>
+ <area id="mappingcollection7" coords="8 65"/>
+ <area id="mappingcollection8" coords="9 65"/>
+ <area id="mappingcollection9" coords="10 65"/>
+ <area id="mappingcollection10" coords="11 65"/>
+ <area id="mappingcollection11" coords="12 65"/>
+ <area id="mappingcollection12" coords="13 65"/>
+ <area id="mappingcollection13" coords="14 65"/>
+ <area id="mappingcollection14" coords="15 65"/>
+ </areaspec>
+ <programlisting><![CDATA[<map
+ name="propertyName"
+ table="table_name"
+ schema="schema_name"
+ lazy="true|extra|false"
+ inverse="true|false"
+ cascade="all|none|save-update|delete|all-delete-orphan|delete-orphan"
+ sort="unsorted|natural|comparatorClass"
+ order-by="column_name asc|desc"
+ where="arbitrary sql where condition"
+ fetch="join|select|subselect"
+ batch-size="N"
+ access="field|property|ClassName"
+ optimistic-lock="true|false"
+ mutable="true|false"
+ node="element-name|."
+ embed-xml="true|false"
+>
+
+ <key .... />
+ <map-key .... />
+ <element .... />
+</map>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="mappingcollection1">
+ <para>
+ <literal>name</literal> �R���N�V�����^�ł���v���p�e�B�̖��O
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection2">
+ <para>
+ <literal>table</literal> �i�I�v�V���� - �f�t�H���g�̓v���p�e�B���j�R���N�V�����e�[�u���̖��O
+ �i��Α��֘A�ł͎g�p���܂���j�B
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection3">
+ <para>
+ <literal>schema</literal> �i�I�v�V�����j�e�[�u���X�L�[�}�̖��O�B
+ ���[�g�v�f�Ő錾����Ă���X�L�[�}���D�悳��܂��B
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection4">
+ <para>
+ <literal>lazy</literal> �i�I�v�V���� - �f�t�H���g�� <literal>true</literal>�j
+ �x���t�F�b�`���ɂ��A�֘A���ɑ����Ƀt�F�b�`�ɂ��邽�߂Ɏg�p���܂��B
+ �܂��́A�uextra-lazy�v�t�F�b�`��L���ɂ��邽�߂Ɏg�p���܂��B
+ �uextra-lazy�v�t�F�b�`�́A�قƂ�ǂ̑���ł̓R���N�V�������������܂���
+ �i���ɑ傫�ȃR���N�V�����ɓK���Ă��܂��j�B
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection5">
+ <para>
+ <literal>inverse</literal> �i�I�v�V���� - �f�t�H���g�� <literal>false</literal>�j
+ ���̃R���N�V�������o�����֘A�́u�t�v���ł���ƃ}�[�N���܂��B
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection6">
+ <para>
+ <literal>cascade</literal> �i�I�v�V���� - �f�t�H���g�� <literal>none</literal>�j
+ �q�G���e�B�e�B�ւ̃J�X�P�[�h�����L���ɂ��܂��B
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection7">
+ <para>
+ <literal>sort</literal> �i�I�v�V�����j�R���N�V�������R�ȏ����Ń\�[�g����ꍇ��
+ <literal>natural</literal> ��w�肵�܂��B
+ ���邢��Comparator�N���X��w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection8">
+ <para>
+ <literal>order-by</literal> �i�I�v�V�����AJDK1.4�̂݁j
+ <literal>Map</literal>�A<literal>Set</literal>�Abag�̃C�e���[�V�����������`����
+ �e�[�u���J������w�肷��Ƌ��ɁA
+ �I�v�V�����Ƃ��� <literal>asc</literal>�A<literal>desc</literal> ��w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection9">
+ <para>
+ <literal>where</literal> �i�I�v�V�����j�R���N�V�����̌�����폜�̍ۂɎg��
+ �C�ӂ�SQL��<literal>WHERE</literal> ����w�肵�܂�
+ �i���p�\�ȃf�[�^�̈ꕔ��������R���N�V�������܂ނׂ��Ƃ��ɁA����͗L�p�ł��j�B
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection10">
+ <para>
+ <literal>fetch</literal>�i�I�v�V���� - �f�t�H���g�� <literal>select</literal>�j
+ �O�������ɂ��t�F�b�`�A�����I��t�F�b�`�isequential select fetch�j�A
+ �����T�u�Z���N�g�t�F�b�`�isequential subselect fetch�j�̂ǂꂩ��I���Ă��������B
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection11">
+ <para>
+ <literal>batch-size</literal> �i�I�v�V���� - �f�t�H���g�� <literal>1</literal>�j
+ �R���N�V�����̃C���X�^���X�̒x���t�F�b�`�̂��߂́u�o�b�`�T�C�Y�v��w�肵�܂��B
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection12">
+ <para>
+ <literal>access</literal> �i�I�v�V���� - �f�t�H���g�� <literal>property</literal>�j
+ �R���N�V�����^�v���p�e�B�̒l�ɃA�N�Z�X���邽�߂Ɏg�p����헪�ł��B
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection13">
+ <para>
+ <literal>optimistic-lock</literal>�i�I�v�V���� - �f�t�H���g�� <literal>true</literal>�j
+ �R���N�V�����̏�Ԃ�ς��邱�Ƃɂ���āA
+ ���̃I�[�i�[�ł���G���e�B�e�B�̃o�[�W�������C���N�������g����邩��w�肵�܂��B
+ �i��Α��֘A�ł́A�قƂ�ǂ̏ꍇ�ɂ����Ė����ɐݒ肷��̂��Ó��ł��B�j
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection14">
+ <para>
+ <literal>mutable</literal>�i�I�v�V���� - �f�t�H���g�� <literal>true</literal>�j
+ <literal>false</literal> �l�́A�R���N�V�����̗v�f���ύX����Ȃ����Ƃ�\���܂�
+ �i����ꍇ�ɂ́A�����p�t�H�[�}���X���߂܂��j�B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <sect2 id="collections-foreignkeys" >
+ <title>�R���N�V�����̊O���L�[</title>
+
+ <para>
+ �R���N�V�����̃C���X�^���X�́A�f�[�^�x�[�X��ł́A
+ ���̃R���N�V�������L����G���e�B�e�B�̊O���L�[�ɂ���Ď��ʂ���܂��B
+ ���̊O���L�[�̓R���N�V�����e�[�u���� <emphasis>�R���N�V�����L�[�J����</emphasis> �ƌĂ�܂��B
+ �R���N�V�����L�[�J������ <literal><key></literal> �v�f�ɂ��}�b�s���O���܂��B
+ </para>
+
+ <para>
+ �O���L�[�J�����ɂ�null�ݒ萧���邩�����܂���B
+ �قƂ�ǂ̃R���N�V�����ɓ��Ă͂܂�ł��傤�B
+ �P�����̈�Α��֘A�ɂ����āA�O���L�[�J�����̓f�t�H���g��null�����ݒ�ɂȂ��Ă��܂��B
+ ����āA<literal>not-null="true"</literal> ��w�肷��K�v�����邩�����܂���B
+ </para>
+
+ <programlisting><![CDATA[<key column="productSerialNumber" not-null="true"/>]]></programlisting>
+
+ <para>
+ �O���L�[�̐��� <literal>ON DELETE CASCADE</literal> ��g���������܂���B
+ </para>
+
+ <programlisting><![CDATA[<key column="productSerialNumber" on-delete="cascade"/>]]></programlisting>
+
+ <para>
+ <literal><key></literal> �v�f�̂��ׂĂ̒�`�ɂ��Ă͑O�̏͂�Q�Ƃ��Ă��������B
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-elements" >
+ <title>�R���N�V�����̗v�f</title>
+
+ <para>
+ �R���N�V�����͑���Hibernate�̌^�̂قƂ�ǁi���ׂĂ̊�{�^�A�J�X�^���^�A�R���|�[�l���g�A
+ ���̃G���e�B�e�B�ւ̎Q�Ɓj��i�[���邱�Ƃ��ł��܂��B
+ ���̓_�͏d�v�ȈႢ�ɂȂ�܂��B
+ �R���N�V�����Ɋi�[���ꂽ�I�u�W�F�N�g���u�l�v�Z�}���e�B�N�X�Ƃ��Ĉ�����̂�
+ �i���C�t�T�C�N���̓R���N�V�����̃I�[�i�[�Ɋ��S�Ɉˑ����܂��j�A
+ ������͂��ꎩ�g�̃��C�t�T�C�N���������ʂ̃G���e�B�e�B�ւ̎Q�Ƃł��邩�̂��Ƃ����Ⴂ�ł��B
+ ��҂́A2�̃I�u�W�F�N�g�Ԃ́u�����N�v��R���N�V�����ɕێ����Ă���ƌ��Ȃ��Ă��邾���ł��B
+ </para>
+
+ <para>
+ �i�[�����^�� <emphasis>�R���N�V�����v�f�^</emphasis> �ƌĂ�܂��B
+ �R���N�V�����v�f�́A<literal><element></literal> �܂��� <literal><composite-element></literal>
+ �ɂ��}�b�s���O����A�G���e�B�e�B�ւ̎Q�Ƃ̏ꍇ�ɂ�
+ <literal><one-to-many></literal> �܂��� <literal><many-to-many></literal>
+ �ɂ��}�b�s���O����܂��B
+ �ŏ��̓�͒l�Ƃ��ėv�f��}�b�s���O���A���̓�̓G���e�B�e�B�̊֘A��}�b�s���O����̂Ɏg���܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-indexed">
+ <title>�C���f�b�N�X�t���̃R���N�V����</title>
+
+ <para>
+ set��bag�����S�ẴR���N�V�����}�b�s���O�ɂ́A
+ �R���N�V�����e�[�u���̒��� <emphasis>�C���f�b�N�X�p�̃J����</emphasis> ���K�v�ł��B
+ ���̃J�����ɁA�z��� <literal>List</literal> �̃C���f�b�N�X�A
+ ������� <literal>Map</literal> �̃L�[��}�b�s���O���܂��B
+ <literal>Map</literal> �̃C���f�b�N�X�́A
+ <literal><map-key></literal> �ɂ��}�b�s���O���ꂽ��{�^���A
+ <literal><map-key-many-to-many></literal> �ɂ��}�b�s���O���ꂽ�G���e�B�e�B�̊֘A���A
+ ���邢�� <literal><composite-map-key></literal> �ɂ��}�b�s���O���ꂽ�R���|�W�b�g�^�ɂȂ�܂��B
+ �z���X�g�̃C���f�b�N�X�́A��� <literal>integer</literal> �^�ŁA
+ <literal><list-index></literal> �v�f�ɂ��}�b�s���O���܂��B
+ �}�b�s���O���ꂽ�J�����ɂ̓V�[�P���V�����Ȑ�����i�[���܂��i�f�t�H���g�ł�0����ԍ����t�����܂��j�B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="index1" coords="2 45"/>
+ <area id="index2" coords="3 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<list-index
+ column="column_name"
+ base="0|1|..."/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="index1">
+ <para>
+ <literal>column_name</literal>�i�K�{�j:�R���N�V�����C���f�b�N�X�̒l��ێ�����J�����̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="index2">
+ <para>
+ <literal>base</literal>�i�I�v�V�����A�f�t�H���g�� <literal>0</literal>�j:
+ ���X�g������͔z��̍ŏ��̗v�f�ɊY������C���f�b�N�X�J�����̒l�B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <programlistingco>
+ <areaspec>
+ <area id="mapkey1" coords="2 45"/>
+ <area id="mapkey2" coords="3 45"/>
+ <area id="mapkey3" coords="4 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<map-key
+ column="column_name"
+ formula="any SQL expression"
+ type="type_name"
+ node="@attribute-name"
+ length="N"/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="mapkey1">
+ <para>
+ <literal>column</literal>�i�I�v�V�����j: �R���N�V�����C���f�b�N�X�̒l��ێ�����J�����̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="mapkey2">
+ <para>
+ <literal>formula</literal>�i�I�v�V�����j: Map�̃L�[��]������̂Ɏg����SQL���B
+ </para>
+ </callout>
+ <callout arearefs="mapkey3">
+ <para>
+ <literal>type</literal>�i�K�{�j: Map�̃L�[�̌^�B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <programlistingco>
+ <areaspec>
+ <area id="indexmanytomany1" coords="2 45"/>
+ <area id="indexmanytomany2" coords="3 45"/>
+ <area id="indexmanytomany3" coords="4 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<map-key-many-to-many
+ column="column_name"
+ formula="any SQL expression"
+ class="ClassName"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="indexmanytomany1">
+ <para>
+ <literal>column</literal> �i�I�v�V�����j:
+ �R���N�V�����C���f�b�N�X�̒l�̂��߂̊O���L�[�J�����̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="indexmanytomany2">
+ <para>
+ <literal>formula</literal> �i�I�v�V�����j:
+ Map�̃L�[�̂��߂̊O���L�[��]�����邽�߂Ɏg��SQL���B
+ </para>
+ </callout>
+ <callout arearefs="indexmanytomany3">
+ <para>
+ <literal>class</literal> �i�K�{�j:
+ Map�̃L�[�Ƃ��Ďg����G���e�B�e�B�N���X�B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+
+ <para>
+ ����e�[�u���ɃC���f�b�N�X�J�������Ȃ��Ă�A�v���p�e�B�^�Ƃ��� <literal>List</literal> ��g��������A
+ Hibernate�� <emphasis><bag></emphasis> �Ƃ��ăv���p�e�B��}�b�s���O���܂��B
+ bag�̓f�[�^�x�[�X���畜������鎞�A������ێ����܂���B
+ �������A�i��������Łj�\�[�g������A�iSQL�Łj�����t��������iorder by�j���邱�Ƃ�ł��܂��B
+ </para>
+
+ </sect2>
+
+ <para>
+ �����̈�ʓI�ȃ����[�V���i�����f����J�o�[�������߂ɁA
+ �R���N�V�����̂��߂ɗ��p�ł���}�b�s���O�ɂ͂��Ȃ�̕�������܂��B
+ �l�X�ȃ}�b�s���O�錾���ǂ̂悤�Ƀf�[�^�x�[�X�e�[�u���ɕϊ�����邩��m�邽�߂ɁA
+ �X�L�[�}�����c�[����g���Ă݂�Ɨǂ��ł��傤�B
+ </para>
+
+ <sect2 id="collections-ofvalues" revision="2">
+ <title>�l�̃R���N�V�����Ƒ��Α��֘A</title>
+
+ <para>
+ �l�̃R���N�V�����⑽�Α��֘A�́A��p�� <emphasis>�R���N�V�����e�[�u��</emphasis> ���K�v�ł��B
+ ���̃e�[�u���́A�O���L�[�J�����ƁA
+ <emphasis>�R���N�V�����v�f�̃J����</emphasis> �ƁA
+ �ꍇ�ɂ���Ă̓C���f�b�N�X�J���������܂��B
+ </para>
+
+ <para>
+ �l�̃R���N�V�����̂��߂ɁA<literal><element></literal>�^�O��g�p���܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="element1b" coords="2 50"/>
+ <area id="element2b" coords="3 50"/>
+ <area id="element3b" coords="4 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<element
+ column="column_name"
+ formula="any SQL expression"
+ type="typename"
+ length="L"
+ precision="P"
+ scale="S"
+ not-null="true|false"
+ unique="true|false"
+ node="element-name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="element1b">
+ <para>
+ <literal>column</literal> �i�I�v�V�����j: �R���N�V�����̗v�f�̒l��ێ�����J�����̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="element2b">
+ <para>
+ <literal>formula</literal> �i�I�v�V�����j: �v�f��]�����邽�߂Ɏg��SQL���B
+ </para>
+ </callout>
+ <callout arearefs="element3b">
+ <para>
+ <literal>type</literal> �i�K�{�j�R���N�V�����̗v�f�̌^�B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <emphasis>���Α��֘A</emphasis> �� <literal><many-to-many></literal> �v�f�Ŏw�肵�܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="manytomany1" coords="2 60"/>
+ <area id="manytomany2" coords="3 60"/>
+ <area id="manytomany3" coords="4 60"/>
+ <area id="manytomany4" coords="5 60"/>
+ <area id="manytomany5" coords="6 60"/>
+ <area id="manytomany6" coords="7 60"/>
+ <area id="manytomany7" coords="8 60"/>
+ <area id="manytomany8" coords="9 60"/>
+ </areaspec>
+ <programlisting><![CDATA[<many-to-many
+ column="column_name"
+ formula="any SQL expression"
+ class="ClassName"
+ fetch="select|join"
+ unique="true|false"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ property-ref="propertyNameFromAssociatedClass"
+ node="element-name"
+ embed-xml="true|false"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="manytomany1">
+ <para>
+ <literal>column</literal> �i�I�v�V�����j: �O���L�[�J�����̗v�f�̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="manytomany2">
+ <para>
+ <literal>formula</literal> �i�I�v�V�����j: �O���L�[�l�̗v�f��]�����邽�߂Ɏg��SQL���B
+ </para>
+ </callout>
+ <callout arearefs="manytomany3">
+ <para>
+ <literal>class</literal> �i�K�{�j: �֘A�N���X�̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="manytomany4">
+ <para>
+ <literal>fetch</literal> (�I�v�V���� - �f�t�H���g�� <literal>join</literal>):
+ �֘A�̂��߂ɁA�O�������������I��t�F�b�`��L���ɂ��܂��B
+ ����͓���ȃP�[�X�ł����A�G���e�B�e�B�Ƒ��̃G���e�B�e�B�Ƃ̑��Α��W��
+ �i�P�� <literal>SELECT</literal> �ɂ��j���S�ɑ����Ƀt�F�b�`���邽�߂ɂ́A
+ ���̃R���N�V�������̂����łȂ��A
+ �l�X�g�����v�f�ł��� <literal><many-to-many></literal> �̂��̑����ɂ��Ă�
+ <literal>join</literal> �t�F�b�`��L������K�v������܂��B
+ </para>
+ </callout>
+ <callout arearefs="manytomany5">
+ <para>
+ <literal>unique</literal> �i�I�v�V�����j:
+ �O���L�[�J�����̃��j�[�N�����DDL������L���ɂ��܂��B
+ ����́A�֘A�̑��d�x�������Α��ɂ��܂��B
+ </para>
+ </callout>
+ <callout arearefs="manytomany6">
+ <para>
+ <literal>not-found</literal> �i�I�v�V���� - �f�t�H���g�� <literal>exception</literal>�j
+ �Q�Ɛ�̍s���Ȃ��O���L�[��ǂ̂悤�Ɉ�������w�肵�܂��B
+ <literal>ignore</literal> �ɂ���ƁA�s���Ȃ����Ƃ�֘A��������̂Ƃ��Ĉ����܂��B
+ </para>
+ </callout>
+ <callout arearefs="manytomany7">
+ <para>
+ <literal>entity-name</literal> �i�I�v�V�����j:
+ <literal>class</literal> �̑�ւł���֘A�N���X�̃G���e�B�e�B���B
+ <literal>class</literal> �̑���Ɏw�肷��A�֘A�N���X�̃G���e�B�e�B���B
+ </para>
+ </callout>
+ <callout arearefs="manytomany8">
+ <para>
+ <literal>property-ref</literal>: �i�I�v�V�����j
+ ���̊O���L�[�Ɍ�������֘A�N���X�̃v���p�e�B���B
+ �w�肵�Ȃ������ꍇ�́A�֘A�N���X�̎�L�[��g���܂��B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ �ȉ��ɂ�����������܂��B
+ �܂���String��set�Ɋւ��Ă̗�ł��B
+ </para>
+
+ <programlisting><![CDATA[<set name="names" table="person_names">
+ <key column="person_id"/>
+ <element column="person_name" type="string"/>
+</set>]]></programlisting>
+
+ <para>
+ �����l��܂�bag�ibag�� <literal>order-by</literal> �����ɂ���Ĕ�����������`����Ă��܂��j
+ </para>
+
+ <programlisting><![CDATA[<bag name="sizes"
+ table="item_sizes"
+ order-by="size asc">
+ <key column="item_id"/>
+ <element column="size" type="integer"/>
+</bag>]]></programlisting>
+
+ <para>
+ �G���e�B�e�B�̔z�� - ���̏ꍇ�A���Α��̊֘A�ł��B
+ </para>
+
+ <programlisting><![CDATA[<array name="addresses"
+ table="PersonAddress"
+ cascade="persist">
+ <key column="personId"/>
+ <list-index column="sortOrder"/>
+ <many-to-many column="addressId" class="Address"/>
+</array>]]></programlisting>
+
+ <para>
+ ������Ɠ��t��map
+ </para>
+
+ <programlisting><![CDATA[<map name="holidays"
+ table="holidays"
+ schema="dbo"
+ order-by="hol_name asc">
+ <key column="id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ �R���|�[�l���g��list�i���̏͂ŏڂ���������܂��j
+ </para>
+
+ <programlisting><![CDATA[<list name="carComponents"
+ table="CarComponents">
+ <key column="carId"/>
+ <list-index column="sortOrder"/>
+ <composite-element class="CarComponent">
+ <property name="price"/>
+ <property name="type"/>
+ <property name="serialNumber" column="serialNum"/>
+ </composite-element>
+</list>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="collections-onetomany">
+ <title>��Α��֘A</title>
+
+ <para>
+ <emphasis>��Α��֘A</emphasis> �́A�R���N�V������e�[�u�������A
+ �O���L�[�ɂ��2�̃N���X�̃e�[�u����֘A�t���܂��B
+ ���̃}�b�s���O�͕W���I��Java�̃R���N�V�����̃Z�}���e�B�N�X�����������܂��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ �G���e�B�e�B�N���X�̃C���X�^���X�́A
+ 2�ȏ�̃R���N�V�����̃C���X�^���X�ɑ����Ă͂����܂���B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �R���N�V�����Ɋ܂܂��G���e�B�e�B�N���X�̃C���X�^���X�́A
+ �R���N�V�����C���f�b�N�X�̒l�Ƃ���2�x�ȏ㌻��Ă͂����܂���B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>Product</literal> ���� <literal>Part</literal> �ւ̊֘A�́A
+ <literal>Part</literal> �e�[�u���ւ̊O���L�[�J�����ƁA�ꍇ�ɂ���Ă̓C���f�b�N�X�J�������K�v�ł��B
+ <literal><one-to-many></literal> �^�O�́A���ꂪ��Α��֘A�ł��邱�Ƃ�\���Ă��܂��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="onetomany1" coords="2 60"/>
+ <area id="onetomany2" coords="3 60"/>
+ <area id="onetomany3" coords="4 60"/>
+ </areaspec>
+ <programlisting><![CDATA[<one-to-many
+ class="ClassName"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ node="element-name"
+ embed-xml="true|false"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="onetomany1">
+ <para>
+ <literal>class</literal> �i�K�{�j: �֘A�N���X�̖��O�B
+ </para>
+ </callout>
+ <callout arearefs="onetomany2">
+ <para>
+ <literal>not-found</literal> �i�I�v�V���� - �f�t�H���g�� <literal>exception</literal>�j:
+ �Q�Ɛ�̍s���Ȃ��L���b�V�����ꂽ���ʎq��ǂ̂悤�Ɉ�������w�肵�܂��B
+ <literal>ignore</literal> ��w�肷��ƁA�s���Ȃ����Ƃ�֘A���Ȃ���̂Ƃ��Ĉ����܂��B
+ </para>
+ </callout>
+ <callout arearefs="onetomany3">
+ <para>
+ <literal>entity-name</literal> �i�I�v�V�����j:
+ <literal>class</literal> �̑�ւł���֘A�N���X�̃G���e�B�e�B���B
+ <literal>class</literal> �̑���Ɏw�肷��A�֘A�N���X�̃G���e�B�e�B���B
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ <literal><one-to-many></literal> �v�f�̓J������錾����K�v���Ȃ����Ƃɒ��ӂ��Ă��������B
+ ���l�� <literal>�e�[�u��</literal> ����w�肷��K�v�����܂���B
+ </para>
+
+ <para>
+ <emphasis>�ƂĂ�d�v�Ȓ���:</emphasis> ��� <literal><one-to-many></literal>
+ �֘A�̊O���L�[�J������ <literal>NOT NULL</literal>�Ɛ錾���ꂽ�ꍇ�A
+ <literal><key></literal> �}�b�s���O�� <literal>not-null="true"</literal> ��錾���邩�A
+ �R���N�V�����}�b�s���O�� <literal>inverse="true"</literal> ��t������ŁA
+ <emphasis>�o�����֘A��g��</emphasis> �K�v������܂��B
+ �o�����֘A�ɂ��Ă͂��̏͂̌�̂ق��Ő�����܂��B
+ </para>
+
+ <para>
+ ���̗�́A���́i<literal>Part</literal> �̉i���I�ȃv���p�e�B�ł��� <literal>partName</literal>�j
+ �ɂ�� <literal>Part</literal> �G���e�B�e�B��map��\���Ă��܂��B
+ formula�ɂ��C���f�b�N�X��g���Ă��邱�Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <programlisting><![CDATA[<map name="parts"
+ cascade="all">
+ <key column="productId" not-null="true"/>
+ <map-key formula="partName"/>
+ <one-to-many class="Part"/>
+</map>]]></programlisting>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="collections-advancedmappings">
+ <title>���x�ȃR���N�V������}�b�s���O</title>
+
+ <sect2 id="collections-sorted" revision="2">
+ <title>�\�[�g���ꂽ�R���N�V����</title>
+
+ <para>
+ Hibernate�� <literal>java.util.SortedMap</literal> �� <literal>java.util.SortedSet</literal>
+ ����������R���N�V������T�|�[�g���Ă��܂��B
+ �J���҂̓}�b�s���O��`�t�@�C���ɃR���p���[�^��w�肵�Ȃ���Ȃ�܂���B
+ </para>
+
+ <programlisting><![CDATA[<set name="aliases"
+ table="person_aliases"
+ sort="natural">
+ <key column="person"/>
+ <element column="name" type="string"/>
+</set>
+
+<map name="holidays" sort="my.custom.HolidayComparator">
+ <key column="year_id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ <literal>sort</literal> �����ɐݒ�ł���l�� <literal>unsorted</literal> �� <literal>natural</literal>
+ ����сA<literal>java.util.Comparator</literal> ����������N���X�̖��O�ł��B
+ </para>
+
+ <para>
+ �\�[�g���ꂽ�R���N�V�����͎����I�ɂ� <literal>java.util.TreeSet</literal> ��
+ <literal>java.util.TreeMap</literal> �̂悤�ɐU�����܂��B
+ </para>
+
+ <para>
+ ����f�[�^�x�[�X���g�ɃR���N�V�����̗v�f����ׂ��������Ȃ�A
+ <literal>set</literal> �� <literal>bag</literal>�A<literal>map</literal> ��
+ <literal>order-by</literal> ������g���܂��B
+ ���̉��@��JDK1.4�A������͂���ȏ�̃o�[�W�����ŗ��p�\�ł�
+ �i<literal>LinkedHashSet</literal> �܂��� <literal>LinkedHashMap</literal>��g���Ď�������Ă��܂��j�B
+ ����̓�������ł͂Ȃ��ASQL�N�G����Ŏ��s����܂��B
+ </para>
+
+ <programlisting><![CDATA[<set name="aliases" table="person_aliases" order-by="lower(name) asc">
+ <key column="person"/>
+ <element column="name" type="string"/>
+</set>
+
+<map name="holidays" order-by="hol_date, hol_name">
+ <key column="year_id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ <literal>order-by</literal> �����̒l��SQL���߂ł����āAHQL���߂ł͂Ȃ����Ƃɒ��ӂ��Ă��������I
+ </para>
+
+ <para>
+ �֘A�́A�R���N�V������ <literal>filter()</literal> ��g�����ƂŁA
+ ���s���ɔC�ӂ�criteria�ɂ���ă\�[�g���邱�Ƃ�\�ł��B
+ </para>
+
+ <programlisting><![CDATA[sortedUsers = s.createFilter( group.getUsers(), "order by this.name" ).list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="collections-bidirectional" revision="1">
+ <title>�o�����֘A</title>
+
+ <para>
+ <emphasis>�o�����֘A</emphasis> �͊֘A�̂ǂ���u���v����ł�i�r�Q�[�V�����ł��܂��B
+ 2��ނ̑o�����֘A���T�|�[�g����Ă��܂��B
+
+ <variablelist>
+ <varlistentry>
+ <term>one-to-many</term>
+ <listitem>
+ <para>
+ �Б���set��bag�A����Е����P��l�ł��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>many-to-many</term>
+ <listitem>
+ <para>
+ ������set��bag�ł��B
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+
+ <para>
+ 2�̑��Α��֘A�œ����f�[�^�x�[�X�e�[�u����}�b�s���O���A
+ �Е��� <emphasis>inverse</emphasis> �Ƃ��Đ錾���邱�ƂŁA
+ �o�����̑��Α��֘A��w�肷�邱�Ƃ��o���܂�
+ �i�ǂ����inverse�ɑI�Ƃ��Ă�A�����瑤�ɂ̓C���f�b�N�X�t���̃R���N�V�����͎g���܂���j�B
+ </para>
+
+ <para>
+ ���ɑo�����̑��Α��֘A�̗�����܂��B
+ �e�J�e�S���͑����̃A�C�e�������Ƃ��ł��A�e�A�C�e���͑����̃J�e�S���ɑ����邱�Ƃ��o���܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Category">
+ <id name="id" column="CATEGORY_ID"/>
+ ...
+ <bag name="items" table="CATEGORY_ITEM">
+ <key column="CATEGORY_ID"/>
+ <many-to-many class="Item" column="ITEM_ID"/>
+ </bag>
+</class>
+
+<class name="Item">
+ <id name="id" column="ITEM_ID"/>
+ ...
+
+ <!-- inverse end -->
+ <bag name="categories" table="CATEGORY_ITEM" inverse="true">
+ <key column="ITEM_ID"/>
+ <many-to-many class="Category" column="CATEGORY_ID"/>
+ </bag>
+</class>]]></programlisting>
+
+ <para>
+ �֘A��inverse���ɂ̂ݍs��ꂽ�ύX�͉i���� <emphasis>����܂���</emphasis>�B
+ ����́AHibernate�͑S�Ă̑o�����֘A�ɂ��āA��������ɂQ�̕\�������Ă���Ƃ����Ӗ��ł��B
+ �܂���A����B�ւ̃����N�ŁA������B����A�ւ̃����N�Ƃ������Ƃł��B
+ Java�̃I�u�W�F�N�g���f���ɂ��čl���AJava�őo�����W��ǂ�����č�邩��l����A
+ ����͗����₷���ł��B���L�ɁAJava�ł̑o�����֘A�����܂��B
+ </para>
+
+ <programlisting><![CDATA[
+category.getItems().add(item); // The category now "knows" about the relationship
+item.getCategories().add(category); // The item now "knows" about the relationship
+
+session.persist(item); // The relationship won't be saved!
+session.persist(category); // The relationship will be saved]]></programlisting>
+
+ <para>
+ �֘A��inverse�ł͂Ȃ����́A��������̕\����f�[�^�x�[�X�ɕۑ�����̂Ɏg���܂��B
+ </para>
+
+ <para>
+ �o�����̈�Α��֘A���`����ɂ́A
+ ��Α��֘A�𑽑Έ�֘A�Ɠ����e�[�u���̃J�����Ƀ}�b�s���O���A
+ ������ <literal>inverse="true"</literal> �Ɛ錾���܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ �֘A�̕Б��� <literal>inverse="true"</literal> ��ݒ肵�Ă�A
+ �J�X�P�[�h����ɉe����^���܂���B�����͒������T�O�ł��I
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-indexedbidirectional">
+ <title>�C���f�b�N�X�t���R���N�V�����Ƒo�����֘A</title>
+ <para>
+ �Б��� <literal><list></literal> �� <literal><map></literal> �ł���
+ �o�����֘A�́A���ɂ悭�l����K�v������܂��B
+ �C���f�b�N�X�J�����Ƀ}�b�v�����q�N���X�̃v���p�e�B������ꍇ�́A���Ȃ��ł��B
+ �R���N�V�����̃}�b�s���O�� <literal>inverse="true"</literal> ��g���������܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <map name="children" inverse="true">
+ <key column="parent_id"/>
+ <map-key column="name"
+ type="string"/>
+ <one-to-many class="Child"/>
+ </map>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <property name="name"
+ not-null="true"/>
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ �������A�q�N���X�ɂ��̂悤�ȃv���p�e�B���Ȃ��ꍇ�́A
+ �֘A��^�ɑo�����ł���ƍl���邱�Ƃ��ł��܂���
+ �i�֘A�̕Б��ɗ��p�ł�������܂����A�������ɂ͂���܂���j�B
+ ���̏ꍇ�́A�R���N�V������ <literal>inverse="true"</literal> ��}�b�s���O�ł��܂���B
+ ����ɁA���̂悤�ȃ}�b�s���O���g���܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <map name="children">
+ <key column="parent_id"
+ not-null="true"/>
+ <map-key column="name"
+ type="string"/>
+ <one-to-many class="Child"/>
+ </map>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ insert="false"
+ update="false"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ ���ӁF ���̃}�b�s���O�ł́A�֘A�̃R���N�V�����l�̑��́A
+ �O���L�[��A�b�v�f�[�g����ӔC������܂��B
+ <!-- TODO: Does this really result in some unnecessary update statements? -->
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-ternary">
+ <title>3���֘A</title>
+
+ <para>
+ 3���֘A�̃}�b�s���O�ɂ�3�̃A�v���[�`������܂��B
+ 1�ڂ͊֘A��C���f�b�N�X�Ƃ��� <literal>Map</literal> ��g�p����A�v���[�`�ł��B
+ </para>
+
+ <programlisting><![CDATA[<map name="contracts">
+ <key column="employer_id" not-null="true"/>
+ <map-key-many-to-many column="employee_id" class="Employee"/>
+ <one-to-many class="Contract"/>
+</map>]]></programlisting>
+
+ <programlisting><![CDATA[<map name="connections">
+ <key column="incoming_node_id"/>
+ <map-key-many-to-many column="outgoing_node_id" class="Node"/>
+ <many-to-many column="connection_id" class="Connection"/>
+</map>]]></programlisting>
+
+ <para>
+ 2�ڂ͒P���Ɋ֘A��G���e�B�e�B��N���X�Ƃ��ă��f�����蒼���A�v���[�`�ŁA
+ �p�ɂɎg���܂��B
+ </para>
+
+ <para>
+ �Ō��composite�v�f��g���A�v���[�`�ł��B����Ɋւ���c�_�͌�قǍs���܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-idbag" revision="1">
+ <title><literal><idbag></literal>�̎g�p</title>
+
+ <para>
+ �����L�[�͈�����̂ŁA�G���e�B�e�B�͐l�H�̎��ʎq(�㗝�L�[)���ׂ��ł���Ƃ����l��������́A
+ ���Α��֘A�ƒl�̃R���N�V�������L�[��p�����e�[�u���փ}�b�s���O����̂͏�����Ɋ����邩�����܂���I
+ �m���ɂ��̍l�����ɂ͋c�_�̗]�n������܂��B
+ �����Ȋ֘A�e�[�u���͑㗝�L�[��g���Ă���v���Ȃ��悤�Ɏv���邩��ł�
+ �i�����l�̃R���N�V�����͗��v������ <emphasis>����</emphasis> ����܂��j�B
+ �Ƃ͂����AHibernate�͑㗝�L�[���e�[�u���֑��Α��֘A�ƒl�̃R���N�V������
+ �}�b�s���O����@�\������Ă��܂��B
+ </para>
+
+ <para>
+ bag�̃Z�}���e�B�b�N�X������ <literal>List</literal>�i�܂��� <literal>Collection</literal>�j��
+ <literal><idbag></literal> �v�f�Ƀ}�b�s���O�ł��܂��B
+ </para>
+
+<programlisting><![CDATA[<idbag name="lovers" table="LOVERS">
+ <collection-id column="ID" type="long">
+ <generator class="sequence"/>
+ </collection-id>
+ <key column="PERSON1"/>
+ <many-to-many column="PERSON2" class="Person" fetch="join"/>
+</idbag>]]></programlisting>
+
+ <para>
+ �����m�̂悤�� <literal><idbag></literal> �̓G���e�B�e�B��N���X�̂悤��
+ �l�H�I��id�W�F�l���[�^�����Ă��܂��I
+ �قȂ�㗝�L�[���ꂼ��̃R���N�V�����̗�Ɋ��蓖�Ă܂��B
+ �������Ȃ���AHibernate�͂���s�̑㗝�L�[�̒l�����o���@�\�����Ă��܂���B
+ </para>
+
+ <para>
+ <literal><idbag></literal> ��X�V����p�t�H�[�}���X��
+ �ʏ�� <literal><bag></literal> ����ǂ����Ƃɒ��ڂ��Ă��������I
+ Hibernate�͌X�̍s����ʓI�Ɍ����邱�Ƃ��ł��A
+ list��map�Aset�̂悤�Ɍʂɂ��̍s��X�V�A�폜�ł��܂��B
+ </para>
+
+ <para>
+ ���݂̎����ł́A<literal>native</literal> �Ƃ���id�����헪��
+ <literal><idbag></literal> �R���N�V�����̎��ʎq�ɑ��Ďg���܂���B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <!--undocumenting this stuff -->
+
+ <!--sect1 id="collections-heterogeneous">
+ <title>Heterogeneous Associations</title>
+
+ <para>
+ The <literal><many-to-any></literal> and <literal><index-many-to-any></literal>
+ elements provide for true heterogeneous associations. These mapping elements work in the
+ same way as the <literal><any></literal> element - and should also be used
+ rarely, if ever.
+ </para>
+
+ </sect1-->
+
+ <sect1 id="collections-example" revision="1">
+ <title>�R���N�V�����̗�</title>
+
+ <para>
+ ����܂ł̐߂̐���ł͗����ɂ����̂ŁA�ȉ��̗���Ă��������B
+ </para>
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+
+public class Parent {
+ private long id;
+ private Set children;
+
+ public long getId() { return id; }
+ private void setId(long id) { this.id=id; }
+
+ private Set getChildren() { return children; }
+ private void setChildren(Set children) { this.children=children; }
+
+ ....
+ ....
+}]]></programlisting>
+
+ <para>
+ ���̃N���X�� <literal>Child</literal> �C���X�^���X�̃R���N�V���������Ă��܂��B
+ ����e�X��child���ő�ł���parent�����Ă���Ȃ�A�ł���R�ȃ}�b�s���O�͈�Α��֘A�ł��B
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ ����͈ȉ��̃e�[�u����`�Ƀ}�b�s���O���܂��B
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null primary key, name varchar(255), parent_id bigint )
+alter table child add constraint childfk0 (parent_id) references parent]]></programlisting>
+
+ <para>
+ ���parent�� <emphasis>�v��</emphasis> �����Ȃ�A�o�����̈�Α��֘A��g�p���Ă��������B
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ <many-to-one name="parent" class="Parent" column="parent_id" not-null="true"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>NOT NULL</literal> ����ɒ��ӂ��Ă��������B
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null
+ primary key,
+ name varchar(255),
+ parent_id bigint not null )
+alter table child add constraint childfk0 (parent_id) references parent]]></programlisting>
+
+ <para>
+ ���邢�́A������̊֘A�͒P�����ł���ׂ��Ƌ����咣����̂ł���A
+ <literal><key></literal> �� <literal>NOT NULL</literal> �����錾�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children">
+ <key column="parent_id" not-null="true"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ ����ŁA���child��������parent���Ă�Ȃ�A���Α��֘A���Ó��ł��B
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children" table="childset">
+ <key column="parent_id"/>
+ <many-to-many class="Child" column="child_id"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ �e�[�u����`�͈ȉ��̂悤�ɂȂ�܂��B
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null primary key, name varchar(255) )
+create table childset ( parent_id bigint not null,
+ child_id bigint not null,
+ primary key ( parent_id, child_id ) )
+alter table childset add constraint childsetfk0 (parent_id) references parent
+alter table childset add constraint childsetfk1 (child_id) references child]]></programlisting>
+
+ <para>
+ parent/child�W�̃}�b�s���O�ɂ��Ă̂�葽���̗�⊮�S�Ȏ菇���K�v�ł���A
+ <xref linkend="example-parentchild"/> �������������B
+ </para>
+
+ <para>
+ �܂��A����ɓ���Ȋ֘A�}�b�s���O��\�ł��B���̏͂ŏڂ����q�ׂ܂��B
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/component_mapping.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/component_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/component_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/component_mapping.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,396 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="components">
+ <title>�R���|�[�l���g�̃}�b�s���O</title>
+
+ <para>
+ <emphasis>�R���|�[�l���g</emphasis> �̊T�O�́AHibernate��ʂ��ėl�X�ȏ̒���
+ �قȂ�ړI�̂��߂ɍė��p����܂��B
+ </para>
+
+ <sect1 id="components-dependentobjects" revision="2" >
+ <title>�ˑ��I�u�W�F�N�g</title>
+
+ <para>
+ �R���|�[�l���g�́A�G���e�B�e�B�̎Q�Ƃł͂Ȃ��l�^�Ƃ��ĉi�������ꂽ�A
+ ��܂��ꂽ�I�u�W�F�N�g�ł��B�R���|�[�l���g�Ƃ������t�ɂ��ẮA�R���|�W�V�����Ƃ���
+ �I�u�W�F�N�g�w���̊T�O��Q�Ƃ��Ă��������i�A�[�L�e�N�`�����x���̃R���|�[�l���g�ł͂���܂���j�B
+ �Ⴆ�A�ȉ���Person���f���̂悤�Ȃ�̂ł��B
+ </para>
+
+ <programlisting><![CDATA[public class Person {
+ private java.util.Date birthday;
+ private Name name;
+ private String key;
+ public String getKey() {
+ return key;
+ }
+ private void setKey(String key) {
+ this.key=key;
+ }
+ public java.util.Date getBirthday() {
+ return birthday;
+ }
+ public void setBirthday(java.util.Date birthday) {
+ this.birthday = birthday;
+ }
+ public Name getName() {
+ return name;
+ }
+ public void setName(Name name) {
+ this.name = name;
+ }
+ ......
+ ......
+}]]></programlisting>
+
+<programlisting><![CDATA[public class Name {
+ char initial;
+ String first;
+ String last;
+ public String getFirst() {
+ return first;
+ }
+ void setFirst(String first) {
+ this.first = first;
+ }
+ public String getLast() {
+ return last;
+ }
+ void setLast(String last) {
+ this.last = last;
+ }
+ public char getInitial() {
+ return initial;
+ }
+ void setInitial(char initial) {
+ this.initial = initial;
+ }
+}]]></programlisting>
+
+ <para>
+ ���܁A<literal>Name</literal> �� <literal>Person</literal> �̃R���|�[�l���g�Ƃ���
+ �i�������邱�Ƃ��o���܂��B������ <literal>Name</literal> �͉i���������ɑ���getter�A
+ setter���\�b�h���`���܂����A�C���^�[�t�F�C�X�⎯�ʎq�v���p�e�B���`����K�v��
+ �Ȃ����Ƃɒ��ӂ��ĉ������B
+ </para>
+
+ <para>
+ �}�b�s���O��`�͈ȉ��̂悤�ɂȂ�܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Person" table="person">
+ <id name="Key" column="pid" type="string">
+ <generator class="uuid"/>
+ </id>
+ <property name="birthday" type="date"/>
+ <component name="Name" class="eg.Name"> <!-- class attribute optional -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </component>
+</class>]]></programlisting>
+
+ <para>
+ Person�e�[�u���� <literal>pid</literal>�A
+ <literal>birthday</literal>�A
+ <literal>initial</literal>�A
+ <literal>first</literal>�A
+ <literal>last</literal> �J���������܂��B
+ </para>
+
+ <para>
+ �S�Ă̒l�^�̂悤�ɁA�R���|�[�l���g�͎Q�Ƃ̋��L���邱�Ƃ��ł��܂���B
+ ����������ƁA��l��Person�͓������O�����Ƃ��ł��܂����A���Person�I�u�W�F�N�g��
+ "�l����������"�̕ʁX��name�I�u�W�F�N�g��܂�ł���Ƃ������Ƃł��B
+ �R���|�[�l���g��null�l�̃Z�}���e�B�N�X�� <emphasis>�A�h�z�b�N</emphasis> �ł��B
+ �R���|�[�l���g�̃I�u�W�F�N�g��ēǂݍ��݂���ہAHibernate�̓R���|�[�l���g�̂��ׂẴJ������
+ null�ł���Ȃ�R���|�[�l���g���̂�null�ł���ƍl���܂��B
+ ����͑��̏ꍇ��肠��܂���B
+
+ </para>
+
+ <para>
+ �R���|�[�l���g�̑����͂ǂ��Hibernate�̌^�ł�\���܂���i�R���N�V�����Amany-to-one�֘A�A
+ ���̃R���|�[�l���g�Ȃǁj�B�l�X�g���ꂽ�R���|�[�l���g�͖ő��Ɏg��Ȃ��ƍl����ׂ��ł�
+ <emphasis>����܂���</emphasis> �BHibernate�͔��ɂ��߂ׂ̍����I�u�W�F�N�g���f����T�|�[�g����悤�ɈӐ}����Ă��܂��B
+ </para>
+
+ <para>
+ <literal><component></literal> �v�f�͐e�G���e�B�e�B�ւ̋t�Q�ƂƂ��āA�R���|�[�l���g�N���X��
+ ������}�b�s���O���� <literal><parent></literal> �T�u�v�f��g�p�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Person" table="person">
+ <id name="Key" column="pid" type="string">
+ <generator class="uuid"/>
+ </id>
+ <property name="birthday" type="date"/>
+ <component name="Name" class="eg.Name" unique="true">
+ <parent name="namedPerson"/> <!-- reference back to the Person -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </component>
+</class>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="components-incollections" revision="1">
+
+ <title>�]������I�u�W�F�N�g�̃R���N�V����</title>
+
+ <para>
+ Hibernate�̓R���|�[�l���g�̃R���N�V������T�|�[�g���Ă��܂��i�Ⴆ�� <literal>Name</literal> �^�̔z��j�B
+ <literal><element></literal> �^�O�� <literal><composite-element></literal> �^�O�Ɏ��ւ��邱�Ƃɂ��
+ �R���|�[�l���g�R���N�V������錾���Ă��������B
+ </para>
+
+ <programlisting><![CDATA[<set name="someNames" table="some_names" lazy="true">
+ <key column="id"/>
+ <composite-element class="eg.Name"> <!-- class attribute required -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </composite-element>
+</set>]]></programlisting>
+
+ <para>
+ ����: �R���|�W�b�g�G�������g�� <literal>Set</literal> ���`�����Ȃ�A
+ <literal>equals()</literal> �� <literal>hashCode()</literal> �𐳂����������邱�Ƃ��d�v�ł��B
+ </para>
+
+ <para>
+ �R���|�W�b�g�G�������g�̓R���N�V������܂܂��A�R���|�[�l���g��܂ނ��Ƃ����܂��B
+ �R���|�W�b�g�G�������g���g���R���|�[�l���g��܂�ł���ꍇ�� <literal><nested-composite-element></literal> ��
+ �g�p���Ă��������B�R���|�[�l���g�̃R���N�V�������g���R���|�[�l���g���Ƃ����P�[�X�͂߂����ɂ���܂���B
+ ���̒i�K�܂łɁAone-to-many�֘A�̕������K�łȂ����Ən�l���Ă��������B
+ �R���|�W�b�g�G�������g��G���e�B�e�B�Ƃ��čēx���f�����O���Ă݂Ă��������B
+ �����������Java�̃��f���Ƃ��Ă͓����ł����A�����[�V���i�����f���Ɖi������͂܂���قȂ邱�Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ ��� <literal><set></literal> ��g�p����̂ł���A�R���|�W�b�g�G�������g�̃}�b�s���O��null�l���\��
+ ������T�|�[�g���Ă��Ȃ����Ƃɒ��ӂ��Ă��������BHibernate�̓I�u�W�F�N�g��폜����Ƃ��A
+ ���R�[�h���ʂ��邽�߂ɂ��ꂼ��̃J�����̒l��g�p����K�v�����邽�߁Anull�l�����Ƃ��o���܂���
+ �i�R���|�W�b�g�G�������g�e�[�u���ɂ͕ʂ̎�L�[�J�����͂���܂���j�B
+ �R���|�W�b�g�G�������g��not-null�̑����݂̂�g�p���邩�A�܂��� <literal><list></literal>�A<literal><map></literal>�A
+ <literal><bag></literal>�A<literal><idbag></literal> ��I����K�v������܂��B
+ </para>
+
+ <para>
+ �R���|�W�b�g�G�������g�̓��ʂȃP�[�X�Ƃ��āA�l�X�g���ꂽ <literal><many-to-one></literal> ��������
+ �R���|�W�b�g�G�������g������܂��B
+ ���̃}�b�s���O�́A�R���|�W�b�g�G�������g�N���X�𑽑Α��֘A�e�[�u����
+ �]���ȃJ�����փ}�b�s���O���܂��B
+ ���̗�� <literal>Order</literal> ����A<literal>Item</literal> �ւ̑��Α��֘A�ł��B
+ <literal>purchaseDate</literal>�A<literal>price</literal>�A<literal>quantity</literal> �͊֘A�̑����ƂȂ�܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Order" .... >
+ ....
+ <set name="purchasedItems" table="purchase_items" lazy="true">
+ <key column="order_id">
+ <composite-element class="eg.Purchase">
+ <property name="purchaseDate"/>
+ <property name="price"/>
+ <property name="quantity"/>
+ <many-to-one name="item" class="eg.Item"/> <!-- class attribute is optional -->
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ ������A�o�����֘A�̃i�r�Q�[�V�����̂��߂ɔ��Α�����purchase�ւ̎Q�Ƃ��邱�Ƃ͏o���܂���B
+ �R���|�[�l���g�͒l�^�ł���A�Q�Ƃ��L�ł��Ȃ����Ƃ�o���Ă����Ă��������B
+ ��� <literal>Purchase</literal> �͈�� <literal>Order</literal> ��set�ɑ��݂ł��܂����A
+ ������ <literal>Item</literal> ����Q�Ƃ��邱�Ƃ͏o���܂���B
+ </para>
+
+ <para>
+ 3���֘A�i���邢��4���Ȃǁj��\�ł��B
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Order" .... >
+ ....
+ <set name="purchasedItems" table="purchase_items" lazy="true">
+ <key column="order_id">
+ <composite-element class="eg.OrderLine">
+ <many-to-one name="purchaseDetails" class="eg.Purchase"/>
+ <many-to-one name="item" class="eg.Item"/>
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ �R���|�W�b�g�G�������g�͑��̃G���e�B�e�B�ւ̊֘A�Ƃ��āA
+ �����V���^�b�N�X��g���Ă���N�G����Ŏg�p�ł��܂��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="components-asmapindex">
+ <title>Map�̃C���f�b�N�X�Ƃ��ẴR���|�[�l���g</title>
+
+ <para>
+ <literal><composite-map-key></literal> �v�f�� <literal>Map</literal> �̃L�[�Ƃ��ăR���|�[�l���g�N���X��
+ �}�b�s���O���܂��B�R���|�[�l���g�N���X��� <literal>hashCode()</literal> �� <literal>equals()</literal>
+ �𐳊m�ɃI�[�o�[���C�h���Ă��������B
+ </para>
+ </sect1>
+
+ <sect1 id="components-compositeid" revision="1">
+ <title>�������ʎq�Ƃ��ẴR���|�[�l���g</title>
+
+ <para>
+ �R���|�[�l���g��G���e�B�e�B�N���X�̎��ʎq�Ƃ��Ďg�����Ƃ��ł��܂��B
+ �R���|�[�l���g�N���X�͈ȉ��̏������K�v������܂��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>java.io.Serializable</literal> ��������Ȃ���Ȃ�܂���B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �f�[�^�x�[�X��̕����L�[�̓������Ɩ����̂Ȃ��悤�ɁA<literal>equals()</literal>
+ �� <literal>hashCode()</literal> ��Ď������Ȃ���Ȃ�܂���B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <emphasis>����: Hibernate3�ɂ����āA2�Ԗڂ̏��͐�ΓI�ȏ��ł͂���܂���B
+ �������Ƃɂ����������Ă��������B
+ </emphasis>
+
+ </para>
+
+ <para>
+ �����L�[�����邽�߂� <literal>IdentifierGenerator</literal> ��g�p���邱�Ƃ͂ł��܂���B
+ ����ɃA�v���P�[�V���������ʎq���蓖�ĂȂ��Ă͂Ȃ�܂���B
+ </para>
+
+ <para>
+ �ʏ�� <literal><id></literal> �錾�̑���� <literal><composite-id></literal> �^�O��
+ �i�l�X�g���ꂽ <literal><key-property></literal> �����Ƌ��Ɂj�g���܂��B
+ �ȉ��̗�ł́A<literal>OrderLine</literal> �N���X�� <literal>Order</literal> �́i�����j��L�[��
+ �ˑ�������L�[�����Ă��܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="OrderLine">
+
+ <composite-id name="id" class="OrderLineId">
+ <key-property name="lineId"/>
+ <key-property name="orderId"/>
+ <key-property name="customerId"/>
+ </composite-id>
+
+ <property name="name"/>
+
+ <many-to-one name="order" class="Order"
+ insert="false" update="false">
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </many-to-one>
+ ....
+
+</class>]]></programlisting>
+
+ <para>
+ ���̂Ƃ��A<literal>OrderLine</literal> �e�[�u���֊֘A����O���L�[��܂������ł��B
+ ���̃N���X�̃}�b�s���O�ł����錾���Ȃ���Ȃ�܂���B
+ <literal>OrderLine</literal> �ւ̊֘A�͎��̂悤�Ƀ}�b�s���O����܂��B
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="orderLine" class="OrderLine">
+<!-- the "class" attribute is optional, as usual -->
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+</many-to-one>]]></programlisting>
+
+ <para>
+ �i<literal><column></literal> �^�O�͂ǂ��ł����Ă� <literal>column</literal> ������
+ ����ɂȂ�܂��B�j
+ </para>
+
+ <para>
+ <literal>OrderLine</literal> �ւ� <literal>many-to-many</literal> �֘A��
+ �����O���L�[��g���܂��B
+ </para>
+
+ <programlisting><![CDATA[<set name="undeliveredOrderLines">
+ <key column name="warehouseId"/>
+ <many-to-many class="OrderLine">
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </many-to-many>
+</set>]]></programlisting>
+
+ <para>
+ <literal>Order</literal> �ɂ��� <literal>OrderLine</literal> �̃R���N�V������
+ ���̂�̂�g�p���܂��B
+ </para>
+
+ <programlisting><![CDATA[<set name="orderLines" inverse="true">
+ <key>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </key>
+ <one-to-many class="OrderLine"/>
+</set>]]></programlisting>
+
+ <para>
+ �i<literal><one-to-many></literal> �����́A��ɂ���ăJ������錾���܂���j
+ </para>
+
+ <para>
+ <literal>OrderLine</literal> ���g���R���N�V���������Ă���ꍇ�A
+ �����ɕ����O���L�[������Ă��܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="OrderLine">
+ ....
+ ....
+ <list name="deliveryAttempts">
+ <key> <!-- a collection inherits the composite key type -->
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </key>
+ <list-index column="attemptId" base="1"/>
+ <composite-element class="DeliveryAttempt">
+ ...
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="components-dynamic" revision="1">
+ <title>���I�R���|�[�l���g</title>
+
+ <para>
+ <literal>Map</literal> �^�̃v���p�e�B�̃}�b�s���O��\�ł��B
+ </para>
+
+ <programlisting><![CDATA[<dynamic-component name="userAttributes">
+ <property name="foo" column="FOO" type="string"/>
+ <property name="bar" column="BAR" type="integer"/>
+ <many-to-one name="baz" class="Baz" column="BAZ_ID"/>
+</dynamic-component>]]></programlisting>
+
+ <para>
+ <literal><dynamic-component></literal> �}�b�s���O�̃Z�}���e�B�N�X�� <literal><component></literal>
+ �Ɠ���̂�̂ł��B���̎�̃}�b�s���O�̗��_�́A�}�b�s���O�h�L�������g�̕ҏW�ɂ��A�z�u����bean�̑�����
+ ����ł���_�ł��B�܂��ADOM�p�[�T�𗘗p���āA�}�b�s���O�h�L�������g�̃����^�C�����삪�\�ł��B
+ ����ɁA<literal>Configuration</literal> �I�u�W�F�N�g�o�R��Hibernate�̃R���t�B�O���[�V�������̃��^���f����
+ �A�N�Z�X�i�܂��͕ύX�j���\�ł��B
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/configuration.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/configuration.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/configuration.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/configuration.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,1725 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="session-configuration" revision="1">
+
+ <title>�ݒ�</title>
+
+ <para>
+ Hibernate�͂��܂��܂Ȋ��œ��삷��悤�Ƀf�U�C������Ă��邽�߁A���ɑ����̐ݒ�v�f������܂��B
+ �K���Ȃ��ƂɁAHibernate�́A���J����Ă���p�b�P�[�W�� <literal>etc/</literal> �t�H���_�� <literal>hibernate.properties</literal>
+ �ɁA�قƂ�ǂ̐ݒ�v�f�̓K�ȃf�t�H���g�l���L�q����Ă��܂��B
+ ���� <literal>hibernate.properties</literal> ��N���X�p�X�ɐݒ肵�A�ݒ�v�f��J�X�^�}�C�Y���邾���ł��B
+ </para>
+
+ <sect1 id="configuration-programmatic" revision="1">
+ <title>�v���O������̐ݒ�</title>
+
+ <para>
+ <literal>org.hibernate.cfg.Configuration</literal> �̃C���X�^���X�́A
+ Java�̌^��SQL�f�[�^�x�[�X�̃}�b�s���O�����ׂĎ����Ă��܂��B
+ The <literal>Configuration</literal> �́A�i�s�ς́j <literal>SessionFactory</literal>
+ ������Ƃ��Ɏg�p���܂��B
+ ������XML�}�b�s���O�t�@�C����ϊ����A�}�b�s���O���ɂ��܂��B
+ </para>
+
+ <para>
+ �ʏ�A<literal>Configuration</literal> �C���X�^���X�́A�����XML�}�b�s���O�t�@�C��
+ �ɂ���Ē��ڏ���������܂��B����A�}�b�s���O�t�@�C�����N���X�p�X�ɐݒ肳��Ă���ꍇ�A
+ ���̃��\�b�h��g���Ă��������B <literal>addResource()</literal> :
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addResource("Item.hbm.xml")
+ .addResource("Bid.hbm.xml");]]></programlisting>
+
+ <para>
+ ��ֈ�(������̂ق����ǂ��Ƃ������܂�)�Ƃ��ă}�b�s���O�N���X��w�肷����@�����܂��BHibernate�ɁA�}�b�s���O�t�@�C����
+ �����������������F
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addClass(org.hibernate.auction.Item.class)
+ .addClass(org.hibernate.auction.Bid.class);]]></programlisting>
+
+ <para>
+ Hibernate�́A�N���X�p�X�ɂ���ȉ��̂悤�Ȗ��O�̃}�b�s���O�t�@�C�������܂��B
+ <literal>/org/hibernate/auction/Item.hbm.xml</literal> �A
+ <literal>/org/hibernate/auction/Bid.hbm.xml</literal> �B
+ ���̕��@���ƁA�n�[�h�R�[�f�B���O���ꂽ�t�@�C������r���ł��܂��B
+ </para>
+
+ <para>
+ <literal>Configuration</literal> �́A�ݒ�v���p�e�B��w�肷�邱�Ƃ�ł��܂��F
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addClass(org.hibernate.auction.Item.class)
+ .addClass(org.hibernate.auction.Bid.class)
+ .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
+ .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
+ .setProperty("hibernate.order_updates", "true");]]></programlisting>
+
+ <para>
+ Hibernate�ɐݒ�v���p�e�B��ʂ����@��1�ł͂���܂���B
+ ���܂��܂ȃI�v�V������p�ӂ��Ă��܂��F
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>java.util.Properties</literal> �C���X�^���X��
+ <literal>Configuration.setProperties()</literal> �ɓn���܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>hibernate.properties</literal> ��
+ �N���X�p�X�̃��[�g�f�B���N�g���ɒu���܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>System</literal> �v���p�e�B��
+ <literal>java -Dproperty=value</literal> ��g���悤�ɐݒ肵�܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal><property></literal> �v�f��
+ <literal>hibernate.cfg.xml</literal> �i��q�j�ɐݒ肵�܂��B
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ �������n�߂����̂Ȃ�A<literal>hibernate.properties</literal>
+ ��g���̂���Ԃ̋ߓ��ł��B
+ </para>
+
+ <para>
+ <literal>Configuration</literal> �́A�N�����ɂ�������I�u�W�F�N�g�ł���A
+ ��x <literal>SessionFactory</literal> ��������́A�j������邱�Ƃ�Ӑ}���Ă��܂��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-sessionfactory">
+ <title>SessionFactory��擾����</title>
+
+ <para>
+ <literal>Configuration</literal> �����ׂẴ}�b�s���O�����͂�����A
+ �A�v���P�[�V�����́A <literal>Session</literal> �t�@�N�g���C���X�^���X��擾���܂��B
+ ����SessionFactory�́AHibernate��g�p���邷�ׂẴX���b�h�ŋ��L�����ׂ��ł��B
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sessions = cfg.buildSessionFactory();]]></programlisting>
+
+ <para>
+ Hibernate�́A <literal>SessionFactory</literal> ���������邱�Ƃ��ł��܂��B
+ ����́A�����̃f�[�^�x�[�X��g�p����ꍇ�ɕ֗��ł��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-hibernatejdbc" revision="1">
+ <title>JDBC�R�l�N�V����</title>
+
+ <para>
+ �ʏ�A�J���҂� <literal>SessionFactory</literal> �����ASessionFactory��JDBC�R�l�N�V������v�[�����O�������ƍl���܂��B
+ ���̃A�v���[�`��̗p����ꍇ�A�P���� <literal>Session</literal> ��I�[�v�����Ă��������F
+ </para>
+
+ <programlisting><![CDATA[Session session = sessions.openSession(); // open a new Session]]></programlisting>
+
+ <para>
+ ���ꂾ���ŁA�v�[�����O����JDBC�R�l�N�V������g���ĖړI�̃f�[�^�x�[�X
+ �ɃA�N�Z�X���邱�Ƃ��ł��܂��B
+ </para>
+
+ <para>
+ ���̂��߂ɂ́AJDBC�R�l�N�V�����̃v���p�e�B��Hibernate�ɐݒ肷��K�v������܂��B
+ ���ׂĂ�Hibernate�v���p�e�B���ƃZ�}���e�B�N�X��
+ <literal>org.hibernate.cfg.Environment</literal> �N���X�ɒ�`����Ă��܂��B
+ ���̐ݒ��JDBC�R�l�N�V�����ݒ�̒��ň�ԏd�v�Ȃ�̂ł��B
+ </para>
+
+ <para>
+ ����A�ȉ��̃v���p�e�B��ݒ肷��ƁAHibernate�̓R�l�N�V������擾����i�v�[����j���߂�
+ <literal>java.sql.DriverManager</literal> ��g���܂��B
+ </para>
+
+ <table frame="topbot">
+ <title>Hibernate JDBC�v���p�e�B</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>�v���p�e�B��</entry>
+ <entry>�Ӗ�</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.connection.driver_class</literal>
+ </entry>
+ <entry>
+ <emphasis>JDBC�h���C�o�N���X</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.url</literal>
+ </entry>
+ <entry>
+ <emphasis>jdbc URL</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.username</literal>
+ </entry>
+ <entry>
+ <emphasis>database user</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.password</literal>
+ </entry>
+ <entry>
+ <emphasis>database user password</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.pool_size</literal>
+ </entry>
+ <entry>
+ <emphasis>�v�[������R�l�N�V�����̍ő吔</emphasis>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Hibernate�̃R�l�N�V�����v�[���A���S���Y���͔��ɏ���I�Ȃ�̂ł��B
+ ����͂����Ɏn�߂���悤�ɂƗp�ӂ��ꂽ��̂ŁA<emphasis>���i�Ƃ��Ďg�p���邱�Ƃ�Ӑ}���Ă��܂���</emphasis> �B
+ �܂��A�p�t�H�[�}���X�̃e�X�g�̂��߂̂�̂ł����܂���B
+ �ō��̃p�t�H�[�}���X�ƈ��萫�������v�[���������������A�T�[�h�p�[�e�B�̃c�[�������߂��܂��B
+ <literal>hibernate.connection.pool_size</literal> �v���p�e�B��
+ �K�ȃR�l�N�V�����v�[���T�C�Y��L�q���Ă��������B
+ ���̂܂܂���Hibernate�̃R�l�N�V�����v�[����g���܂��B
+ �Ⴆ�Ύ��̂悤��C3P0��g���܂��B
+ </para>
+
+ <para>
+ C3P0�̓I�[�v���\�[�XJDBC�R�l�N�V�����v�[���ŁAHibernate�� <literal>lib</literal>
+ �f�B���N�g���ɂ���܂��B����A<literal>hibernate.c3p0.*</literal> �v���p�e�B��
+ �Z�b�g����AHibernate�́A <literal>C3P0ConnectionProvider</literal> ��g���܂��B
+ ���Proxool��g�������ꍇ�́A <literal>hibernate.properties</literal> �p�b�P�[�W��
+ �Q�Ƃ�����AHibernate��Web�T�C�g�ł�葽���̏���擾���Ă��������B
+ </para>
+
+ <para>
+ C3P0�p�� <literal>hibernate.properties</literal> �t�@�C�����Ƃ��Ď����܂��F
+ </para>
+
+ <programlisting id="c3p0-configuration" revision="1"><![CDATA[hibernate.connection.driver_class = org.postgresql.Driver
+hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
+hibernate.connection.username = myuser
+hibernate.connection.password = secret
+hibernate.c3p0.min_size=5
+hibernate.c3p0.max_size=20
+hibernate.c3p0.timeout=1800
+hibernate.c3p0.max_statements=50
+hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
+
+ <para>
+ �A�v���P�[�V�����T�[�o��Ŏg���ꍇ�́AHibernate��ݒ肵�A
+ �A�v���P�[�V�����T�[�o����R�l�N�V������擾����悤�ɂ��Ă��������B
+ <literal>Datasource</literal> ��JNDI�ɓo�^���܂��B������
+ �v���p�e�B��ȉ��̂悤�ɐݒ肵�Ă��������B
+ </para>
+
+ <table frame="topbot">
+ <title>Hibernate �f�[�^�\�[�X�v���p�e�B</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>�v���p�e�B��</entry>
+ <entry>�Ӗ�</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.connection.datasource</literal>
+ </entry>
+ <entry>
+ <emphasis>�f�[�^�\�[�X��JNDI��</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.url</literal>
+ </entry>
+ <entry>
+ <emphasis>JNDI�v���o�C�_��URL</emphasis> (�I�v�V����)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.class</literal>
+ </entry>
+ <entry>
+ <emphasis>JNDI�N���X <literal>InitialContextFactory</literal> </emphasis> (�I�v�V����)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.username</literal>
+ </entry>
+ <entry>
+ <emphasis>database user</emphasis> (�I�v�V����)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.password</literal>
+ </entry>
+ <entry>
+ <emphasis>database user password</emphasis> (�I�v�V����)
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ �A�v���P�[�V�����T�[�o������ꂽJNDI�f�[�^�\�[�X��g��
+ <literal>hibernate.properties</literal> �t�@�C���̗�����܂��F
+ </para>
+
+ <programlisting><![CDATA[hibernate.connection.datasource = java:/comp/env/jdbc/test
+hibernate.transaction.factory_class = \
+ org.hibernate.transaction.JTATransactionFactory
+hibernate.transaction.manager_lookup_class = \
+ org.hibernate.transaction.JBossTransactionManagerLookup
+hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
+
+ <para>
+ JNDI�f�[�^�\�[�X����擾����JDBC�R�l�N�V�����́A�A�v���P�[�V�����T�[�o��
+ �R���e�i�Ǘ��g�����U�N�V�����Ɏ����I�ɎQ�����܂��B
+ </para>
+
+ <para>
+ �C�ӂ̃R�l�N�V�����v���p�e�B�́A�^����ꂽ�h <literal>hibernate.connnection</literal> �h
+ �v���p�e�B���ɂ���ė^�����܂��B�Ⴆ�A <literal>charSet</literal> ��ݒ肵�����ꍇ�́A
+ <literal>hibernate.connection.charSet</literal> ��g���܂��B
+ </para>
+
+ <para>
+ JDBC�R�l�N�V������擾����헪���Ǝ��̃v���O�C�����`����ꍇ�́A
+ <literal>org.hibernate.connection.ConnectionProvider</literal> �C���^�[�t�F�C�X��
+ �������Ă��������B�����āA�����N���X�� <literal>hibernate.connection.provider_class</literal>
+ �ɐݒ肵�Ă��������B
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-optional" revision="1">
+ <title>�I�v�V�����ݒ�v���p�e�B</title>
+
+ <para>
+ �����̃v���p�e�B��Hibernate�̋����𐧌䂷���̂ł��B
+ �����̃v���p�e�B�͂��ׂđÓ��ȃf�t�H���g�l������A�C�ӂŐݒ肵�܂��B
+ </para>
+
+ <para>
+ <emphasis>���ӁF�����̃v���p�e�B��"�V�X�e�����x��"�݂̂ł��B</emphasis>
+ �V�X�e�����x���v���p�e�B�� <literal>java -Dproperty=value</literal> �A�������
+ <literal>hibernate.properties</literal> �ł̂ݐݒ�\�ł��B
+ ����ȊO�̐ݒ���@�� <emphasis>����܂���</emphasis> �B
+ </para>
+
+ <table frame="topbot" id="configuration-optional-properties" revision="8">
+ <title>Hibernate�ݒ�v���p�e�B</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>�v���p�e�B��</entry>
+ <entry>�Ӗ�</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.dialect</literal>
+ </entry>
+ <entry>
+ Hibernate <literal>Dialect</literal> �N���X��������܂��B
+ ����̓����[�V���i���f�[�^�x�[�X���ƂɍœK�����ꂽSQL�����܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>full.classname.of.Dialect</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.show_sql</literal>
+ </entry>
+ <entry>
+ ���s���ꂽ���ׂĂ�SQL��R���\�[���ɏo�͂��܂��B
+ ����̓��O�J�e�S���� <literal>org.hibernate.SQL</literal>
+ �� <literal>debug</literal> ��ݒ肷����@�̑�֎�i�ł��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.format_sql</literal>
+ </entry>
+ <entry>
+ ���O�ƃR���\�[����SQL��������\�����܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_schema</literal>
+ </entry>
+ <entry>
+ ���������SQL���̃e�[�u���ɐݒ肷��X�L�[�}/�e�[�u���X�y�[�X�ł��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>SCHEMA_NAME</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_catalog</literal>
+ </entry>
+ <entry>
+ ���������SQL���̃e�[�u���ɐݒ肷��J�^���O�ł��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>CATALOG_NAME</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.session_factory_name</literal>
+ </entry>
+ <entry>
+ <literal>SessionFactory</literal> �͐�����A���̖��O��JNDI�ɓo�^����܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>jndi/composite/name</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.max_fetch_depth</literal>
+ </entry>
+ <entry>
+ �O�������t�F�b�`�̍ő�[�x��ݒ肵�܂��B��������֘A��
+ �Έ�֘A�̂݁i��Έ�A���Έ�j�ł��B
+ <literal>0</literal> ��w�肷��ƊO�������t�F�b�`�͖����ɂȂ�܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ ��������l�� <literal>0</literal> ���� <literal>3</literal> �ł��B
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_batch_fetch_size</literal>
+ </entry>
+ <entry>
+ �֘A�t�F�b�`�̃f�t�H���g�o�b�`�T�C�Y��w�肵�܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ ��������l�� <literal>4</literal> , <literal>8</literal> , <literal>16</literal> �ł��B
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_entity_mode</literal>
+ </entry>
+ <entry>
+ <literal>SessionFactory</literal> ����Z�b�V������I�[�v�������Ƃ���
+ �g�p����G���e�B�e�B�̃f�t�H���g���[�h��ݒ肵�܂��B
+ <para>
+ <literal>dynamic-map</literal>, <literal>dom4j</literal>,
+ <literal>pojo</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.order_updates</literal>
+ </entry>
+ <entry>
+ ���ڂ��X�V���ꂽ�Ƃ��ɁA�ʂ�SQL�Ŏ�L�[��X�V���邱�Ƃ������܂��B
+ ���̏ꍇ�A�������s�\�ȃV�X�e���ł́A�܂�Ƀf�b�h���b�N����������\��������܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.generate_statistics</literal>
+ </entry>
+ <entry>
+ �L���̏ꍇ�AHibernate�̓p�t�H�[�}���X�`���[�j���O��
+ �L���ȓ��v������W���܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.use_identifer_rollback</literal>
+ </entry>
+ <entry>
+ �L���̏ꍇ�A�I�u�W�F�N�g���폜���ꂽ�Ƃ���
+ ���ʎq�v���p�e�B���Z�b�g���A�f�t�H���g�l�ɂ�����̂����܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.use_sql_comments</literal>
+ </entry>
+ <entry>
+ �L���̏ꍇ�ASQL��ɃR�����g�����܂��B����̓f�o�b�N��e�Ղɂ��܂��B
+ �f�t�H���g�̒l�� <literal>false</literal> �ł��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-jdbc-properties" revision="8">
+ <title>Hibernate JDBC �ƃR�l�N�V�����v���p�e�B</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>�v���p�e�B��</entry>
+ <entry>�Ӗ�</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.fetch_size</literal>
+ </entry>
+ <entry>
+ �l��0�łȂ��ꍇ�AJDBC�t�F�b�`�T�C�Y���肵�܂�
+ ( <literal>Statement.setFetchSize()</literal> ��Ăт܂�)�B
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.batch_size</literal>
+ </entry>
+ <entry>
+ �l��0�łȂ��ꍇ�AHibernate��JDBC2�o�b�`�X�V��g�p���܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ ��������l�� <literal>5</literal> ���� <literal>30</literal> �ł��B
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.batch_versioned_data</literal>
+ </entry>
+ <entry>
+ ���JDBC�h���C�o�� <literal>executeBatch()</literal> �ɂ���Đ��m�ȍs����
+ �Ԃ��ꍇ�A���̃v���p�e�B�� <literal>true</literal> �ɂ��Ă�������
+ �i�ʏ�͂��̃I�v�V������ON�ɂ��܂��j�B
+ Hibernate�́A�����o�[�W�����f�[�^�̂��߃o�b�`DML��g���܂��B
+ �f�t�H���g�̒l�� <literal>false</literal> �ł��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.factory_class</literal>
+ </entry>
+ <entry>
+ �J�X�^�� <literal>Batcher</literal> ��I�т܂��B
+ �قƂ�ǂ̃A�v���P�[�V�����ɁA���̐ݒ�͕K�v����܂���B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>classname.of.BatcherFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.use_scrollable_resultset</literal>
+ </entry>
+ <entry>
+ �X�N���[���\�ȃ��U���g�Z�b�g��AHibernate���g�p���܂��B
+ ���̃v���p�e�B�́AJDBC�R�l�N�V�������R�l�N�V�������^�f�[�^��
+ �T�|�[�g���Ă��邱�Ƃ��K�{���ɂȂ�܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.use_streams_for_binary</literal>
+ </entry>
+ <entry>
+ JDBC��/���� <literal>binary</literal> �� <literal>serializable</literal>
+ �̏�������/�ǂݍ��݃X�g���[����g���܂�(�V�X�e�����x���̃v���p�e�B)�B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.use_get_generated_keys</literal>
+ </entry>
+ <entry>
+ �}���̌�Ɏ����������ꂽ��L�[��擾���邽�߂�
+ JDBC3 <literal>PreparedStatement.getGeneratedKeys()</literal> �̎g�p��L���ɂ��܂��B
+ �����JDBC3+�h���C�o��JRE1.4+��K�v�Ƃ��A
+ ���Hibernate�̎��ʎq�W�F�l���[�^�ɖ�肪��������悤�Ȃ�false�ɐݒ肵�Ă��������B
+ �f�t�H���g�ł̓R�l�N�V�������^�f�[�^��g���h���C�o�̔\�͂��肵�܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.provider_class</literal>
+ </entry>
+ <entry>
+ JDBC�R�l�N�V������Hibernate�ɒ���Ǝ��� <literal>ConnectionProvider</literal> ��
+ ���O��w�肵�܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>classname.of.ConnectionProvider</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.isolation</literal>
+ </entry>
+ <entry>
+ JDBC�g�����U�N�V�����������x����ݒ肵�܂��B
+ �Ó��Ȓl�ׂ邽�߂ɂ� <literal>java.sql.Connection</literal> ��`�F�b�N���Ă��������B
+ �������g�p����f�[�^�x�[�X���A���ׂĂ̕������x����T�|�[�g���Ă���Ƃ͌���܂���B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>1, 2, 4, 8</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.autocommit</literal>
+ </entry>
+ <entry>
+ �v�[������Ă���JDBC�R�l�N�V�����̎����R�~�b�g��L���ɂ���i���j�B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.release_mode</literal>
+ </entry>
+ <entry>
+ Hibernate��JDBC�R�l�N�V���������[�X���邩��w�肵�܂��B�f�t�H���g�ł�
+ �Z�b�V�����������I�ɃN���[�Y�܂��͐ؒf����Ă�R�l�N�V�����͕ێ����܂��B
+ �A�v���P�[�V�����T�[�o��JTA�f�[�^�\�[�X�̏ꍇ�A
+ ���ׂĂ�JDBC�R�[���̌�A�����I�ɃR�l�N�V���������[�X���邽�߂� <literal>after_statement</literal> ��
+ �g�����������B
+ ��JTA�R�l�N�V�����̏ꍇ�A�e�g�����U�N�V�������I�������Ƃ��� <literal>after_transaction</literal>
+ ��g���A�R�l�N�V���������[�X�����������B
+ <literal>auto</literal> �ɂ���ƁA
+ JTA��CMT�g�����U�N�V�����̏ꍇ�A <literal>after_statement</literal> �ŃN���[�Y���A
+ JDBC�g�����U�N�V�����̏ꍇ�A <literal>after_transaction</literal> �ŃN���[�Y���܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>auto</literal> (default) | <literal>on_close</literal> |
+ <literal>after_transaction</literal> | <literal>after_statement</literal>
+ </para>
+ <para>
+ ���ӂ��Ă��������B���̐ݒ�� <literal>SessionFactory.openSession</literal> ����
+ �擾���� <literal>Session</literal> �����Ɍ��ʂ�����܂��B
+ <literal>SessionFactory.getCurrentSession</literal> ��ʂ��Ď擾����
+ <literal>Session</literal> �ł́A<literal>CurrentSessionContext</literal>
+ �̎����ɂ���āA�R�l�N�V�����̃����[�X���[�h��ݒ肵�܂��B
+ <xref linkend="architecture-current-session"/> ��Q�Ƃ��Ă��������B
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.<emphasis><propertyName></emphasis></literal>
+ </entry>
+ <entry>
+ JDBC�� <literal>propertyName</literal> �v���p�e�B��A
+ <literal>DriverManager.getConnection()</literal> �ɓn���܂��B
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.<emphasis><propertyName></emphasis></literal>
+ </entry>
+ <entry>
+ <literal>propertyName</literal> �v���p�e�B��A
+ JNDI <literal>InitialContextFactory</literal> �ɓn���܂��B
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-cache-properties" revision="7">
+ <title>Hibernate �L���b�V���v���p�e�B</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>�v���p�e�B��</entry>
+ <entry>�Ӗ�</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.cache.provider_class</literal>
+ </entry>
+ <entry>
+ �J�X�^�� <literal>CacheProvider</literal> �̃N���X���ł��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>classname.of.CacheProvider</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_minimal_puts</literal>
+ </entry>
+ <entry>
+ �������݂�ŏ����ɂ��邽�߂ɁA�L���b�V���̑����œK�����܂��B
+ ���̑���ɁA�ǂݍ��݂����p�ɂɔ�������悤�ɂȂ�܂��B
+ ���̃Z�b�e�B���O�̓N���X�^�L���b�V���Ŗ�ɗ����܂��B
+ Hibernate3�ł̓N���X�^�L���b�V�������p�Ƀf�t�H���g�ł͗L���ɂȂ��Ă��܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_query_cache</literal>
+ </entry>
+ <entry>
+ ����̃N�G�����L���b�V���\�ȏꍇ�ɁA�N�G���L���b�V����L���ɂ��܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_second_level_cache</literal>
+ </entry>
+ <entry>
+ �L���b�V�����S�ɖ����ɂ���ꍇ�Ɏg���܂��B
+ �f�t�H���g�ł͗L���ŁA�N���X�� <literal><cache></literal> �}�b�s���O
+ �Ő��䂵�܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.query_cache_factory</literal>
+ </entry>
+ <entry>
+ �J�X�^�� <literal>QueryCache</literal> �C���^�[�t�F�C�X�̃N���X����
+ �w�肵�܂��B�f�t�H���g�ł� <literal>StandardQueryCache</literal> �ɂȂ�܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>classname.of.QueryCache</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.region_prefix</literal>
+ </entry>
+ <entry>
+ �L���b�V���̗̈於�̐ړ����ł��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>prefix</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cache.use_structured_entries</literal>
+ </entry>
+ <entry>
+ �L���b�V���Ɋi�[����f�[�^��A�l�������₷���t�H�[�}�b�g�ɂ��܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-transaction-properties" revision="9">
+ <title>Hibernate �g�����U�N�V�����v���p�e�B</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>�v���p�e�B��</entry>
+ <entry>�Ӗ�</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.factory_class</literal>
+ </entry>
+ <entry>
+ Hibernate <literal>Transaction</literal> API�ƈꏏ�Ɏg����
+ <literal>TransactionFactory</literal> �̃N���X���ł��B
+ �i�f�t�H���g�ł� <literal>JDBCTransactionFactory</literal> �ł��j�B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>classname.of.TransactionFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>jta.UserTransaction</literal>
+ </entry>
+ <entry>
+ �A�v���P�[�V�����T�[�o����JTA <literal>UserTransaction</literal> ��擾���邽�߂�
+ <literal>JTATransactionFactory</literal> �Ɏg����JNDI���ł��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>jndi/composite/name</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.manager_lookup_class</literal>
+ </entry>
+ <entry>
+ <literal>TransactionManagerLookup</literal> �̃N���X���ł��B
+ JTA���ɂ����āAJVM���x���̃L���b�V����L���ɂ��邽�߂ɕK�v�ł��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>classname.of.TransactionManagerLookup</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.flush_before_completion</literal>
+ </entry>
+ <entry>
+ �L���̏ꍇ�A�g�����U�N�V������completion�t�F�[�Y�̑O�Ɏ����I��
+ �Z�b�V������t���b�V�����܂��B����̎����Z�b�V�����R���e�L�X�g�Ǘ��ɓK���Ă��܂��B
+ <xref linkend="architecture-current-session"/>��Q�Ƃ��Ă��������B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.transaction.auto_close_session</literal>
+ </entry>
+ <entry>
+ �L���̏ꍇ�A�g�����U�N�V������completion�t�F�[�Y�̌��
+ �Z�b�V���������I�ɃN���[�Y���܂��B����̎����Z�b�V�����R���e�L�X�g�Ǘ��ɓK���Ă��܂��B
+ <xref linkend="architecture-current-session"/>��Q�Ƃ��Ă��������B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-misc-properties" revision="10">
+ <title>���̑��̃v���p�e�B</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>�v���p�e�B��</entry>
+ <entry>�Ӗ�</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.current_session_context_class</literal>
+ </entry>
+ <entry>
+ �u���݂́v<literal>Session</literal> �̂��߂́i�J�X�^���j�헪����܂��B
+ �r���g�C���X�g���e�W�[�Ɋւ��邻�̑��̏��ɂ��Ă�
+ <xref linkend="architecture-current-session"/>��Q�Ƃ��Ă��������B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>jta</literal> | <literal>thread</literal> |
+ <literal>managed</literal> | <literal>custom.Class</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.query.factory_class</literal>
+ </entry>
+ <entry>
+ HQL�p�[�T�[�̎�����I���܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>org.hibernate.hql.ast.ASTQueryTranslatorFactory</literal> or
+ <literal>org.hibernate.hql.classic.ClassicQueryTranslatorFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.query.substitutions</literal>
+ </entry>
+ <entry>
+ HQL��SQL�̃g�[�N����}�b�s���O���܂��B
+ �i�Ⴆ�A�g�[�N���͊���e�������ł��j�B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.hbm2ddl.auto</literal>
+ </entry>
+ <entry>
+ <literal>SessionFactory</literal> �������Ƃ��ɁA
+ �����I�ɃX�L�[�}DDL��DB�ɏo�͂��܂��B
+ <literal>create-drop</literal> �̏ꍇ�A <literal>SessionFactory</literal> ��
+ �N���[�Y�����Ƃ��ɁA�f�[�^�x�[�X�X�L�[�}��h���b�v���܂��B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>validate</literal> | <literal>update</literal> |
+ <literal>create</literal> | <literal>create-drop</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.cglib.use_reflection_optimizer</literal>
+ </entry>
+ <entry>
+ ���s�����t���N�V�����̑����CGLIB�̎g�p��L���ɂ��܂�
+ �i�V�X�e�����x���̃v���p�e�B�j
+ ���t���N�V�����̓g���u���V���[�e�B���O�̂Ƃ��ɖ𗧂��Ƃ�����܂��B
+ �I�v�e�B�}�C�U��I�t�ɂ��Ă���Ƃ��ł����A
+ Hibernate�ɂ͕K��CGLIB���K�v�Ȃ��Ƃɒ��ӂ��Ă��������B
+ ���̃v���p�e�B�� <literal>hibernate.cfg.xml</literal> �Őݒ�ł��܂���B
+ <para>
+ <emphasis role="strong">��F</emphasis>
+ <literal>true</literal> | <literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="configuration-optional-dialects" revision="1">
+ <title>SQL �����iDialect�j</title>
+
+ <para>
+ <literal>hibernate.dialect</literal> �v���p�e�B�ɂ́A
+ �g�p����f�[�^�x�[�X�̐����� <literal>org.hibernate.dialect.Dialect</literal> �̃T�u�N���X��A
+ �K���w�肷�ׂ��ł��B
+ ������������w�肷��AHibernate�͏�q�����v���p�e�B�̂������ɂ��āA
+ ���K�ȃf�t�H���g�l��g���܂��B
+ ��������A��������ƂŐݒ肷���Ԃ��Ȃ��܂��B
+ </para>
+
+ <table frame="topbot" id="sql-dialects" revision="2">
+ <title>Hibernate SQL Dialects (<literal>hibernate.dialect</literal>)</title>
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>RDBMS</entry>
+ <entry>Dialect</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>DB2</entry> <entry><literal>org.hibernate.dialect.DB2Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>DB2 AS/400</entry> <entry><literal>org.hibernate.dialect.DB2400Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>DB2 OS390</entry> <entry><literal>org.hibernate.dialect.DB2390Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>PostgreSQL</entry> <entry><literal>org.hibernate.dialect.PostgreSQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL</entry> <entry><literal>org.hibernate.dialect.MySQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL with InnoDB</entry> <entry><literal>org.hibernate.dialect.MySQLInnoDBDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL with MyISAM</entry> <entry><literal>org.hibernate.dialect.MySQLMyISAMDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Oracle (any version)</entry> <entry><literal>org.hibernate.dialect.OracleDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Oracle 9i/10g</entry> <entry><literal>org.hibernate.dialect.Oracle9Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>Sybase</entry> <entry><literal>org.hibernate.dialect.SybaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Sybase Anywhere</entry> <entry><literal>org.hibernate.dialect.SybaseAnywhereDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Microsoft SQL Server</entry> <entry><literal>org.hibernate.dialect.SQLServerDialect</literal></entry>
+ </row>
+ <row>
+ <entry>SAP DB</entry> <entry><literal>org.hibernate.dialect.SAPDBDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Informix</entry> <entry><literal>org.hibernate.dialect.InformixDialect</literal></entry>
+ </row>
+ <row>
+ <entry>HypersonicSQL</entry> <entry><literal>org.hibernate.dialect.HSQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Ingres</entry> <entry><literal>org.hibernate.dialect.IngresDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Progress</entry> <entry><literal>org.hibernate.dialect.ProgressDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Mckoi SQL</entry> <entry><literal>org.hibernate.dialect.MckoiDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Interbase</entry> <entry><literal>org.hibernate.dialect.InterbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Pointbase</entry> <entry><literal>org.hibernate.dialect.PointbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>FrontBase</entry> <entry><literal>org.hibernate.dialect.FrontbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Firebird</entry> <entry><literal>org.hibernate.dialect.FirebirdDialect</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-outerjoin" revision="4">
+ <title>�O�������t�F�b�`</title>
+
+ <para>
+ ���DB��ANSI���AOracle��Sybase�X�^�C���̊O��������T�|�[�g���Ă���ꍇ�A
+ <emphasis>outer join fetching</emphasis> �́ADB��SQL���s��ߖ�
+ �p�t�H�[�}���X��ǂ����܂��B�iDB��ł�葽���̏����R�X�g���������܂��j
+ �O�������t�F�b�`�́A���Έ�A��Α��A���Α��A��Έ�̃I�u�W�F�N�g�֘A��
+ �O���[�v�I�u�W�F�N�g��1��SQL�� <literal>SELECT</literal> ���܂��B
+ </para>
+
+ <para>
+ <literal>hibernate.max_fetch_depth</literal> �v���p�e�B�̒l�� <literal>0</literal> �ɂ����
+ Outer join fetching�� <emphasis>���ׂ�</emphasis> �����ɂ��邱�ƂɂȂ�܂��B
+ <literal>1</literal> �₻��ȏ�̒l��ݒ肷��ƁA�O�������t�F�b�`���L���ɂȂ�A
+ ��Έ�Ƒ��Έ�֘A�� <literal>fetch="join"</literal> �Ƃ��ă}�b�s���O����܂��B
+ </para>
+
+ <para>
+ See <xref linkend="performance-fetching"/> for more information.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-binarystreams" revision="1">
+ <title>�o�C�i���X�g���[��</title>
+
+ <para>
+ Oracle��JDBC�h���C�o�Ƃ̊Ԃł��Ƃ肳��� <literal>byte</literal> �z��̃T�C�Y�𐧌����܂��B
+ <literal>binary</literal> �� <literal>serializable</literal> �^�̑傫�ȃC���X�^���X��g��������A
+ <literal>hibernate.jdbc.use_streams_for_binary</literal> ��L���ɂ��Ă��������B
+ ������ <emphasis>����̓V�X�e�����x���̐ݒ肾���ł�</emphasis> �B
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-cacheprovider" revision="2">
+ <title>2���L���b�V���ƃN�G���[�L���b�V��</title>
+
+ <para>
+ <literal>hibernate.cache</literal> �v���p�e�B�ړ�����
+ Hibernate�Ńv���Z�X��N���X�^�L���b�V����g���Ƃ��Ƃ����܂��B
+ <xref linkend="performance-cache"/>�ɂ�葽���̏ڍׂ�����܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-querysubstitution">
+ <title>�N�G���[����̒u������</title>
+
+ <para>
+ <literal>hibernate.query.substitutions</literal> ��g�����ƂŁA
+ �V����Hibernate�N�G���g�[�N�����`�ł��܂��B
+ ��F
+ </para>
+
+ <programlisting>hibernate.query.substitutions true=1, false=0</programlisting>
+
+ <para>
+ ����̓g�[�N�� <literal>true</literal> �� <literal>false</literal> ��A
+ ���������SQL�ɂ����Đ������e�����ɖ|�܂��B
+ </para>
+
+ <programlisting>hibernate.query.substitutions toLowercase=LOWER</programlisting>
+
+ <para>
+ �����SQL�� <literal>LOWER</literal> ���̖��O�̕t���ւ���\�ɂ��܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-statistics" revision="2">
+ <title>Hibernate ���v</title>
+
+ <para>
+ <literal>hibernate.generate_statistics</literal> ��L���ɂ����ꍇ�A
+ ���삵�Ă���V�X�e����`���[�j���O����Ƃ��ɁA<literal>SessionFactory.getStatistics()</literal>
+ ��o�R���āAHibernate�͕֗��ȓ��v����o�͂��܂��B
+ JMX��o�R���ē��v����o�͂��邱�Ƃ�\�ł��B
+ Javadoc�� <literal>org.hibernate.stats</literal> �p�b�P�[�W���
+ �C���^�[�t�F�C�X�ɂ͂�葽���̏����܂��B
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="configuration-logging">
+ <title>���M���O</title>
+
+ <para>
+ Hibernate��Apache commons-loggin��g���āA���܂��܂ȃC�x���g���O�Ƃ���
+ �o�͂��܂��B
+ </para>
+
+ <para>
+ commons-logging�T�[�r�X�́i�N���X�p�X�� <literal>log4j.jar</literal> ��܂߂�jApache Log4j�ɁA
+ �܂��iJDK1.4������ȏ�Ŏ��s������jJDK1.4 logging�ɒ��ڏo�͂��܂��B
+ Log4j�� <literal>http://jakarta.apache.org</literal> ����_�E�����[�h�ł��܂��B
+ Log4j��g�����߂ɂ́A�N���X�p�X�� <literal>log4j.properties</literal> �t�@�C����z�u����K�v������܂��B
+ ��̃v���p�e�B�t�@�C����Hibernate�ƈꏏ�ɔz�z����A����� <literal>src/</literal> �f�B���N�g���ɂ���܂��B
+ </para>
+
+ <para>
+ Hibernate�̃��O���b�Z�[�W�Ɋ���邱�Ƃ����������߂��܂��B
+ Hibernate�̃��O�͓ǂ݂₷���A�ł������ڍׂɂȂ�悤�ɓw�͂���Ă��܂��B
+ ����͕K�{�̃g���u���V���[�e�B���O�f�o�C�X�ł��B
+ �ȉ��ɏd�v�ȃ��O�̃J�e�S�������܂��B
+ </para>
+
+ <table frame="topbot" id="log-categories" revision="2">
+ <title>Hibernate ���O�J�e�S��</title>
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>�J�e�S��</entry>
+ <entry>�@�\</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>org.hibernate.SQL</literal></entry>
+ <entry>���s�������ׂĂ�SQL�iDDL�j�X�e�[�g�����g���M���O���܂��B</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.type</literal></entry>
+ <entry>���ׂĂ�JDBC�p�����[�^���M���O���܂��B</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.tool.hbm2ddl</literal></entry>
+ <entry>���s�������ׂĂ�SQL�iDDL�j�X�e�[�g�����g���M���O���܂��B</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.pretty</literal></entry>
+ <entry>
+ session�Ɋ֘A���邷�ׂẴG���e�B�e�B�i�ő�Q�O�j�̃t���b�V�����Ԃ��M���O���܂��B
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.cache</literal></entry>
+ <entry>���ׂĂ̂Q���L���b�V���̓�����M���O���܂��B</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction</literal></entry>
+ <entry>�g�����U�N�V�����Ɋ֘A���铮����M���O���܂��B</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.jdbc</literal></entry>
+ <entry>JDBC���\�[�X�擾���M���O���܂��B</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.hql.ast.AST</literal></entry>
+ <entry>
+ HQL��SQL��AST�̃N�G���[�p�[�X���M���O���܂��B
+ </entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.secure</literal></entry>
+ <entry>���ׂĂ�JAAS���͂��M���O���܂��B</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate</literal></entry>
+ <entry>
+ ���ׂĂ��M���O���܂��B�i���ʂɂȂ�܂����A�g���u���V���[�e�B���O�ɂ͕֗��ł��j
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Hibernate�ŃA�v���P�[�V������쐬����Ƃ��́A<literal>org.hibernate.SQL</literal>
+ �J�e�S���� <literal>debug</literal> ���ɗL���ɂ��Ă������ق����ǂ��ł��傤�B
+ ��֕��@�Ƃ��āA<literal>hibernate.show_sql</literal> ��L���ɂ�����@������܂��B
+ </para>
+
+
+ </sect1>
+
+ <sect1 id="configuration-namingstrategy">
+ <title><literal>NamingStrategy</literal> �̎���</title>
+
+ <para>
+ �C���^�[�t�F�C�X <literal>net.sf.hibernate.cfg.NamingStrategy</literal> ��g����
+ �f�[�^�x�[�X�I�u�W�F�N�g�ƃX�L�[�}�v�f�̂��߂́u�����W���v��w��ł��܂��B
+ </para>
+
+ <para>
+ Java�̎��ʎq����f�[�^�x�[�X�̎��ʎq�����������邽�߂̃��[����A
+ �}�b�s���O�t�@�C���ŗ^�����u�_���I�ȁv�J�����ƃe�[�u��������
+ �u�����I�ȁv�e�[�u���ƃJ�����������邽�߂̃��[����p�ӂ��邱�Ƃ��ł��܂��B
+ ���̋@�\�͌J��Ԃ��̎G���i�Ⴆ�� <literal>TBL_</literal> �v���t�B�b�N�X�j���菜���A
+ �}�b�s���O�h�L�������g�̏璷�����炷���Ƃɖ𗧂��܂��B
+ Hibernate���g���f�t�H���g�̐헪�͂��Ȃ�ŏ����ɋ߂���̂ł��B
+ </para>
+
+ <para>
+ �}�b�s���O��lj�����O�� <literal>Configuration.setNamingStrategy()</literal> ��ĂԂ��Ƃ�
+ �ȉ��̂悤�ɈقȂ�헪��w�肷�邱�Ƃ��ł��܂��F
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration()
+ .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
+ .addFile("Item.hbm.xml")
+ .addFile("Bid.hbm.xml")
+ .buildSessionFactory();]]></programlisting>
+
+ <para>
+ <literal>org.hibernate.cfg.ImprovedNamingStrategy</literal> �͑g�ݍ��݂̐헪�ł��B
+ ����͂������̃A�v���P�[�V�����ɂƂ��ėL�p�ȊJ�n�_�ƂȂ邩�����܂���B
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-xmlconfig" revision="2">
+ <title>XML�ݒ�t�@�C��</title>
+
+ <para>
+ ���1�̕��@�� <literal>hibernate.cfg.xml</literal> �Ƃ������O�̃t�@�C����
+ �\���Ȑݒ��w�肷����@�ł��B
+ ���̃t�@�C���� <literal>hibernate.properties</literal> �t�@�C���̑���ƂȂ�܂��B
+ ��������̃t�@�C��������A�v���p�e�B���u���������܂��B
+ </para>
+
+ <para>
+ XML�ݒ�t�@�C���͏����ݒ�� <literal>CLASSPATH</literal> �ɔz�u���Ă��������B
+ ���ꂪ��ł��F
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <!-- a SessionFactory instance listed as /jndi/name -->
+ <!-- /jndi/name�̂悤�Ƀ��X�g�A�b�v���ꂽSessionFactory�C���X�^���X -->
+ <session-factory
+ name="java:hibernate/SessionFactory">
+
+ <!-- properties -->
+ <property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
+ <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
+ <property name="show_sql">false</property>
+ <property name="transaction.factory_class">
+ org.hibernate.transaction.JTATransactionFactory
+ </property>
+ <property name="jta.UserTransaction">java:comp/UserTransaction</property>
+
+ <!-- mapping files -->
+ <mapping resource="org/hibernate/auction/Item.hbm.xml"/>
+ <mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
+
+ <!-- cache settings -->
+ <class-cache class="org.hibernate.auction.Item" usage="read-write"/>
+ <class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
+ <collection-cache collection="org.hibernate.auction.Item.bids" usage="read-write"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ ���Ă̂Ƃ���A���̕��@�̗D�ʐ��͐ݒ�̂��߂̃}�b�s���O�t�@�C������O�o���ɂł��邱�Ƃł��B
+ Hibernate�L���b�V����`���[�j���O���Ȃ���Ȃ�Ȃ��̂ł���A
+ <literal>hibernate.cfg.xml</literal> �͂��֗��ł��B
+ <literal>hibernate.properties</literal> �� <literal>hibernate.cfg.xml</literal> ��
+ �ǂ��炩��g���邱�Ƃ�o���Ă����Ă��������B
+ ��͓�����̂ŁA�Ⴄ�Ƃ���Ƃ�����XML�\����g�����Ƃ̗��_�����ł��B
+ </para>
+
+ <para>
+ XML�ݒ��g�����ƂŁAHibernate�͈ȉ��̂悤�ɃV���v���ɂȂ�܂��B
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration().configure().buildSessionFactory();]]></programlisting>
+
+ <para>
+ �ႤXML�ݒ�t�@�C����g�����Ƃ�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration()
+ .configure("catdb.cfg.xml")
+ .buildSessionFactory();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="configuration-j2ee" revision="1">
+ <title>J2EE�A�v���P�[�V�����T�[�o�Ƃ̓���</title>
+
+ <para>
+ Hibernate��J2EE�\���Ɠ�������|�C���g��T�|�[�g���Ă��܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>�R���e�i�Ǘ��f�[�^�\�[�X</emphasis>�FHibernate��
+ JNDI�����A�R���e�i���Ǘ�����JDBC�R�l�N�V������g�p�ł��܂��B
+ �ʏ�AJTA������ <literal>TransactionManager</literal> ��
+ <literal>ResourceManager</literal> ���g�����U�N�V�����Ǘ�(CMT)�A
+ ���ɗl�X�ȃf�[�^�\�[�X�ɂ܂����镪�U�g�����U�N�V���������܂��B
+ ���R�v���O�����Ńg�����U�N�V�������E��w��ł��܂�(BMT)�B
+ ���邢�́A�L�q�����R�[�h�̃|�[�^�r���e�B��ۂ��߂ɁA
+ �I�v�V������Hibernate�� <literal>Transaction</literal> API��g�������Ȃ邩�����܂���B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>����JNDI�o�C���f�B���O</emphasis>�FHibernate��JNDI�������オ�������
+ <literal>SessionFactory</literal> �����܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>JTA�Z�b�V�����o�C���f�B���O</emphasis> �F
+ Hibernate <literal>Session</literal> �̃g�����U�N�V�������E��JTA�g�����U�N�V�����Ɠ����ɂȂ�܂��B
+ �P���� <literal>SessionFactory</literal> ��JNDI����lookup���āA
+ ���݂� <literal>Session</literal> ��擾���܂��B
+ JTA�g�����U�N�V���������������Ƃ��ɁAHibernate�� <literal>Session</literal> ��t���b�V�����A�N���[�Y���܂��B
+ EJB�f�v���C�����g�f�B�X�N���v�^�̒��ɁA�g�����U�N�V�������E��錾���܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>JMX�f�v���C:</emphasis> ���JMX���g�p�\�ȃA�v���P�[�V�����T�[�o�i�Ⴆ��JBOSS�j
+ ������ꍇ�AHibernate��MBean�Ƃ��ăf�v���C���邱�Ƃ�I�ׂ܂��B
+ ����� <literal>Configuration</literal> ���� <literal>SessionFactory</literal> ��
+ ��������R�[�h�������Ƃ��ł��܂��B
+ �R���e�i�� <literal>HibernateService</literal> ��N�����A
+ �T�[�r�X�̈ˑ��𗝑z�I�ɊǗ����܂��i�f�[�^�\�[�X��Hibernate�₻�̑����N������O��
+ �g�p�ł���悤�ɂ��Ȃ���Ȃ�܂���j�B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ���Ɉˑ����܂����A����A�A�v���P�[�V�����T�[�o��"connection containment"�̗�O��X���[����Ȃ�
+ �ݒ�̃I�v�V���� <literal>hibernate.connection.aggressive_release</literal>
+ ��true�ɂ��Ă��������B
+ </para>
+
+ <sect2 id="configuration-optional-transactionstrategy" revision="3">
+ <title>�g�����U�N�V�����헪�ݒ�</title>
+
+ <para>
+ Hibernate <literal>Session</literal> API�́A�A�[�L�e�N�`����̃V�X�e���̊NJ��ł���
+ ������g�����U�N�V�����Ɉˑ����܂���B
+ ����R�l�N�V�����v�[����JDBC�ڎg�������ꍇ�AJDBC API����
+ �g�����U�N�V������ĂԂ��Ƃ��ł��܂��B
+ ����AJ2EE�A�v���P�[�V�����T�[�o�œ��삳����Ȃ�ABean�Ǘ��g�����U�N�V������g���A
+ �K�v�ɉ����� <literal>UserTransaction</literal> ��JTA API����ĂԂ��ƂɂȂ�ł��傤�B
+ </para>
+
+ <para>
+ 2�i����ȏ�j�̊��Ō݊����̂���R�[�h��ێ����邽�߂ɁA�I�v�V�����Ƃ��č��{�I�ȃV�X�e����
+ ���b�s���O����Hibernate <literal>Transaction</literal> API�𐄏����܂��B
+ Hibernate�ݒ�v���p�e�B�� <literal>hibernate.transaction.factory_class</literal> ��ݒ肷�邱�Ƃ�
+ �������� <literal>Transaction</literal> �N���X�̃C���X�^���X�����Ƃ��ł��܂��B
+ </para>
+
+ <para>
+ 3�̊�{�I�ȁi���ɂ���j�I������܂��F
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term><literal>org.hibernate.transaction.JDBCTransactionFactory</literal></term>
+ <listitem>
+ <para>�f�[�^�x�[�X(JDBC)�g�����U�N�V�����ɈϏ����܂��i�f�t�H���g�j</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>org.hibernate.transaction.JTATransactionFactory</literal></term>
+ <listitem>
+ <para>
+ ����A���̃R���e�L�X�g�i�Ⴆ�AEJB�Z�b�V����Bean���\�b�h�j�Ői�s���̃g�����U�N�V���������݂���A�������
+ �V�����g�����U�N�V�������J�n����Ă���ABean�Ǘ��g�����U�N�V�������g���Ă���ꍇ�A
+ �R���e�i�Ǘ��g�����U�N�V�����ɈϏ����܂��B
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>org.hibernate.transaction.CMTTransactionFactory</literal></term>
+ <listitem>
+ <para>�R���e�i�Ǘ�JTA�g�����U�N�V�����ɈϏ����܂�</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ �������g�̃g�����U�N�V�����헪�i�Ⴆ�ACORBA�g�����U�N�V�����T�[�r�X�j���`���邱�Ƃ�ł��܂��B
+ </para>
+
+ <para>
+ Hibernate�̂������̋@�\�i�Ⴆ�A�L���b�V���AJTA�ɂ��R���e�L�X�g�Z�b�V���� ���j��
+ �Ǘ����ꂽ���̒���JTA <literal>TransactionManager</literal> �ւ̃A�N�Z�X��v�����܂��B
+ J2EE���ЂƂ̃��J�j�Y���ɋK�i������Ă��Ȃ��̂ŁA
+ �A�v���P�[�V�����T�[�o�ɂ����āAHibernate�� <literal>TransactionManager</literal> �̃��t�@�����X
+ ��擾������@�m�ɂ���K�v������܂��B
+ </para>
+
+ <table frame="topbot" id="jtamanagerlookup" revision="1">
+ <title>JTA �g�����U�N�V�����}�l�[�W��</title>
+ <tgroup cols="2">
+ <colspec colwidth="2.5*"/>
+ <colspec colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Transaction Factory</entry>
+ <entry align="center">Application Server</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>org.hibernate.transaction.JBossTransactionManagerLookup</literal></entry>
+ <entry align="center">JBoss</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.WeblogicTransactionManagerLookup</literal></entry>
+ <entry align="center">Weblogic</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.WebSphereTransactionManagerLookup</literal></entry>
+ <entry align="center">WebSphere</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</literal></entry>
+ <entry align="center">WebSphere 6</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.OrionTransactionManagerLookup</literal></entry>
+ <entry align="center">Orion</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.ResinTransactionManagerLookup</literal></entry>
+ <entry align="center">Resin</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.JOTMTransactionManagerLookup</literal></entry>
+ <entry align="center">JOTM</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.JOnASTransactionManagerLookup</literal></entry>
+ <entry align="center">JOnAS</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.JRun4TransactionManagerLookup</literal></entry>
+ <entry align="center">JRun4</entry>
+ </row>
+ <row>
+ <entry><literal>org.hibernate.transaction.BESTransactionManagerLookup</literal></entry>
+ <entry align="center">Borland ES</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-jndi" revision="3">
+ <title><literal>SessionFactory</literal> ��JNDI�ւ̓o�^</title>
+
+ <para>
+ JNDI�ɓo�^����Hibernate <literal>SessionFactory</literal> �͒P����
+ �t�@�N�g�����b�N�A�b�v���A�V���� <literal>Session</literal> ����܂��B
+ �����JNDI�ɓo�^���ꂽ <literal>Datasource</literal> �ɂ͊֘A�����A
+ ���݂��ɃV���v���ɂ����̓o�^��g�����Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ ��� <literal>SessionFactory</literal> ��JNDI�l�[���X�y�[�X�ɓo�^�������ꍇ�A
+ ���ʂȖ��O�i�Ⴆ�A <literal>java:hibernate/SessionFactory</literal> �j��
+ <literal>hibernate.session_factory_name</literal> �v���p�e�B�Ɏg���Ă�������
+ ������̃v���p�e�B��ȗ������ꍇ�A <literal>SessionFactory</literal> ��
+ JNDI�ɓo�^����܂���B�i�����Tomcat�̂悤�ȃf�t�H���g������JNDI���ǂ݂���p�̊��̏ꍇ���ɕ֗��ł��B�j
+ </para>
+
+ <para>
+ <literal>SessionFactory</literal> ��JNDI�ɓo�^����Ƃ��AHibernate��
+ <literal>hibernate.jndi.url</literal> �̒l��g�p���A<literal>hibernate.jndi.class</literal>
+ ��C�j�V�����R���e�L�X�g�Ƃ��ċ�̉����܂��B
+ �������ݒ肵�Ȃ��ꍇ�́A�f�t�H���g�� <literal>InitialContext</literal> ��g�p���܂��B
+ </para>
+
+ <para>
+ <literal>cfg.buildSessionFactory()</literal> ��R�[����
+ Hibernate�͎����I�� <literal>SessionFactory</literal> ��JNDI�ɔz�u���܂��B
+ <literal>HibernateService</literal> �ƈꏏ��JMX�f�v���C�����g��g��Ȃ�����A
+ ����͂��̌Ăяo����A�v���P�[�V������̉��炩�̃X�^�[�g�A�b�v�R�[�h�i������̓��[�e�B���e�B�N���X�j
+ �ɔz�u���Ȃ���Ȃ�Ȃ����Ƃ�Ӗ����܂��B�i��ŋc�_���܂��j
+ </para>
+
+ <para>
+ ���JNDI <literal>SessionFactory</literal> ��g���ꍇ�AEJB�⑼�̃N���X��
+ JNDI���b�N�A�b�v��g���� <literal>SessionFactory</literal> ��擾���܂��B
+ </para>
+
+ <para>
+ �Ǘ����ꂽ���ł� <literal>SessionFactory</literal> ��JNDI�Ƀo�C���h���A
+ �����łȂ���� <literal>static</literal> �V���O���g����g�����Ƃ𐄏����܂��B
+ �����������ڍׂ���A�v���P�[�V�����R�[�h��ی삷�邽�߂ɁA
+ <literal>HibernateUtil.getSessionFactory()</literal> �̂悤�ȃw���p�[�N���X�̒��ɁA
+ <literal>SessionFactory</literal> ���b�N�A�b�v����R�[�h��B�����Ƃ𐄏����܂��B
+ ���̂悤�ȃw���p�[�N���X��Hibernate��J�n����֗��Ȏ�i�ł����܂��B
+ —�P�͂�Q�Ƃ��Ă��������B
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-j2ee-currentsession" revision="4">
+ <title>JTA�ɂ�錻�݂̃Z�b�V�����R���e�L�X�g�}�l�[�W�����g</title>
+
+ <para>
+ ����Ƃ�ȒP�� <literal>Session</literal> �ƃg�����U�N�V�����������@�́A
+ Hibernate�������I�Ɂu���݂́v <literal>Session</literal> ��Ǘ����邱�Ƃł��B
+ <xref linkend="architecture-current-session">�J�����g�Z�b�V����</xref> �̐����Q�Ƃ��Ă��������B
+ ��� <literal>�uJTA�v</literal> �Z�b�V�����R���e�L�X�g��g������ŁA
+ ���݂�JTA�g�����U�N�V������Hibernate <literal>Session</literal> ���֘A���Ă��Ȃ��ꍇ�́A
+ �ŏ��� <literal>sessionFactory.getCurrentSession()</literal> ��R�[�����A
+ JTA�g�����U�N�V�����Ƃ̊֘A�t����s���Ă��������B
+ <literal>�uJTA�v</literal> �R���e�L�X�g�� <literal>getCurrentSession()</literal> ��
+ �ʂ��Ď擾���� <literal>Session</literal> �́A�g�����U�N�V��������������O��
+ �����I�Ƀt���b�V�����A����������ɂ͎����I�ɃN���[�Y���܂��B
+ �܂��A�e�X�e�[�g�����g���JDBC�R�l�N�V������ϋɓI�Ƀ����[�X���܂��B
+ ����ɂ��JTA�g�����U�N�V�����̃��C�t�T�C�N���� <literal>Session</literal> ��Ǘ����邱�Ƃ��ł��A
+ ���[�U�[�̃R�[�h���炻�̂悤�ȊǗ�����R�[�h��r���ł��܂��B
+ <literal>UserTransaction</literal> ��ʂ���JTA��v���O�����ŊǗ����邱�Ƃ��ł��܂��B
+ �܂��́A�i�|�[�^�u���ȃR�[�h�ł���jHibernate <literal>Transaction</literal> API��
+ �g�����U�N�V�������E�Ƃ��Ďg�����Ƃ�ł��܂��B
+ EJB�R���e�i��g���Ƃ��́ACMT�ɂ��錾�I�g�����U�N�V�������E���D�܂����ł��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-j2ee-jmx" revision="1">
+ <title>JMX�f�v���C�����g</title>
+
+ <para>
+ <literal>SessionFactory</literal> ��JNDI����擾���邽�߂ɂ�
+ <literal>cfg.buildSessionFactory()</literal> �s��ǂ����Ŏ��s���Ă��Ȃ���Ȃ�܂���B
+ ���Ȃ��͂����A<literal>static</literal> �������u���b�N��i <literal>HibernateUtil</literal> �̂悤�ȁj��
+ <emphasis>managed service</emphasis> �Ƃ���Hibernate��f�v���C���邩�A�ǂ��炩�Ŏ��s�ł��܂��B
+ </para>
+
+ <para>
+ JBOSS�̂悤��JMX�̋@�\�ŃA�v���P�[�V�����T�[�o�Ƀf�v���C���邽�߂�
+ <literal>org.hibernate.jmx.HibernateService</literal> ��g���āA�z�u���܂��B
+ ���ۂ̃f�v���C�����g�Ɛݒ�̓x���_�[���L�ł��B
+ �����ŗ�Ƃ���JBOSS 4.0.x�p�� <literal>jboss-service.xml</literal> �����܂��B
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<server>
+
+<mbean code="org.hibernate.jmx.HibernateService"
+ name="jboss.jca:service=HibernateFactory,name=HibernateFactory">
+
+ <!-- Required services -->
+ <depends>jboss.jca:service=RARDeployer</depends>
+ <depends>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>
+
+ <!-- Bind the Hibernate service to JNDI -->
+ <attribute name="JndiName">java:/hibernate/SessionFactory</attribute>
+
+ <!-- Datasource settings -->
+ <attribute name="Datasource">java:HsqlDS</attribute>
+ <attribute name="Dialect">org.hibernate.dialect.HSQLDialect</attribute>
+
+ <!-- Transaction integration -->
+ <attribute name="TransactionStrategy">
+ org.hibernate.transaction.JTATransactionFactory</attribute>
+ <attribute name="TransactionManagerLookupStrategy">
+ org.hibernate.transaction.JBossTransactionManagerLookup</attribute>
+ <attribute name="FlushBeforeCompletionEnabled">true</attribute>
+ <attribute name="AutoCloseSessionEnabled">true</attribute>
+
+ <!-- Fetching options -->
+ <attribute name="MaximumFetchDepth">5</attribute>
+
+ <!-- Second-level caching -->
+ <attribute name="SecondLevelCacheEnabled">true</attribute>
+ <attribute name="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>
+ <attribute name="QueryCacheEnabled">true</attribute>
+
+ <!-- Logging -->
+ <attribute name="ShowSqlEnabled">true</attribute>
+
+ <!-- Mapping files -->
+ <attribute name="MapResources">auction/Item.hbm.xml,auction/Category.hbm.xml</attribute>
+
+</mbean>
+
+</server>]]></programlisting>
+
+ <para>
+ ���̃t�@�C���� <literal>META-INF</literal> �f�B���N�g���ɔz�u����A
+ JAR�t�@�C����g������ <literal>.sar</literal> (service archive)�Ńp�b�P�[�W������܂��B
+ ���l��Hibernate�p�b�P�[�W��K�v�ł��B�܂��AHibernate�̓T�[�h�p�[�e�B�̃��C�u������v�����܂��B
+ �R���p�C�������i�����N���X�Ƃ��̃}�b�s���O�t�@�C������l�ɃA�[�J�C�u�i.sar�t�@�C���j�ɓ���܂��B
+ �G���^�[�v���C�Ybean�i�ʏ�̓Z�b�V����bean�j�͎��g��JAR�t�@�C����ێ����܂����A
+ 1��Łi�z�b�g�j�f�v���C�\�ȃ��j�b�g�̂��߂Ƀ��C���T�[�r�X�A�[�J�C�u�Ƃ��Ă���EJB JAR�t�@�C����C���N���[�h����
+ ���Ƃ��ł��܂��BJBoss�A�v���P�[�V�����T�[�o�̃h�L�������g��JXM�T�[�r�X��
+ EJB�f�v���C�����g�̂�葽���̏����܂��B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/events.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/events.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/events.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/events.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,274 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="events">
+ <title>�C���^�[�Z�v�^�ƃC�x���g</title>
+
+ <para>
+ �A�v���P�[�V������Hibernate�̓���Ŕ�������C�x���g�ɑΉ��ł���Ɩ�ɗ����Ƃ�����܂��B
+ �����̈�ʓI�ȋ@�\������ł���悤�ɂȂ�A
+ �܂�Hibernate�̋@�\��g�����邱�Ƃ�ł���悤�ɂȂ�܂��B
+ </para>
+
+ <sect1 id="objectstate-interceptors" revision="3">
+ <title>�C���^�[�Z�v�^</title>
+
+ <para>
+ <literal>Interceptor</literal> �C���^�[�t�F�C�X��g���āA
+ �Z�b�V��������A�v���P�[�V�����փR�[���o�b�N���邱�Ƃ��ł��܂��B
+ ����ɂ��i���I�u�W�F�N�g�̕ۑ��A�X�V�A�폜�A�ǂݍ��݂̑O�ɁA
+ �A�v���P�[�V�������v���p�e�B���������葀�삵����ł���悤�ɂȂ�܂��B
+ ����͊č����̒ǐՂɗ��p�ł��܂��B
+ ���̗�� <literal>Interceptor</literal> �� <literal>Auditable</literal>
+ ���쐬�����Ǝ����I�� <literal>createTimestamp</literal> ��ݒ肵�A
+ <literal>Auditable</literal> ���X�V�����Ǝ����I��
+ <literal>lastUpdateTimestamp</literal> �v���p�e�B��X�V���܂��B
+ </para>
+
+ <para>
+ <literal>Interceptor</literal> �ڎ���������A
+ �i����ɂ悢�̂́j<literal>EmptyInterceptor</literal> ��g��������ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[package org.hibernate.test;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.Transaction;
+import org.hibernate.type.Type;
+
+public class AuditInterceptor extends EmptyInterceptor {
+
+ private int updates;
+ private int creates;
+ private int loads;
+
+ public void onDelete(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+ // do nothing
+ }
+
+ public boolean onFlushDirty(Object entity,
+ Serializable id,
+ Object[] currentState,
+ Object[] previousState,
+ String[] propertyNames,
+ Type[] types) {
+
+ if ( entity instanceof Auditable ) {
+ updates++;
+ for ( int i=0; i < propertyNames.length; i++ ) {
+ if ( "lastUpdateTimestamp".equals( propertyNames[i] ) ) {
+ currentState[i] = new Date();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean onLoad(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+ if ( entity instanceof Auditable ) {
+ loads++;
+ }
+ return false;
+ }
+
+ public boolean onSave(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if ( entity instanceof Auditable ) {
+ creates++;
+ for ( int i=0; i<propertyNames.length; i++ ) {
+ if ( "createTimestamp".equals( propertyNames[i] ) ) {
+ state[i] = new Date();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void afterTransactionCompletion(Transaction tx) {
+ if ( tx.wasCommitted() ) {
+ System.out.println("Creations: " + creates + ", Updates: " + updates, "Loads: " + loads);
+ }
+ updates=0;
+ creates=0;
+ loads=0;
+ }
+
+}]]></programlisting>
+
+ <para>
+ �C���^�[�Z�v�^�ɂ͓��ނ���܂��F
+ <literal>Session</literal> �X�R�[�v�̂�̂�
+ <literal>SessionFactory</literal> �X�R�[�v�̂�̂ł��B
+ </para>
+
+ <para>
+ <literal>Session</literal> �X�R�[�v�̃C���^�[�Z�v�^�́A
+ �Z�b�V������I�[�v������Ƃ��Ɏw�肵�܂��B
+ <literal>Interceptor</literal> ������Ɏ��SessionFactory.openSession()
+ �̃I�[�o�[���[�h���\�b�h�̈��g���܂��B
+ </para>
+
+ <programlisting><![CDATA[Session session = sf.openSession( new AuditInterceptor() );]]></programlisting>
+
+ <para>
+ <literal>SessionFactory</literal> �X�R�[�v�̃C���^�[�Z�v�^�� <literal>Configuration</literal>
+ �I�u�W�F�N�g��g���ēo�^���܂��B
+ ����� <literal>SessionFactory</literal> �̍\�z����D�悳��܂��B
+ ���̏ꍇ�A�����C���^�[�Z�v�^�� <literal>SessionFactory</literal>
+ ����I�[�v�����ꂽ���ׂẴZ�b�V�����ɓK�p����܂��B
+ ����͎g�p����C���^�[�Z�v�^���I�Ɏw�肵�ăZ�b�V������I�[�v�����Ȃ�����A�����Ȃ�܂��B
+ <literal>SessionFactory</literal> �X�R�[�v�̃C���^�[�Z�v�^�̓X���b�h�Z�[�t�łȂ���Ȃ�܂���B
+ �����̃Z�b�V�������i���ݓI�Ɂj���̃C���^�[�Z�v�^�����s�Ŏg�p���邱�ƂɂȂ邽�߁A
+ �Z�b�V�����ŗL�̏�Ԃ�i�[���Ȃ��悤�ɋC����Ă��������B
+ </para>
+
+ <programlisting><![CDATA[new Configuration().setInterceptor( new AuditInterceptor() );]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="objectstate-events" revision="4">
+ <title>�C�x���g�V�X�e��</title>
+
+ <para>
+ �i�����w�œ���̃C�x���g�ɑΉ����Ȃ���Ȃ�Ȃ��ꍇ�A
+ Hibernate3�� <emphasis>�C�x���g</emphasis> �A�[�L�e�N�`����g�����Ƃ�ł��܂��B
+ �C�x���g�V�X�e���̓C���^�[�Z�v�^�ƈꏏ�Ɏg�����A�܂��̓C���^�[�Z�v�^�̑���Ƃ��Ďg�����Ƃ��ł��܂��B
+ </para>
+
+ <para>
+ �{���I�� <literal>Session</literal> �C���^�[�t�F�C�X�̂��ׂẴ��\�b�h�́A
+ 1�̃C�x���g�Ƒ��݂Ɋ֘A���܂��B
+ �Ⴆ�� <literal>LoadEvent</literal>�A<literal>FlushEvent</literal> �Ȃǂ�����܂�
+ �i��`�ς݂̃C�x���g�^�̈ꗗ�ɂ��ẮAXML�ݒ�t�@�C����DTD��
+ <literal>org.hibernate.event</literal> �p�b�P�[�W�ׂĂ��������j�B
+ ���N�G�X�g�������̃��\�b�h��1��������Ƃ��A
+ Hibernate�� <literal>Session</literal> �͓K�ȃC�x���g�����A
+ ���̃C�x���g�^�ɐݒ肳�ꂽ�C�x���g���X�i�ɓn���܂��B
+ ���炵�����ƂɁA�����̃��X�i�͂��̃��\�b�h�Ɠ���������������܂��B
+ �Ƃ͂����A���X�i�C���^�[�t�F�C�X�̈���R�ɃJ�X�^�������ł��܂�
+ �i�܂�A<literal>LoadEvent</literal> �͓o�^���ꂽ <literal>LoadEventListener</literal>
+ �C���^�[�t�F�C�X�̎����ɂ�菈������܂��j�B
+ ���̏ꍇ�A���̎����ɂ� <literal>Session</literal> ������ꂽ�ǂ̂悤�� <literal>load()</literal>
+ ���N�G�X�g����������ӔC������܂��B
+ </para>
+
+ <para>
+ ���X�i�͎�����V���O���g���ł���ƌ��Ȃ��܂��B
+ �܂胊�X�i�̓��N�G�X�g�Ԃŋ��L����邽�߁A
+ �C���X�^���X�ϐ��Ƃ��ď�Ԃ�ێ�����ׂ��ł͂Ȃ��Ƃ������Ƃł��B
+ </para>
+
+ <para>
+ �J�X�^�����X�i�͏����������C�x���g�ɂ��ēK�ȃC���^�[�t�F�C�X���������ׂ��ł��B
+ �֗��Ȋ��N���X�̂����̈��p�����Ă�悢�ł�
+ �i�܂���Hibernate���f�t�H���g�Ŏg�p����C�x���g���X�i��p�����Ă�悢�ł��B
+ ���炵�����ƂɁA���̖ړI�̂��߂ɔ�final�Ƃ��Đ錾����Ă��܂��j�B
+ �J�X�^�����X�i�� <literal>Configuration</literal> �I�u�W�F�N�g��g���ăv���O��������o�^���邩�A
+ Hibernate��XML�ݒ�t�@�C���Ŏw��ł��܂�
+ �i�v���p�e�B�t�@�C���Ő錾�I�ɐݒ肷����@�̓T�|�[�g����Ă��܂���j�B
+ �J�X�^�����[�h�C�x���g���X�i�̗�����܂��B
+ </para>
+
+ <programlisting><![CDATA[public class MyLoadListener implements LoadEventListener {
+ // this is the single method defined by the LoadEventListener interface
+ public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType)
+ throws HibernateException {
+ if ( !MySecurity.isAuthorized( event.getEntityClassName(), event.getEntityId() ) ) {
+ throw MySecurityException("Unauthorized access");
+ }
+ }
+}]]></programlisting>
+
+ <para>
+ �f�t�H���g���X�i�ȊO�̃��X�i��g���ɂ́AHibernate�ւ̐ݒ��K�v�ł��F
+ </para>
+
+<programlisting><![CDATA[<hibernate-configuration>
+ <session-factory>
+ ...
+ <event type="load">
+ <listener class="com.eg.MyLoadListener"/>
+ <listener class="org.hibernate.event.def.DefaultLoadEventListener"/>
+ </event>
+ </session-factory>
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ �܂����̑��ɁA�v���O�����œo�^������@�����܂��F
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration();
+LoadEventListener[] stack = { new MyLoadListener(), new DefaultLoadEventListener() };
+cfg.EventListeners().setLoadEventListeners(stack);]]></programlisting>
+
+ <para>
+ ���X�i��錾�I�ɓo�^����ƁA���̃��X�i�̃C���X�^���X���L�ł��܂���B
+ ������ <literal><listener/></literal> �v�f�œ����N���X�����g����ƁA
+ ���ꂼ��̎Q�Ƃ͂��̃N���X�̕ʁX�̃C���X�^���X��w�����ƂɂȂ�܂��B
+ ���X�i�^�̊ԂŃ��X�i�C���X�^���X���L����K�v������A
+ �v���O�����œo�^������@��̂�Ȃ���Ȃ�܂���B
+ </para>
+
+ <para>
+ �Ȃ��C���^�[�t�F�C�X��������āA���������^��ݒ莞�Ɏw�肷��̂ł��傤���H
+ ���X�i�̎����N���X�ɁA�����̃C�x���g���X�i�C���^�[�t�F�C�X������ł��邩��ł��B
+ �o�^���ɒlj��Ō^��w�肷�邱�ƂŁA�J�X�^�����X�i��on/off��ݒ莞�ɊȒP�ɐ�ւ����܂��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-decl-security" revision="2">
+ <title>Hibernate�̐錾�I�ȃZ�L�����e�B</title>
+ <para>
+ ��ʓI��Hibernate�A�v���P�[�V�����̐錾�I�ȃZ�L�����e�B�́A�Z�b�V�����t�@�T�[�h�w�ŊǗ����܂��B
+ ���݁AHiberenate3��JACC�ŋ������AJAAS�ŔF�����A�N�V���������Ă��܂��B
+ ����̓C�x���g�A�[�L�e�N�`���̍ŏ�ʂɑg�ݍ��܂�Ă���I�v�V�����̋@�\�ł��B
+ </para>
+
+ <para>
+ �܂��ŏ��ɁA�K�ȃC�x���g���X�i��ݒ肵��JAAS�F��g����悤�ɂ��Ȃ���Ȃ�܂���B
+ </para>
+
+ <programlisting><![CDATA[<listener type="pre-delete" class="org.hibernate.secure.JACCPreDeleteEventListener"/>
+<listener type="pre-update" class="org.hibernate.secure.JACCPreUpdateEventListener"/>
+<listener type="pre-insert" class="org.hibernate.secure.JACCPreInsertEventListener"/>
+<listener type="pre-load" class="org.hibernate.secure.JACCPreLoadEventListener"/>]]></programlisting>
+
+ <para>
+ ����̃C�x���g�^�ɑ��Ă��傤�Lj�̃��X�i������Ƃ��A
+ <literal><listener type="..." class="..."/></literal>
+ �� <literal><event type="..."><listener class="..."/></event></literal>
+ �̊ȗ��`�ɉ߂��Ȃ����Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ ���ɁA������ <literal>hibernate.cfg.xml</literal> �Ń��[���Ƀp�[�~�b�V������^���Ă��������F
+ </para>
+
+ <programlisting><![CDATA[<grant role="admin" entity-name="User" actions="insert,update,read"/>
+<grant role="su" entity-name="User" actions="*"/>]]></programlisting>
+
+ <para>
+ ���̃��[�����͎g�p����JACC�v���o�C�_�ɗ�����郍�[���ł��B
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/example_mappings.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/example_mappings.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/example_mappings.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/example_mappings.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,659 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<chapter id="example-mappings">
+ <title>��F���낢��ȃ}�b�s���O</title>
+
+ <para>
+ ���̏͂ł́A��蕡�G�Ȋ֘A�̃}�b�s���O�������Љ�܂��B
+ </para>
+
+ <sect1 id="example-mappings-emp">
+ <title>�ٗp��/�]�ƈ�</title>
+
+ <para>
+ <literal>Employer</literal> �� <literal>Employee</literal> �̊W��\���ȉ��̃��f���́A
+ �֘A�̕\���Ɏ��ۂ̃G���e�B�e�B�N���X�i <literal>Employment</literal> �j
+ ��g���܂��B
+ �Ȃ��Ȃ�A����2�̃p�[�e�B�ɕ����̊��Ԍٗp�����Ƃ������Ƃ����肦�邩��ł��B
+ ����̒l�Ə]�ƈ��̖��O���f�������邽�߂ɃR���|�[�l���g��g���Ă��܂��B
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/EmployerEmployee.png" format="PNG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/EmployerEmployee.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ �}�b�s���O�h�L�������g�̈��ł��F
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Employer" table="employers">
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employer_id_seq</param>
+ </generator>
+ </id>
+ <property name="name"/>
+ </class>
+
+ <class name="Employment" table="employment_periods">
+
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employment_id_seq</param>
+ </generator>
+ </id>
+ <property name="startDate" column="start_date"/>
+ <property name="endDate" column="end_date"/>
+
+ <component name="hourlyRate" class="MonetaryAmount">
+ <property name="amount">
+ <column name="hourly_rate" sql-type="NUMERIC(12, 2)"/>
+ </property>
+ <property name="currency" length="12"/>
+ </component>
+
+ <many-to-one name="employer" column="employer_id" not-null="true"/>
+ <many-to-one name="employee" column="employee_id" not-null="true"/>
+
+ </class>
+
+ <class name="Employee" table="employees">
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employee_id_seq</param>
+ </generator>
+ </id>
+ <property name="taxfileNumber"/>
+ <component name="name" class="Name">
+ <property name="firstName"/>
+ <property name="initial"/>
+ <property name="lastName"/>
+ </component>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>SchemaExport</literal> �Ő��������e�[�u���X�L�[�}�ł��B
+ </para>
+
+ <programlisting><![CDATA[create table employers (
+ id BIGINT not null,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+create table employment_periods (
+ id BIGINT not null,
+ hourly_rate NUMERIC(12, 2),
+ currency VARCHAR(12),
+ employee_id BIGINT not null,
+ employer_id BIGINT not null,
+ end_date TIMESTAMP,
+ start_date TIMESTAMP,
+ primary key (id)
+)
+
+create table employees (
+ id BIGINT not null,
+ firstName VARCHAR(255),
+ initial CHAR(1),
+ lastName VARCHAR(255),
+ taxfileNumber VARCHAR(255),
+ primary key (id)
+)
+
+alter table employment_periods
+ add constraint employment_periodsFK0 foreign key (employer_id) references employers
+alter table employment_periods
+ add constraint employment_periodsFK1 foreign key (employee_id) references employees
+create sequence employee_id_seq
+create sequence employment_id_seq
+create sequence employer_id_seq]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-mappings-authorwork">
+ <title>���/��i</title>
+
+ <para>
+ <literal>Work</literal> , <literal>Author</literal> ������ <literal>Person</literal>
+ �̊W��\���ȉ��̃��f����l���Ă݂Ă��������B
+ <literal>Work</literal> �� <literal>Author</literal> �̊W�𑽑Α��֘A�ŕ\���Ă��܂��B
+ <literal>Author</literal> �� <literal>Person</literal> �̊W�͈�Έ�֘A�Ƃ��ĕ\���Ă��܂��B
+ ���ɂ� <literal>Author</literal> �� <literal>Person</literal> ��g������Ƃ������@�����܂��B
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/AuthorWork.png" format="PNG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/AuthorWork.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ �ȉ��̃}�b�s���O�h�L�������g�͂��̂悤�ȊW�𐳊m�ɕ\�����Ă��܂��B
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Work" table="works" discriminator-value="W">
+
+ <id name="id" column="id">
+ <generator class="native"/>
+ </id>
+ <discriminator column="type" type="character"/>
+
+ <property name="title"/>
+ <set name="authors" table="author_work">
+ <key column name="work_id"/>
+ <many-to-many class="Author" column name="author_id"/>
+ </set>
+
+ <subclass name="Book" discriminator-value="B">
+ <property name="text"/>
+ </subclass>
+
+ <subclass name="Song" discriminator-value="S">
+ <property name="tempo"/>
+ <property name="genre"/>
+ </subclass>
+
+ </class>
+
+ <class name="Author" table="authors">
+
+ <id name="id" column="id">
+ <!-- The Author must have the same identifier as the Person -->
+ <generator class="assigned"/>
+ </id>
+
+ <property name="alias"/>
+ <one-to-one name="person" constrained="true"/>
+
+ <set name="works" table="author_work" inverse="true">
+ <key column="author_id"/>
+ <many-to-many class="Work" column="work_id"/>
+ </set>
+
+ </class>
+
+ <class name="Person" table="persons">
+ <id name="id" column="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ ���̃}�b�s���O�ɂ�4�̃e�[�u��������܂��B
+ <literal>works</literal> , <literal>authors</literal> , <literal>persons</literal>
+ �͂��ꂼ��A�d���A��ҁA�l�̃f�[�^��ێ����܂��B
+ <literal>author_work</literal> �͍�҂ƍ�i�����N����֘A�e�[�u���ł��B
+ �ȉ��� <literal>SchemaExport</literal> �Ő��������e�[�u���X�L�[�}�ł��B
+ </para>
+
+ <programlisting><![CDATA[create table works (
+ id BIGINT not null generated by default as identity,
+ tempo FLOAT,
+ genre VARCHAR(255),
+ text INTEGER,
+ title VARCHAR(255),
+ type CHAR(1) not null,
+ primary key (id)
+)
+
+create table author_work (
+ author_id BIGINT not null,
+ work_id BIGINT not null,
+ primary key (work_id, author_id)
+)
+
+create table authors (
+ id BIGINT not null generated by default as identity,
+ alias VARCHAR(255),
+ primary key (id)
+)
+
+create table persons (
+ id BIGINT not null generated by default as identity,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+alter table authors
+ add constraint authorsFK0 foreign key (id) references persons
+alter table author_work
+ add constraint author_workFK0 foreign key (author_id) references authors
+alter table author_work
+ add constraint author_workFK1 foreign key (work_id) references works]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-mappings-customerorderproduct">
+ <title>�ڋq/����/���i</title>
+
+ <para>
+ ���āA <literal>Customer</literal> , <literal>Order</literal> , <literal>LineItem</literal>
+ <literal>Product</literal> �̊W��\�����f����l���Ă݂܂��傤�B
+ <literal>Customer</literal> �� <literal>Order</literal> �͈�Α��̊֘A�ł����A
+ <literal>Order</literal> / <literal>LineItem</literal> / <literal>Product</literal>
+ �͂ǂ̂悤�ɕ\������ׂ��ł��傤���H
+ <literal>LineItem</literal> ��A<literal>Order</literal> �� <literal>Product</literal>
+ �̑��Α��֘A��\������֘A�N���X�Ƃ��ă}�b�s���O���܂����B
+ Hibernate�ł͂����R���|�W�b�g�v�f�ƌĂт܂��B
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/CustomerOrderProduct.png" format="PNG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/CustomerOrderProduct.png" format="PNG" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ �}�b�s���O�h�L�������g�F
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Customer" table="customers">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ <set name="orders" inverse="true">
+ <key column="customer_id"/>
+ <one-to-many class="Order"/>
+ </set>
+ </class>
+
+ <class name="Order" table="orders">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="date"/>
+ <many-to-one name="customer" column="customer_id"/>
+ <list name="lineItems" table="line_items">
+ <key column="order_id"/>
+ <list-index column="line_number"/>
+ <composite-element class="LineItem">
+ <property name="quantity"/>
+ <many-to-one name="product" column="product_id"/>
+ </composite-element>
+ </list>
+ </class>
+
+ <class name="Product" table="products">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="serialNumber"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>customers</literal> , <literal>orders</literal> , <literal>line_items</literal> ,
+ <literal>products</literal> �͂��ꂼ��A�ڋq�A�����A�������ׁA���i�̃f�[�^��ێ����܂��B
+ <literal>line_items</literal> �͒����Ɛ��i�����N����֘A�e�[�u���Ƃ��Ă�����܂��B
+ </para>
+
+ <programlisting><![CDATA[create table customers (
+ id BIGINT not null generated by default as identity,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+create table orders (
+ id BIGINT not null generated by default as identity,
+ customer_id BIGINT,
+ date TIMESTAMP,
+ primary key (id)
+)
+
+create table line_items (
+ line_number INTEGER not null,
+ order_id BIGINT not null,
+ product_id BIGINT,
+ quantity INTEGER,
+ primary key (order_id, line_number)
+)
+
+create table products (
+ id BIGINT not null generated by default as identity,
+ serialNumber VARCHAR(255),
+ primary key (id)
+)
+
+alter table orders
+ add constraint ordersFK0 foreign key (customer_id) references customers
+alter table line_items
+ add constraint line_itemsFK0 foreign key (product_id) references products
+alter table line_items
+ add constraint line_itemsFK1 foreign key (order_id) references orders]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="misc">
+ <title>��X�G���ȃ}�b�s���O��</title>
+
+ <para>
+ �����ɂ����͂��ׂ�Hibernate�̃e�X�g�X�C�[�g������܂����B
+ �����ɂ́A���ɂ��������̃}�b�s���O�̗Ⴊ����܂��B
+ Hibernate�f�B�X�g���r���[�V������ <literal>test</literal> �t�H���_�����������B
+ </para>
+
+ <para>TODO: �����ɕ��͂߂�</para>
+
+ <sect2 id="example-mappings-typed-onetone">
+ <title>�u�^�t�����ꂽ�v��Έ�֘A</title>
+<programlisting><![CDATA[<class name="Person">
+ <id name="name"/>
+ <one-to-one name="address"
+ cascade="all">
+ <formula>name</formula>
+ <formula>'HOME'</formula>
+ </one-to-one>
+ <one-to-one name="mailingAddress"
+ cascade="all">
+ <formula>name</formula>
+ <formula>'MAILING'</formula>
+ </one-to-one>
+</class>
+
+<class name="Address" batch-size="2"
+ check="addressType in ('MAILING', 'HOME', 'BUSINESS')">
+ <composite-id>
+ <key-many-to-one name="person"
+ column="personName"/>
+ <key-property name="type"
+ column="addressType"/>
+ </composite-id>
+ <property name="street" type="text"/>
+ <property name="state"/>
+ <property name="zip"/>
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-composite-key">
+ <title>�����L�[�̗�</title>
+<programlisting><![CDATA[<class name="Customer">
+
+ <id name="customerId"
+ length="10">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="name" not-null="true" length="100"/>
+ <property name="address" not-null="true" length="200"/>
+
+ <list name="orders"
+ inverse="true"
+ cascade="save-update">
+ <key column="customerId"/>
+ <index column="orderNumber"/>
+ <one-to-many class="Order"/>
+ </list>
+
+</class>
+
+<class name="Order" table="CustomerOrder" lazy="true">
+ <synchronize table="LineItem"/>
+ <synchronize table="Product"/>
+
+ <composite-id name="id"
+ class="Order$Id">
+ <key-property name="customerId" length="10"/>
+ <key-property name="orderNumber"/>
+ </composite-id>
+
+ <property name="orderDate"
+ type="calendar_date"
+ not-null="true"/>
+
+ <property name="total">
+ <formula>
+ ( select sum(li.quantity*p.price)
+ from LineItem li, Product p
+ where li.productId = p.productId
+ and li.customerId = customerId
+ and li.orderNumber = orderNumber )
+ </formula>
+ </property>
+
+ <many-to-one name="customer"
+ column="customerId"
+ insert="false"
+ update="false"
+ not-null="true"/>
+
+ <bag name="lineItems"
+ fetch="join"
+ inverse="true"
+ cascade="save-update">
+ <key>
+ <column name="customerId"/>
+ <column name="orderNumber"/>
+ </key>
+ <one-to-many class="LineItem"/>
+ </bag>
+
+</class>
+
+<class name="LineItem">
+
+ <composite-id name="id"
+ class="LineItem$Id">
+ <key-property name="customerId" length="10"/>
+ <key-property name="orderNumber"/>
+ <key-property name="productId" length="10"/>
+ </composite-id>
+
+ <property name="quantity"/>
+
+ <many-to-one name="order"
+ insert="false"
+ update="false"
+ not-null="true">
+ <column name="customerId"/>
+ <column name="orderNumber"/>
+ </many-to-one>
+
+ <many-to-one name="product"
+ insert="false"
+ update="false"
+ not-null="true"
+ column="productId"/>
+
+</class>
+
+<class name="Product">
+ <synchronize table="LineItem"/>
+
+ <id name="productId"
+ length="10">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="description"
+ not-null="true"
+ length="200"/>
+ <property name="price" length="3"/>
+ <property name="numberAvailable"/>
+
+ <property name="numberOrdered">
+ <formula>
+ ( select sum(li.quantity)
+ from LineItem li
+ where li.productId = productId )
+ </formula>
+ </property>
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-composite-key-manytomany">
+ <title>�����L�[�������L���鑽�Α�</title>
+<programlisting><![CDATA[<class name="User" table="`User`">
+ <composite-id>
+ <key-property name="name"/>
+ <key-property name="org"/>
+ </composite-id>
+ <set name="groups" table="UserGroup">
+ <key>
+ <column name="userName"/>
+ <column name="org"/>
+ </key>
+ <many-to-many class="Group">
+ <column name="groupName"/>
+ <formula>org</formula>
+ </many-to-many>
+ </set>
+</class>
+
+<class name="Group" table="`Group`">
+ <composite-id>
+ <key-property name="name"/>
+ <key-property name="org"/>
+ </composite-id>
+ <property name="description"/>
+ <set name="users" table="UserGroup" inverse="true">
+ <key>
+ <column name="groupName"/>
+ <column name="org"/>
+ </key>
+ <many-to-many class="User">
+ <column name="userName"/>
+ <formula>org</formula>
+ </many-to-many>
+ </set>
+</class>
+]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-content-discrimination">
+ <title>discrimination�Ɋ�Â���e</title>
+<programlisting><![CDATA[<class name="Person"
+ discriminator-value="P">
+
+ <id name="id"
+ column="person_id"
+ unsaved-value="0">
+ <generator class="native"/>
+ </id>
+
+
+ <discriminator
+ type="character">
+ <formula>
+ case
+ when title is not null then 'E'
+ when salesperson is not null then 'C'
+ else 'P'
+ end
+ </formula>
+ </discriminator>
+
+ <property name="name"
+ not-null="true"
+ length="80"/>
+
+ <property name="sex"
+ not-null="true"
+ update="false"/>
+
+ <component name="address">
+ <property name="address"/>
+ <property name="zip"/>
+ <property name="country"/>
+ </component>
+
+ <subclass name="Employee"
+ discriminator-value="E">
+ <property name="title"
+ length="20"/>
+ <property name="salary"/>
+ <many-to-one name="manager"/>
+ </subclass>
+
+ <subclass name="Customer"
+ discriminator-value="C">
+ <property name="comments"/>
+ <many-to-one name="salesperson"/>
+ </subclass>
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-association-alternatekeys" revision="2">
+ <title>��փL�[�̊֘A</title>
+<programlisting><![CDATA[<class name="Person">
+
+ <id name="id">
+ <generator class="hilo"/>
+ </id>
+
+ <property name="name" length="100"/>
+
+ <one-to-one name="address"
+ property-ref="person"
+ cascade="all"
+ fetch="join"/>
+
+ <set name="accounts"
+ inverse="true">
+ <key column="userId"
+ property-ref="userId"/>
+ <one-to-many class="Account"/>
+ </set>
+
+ <property name="userId" length="8"/>
+
+</class>
+
+<class name="Address">
+
+ <id name="id">
+ <generator class="hilo"/>
+ </id>
+
+ <property name="address" length="300"/>
+ <property name="zip" length="5"/>
+ <property name="country" length="25"/>
+ <many-to-one name="person" unique="true" not-null="true"/>
+
+</class>
+
+<class name="Account">
+ <id name="accountId" length="32">
+ <generator class="uuid"/>
+ </id>
+
+ <many-to-one name="user"
+ column="userId"
+ property-ref="userId"/>
+
+ <property name="type" not-null="true"/>
+
+</class>]]></programlisting>
+ </sect2>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/example_parentchild.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/example_parentchild.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/example_parentchild.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/example_parentchild.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,362 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="example-parentchild">
+ <title>��F�e/�q��
+ </title>
+
+ <para>
+ �V�K���[�U��Hibernate��g���Ă܂��ŏ��Ɉ������f���̈�ɁA�e�q�^�̃��f����������܂��B
+ ���̃��f�����ɂ͓�̃A�v���[�`�����݂��܂��B�Ƃ�킯�V�K���[�U�ɂƂ��āA
+ ���܂��܂ȗ��R����ł�֗����Ǝv����A�v���[�`�́A<literal>�e</literal> ���� <literal>�q��</literal>
+ �ւ� <literal><one-to-many></literal> �֘A�ɂ�� <literal>�e</literal> �� <literal>�q��</literal>
+ �̗�����G���e�B�e�B�N���X�Ƃ��ă��f�����O������@�ł�
+ �i�����̕��@�́A<literal>�q��</literal> �� <literal><composite-element></literal> �Ƃ��Ē�`�����̂ł��j�B
+ ����ŁiHibernate�ɂ�����j��Α��֘A�̃f�t�H���g�̃Z�}���e�B�N�X���A�ʏ�̕����v�f�̃}�b�s���O����A
+ �e�q�W�̃Z�}���e�B�N�X���牓�����Ƃ��킩��܂��B
+ ����ł͐e�q�W������I���G���K���g�Ƀ��f�����O���邽�߂ɁA
+ <emphasis>�J�X�P�[�h�����g�����o������Α��֘A</emphasis> �̈������������܂��B����͂܂����������̂ł͂���܂���B
+
+ </para>
+
+ <sect1 id="example-parentchild-collections">
+ <title>�R���N�V�����Ɋւ��钍��</title>
+
+ <para>
+ Hibernate�̃R���N�V�����͎��g�̃G���e�B�e�B�̘_���I�ȕ����ƍl�����A
+ �����ĕ�܂���G���e�B�e�B�̂�̂ł͂���܂���B����͒v���I�ȈႢ�ł��I
+ ����͈ȉ��̂悤�Ȍ��ʂɂȂ�܂��F
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ �I�u�W�F�N�g��R���N�V��������폜�A�܂��̓R���N�V�����ɒlj�����Ƃ��A
+ �R���N�V�����̃I�[�i�[�̃o�[�W�����ԍ��̓C���N�������g����܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ����R���N�V��������폜���ꂽ�I�u�W�F�N�g���l�^�̃C���X�^���X
+ �i�Ⴆ�R���|�W�b�g�G�������g)�������Ȃ�A���̃I�u�W�F�N�g�͉i���I�ł͂Ȃ��Ȃ�A
+ ���̏�Ԃ̓f�[�^�x�[�X���犮�S�ɍ폜����܂��B
+ �����悤�ɁA�l�^�̃C���X�^���X��R���N�V�����ɒlj�����ƁA���̏�Ԃ͂����ɉi���I�ɂȂ�܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ����A����G���e�B�e�B���R���N�V�����i��Α��܂��͑��Α��֘A)����폜����Ă�A
+ �f�t�H���g�ł͂���͍폜����܂���B���̓���͊��S�Ɉ�т��Ă��܂��B
+ ���Ȃ킿�A���̃G���e�B�e�B�̓����Ԃ�ύX���Ă�A�֘A����G���e�B�e�B�����ł��ׂ��ł͂Ȃ��Ƃ������Ƃł��B
+ ���l�ɁA�G���e�B�e�B���R���N�V�����ɒlj�����Ă�A�f�t�H���g�ł͂��̃G���e�B�e�B�͉i���I�ɂ͂Ȃ�܂���B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ���̑���ɁA�f�t�H���g�̓���ł́A�G���e�B�e�B��R���N�V�����ɒlj�����ƒP�ɓ�̃G���e�B�e�B�Ԃ̃����N��쐬���A
+ ����G���e�B�e�B��폜����ƃ����N��폜���܂��B����͂��ׂẴP�[�X�ɂ����Ĕ��ɓK�ł��B
+ ���ꂪ�K�łȂ��̂͐e/�q�W�̏ꍇ�ł��B���̏ꍇ�q���̐����͐e�̃��C�t�T�C�N���ɐ�������邩��ł��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-bidir">
+ <title>�o������Α�
+ </title>
+
+ <para>
+ <literal>Parent</literal> ���� <literal>Child</literal> �ւ̒P���� <literal><one-to-many></literal> �֘A����n�߂�Ƃ��܂��B
+ </para>
+
+ <programlisting><![CDATA[<set name="children">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ �ȉ��̃R�[�h����s����ƁA
+ </para>
+
+ <programlisting><![CDATA[Parent p = .....;
+Child c = new Child();
+p.getChildren().add(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ <para>
+ Hibernate�͓��SQL���s���܂�:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>c</literal>�ɑ��郌�R�[�h������<literal>INSERT</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>p</literal>����<literal>c</literal>�ւ̃����N��쐬����<literal>UPDATE</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ����͔�����I�Ȃ����ł͂Ȃ��A<literal>parent_id</literal> �J�����ɂ����� <literal>NOT NULL</literal> ����Ɉᔽ���܂��B
+ �R���N�V�����̃}�b�s���O�� <literal>not-null="true"</literal> �Ǝw�肷�邱�ƂŁAnull����ᔽ������邱�Ƃ��ł��܂�:
+ </para>
+
+ <programlisting><![CDATA[<set name="children">
+ <key column="parent_id" not-null="true"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ ���������̉���͐����ł��܂���B
+ </para>
+ <para>
+ ���̓���̍��{�I�Ȍ����́A<literal>p</literal> ���� <literal>c</literal> �ւ̃����N
+ �i�O���L�[ <literal>parent_id</literal>)�� <literal>Child</literal> �I�u�W�F�N�g�̏�Ԃ̈ꕔ�Ƃ͍l����ꂸ�A
+ ���̂��� <literal>INSERT</literal> �ɂ���ă����N����������Ȃ����Ƃł��B
+ �ł�����A����̓����N��Child�}�b�s���O�̈ꕔ�ɂ��邱�Ƃł��B
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="parent" column="parent_id" not-null="true"/>]]></programlisting>
+
+ <para>
+ (�܂� <literal>Child</literal> �N���X�� <literal>parent</literal> �v���p�e�B��lj�����K�v������܂��B)
+ </para>
+
+ <para>
+ ����ł� <literal>Child</literal> �G���e�B�e�B�������N�̏�Ԃ𐧌䂷��悤�ɂȂ����̂ŁA
+ �R���N�V�����������N��X�V���Ȃ��悤�ɂ��܂��傤�B����ɂ� <literal>inverse</literal> ������g���܂��B
+ </para>
+
+ <programlisting><![CDATA[<set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ �ȉ��̃R�[�h��g���A�V���� <literal>Child</literal> ��lj����邱�Ƃ��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+c.setParent(p);
+p.getChildren().add(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ <para>
+ ����ɂ��ASQL�� <literal>INSERT</literal> ��������������s�����悤�ɂȂ�܂����I
+ </para>
+
+ <para>
+ ���������������ɂ́A<literal>Parent</literal> �� <literal>addChild()</literal> ���\�b�h��쐬���܂��B
+ </para>
+
+ <programlisting><![CDATA[public void addChild(Child c) {
+ c.setParent(this);
+ children.add(c);
+}]]></programlisting>
+
+ <para>
+ <literal>Child</literal> ��lj�����R�[�h�͂��̂悤�ɂȂ�܂��B
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+p.addChild(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-cascades">
+ <title>���C�t�T�C�N���̃J�X�P�[�h</title>
+
+ <para>
+ �����I�� <literal>save()</literal> ��R�[������̂͂܂��ς킵����̂ł��B�����J�X�P�[�h��g���đΏ����܂��B
+ </para>
+
+ <programlisting><![CDATA[<set name="children" inverse="true" cascade="all">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ ����ɂ���قǂ̃R�[�h���̂悤�ɒP�������܂�
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+p.addChild(c);
+session.flush();]]></programlisting>
+
+ <para>
+ ���l�� <literal>Parent</literal> ��ۑ��܂��͍폜����Ƃ��ɁA�q��������o���Ĉ����K�v�͂���܂���B
+ �ȉ��̃R�[�h�� <literal>p</literal> ��폜���A�����ăf�[�^�x�[�X���炻�̎q�����ׂč폜���܂��B
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+session.delete(p);
+session.flush();]]></programlisting>
+
+ <para>
+ ���������̃R�[�h��
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = (Child) p.getChildren().iterator().next();
+p.getChildren().remove(c);
+c.setParent(null);
+session.flush();]]></programlisting>
+
+ <para>
+ �f�[�^�x�[�X���� <literal>c</literal> ��폜���܂���B<literal>p</literal> �ւ̃����N��폜����
+ �i�����Ă��̃P�[�X�ł� <literal>NOT NULL</literal> ����ᔽ������N�����j�����ł��B
+ <literal>Child</literal> �� <literal>delete()</literal> ������K�v������܂��B
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = (Child) p.getChildren().iterator().next();
+p.getChildren().remove(c);
+session.delete(c);
+session.flush();]]></programlisting>
+
+ <para>
+ �����̃P�[�X�ł͎��ۂ� <literal>Child</literal> ���e�Ȃ��ł͑��݂ł��Ȃ��悤�ɂȂ�܂����B
+ ���̂��߁A����R���N�V�������� <literal>Child</literal> ���菜���ꍇ�A�����폜�������ł��B
+ ���̂��߂ɂ� <literal>cascade="all-delete-orphan"</literal> ��g��Ȃ���Ȃ�܂���B
+ </para>
+
+ <programlisting><![CDATA[<set name="children" inverse="true" cascade="all-delete-orphan">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ ���ӁF�R���N�V�����̃}�b�s���O�� <literal>inverse="true"</literal> �Ǝw�肵�Ă�A
+ �R���N�V�����̗v�f�̃C�e���[�V�����ɂ���āA�ˑR�J�X�P�[�h�����s����܂��B
+ ���̂��߂���J�X�P�[�h�ŃI�u�W�F�N�g��Z�[�u�A�폜�A�X�V����K�v������Ȃ�A
+ �����R���N�V�����ɒlj����Ȃ���Ȃ�܂���B�P�� <literal>setParent()</literal> ��ĂԂ����ł͕s�\���ł��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-update">
+ <title>�J�X�P�[�h�� <literal>unsaved-value</literal></title>
+
+ <para>
+ <literal>Parent</literal> ���A���� <literal>Session</literal> �Ń��[�h����AUI�̃A�N�V�����ŕύX���������A
+ <literal>update()</literal> ��Ă�ł��̕ύX��V�����Z�b�V�����ʼni�����������Ƃ��܂��B
+ <literal>Parent</literal> ���q���̃R���N�V���������A�J�X�P�[�h�X�V���L���ɂȂ��Ă��邽�߁A
+ Hibernate�͂ǂ̎q�����V�����C���X�^���X�����ꂽ���A�ǂꂪ�f�[�^�x�[�X�̊����̍s�ɑ�������̂���m��K�v������܂��B
+ <literal>Parent</literal> �� <literal>Child</literal> �̗����� <literal>java.lang.Long</literal>
+ �^�̎��ʃv���p�e�B�������Ƃ��܂��傤�B
+ Hibernate�͂ǂ̎q�����V������̂����肷�邽�߂Ɏ��ʃv���p�e�B�̒l��g���܂�(version��timestamp�v���p�e�B��g���܂��B
+ <xref linkend="manipulatingdata-updating-detached"/> �Q��)�BHibernate3�ɂȂ��āA
+ �����I�� <literal>unsaved-value</literal> ��w�肷��K�v�͂Ȃ��Ȃ�܂����B
+ </para>
+
+ <para>
+ �ȉ��̃R�[�h�� <literal>parent</literal> �� <literal>child</literal> ��X�V���A<literal>newChild</literal> ��}�����܂��B
+ </para>
+
+ <programlisting><![CDATA[//parent and child were both loaded in a previous session
+//parent��child�͗����Ƃ�A�ȑO��Session�Ń��[�h����Ă��܂�
+parent.addChild(child);
+Child newChild = new Child();
+parent.addChild(newChild);
+session.update(parent);
+session.flush();]]></programlisting>
+
+ <para>
+ �����͐������ꂽ���ʎq�̏ꍇ�ɂ͔��ɗǂ��̂ł����A���蓖�Ă�ꂽ���ʎq�ƕ������ʎq�̏ꍇ�͂ǂ��ł��傤���H
+ �����Hibernate���A�i���[�U�ɂ�芄�蓖�Ă�ꂽ���ʎq���j�V�����C���X�^���X�����ꂽ�I�u�W�F�N�g�ƁA
+ �ȑO��Session�Ń��[�h���ꂽ�I�u�W�F�N�g���ʂł��Ȃ����߁A������ł��B
+ ���̏ꍇ�AHibernate�̓^�C���X�^���v���o�[�W�����̃v���p�e�B�̂ǂ��炩��g�����A�L���b�V���ɖ₢���킹�܂��B
+ �ň��̏ꍇ�A�s�����݂��邩�ǂ����f�[�^�x�[�X���܂��B
+ </para>
+
+ <!-- undocumenting
+ <para>
+ There is one further possibility. The <literal>Interceptor</literal> method named
+ <literal>isUnsaved()</literal> lets the application implement its own strategy for distinguishing
+ newly instantiated objects. For example, you could define a base class for your persistent classes.
+ </para>
+
+ <programlisting><![CDATA[public class Persistent {
+ private boolean _saved = false;
+ public void onSave() {
+ _saved=true;
+ }
+ public void onLoad() {
+ _saved=true;
+ }
+ ......
+ public boolean isSaved() {
+ return _saved;
+ }
+}]]></programlisting>
+
+ <para>
+ (The <literal>saved</literal> property is non-persistent.)
+ Now implement <literal>isUnsaved()</literal>, along with <literal>onLoad()</literal>
+ and <literal>onSave()</literal> as follows.
+ </para>
+
+ <programlisting><![CDATA[public Boolean isUnsaved(Object entity) {
+ if (entity instanceof Persistent) {
+ return new Boolean( !( (Persistent) entity ).isSaved() );
+ }
+ else {
+ return null;
+ }
+}
+
+public boolean onLoad(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if (entity instanceof Persistent) ( (Persistent) entity ).onLoad();
+ return false;
+}
+
+public boolean onSave(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if (entity instanceof Persistent) ( (Persistent) entity ).onSave();
+ return false;
+}]]></programlisting>
+
+ <para>
+ Don't worry; in Hibernate3 you don't need to write any of this kind of code if you don't want to.
+ </para>
+ -->
+ </sect1>
+
+ <sect1 id="example-parentchild-conclusion">
+ <title>���_
+ </title>
+
+ <para>
+ �����ł͂��Ȃ�̗ʂ�v���̂ŁA�ŏ��̍��͍������Ă���悤�Ɏv���邩�����܂���B
+ ���������ۂ́A���ׂĔ��ɗǂ����삵�܂��B�قƂ�ǂ�Hibernate�A�v���P�[�V�����ł́A�����̏�ʂŐe�q�p�^�[����g�p���܂��B
+ </para>
+
+ <para>
+ �ŏ��̒i���ő�֕��@�ɂ��ĐG��܂����B��L�̂悤�Ȗ��� <literal><composite-element></literal> �}�b�s���O�̏ꍇ�͑��݂����A
+ �ɂ������炸����͊m���ɐe�q�W�̃Z�}���e�B�N�X�����܂��B
+ �������c�O�Ȃ���A�����v�f�N���X�ɂ͓�̑傫�Ȑ���������܂��F
+ 1�͕����v�f�̓R���N�V���������Ƃ��ł��Ȃ����Ƃł��B����ЂƂ́A
+ ���j�[�N�Ȑe�ł͂Ȃ��G���e�B�e�B�̎q���ƂȂ�ׂ��ł͂Ȃ��Ƃ������Ƃł�
+ </para>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/example_weblog.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/example_weblog.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/example_weblog.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/example_weblog.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,433 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="example-weblog">
+ <title>��: Weblog�A�v���P�[�V����</title>
+
+ <sect1 id="example-weblog-classes">
+ <title>�i���N���X
+ </title>
+
+ <para>
+ �i���N���X���E�F�u���O�ƁA�E�F�u���O�Ɍf�����ꂽ���ڂ�\���Ă��܂��B
+ �����͒ʏ�̐e�q�W�Ƃ��ă��f�����O����܂����A
+ set�ł͂Ȃ�����������bag��g�p���邱�Ƃɂ��܂��B
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+import java.util.List;
+
+public class Blog {
+ private Long _id;
+ private String _name;
+ private List _items;
+
+ public Long getId() {
+ return _id;
+ }
+ public List getItems() {
+ return _items;
+ }
+ public String getName() {
+ return _name;
+ }
+ public void setId(Long long1) {
+ _id = long1;
+ }
+ public void setItems(List list) {
+ _items = list;
+ }
+ public void setName(String string) {
+ _name = string;
+ }
+}]]></programlisting>
+
+ <programlisting><![CDATA[package eg;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+
+public class BlogItem {
+ private Long _id;
+ private Calendar _datetime;
+ private String _text;
+ private String _title;
+ private Blog _blog;
+
+ public Blog getBlog() {
+ return _blog;
+ }
+ public Calendar getDatetime() {
+ return _datetime;
+ }
+ public Long getId() {
+ return _id;
+ }
+ public String getText() {
+ return _text;
+ }
+ public String getTitle() {
+ return _title;
+ }
+ public void setBlog(Blog blog) {
+ _blog = blog;
+ }
+ public void setDatetime(Calendar calendar) {
+ _datetime = calendar;
+ }
+ public void setId(Long long1) {
+ _id = long1;
+ }
+ public void setText(String string) {
+ _text = string;
+ }
+ public void setTitle(String string) {
+ _title = string;
+ }
+}]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-weblog-mappings">
+ <title>Hibernate�̃}�b�s���O
+ </title>
+
+ <para>
+ XML�}�b�s���O�́A���ł͂ƂĂ�ȒP�Ȃ͂��ł��B
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class
+ name="Blog"
+ table="BLOGS">
+
+ <id
+ name="id"
+ column="BLOG_ID">
+
+ <generator class="native"/>
+
+ </id>
+
+ <property
+ name="name"
+ column="NAME"
+ not-null="true"
+ unique="true"/>
+
+ <bag
+ name="items"
+ inverse="true"
+ order-by="DATE_TIME"
+ cascade="all">
+
+ <key column="BLOG_ID"/>
+ <one-to-many class="BlogItem"/>
+
+ </bag>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class
+ name="BlogItem"
+ table="BLOG_ITEMS"
+ dynamic-update="true">
+
+ <id
+ name="id"
+ column="BLOG_ITEM_ID">
+
+ <generator class="native"/>
+
+ </id>
+
+ <property
+ name="title"
+ column="TITLE"
+ not-null="true"/>
+
+ <property
+ name="text"
+ column="TEXT"
+ not-null="true"/>
+
+ <property
+ name="datetime"
+ column="DATE_TIME"
+ not-null="true"/>
+
+ <many-to-one
+ name="blog"
+ column="BLOG_ID"
+ not-null="true"/>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-weblog-code">
+ <title>Hibernate�̃R�[�h</title>
+
+ <para>
+ �ȉ��̃N���X�́A
+ Hibernate�ł����̃N���X��g���Ăł��邱�Ƃ����������Ă��܂��B
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.tool.hbm2ddl.SchemaExport;
+
+public class BlogMain {
+
+ private SessionFactory _sessions;
+
+ public void configure() throws HibernateException {
+ _sessions = new Configuration()
+ .addClass(Blog.class)
+ .addClass(BlogItem.class)
+ .buildSessionFactory();
+ }
+
+ public void exportTables() throws HibernateException {
+ Configuration cfg = new Configuration()
+ .addClass(Blog.class)
+ .addClass(BlogItem.class);
+ new SchemaExport(cfg).create(true, true);
+ }
+
+ public Blog createBlog(String name) throws HibernateException {
+
+ Blog blog = new Blog();
+ blog.setName(name);
+ blog.setItems( new ArrayList() );
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.persist(blog);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return blog;
+ }
+
+ public BlogItem createBlogItem(Blog blog, String title, String text)
+ throws HibernateException {
+
+ BlogItem item = new BlogItem();
+ item.setTitle(title);
+ item.setText(text);
+ item.setBlog(blog);
+ item.setDatetime( Calendar.getInstance() );
+ blog.getItems().add(item);
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.update(blog);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return item;
+ }
+
+ public BlogItem createBlogItem(Long blogid, String title, String text)
+ throws HibernateException {
+
+ BlogItem item = new BlogItem();
+ item.setTitle(title);
+ item.setText(text);
+ item.setDatetime( Calendar.getInstance() );
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ Blog blog = (Blog) session.load(Blog.class, blogid);
+ item.setBlog(blog);
+ blog.getItems().add(item);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return item;
+ }
+
+ public void updateBlogItem(BlogItem item, String text)
+ throws HibernateException {
+
+ item.setText(text);
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.update(item);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ }
+
+ public void updateBlogItem(Long itemid, String text)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ BlogItem item = (BlogItem) session.load(BlogItem.class, itemid);
+ item.setText(text);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ }
+
+ public List listAllBlogNamesAndItemCounts(int max)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ List result = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "select blog.id, blog.name, count(blogItem) " +
+ "from Blog as blog " +
+ "left outer join blog.items as blogItem " +
+ "group by blog.name, blog.id " +
+ "order by max(blogItem.datetime)"
+ );
+ q.setMaxResults(max);
+ result = q.list();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return result;
+ }
+
+ public Blog getBlogAndAllItems(Long blogid)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ Blog blog = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "from Blog as blog " +
+ "left outer join fetch blog.items " +
+ "where blog.id = :blogid"
+ );
+ q.setParameter("blogid", blogid);
+ blog = (Blog) q.uniqueResult();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return blog;
+ }
+
+ public List listBlogsAndRecentItems() throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ List result = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "from Blog as blog " +
+ "inner join blog.items as blogItem " +
+ "where blogItem.datetime > :minDate"
+ );
+
+ Calendar cal = Calendar.getInstance();
+ cal.roll(Calendar.MONTH, false);
+ q.setCalendar("minDate", cal);
+
+ result = q.list();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return result;
+ }
+}]]></programlisting>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/filters.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/filters.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/filters.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/filters.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="filters">
+ <title>�f�[�^�̃t�B���^�����O</title>
+
+ <para>
+ Hibernate3�ł́u�����v���[���Ɋ�Â��ăf�[�^�������߂̉���I�ȕ��@��p�ӂ��Ă��܂��B
+ <emphasis>Hibernate filter</emphasis> �̓O���[�o���ŁA���O�t���ŁA�p�����[�^�����ꂽ�t�B���^�ł��B
+ �����Hibernate�Z�b�V�������ƂɗL���������ւ����܂��B
+ </para>
+
+ <sect1 id="objectstate-filters">
+ <title>Hibernate�̃t�B���^</title>
+
+ <para>
+ Hibernate3�̓t�B���^�N���C�e���A���炩���ߒ�`���A
+ �����̃t�B���^��N���X��R���N�V�������x���ɉ�����@�\������܂����B
+ �t�B���^�N���C�e���A�͐���߂��`����@�\�ł��B
+ �����̃t�B���^���̓p�����[�^���ł���Ƃ������Ƃ����A
+ �N���X�₳�܂��܂ȃR���N�V�����v�f�ŗ��p�\�Ȣwhere���ɔ��ɂ悭���Ă��܂��B
+ �A�v���P�[�V�����́A�^����ꂽ�t�B���^��\�ɂ��ׂ����A
+ �����Ă��̃p�����[�^�l���ɂ��ׂ�������s���Ɍ��肷�邱�Ƃ��ł��܂��B
+ �t�B���^�̓f�[�^�x�[�X�r���[�̂悤�Ɏg�p����܂����A�A�v���P�[�V������ł̓p�����[�^������܂��B
+
+ </para>
+
+ <para>
+ �t�B���^��g�����߂ɂ͂܂��A�K�ȃ}�b�s���O�v�f�ɒ�`�A�lj����Ȃ��Ă͂Ȃ�܂���B
+ �t�B���^���`���邽�߂ɂ́A
+ <literal><hibernate-mapping/></literal> �v�f��� <literal><filter-def/></literal> �v�f��g�p���܂��B�F
+ </para>
+
+ <programlisting><![CDATA[<filter-def name="myFilter">
+ <filter-param name="myFilterParam" type="string"/>
+</filter-def>]]></programlisting>
+
+ <para>
+ �������ăt�B���^�̓N���X�ւƌ��ѕt�����܂��B�F
+ </para>
+
+ <programlisting><![CDATA[<class name="myClass" ...>
+ ...
+ <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/>
+</class>]]></programlisting>
+
+ <para>
+ �܂��A�R���N�V�����ɑ��Ă͎��̂悤�ɂȂ�܂��B�F
+ </para>
+
+ <programlisting><![CDATA[<set ...>
+ <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/>
+</set>]]></programlisting>
+
+ <para>
+ �ǂ���ɑ��Ă�(�܂��A���ꂼ���)�����ɐݒ肷�邱�Ƃ�ł��܂��B
+ </para>
+
+ <para>
+ <literal>Session</literal> ��̃��\�b�h�� <literal>enableFilter(String filterName)</literal>,
+ <literal>getEnabledFilter(String filterName)</literal>, <literal>disableFilter(String filterName)</literal> �ł��B
+ �f�t�H���g�ł́A�t�B���^�͗^����ꂽ�Z�b�V�����ɑ��Ďg�p <emphasis>�ł��܂���</emphasis> �B
+ <literal>Filter</literal> �C���X�^���X��Ԃ�l�Ƃ��� <literal>Session.enabledFilter()</literal> ���\�b�h��g�����ƂŁA
+ �t�B���^�͖����I�Ɏg�p�\�ƂȂ�܂��B
+ ��Œ�`�����P���ȃt�B���^�̎g�p�́A���̂悤�ɂȂ�܂��B�F
+ </para>
+
+ <programlisting><![CDATA[session.enableFilter("myFilter").setParameter("myFilterParam", "some-value");]]></programlisting>
+
+ <para>
+ org.hibernate.Filter�C���^�[�t�F�C�X�̃��\�b�h�́A
+ Hibernate�̑����ɋ��ʂ��Ă��郁�\�b�h�A�������Ă��邱�Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ �L���ȃ��R�[�h�f�[�^�p�^�[�����ꎞ�f�[�^��g�������S�ȗ�ł��F
+ </para>
+
+ <programlisting><![CDATA[<filter-def name="effectiveDate">
+ <filter-param name="asOfDate" type="date"/>
+</filter-def>
+
+<class name="Employee" ...>
+...
+ <many-to-one name="department" column="dept_id" class="Department"/>
+ <property name="effectiveStartDate" type="date" column="eff_start_dt"/>
+ <property name="effectiveEndDate" type="date" column="eff_end_dt"/>
+...
+ <!--
+ Note that this assumes non-terminal records have an eff_end_dt set to
+ a max db date for simplicity-sake
+
+
+ -->
+ <filter name="effectiveDate"
+ condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
+</class>
+
+<class name="Department" ...>
+...
+ <set name="employees" lazy="true">
+ <key column="dept_id"/>
+ <one-to-many class="Employee"/>
+ <filter name="effectiveDate"
+ condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ ��Ɍ��݂̗L�����R�[�h��ԋp���邱�Ƃ�ۏ��邽�߂ɁA
+ �P���ɁA�Ј��f�[�^�̌������O�ɃZ�b�V������̃t�B���^��L���ɂ��܂��B
+
+
+ </para>
+
+<programlisting><![CDATA[Session session = ...;
+session.enabledFilter("effectiveDate").setParameter("asOfDate", new Date());
+List results = session.createQuery("from Employee as e where e.salary > :targetSalary")
+ .setLong("targetSalary", new Long(1000000))
+ .list();
+]]></programlisting>
+
+ <para>
+ ��L��HQL�ł́A���ʂ̋����̐���ɂ��Ė����I�ɐG�ꂽ�����ł����A
+ �L���ɂȂ��Ă���t�B���^�̂������ŁA���̃N�G���͋�����100���h���ȏ�̌���̎Ј�������Ԃ��܂��B
+ </para>
+
+ <para>
+ (HQL�����[�h�t�F�b�`�Łj�O���������t�B���^��g�����Ȃ�A
+ �����̕����ɒ��ӂ��Ă��������B
+
+ ����͍��O�������̂��߂ɐݒ肷��̂��ł���S�ł��B
+ ��ʓI�ɁA���Z�q�̌�J�������ɑ����čŏ��̃p�����[�^��z�u���Ă��������B
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/inheritance_mapping.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/inheritance_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/inheritance_mapping.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/inheritance_mapping.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,487 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="inheritance">
+ <title>�p���}�b�s���O</title>
+
+ <sect1 id="inheritance-strategies" revision="3">
+ <title>3�̐헪</title>
+
+ <para>
+ Hibernate��3�̊�{�I�Ȍp���̃}�b�s���O�헪��T�|�[�g���܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ �N���X�K�w���Ƃ̃e�[�u���itable-per-class-hierarchy�j
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �T�u�N���X���Ƃ̃e�[�u���itable-per-subclass�j
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ��ۃN���X���Ƃ̃e�[�u���itable-per-concrete-class�j
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ������4�ڂɁAHibernate�͂킸���ɈقȂ鐫���������|�����[�t�B�Y����T�|�[�g���܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ �ÖٓI�|�����[�t�B�Y��
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ����̌p���K�w�̈قȂ�u�����`�ɑ��ĈقȂ�}�b�s���O�헪��g�����Ƃ��ł��܂��B
+ ���̏ꍇ�ɂ͑S�̂̊K�w�ɓn��|�����[�t�B�Y����������邽�߂ɈÖٓI�|�����[�t�B�Y����g�p���܂��B
+ �������AHibernate�͓������[�g <literal><class></literal> �v�f���
+ <literal><subclass></literal> �}�b�s���O�A<literal><joined-subclass></literal> �}�b�s���O�A
+ <literal><union-subclass></literal> �}�b�s���O�̓����g�p��T�|�[�g���Ă��܂���B
+ <literal><subclass></literal> �v�f�� <literal><join></literal> �v�f��g�ݍ��킹�邱�ƂŁA
+ ���� <literal><class></literal> �v�f��ł� table-per-hierarchy �헪��
+ table-per-subclass �헪�̓����g�p�͉\�ł��B���̗���Ă��������B
+ </para>
+
+ <para>
+ <literal>subclass</literal>, <literal>union-subclass</literal> ��
+ <literal>joined-subclass</literal> �}�b�s���O���̃}�b�s���O�h�L�������g�ɒ�`���邱�Ƃ��o���A
+ <literal>hibernate-mapping</literal> �̒����ɔz�u���܂��B
+ ����͐V�����}�b�s���O�t�@�C����lj����邾���ŁA�N���X�K�w��g���ł���Ƃ������Ƃł��B
+ ���炩���߃}�b�v�����X�[�p�[�N���X��w�肵�āA�T�u�N���X�}�b�s���O�� <literal>extends</literal>
+ ������L�q���Ȃ���Ȃ�܂���B
+ ���ӁF���̓����ɂ��A�ȑO�̓}�b�s���O�E�h�L�������g�̏��Ԃ��d�v�ł����B
+ Hibernate3����́Aextends�L�[���[�h��g���ꍇ�A�}�b�s���O�h�L�������g�̏��Ԃ͖��ɂȂ�܂���B
+
+ �P�̃}�b�s���O�t�@�C����ŏ��ԕt����s���Ƃ��́A
+ �ˑR�Ƃ��āA�T�u�N���X���`����O�ɃX�[�p�[�N���X���`����K�v������܂��B)
+ </para>
+
+ <programlisting><![CDATA[
+ <hibernate-mapping>
+ <subclass name="DomesticCat" extends="Cat" discriminator-value="D">
+ <property name="name" type="string"/>
+ </subclass>
+ </hibernate-mapping>]]></programlisting>
+
+
+ <sect2 id="inheritance-tableperclass" >
+ <title>�N���X�K�w���Ƃ̃e�[�u���itable-per-class-hierarchy�j</title>
+
+ <para>
+ �Ⴆ�A�C���^�[�t�F�C�X <literal>Payment</literal> �ƁA������������
+ <literal>CreditCardPayment</literal>�A<literal>CashPayment</literal>�A
+ <literal>ChequePayment</literal> ������Ƃ��܂��B�K�w���Ƃ̃e�[�u���}�b�s���O��
+ �ȉ��̂悤�ɂȂ�܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ ...
+ </subclass>
+ <subclass name="ChequePayment" discriminator-value="CHEQUE">
+ ...
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ ���傤�Lj�̃e�[�u�����K�v�ł��B
+ ���̃}�b�s���O�헪�ɂ͈�傫�Ȑ���������܂��B
+ <literal>CCTYPE</literal> �̂悤�ȁA�T�u�N���X�Ő錾���ꂽ�J������ <literal>NOT NULL</literal>
+ ������Ă܂���B
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tablepersubclass">
+ <title>�T�u�N���X���Ƃ̃e�[�u���itable-per-subclass�j</title>
+
+ <para>
+ table-per-subclass �}�b�s���O�͈ȉ��̂悤�ɂȂ�܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="CashPayment" table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </joined-subclass>
+</class>]]></programlisting>
+
+ <para>
+ ���̃}�b�s���O�ɂ�4�̃e�[�u�����K�v�ł��B3�̃T�u�N���X�e�[�u����
+ �X�[�p�[�N���X�e�[�u���Ƃ̊֘A������L�[�����Ă��܂�
+ �i���ہA�W���f����͈�Έ�֘A�ł��j�B
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tablepersubclass-discriminator" revision="2">
+ <title>�ٕʎq��p���� table-per-subclass</title>
+
+ <para>
+ Hibernate�� table-per-subclass �����́Adiscriminator�J������K�v�Ƃ��Ȃ����Ƃ�o���Ă����Ă��������B
+ Hibernate�ȊO��O/R�}�b�p�[�́Atable-per-subclass �ɈقȂ������p���܂��B
+ ����́A�X�[�p�[�N���X�̃e�[�u���Ƀ^�C�vdiscriminator�J������K�v�Ƃ��܂��B
+ ���̃A�v���[�`�͎���������ɂȂ�܂����A�W�̎��_���猩��ƁA��萳�m�Ȃ�̂ł��B
+ table-per-subclass �헪��discriminator�J������g��������A
+ <literal><subclass></literal> �� <literal><join></literal>
+ ��ȉ��̂悤�ɑg�ݍ��킹�Ďg���Ă��������B
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+ <join table="CREDIT_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ <join table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="ChequePayment" discriminator-value="CHEQUE">
+ <join table="CHEQUE_PAYMENT" fetch="select">
+ <key column="PAYMENT_ID"/>
+ ...
+ </join>
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ �I�v�V������ <literal>fetch="select"</literal> �錾�́A
+ �X�[�p�[�N���X�̃N�G�����s���ɊO��������g���āA
+ �T�u�N���X�� <literal>ChequePayment</literal> �f�[�^��擾���Ȃ��悤�Ɏw�肷�邽�߂̂�̂ł��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-mixing-tableperclass-tablepersubclass">
+ <title>table-per-subclass �� table-per-class-hierarchy �̍���</title>
+
+ <para>
+ ���̃A�v���[�`��g�p����ƁAtable-per-hierarchy �� table-per-subclass �헪��
+ �g�ݍ��킹�鎖��\�ł��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+ <join table="CREDIT_PAYMENT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ ...
+ </subclass>
+ <subclass name="ChequePayment" discriminator-value="CHEQUE">
+ ...
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ ������̃}�b�s���O�헪�ł����Ă�A���[�g�ł��� <literal>Payment</literal> �N���X�ւ�
+ �|�����[�t�B�b�N�Ȋ֘A�� <literal><many-to-one></literal> ��g���ă}�b�s���O���܂��B
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="payment" column="PAYMENT_ID" class="Payment"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="inheritance-tableperconcrete" revision="2">
+ <title>��ۃN���X���Ƃ̃e�[�u���itable-per-concrete-class�j</title>
+
+ <para>
+ table-per-concrete-class �헪�̃}�b�s���O�ɑ���A�v���[�`�́A2����܂��B
+ 1�ڂ� <literal><union-subclass></literal> �𗘗p������@�ł��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="sequence"/>
+ </id>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </union-subclass>
+ <union-subclass name="CashPayment" table="CASH_PAYMENT">
+ ...
+ </union-subclass>
+ <union-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+ ...
+ </union-subclass>
+</class>]]></programlisting>
+
+ <para>
+ �T�u�N���X���Ƃ�3�̃e�[�u�����K�v�ł��B���ꂼ��̃e�[�u���́A�p���v���p�e�B��܂A
+ �N���X�̑S�Ẵv���p�e�B�ɑ���J�������`���܂��B
+ </para>
+
+ <para>
+ ���̃A�v���[�`�ɂ͐���������܂��B
+ ����́A�v���p�e�B���X�[�p�[�N���X�Ƀ}�b�s���O����Ă����ꍇ�A
+ �S�ẴT�u�N���X�ɂ����ăJ�������������łȂ���Ȃ�Ȃ��Ƃ�����̂ł��B
+ �iHibernate�̍���̃����[�X�Ŋɘa����邩�����܂���j�B
+ <union-subclass> ��g���� table-per-concrete-class �헪�ł͎��ʎq�����헪��g�p�ł��܂���B
+ ��L�[�����邽�߂̃V�[�h�́A�S�Ă� union subclass �̊K�w��ŋ��L����K�v�����邩��ł��B
+ </para>
+
+ <para>
+ ����X�[�p�[�N���X�����ۃN���X�Ȃ�A<literal>abstract="true"</literal>�ƃ}�b�s���O���܂��B
+ ������A�X�[�p�[�N���X�����ۃN���X�łȂ��Ȃ�A�X�[�p�[�N���X�̃C���X�^���X��
+ �ێ����邽�߂̃e�[�u���̒lj����K�v�ƂȂ�܂�(��̗�ł̃f�t�H���g�� <literal>PAYMENT</literal> )�B
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tableperconcreate-polymorphism">
+ <title>�ÖٓI�|�����[�t�B�Y����p���� table-per-concrete-class</title>
+
+ <para>
+ �����̃A�v���[�`�͈ÖٓI�|�����[�t�B�Y���̎g�p�ł��B
+ </para>
+
+ <programlisting><![CDATA[<class name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <id name="id" type="long" column="CREDIT_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CREDIT_AMOUNT"/>
+ ...
+</class>
+
+<class name="CashPayment" table="CASH_PAYMENT">
+ <id name="id" type="long" column="CASH_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CASH_AMOUNT"/>
+ ...
+</class>
+
+<class name="ChequePayment" table="CHEQUE_PAYMENT">
+ <id name="id" type="long" column="CHEQUE_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CHEQUE_AMOUNT"/>
+ ...
+</class>]]></programlisting>
+
+ <para>
+ <literal>Payment</literal> �C���^�[�t�F�C�X���ǂ��ɂ�����I�Ɏ�����Ă��Ȃ����Ƃɒ��ӂ��Ă��������B
+ �����āA<literal>Payment</literal> �v���p�e�B�����ꂼ��̃T�u�N���X�Ƀ}�b�s���O����Ă��邱�Ƃɂ���ӂ��Ă��������B
+ ����d����������̂ł���AXML�G���e�B�e�B�̗��p��l���Ă��������B
+ �i��F <literal>DOCTYPE</literal> �錾�ɂ����� <literal>[ <!ENTITY allproperties SYSTEM "allproperties.xml"> ]</literal>
+ �ƁA�}�b�s���O�ɂ����� <literal>&allproperties;</literal>�j
+ </para>
+
+ <para>
+ ���̃A�v���[�`�̌��_�́AHibernate���|�����[�t�B�b�N�ȃN�G���̎��s����SQL <literal>UNION</literal>
+ �����Ȃ��_�ł��B
+ </para>
+
+ <para>
+ ���̃}�b�s���O�헪�ɑ��ẮA<literal>Payment</literal> �ւ̃|�����[�t�B�b�N�Ȋ֘A��
+ �ʏ�A<literal><any></literal> ��g���ă}�b�s���O����܂��B
+ </para>
+
+ <programlisting><![CDATA[<any name="payment" meta-type="string" id-type="long">
+ <meta-value value="CREDIT" class="CreditCardPayment"/>
+ <meta-value value="CASH" class="CashPayment"/>
+ <meta-value value="CHEQUE" class="ChequePayment"/>
+ <column name="PAYMENT_CLASS"/>
+ <column name="PAYMENT_ID"/>
+</any>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="inheritace-mixingpolymorphism">
+ <title>���̌p���}�b�s���O�ƈÖٓI�|�����[�t�B�Y���̑g�ݍ��킹</title>
+
+ <para>
+ ���̃}�b�s���O�ɂ��Ă̍X�Ȃ钍�ӓ_������܂��B
+ �T�u�N���X�����g�� <literal><class></literal> �v�f�Ƃ��ă}�b�s���O���Ă���̂ŁA
+ �i���� <literal>Payment</literal> �͒P�Ȃ�C���^�[�t�F�C�X�Ȃ̂Łj�A
+ ���ꂼ��̃T�u�N���X�͊ȒP�ɂ��̑��̌p���K�w�̈ꕔ�ƂȂ�܂��B
+ �i������A���܂łǂ��� <literal>Payment</literal> �C���^�[�t�F�C�X�ɑ���|�����[�t�B�b�N�ȃN�G��
+ ��g�p���邱�Ƃ��ł��܂��j
+ </para>
+
+ <programlisting><![CDATA[<class name="CreditCardPayment" table="CREDIT_PAYMENT">
+ <id name="id" type="long" column="CREDIT_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="CREDIT_CARD" type="string"/>
+ <property name="amount" column="CREDIT_AMOUNT"/>
+ ...
+ <subclass name="MasterCardPayment" discriminator-value="MDC"/>
+ <subclass name="VisaPayment" discriminator-value="VISA"/>
+</class>
+
+<class name="NonelectronicTransaction" table="NONELECTRONIC_TXN">
+ <id name="id" type="long" column="TXN_ID">
+ <generator class="native"/>
+ </id>
+ ...
+ <joined-subclass name="CashPayment" table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="amount" column="CASH_AMOUNT"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="amount" column="CHEQUE_AMOUNT"/>
+ ...
+ </joined-subclass>
+</class>]]></programlisting>
+
+ <para>
+ �����x�q�ׂ܂����A<literal>Payment</literal> �͖����I�ɒ�`����܂���B
+ ����A<literal>Payment</literal> �C���^�[�t�F�C�X�ɑ��ăN�G������s����Ȃ�
+ �i�Ⴆ�� <literal>from Payment</literal> �߂�g���āj�A
+ Hibernate�͎����I�� <literal>CreditCardPayment</literal>
+ �i��CreditCardPayment�̃T�u�N���X�A<literal>Payment</literal> �̎����ł��邽�߁j�A
+ ����сA<literal>CashPayment</literal> �A<literal>ChequePayment</literal>
+ �̃C���X�^���X��Ԃ��܂��B
+ <literal>NonelectronicTransaction</literal> �C���X�^���X�͕Ԃ��܂���B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="inheritance-limitations">
+ <title>����</title>
+
+ <para>
+ table-per-concrete-class �}�b�s���O�헪�ւ́u�ÖٓI�|�����[�t�B�Y���v�A�v���[�`�ɂ�
+ �������̐���������܂��B<literal><union-subclass></literal> �}�b�s���O�ɑ��Ă�
+ ������߂̐���������܂��B
+ </para>
+
+ <para>
+ ���̃e�[�u���ɁAHibernate�ɂ�����table-per-concrete-class�}�b�s���O��
+ ������ÖٓI�|�����[�t�B�Y���̐��������܂��B
+ </para>
+
+ <table frame="topbot">
+ <title>�p���}�b�s���O�̋@�\</title>
+ <tgroup cols='8' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="1*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <colspec colname='c6' colwidth="1*"/>
+ <colspec colname='c7' colwidth="1*"/>
+ <colspec colname='c8' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>�p���헪</entry>
+ <entry>���Έ�̃|�����[�t�B�Y��</entry>
+ <entry>��Έ�̃|�����[�t�B�Y��</entry>
+ <entry>��Α��̃|�����[�t�B�Y��</entry>
+ <entry>���Α��̃|�����[�t�B�Y��</entry>
+ <entry>�|�����[�t�B�Y����g����<literal>load()/get()</literal></entry>
+ <entry>�|�����[�t�B�Y����g�����N�G��</entry>
+ <entry>�|�����[�t�B�Y����g��������</entry>
+ <entry>�O�������ɂ��t�F�b�`</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>table per class-hierarchy</entry>
+ <entry><literal><many-to-one></literal></entry>
+ <entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal></entry>
+ <entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class, id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment p</literal></entry>
+ <entry><emphasis>�T�|�[�g</emphasis></entry>
+ </row>
+ <row>
+ <entry>table per subclass</entry>
+ <entry><literal><many-to-one></literal></entry>
+ <entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal></entry>
+ <entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class, id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment p</literal></entry>
+ <entry><emphasis>�T�|�[�g</emphasis></entry>
+ </row>
+ <row>
+ <entry>table per concrete-class (union-subclass)</entry>
+ <entry><literal><many-to-one></literal></entry>
+ <entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal> (for <literal>inverse="true"</literal> only)</entry>
+ <entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class, id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment p</literal></entry>
+ <entry><emphasis>�T�|�[�g</emphasis></entry>
+ </row>
+ <row>
+ <entry>table per concrete class (implicit polymorphism)</entry>
+ <entry><literal><any></literal></entry>
+ <entry><emphasis>�T�|�[�g���Ă��܂���</emphasis></entry>
+ <entry><emphasis>�T�|�[�g���Ă��܂���</emphasis></entry>
+ <entry><literal><many-to-any></literal></entry>
+ <entry><literal>s.createCriteria(Payment.class).add( Restrictions.idEq(id) ).uniqueResult()</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><emphasis>�T�|�[�g���Ă��܂���</emphasis></entry>
+ <entry><emphasis>�T�|�[�g���Ă��܂���</emphasis></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/performance.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/performance.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/performance.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/performance.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,1378 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="performance">
+ <title>�p�t�H�[�}���X�̉��P</title>
+
+ <sect1 id="performance-fetching" revision="2">
+ <title>�t�F�b�`�헪</title>
+
+ <para>
+ <emphasis>�t�F�b�`�헪</emphasis> �́A�A�v���P�[�V�������֘A��i�r�Q�[�g����K�v������
+ �Ƃ��ɁAHibernate���֘A�I�u�W�F�N�g�����邽�߂Ɏg�p����헪�ł��B�t�F�b�`�헪��O/R�}�b�s���O��
+ ���^�f�[�^�ɐ錾���邩�A�����HQL�A <literal>Criteria</literal> �N�G���ŃI�[�o�[���C�h���܂��B
+ </para>
+
+ <para>
+ Hibernate3�͎��Ɏ����t�F�b�`�헪���`���Ă��܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>�����t�F�b�`</emphasis> - Hibernate�� <literal>OUTER JOIN</literal> ��g���āA
+ �֘A����C���X�^���X��R���N�V������P�� <literal>SELECT</literal>
+ �ŕ������܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>�Z���N�g�t�F�b�`</emphasis> - 2��ڂ� <literal>SELECT</literal>
+ �Ŋ֘A����G���e�B�e�B��R���N�V���������܂��B <literal>lazy="false"</literal>
+ �Ŗ����I�ɒx���t�F�b�`���ɂ��Ȃ���A����2��ڂ�select�͎��ۂ�
+ �֘A�ɃA�N�Z�X�����Ƃ��̂ݎ��s�����ł��傤�B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>�T�u�Z���N�g�t�F�b�`</emphasis> - 2��ڂ� <literal>SELECT</literal>
+ �ŁA���O�̃N�G����t�F�b�`�ŕ����������ׂĂ̗v�f�Ɋ֘A����R���N�V������
+ �������܂��B <literal>lazy="false"</literal>
+ �Ŗ����I�ɒx���t�F�b�`���ɂ��Ȃ���A����2��ڂ�select�͎��ۂ�
+ �֘A�ɃA�N�Z�X�����Ƃ��̂ݎ��s�����ł��傤�B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>�o�b�`�t�F�b�`</emphasis> - �Z���N�g�t�F�b�`�̂��߂̍œK�����ꂽ�헪
+ - Hibernate�̓G���e�B�e�B�̃C���X�^���X��R���N�V�����̈�Q��1���
+ <literal>SELECT</literal> �ŕ������܂��B����͎�L�[��O���L�[�̃��X�g��w�肷�邱�Ƃ�
+ �ɂ��s���܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate�͎��Ɏ����헪�Ƃ��ʂ��܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>�����t�F�b�`</emphasis> - ���L�҂̃I�u�W�F�N�g�����[�h���ꂽ�Ƃ��ɁA
+ �֘A�A�R���N�V�����͑����Ƀt�F�b�`����܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>�x���R���N�V�����t�F�b�`</emphasis> - �A�v���P�[�V�������R���N�V������
+ ���đ����s�����Ƃ��ɃR���N�V������t�F�b�`���܂��B
+ (����̓R���N�V�����ɑ���f�t�H���g�̓���ł�)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>"���ʂȒx��"�R���N�V�����t�F�b�`</emphasis> - �R���N�V�����̗v�f
+ �P�P���Ɨ����āA�K�v�ȂƂ��Ƀf�[�^�x�[�X����擾����܂��B
+ Hibernate�͕K�v�Ȃ��Ȃ�A�R���N�V�����S�̂������Ƀt�F�b�`���邱�Ƃ�
+ ���܂��i�ƂĂ�傫�ȃR���N�V�����ɓK���Ă��܂��j�B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>�v���L�V�t�F�b�`</emphasis> - �P��l�֘A�́A���ʎq��getter�ȊO��
+ ���\�b�h���֘A�I�u�W�F�N�g�ŌĂяo�����Ƃ��Ƀt�F�b�`����܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>"�v���L�V�Ȃ�"�t�F�b�`</emphasis> - �P��l�֘A�́A�C���X�^���X�ϐ���
+ �A�N�Z�X���ꂽ�Ƃ��Ƀt�F�b�`����܂��B�v���L�V�t�F�b�`�Ɣ�r����ƁA���̕��@��
+ �x���̓x���������Ȃ��i�֘A�͎��ʎq�ɃA�N�Z�X���������ł�t�F�b�`����܂��j
+ �ł����A��蓧�ߓI�ŁA�A�v���P�[�V�����Ƀv���L�V�����݂��Ȃ��悤�Ɍ����܂��B
+ ���̕��@�̓r���h���̃o�C�g�R�[�h�g�ݍ��݂��K�v�ɂȂ�A�g����ʂ͂܂�ł��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>�x�������t�F�b�`</emphasis> - ������P��l�֘A�́A�C���X�^���X�ϐ��ɃA�N�Z�X����
+ �Ƃ��Ƀt�F�b�`����܂��B���̕��@�̓r���h���̃o�C�g�R�[�h�g�ݍ��݂��K�v�ɂȂ�A
+ �g����ʂ͂܂�ł��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ��̒��s����T�O������܂�: <emphasis>����</emphasis> �֘A��t�F�b�`���邩�A
+ �����āA <emphasis>�ǂ������</emphasis> �t�F�b�`���邩�i�ǂ��SQL��g���āj�B
+ �����������Ȃ��ł��������I <literal>fetch</literal> �̓p�t�H�[�}���X�`���[�j���O�Ɏg���܂��B
+ <literal>lazy</literal> �͂���N���X�̕������ꂽ�C���X�^���X�̂����A�ǂ̃f�[�^����
+ �g�p�\�ɂ��邩�̎�茈�߂��`���܂��B
+ </para>
+
+ <sect2 id="performance-fetching-lazy">
+ <title>�x���֘A�̓���</title>
+
+ <para>
+ �f�t�H���g�ł́AHibernate3�̓R���N�V�����ɑ��Ă͒x���Z���N�g�t�F�b�`��g���A
+ �P��l�֘A�ɂ͒x���v���L�V�t�F�b�`��g���܂��B�����̃f�t�H���g����͂قڂ��ׂĂ�
+ �A�v���P�[�V�����̂قڂ��ׂĂ̊֘A�ňӖ�������܂��B
+ </para>
+
+ <para>
+ <emphasis>��:</emphasis>
+ <literal>hibernate.default_batch_fetch_size</literal> ��Z�b�g�����Ƃ��́AHibernate��
+ �x���t�F�b�`�̂��߂̃o�b�`�t�F�b�`�œK����g���ł��傤
+ �i���̍œK���͂��ׂ������x���ŗL���ɂ��邱�Ƃ�o���܂��j�B
+ </para>
+
+ <para>
+ �������A�x���t�F�b�`�͒m���Ă����Ȃ���Ȃ�Ȃ���̖�肪����܂��B
+ Hibernate��session��I�[�v�����Ă���R���e�L�X�g�̊O����x���֘A�ɃA�N�Z�X����ƁA
+ ��O���������܂��B��F
+ </para>
+
+ <programlisting><![CDATA[s = sessions.openSession();
+Transaction tx = s.beginTransaction();
+
+User u = (User) s.createQuery("from User u where u.name=:userName")
+ .setString("userName", userName).uniqueResult();
+Map permissions = u.getPermissions();
+
+tx.commit();
+s.close();
+
+Integer accessLevel = (Integer) permissions.get("accounts"); // Error!]]></programlisting>
+
+ <para>
+ <literal>Session</literal> ���N���[�Y���ꂽ�Ƃ��Apermissions�R���N�V������
+ ����������Ă��Ȃ����߁A���̃R���N�V�����͎��g�̏�Ԃ��[�h�ł��܂���B
+ <emphasis>Hibernate�͐藣���ꂽ�I�u�W�F�N�g�̒x���������̓T�|�[�g
+ ���Ă��܂���</emphasis> �B�C�����@�Ƃ��āA�R���N�V��������ǂݍ��݂�s���R�[�h��
+ �g�����U�N�V������R�~�b�g���钼�O�Ɉړ������܂��B
+ </para>
+
+ <para>
+ ����ŁA <literal>lazy="false"</literal> ��֘A�}�b�s���O�Ɏw�肷�邱�ƂŁA
+ �x���������Ȃ��R���N�V������֘A��g�����Ƃ��o���܂��B
+ �������Ȃ���A�x���������͂قڂ��ׂẴR���N�V������֘A�Ŏg���邱�Ƃ�
+ �Ӑ}���Ă��܂��B������Ȃ��̃I�u�W�F�N�g���f���̒��ɒx���������Ȃ��֘A��
+ ������`���Ă��܂��ƁAHibernate�͍ŏI�I�ɂ̓g�����U�N�V��������
+ �قڊ��S�ȃf�[�^�x�[�X�������̒��Ƀt�F�b�`���邱�ƂɂȂ�ł��傤�I
+ </para>
+
+ <para>
+ �����ł́A����̃g�����U�N�V�����ɂ����ăZ���N�g�t�F�b�`�̑����
+ �����t�F�b�`�i���R����͒x�������ł͂Ȃ��Ȃ�܂��j��I���������Ƃ�
+ ���X����܂��B���ꂩ��t�F�b�`�헪��J�X�^�}�C�Y������@���������܂��B
+ Hibernate3�ł́A�t�F�b�`�헪��I����d�g�݂͒P��l�֘A�ƃR���N�V������
+ �ς��͂���܂���B
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-custom" revision="4">
+ <title>�t�F�b�`�헪�̃`���[�j���O</title>
+
+ <para>
+ �Z���N�g�t�F�b�`�i�f�t�H���g�j��N+1�Z���N�g���Ƃ����傫�Ȏ�_�����邽�߁A
+ �}�b�s���O��`�Ō����t�F�b�`��L���ɂ��邱�Ƃ��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<set name="permissions"
+ fetch="join">
+ <key column="userId"/>
+ <one-to-many class="Permission"/>
+</set]]></programlisting>
+
+ <programlisting><![CDATA[<many-to-one name="mother" class="Cat" fetch="join"/>]]></programlisting>
+
+ <para>
+ �}�b�s���O��`�Œ�`���� <literal>�t�F�b�`</literal> �헪�͎��̂�̂ɉe�����܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>get()</literal> �� <literal>load()</literal> �ɂ�镜��
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+
+ �֘A�Ƀi�r�Q�[�g�����Ƃ��ɔ�������ÖٓI�ȕ���
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Criteria</literal> �N�G��
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>�T�u�Z���N�g</literal> �t�F�b�`��g��HQL�N�G��
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ���Ƃ��ǂ�ȃt�F�b�`�헪��g�����Ƃ��Ă�A�x���ł͂Ȃ��O���t�̓������ɓǂݍ��܂�邱�Ƃ�
+ �ۏ���܂��B�܂�A�����HQL�N�G������s���邽�߂ɂ�������SELECT�����������s�����
+ ���Ƃ�����̂Œ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ �ʏ�́A�}�b�s���O��`�Ńt�F�b�`�̃J�X�^�}�C�Y�͍s���܂���B
+ ����ɁA�f�t�H���g�̓���̂܂܂ɂ��Ă����āAHQL�� <literal>left join fetch</literal> ��
+ �w�肷�邱�Ƃœ���̃g�����U�N�V�����œ����I�[�o�[���C�h���܂��B
+ �����Hibernate�ɏ���̃Z���N�g�ŊO��������g���Ċ֘A���Ƀt�F�b�`����悤�Ɏw�肵�Ă��܂��B
+ <literal>Criteria</literal> �N�G����API�ł́A
+ <literal>setFetchMode(FetchMode.JOIN)</literal> ��g�����Ƃ��o���܂��B
+ </para>
+
+ <para>
+ ��� <literal>get()</literal> �� <literal>load()</literal> �Ŏg����
+ �t�F�b�`�헪��ς������Ɗ������Ƃ��ɂ́A�P����
+ <literal>Criteria</literal> �N�G����g�����������B��F
+ </para>
+
+ <programlisting><![CDATA[User user = (User) session.createCriteria(User.class)
+ .setFetchMode("permissions", FetchMode.JOIN)
+ .add( Restrictions.idEq(userId) )
+ .uniqueResult();]]></programlisting>
+
+ <para>
+ �i����͂�������ORM�\�����[�V������"fetch plan"�ƌĂ�ł����̂Ɠ����ł��B�j
+ </para>
+
+ <para>
+ N+1�Z���N�g������邽�߂̂܂������Ⴄ���@�́A��2���x���L���b�V����g�����Ƃł��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-proxies" revision="2">
+ <title>�P��[�֘A�v���L�V</title>
+
+ <para>
+ �R���N�V�����̒x���t�F�b�`�́AHibernate���g�̎����ɂ��i���R���N�V������g����
+ �������Ă��܂��B�������A�P��[�֘A�ɂ�����x�������ł́A�Ⴄ�d�g�݂�
+ �K�v�ł��B�Ώۂ̊֘A�G���e�B�e�B�̓v���L�V�łȂ���Ȃ�܂���BHibernate��
+ �i���炵��CGLIB���C�u�����ɂ��j���s���̃o�C�g�R�[�h�g����
+ �g���ĉi���I�u�W�F�N�g�̒x���������v���L�V��������Ă��܂��B
+ </para>
+
+ <para>
+ �f�t�H���g�ł́AHibernate3�́i�J�n���Ɂj���ׂẲi���N���X�̃v���L�V�����A
+ ������g���āA <literal>many-to-one</literal> �� <literal>one-to-one</literal> �֘A��
+ �x���t�F�b�`��\�ɂ��Ă��܂��B
+ </para>
+
+ <para>
+ �}�b�s���O�t�@�C���� <literal>proxy</literal> �����ɂ���āA�N���X�̃v���L�V�C���^�[�t�F�C�X�Ƃ���
+ �g���C���^�[�t�F�C�X��錾�ł��܂��B�f�t�H���g�ł́AHibernate�͂��̃N���X�̃T�u�N���X��g���܂��B
+ <emphasis>�v���L�V�N���X�͏��Ȃ��Ƃ�p�b�P�[�W���Ńf�t�H���g�R���X�g���N�^��������Ȃ����
+ �Ȃ�Ȃ����Ƃɒ��ӂ��Ă��������B���ׂẲi���N���X�ɂ��̃R���X�g���N�^�𐄏����܂��I</emphasis>
+ </para>
+
+ <para>
+ �|�����[�t�B�Y���̃N���X�ɑ��Ă��̕��@��K�p����Ƃ��ɂ������l�����邱�Ƃ�����܂��B
+ ��F
+ </para>
+
+ <programlisting><![CDATA[<class name="Cat" proxy="Cat">
+ ......
+ <subclass name="DomesticCat">
+ .....
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ ���ɁA <literal>Cat</literal> �̃C���X�^���X�� <literal>DomesticCat</literal>
+ �ɃL���X�g�ł��܂���B���Ƃ���ƂȂ�C���X�^���X�� <literal>DomesticCat</literal>
+ �ł������Ƃ��Ă�ł��B
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(Cat.class, id); // instantiate a proxy (does not hit the db)
+if ( cat.isDomesticCat() ) { // hit the db to initialize the proxy
+ DomesticCat dc = (DomesticCat) cat; // Error!
+ ....
+}]]></programlisting>
+
+ <para>
+ ���ɁA�v���L�V�� <literal>==</literal> �͐������Ȃ����Ƃ�����܂��B
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(Cat.class, id); // instantiate a Cat proxy
+DomesticCat dc =
+ (DomesticCat) session.load(DomesticCat.class, id); // acquire new DomesticCat proxy!
+System.out.println(cat==dc); // false]]></programlisting>
+
+ <para>
+ �������A����͌������قLj����Ƃ����킯�ł͂���܂���B���Ƃ��قȂ����v���L�V�I�u�W�F�N�g�ւ�
+ ��̎Q�Ƃ��������Ƃ��Ă�A��ƂȂ�C���X�^���X�͓����I�u�W�F�N�g�ł��B
+ </para>
+
+ <programlisting><![CDATA[cat.setWeight(11.0); // hit the db to initialize the proxy
+System.out.println( dc.getWeight() ); // 11.0]]></programlisting>
+
+ <para>
+ ��O�ɁA <literal>final</literal> �N���X�� <literal>final</literal> ���\�b�h���N���X��
+ CGLIB�v���L�V��g���܂���B
+ </para>
+
+ <para>
+ �Ō�ɁA����i���I�u�W�F�N�g�̃C���X�^���X����(�Ⴆ�A������������f�t�H���g�R���X�g���N�^�̒���)
+ �ɂȂ�炩�̃��\�[�X���K�v�ƂȂ�Ȃ�A���̃��\�[�X��܂��v���L�V��ʂ��Ď擾����܂��B
+ ���ۂɂ́A�v���L�V�N���X�͉i���N���X�̃T�u�N���X�ł��B
+ </para>
+
+ <para>
+ �����̖���Java�̒P��p�����f���̌�����̐����̂��߂ł��B��������̖���������̂Ȃ�A
+ �r�W�l�X���\�b�h��錾�����C���^�[�t�F�C�X���ꂼ��i���N���X�Ŏ������Ȃ���Ȃ�܂���B
+ �}�b�s���O�t�@�C���ł����̃C���^�[�t�F�C�X��w�肷��K�v������܂��B��F
+ </para>
+
+ <programlisting><![CDATA[<class name="CatImpl" proxy="Cat">
+ ......
+ <subclass name="DomesticCatImpl" proxy="DomesticCat">
+ .....
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ <literal>CatImpl</literal> �� <literal>Cat</literal> �C���^�[�t�F�C�X���������̂ɑ��A
+ <literal>DomesticCatImpl</literal> �� <literal>DomesticCat</literal> ��������܂��B
+ ����ƁA <literal>load()</literal> �� <literal>iterate()</literal> �́A
+ <literal>Cat</literal> �� <literal>DomesticCat</literal> �̃C���X�^���X�̃v���L�V��
+ �Ԃ��܂��B�i <literal>list()</literal> �͒ʏ�̓v���L�V��Ԃ��Ȃ����Ƃɒ��ӂ��Ă��������B�j
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(CatImpl.class, catid);
+Iterator iter = session.createQuery("from CatImpl as cat where cat.name='fritz'").iterate();
+Cat fritz = (Cat) iter.next();]]></programlisting>
+
+ <para>
+ �֘A��x������������܂��B����̓v���p�e�B�� <literal>Cat</literal> �^�Ő錾���Ȃ����
+ �Ȃ�Ȃ����Ƃ�Ӗ����܂��B <literal>CatImpl</literal> �ł͂���܂���B
+ </para>
+
+ <para>
+ �v���L�V�̏������� <emphasis>�K�v�Ƃ��Ȃ�</emphasis> �������݂��܂��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>equals()</literal> �i�i���N���X�� <literal>equals()</literal> ��
+ �I�[�o�[���C�h���Ȃ��Ƃ��j
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>hashCode()</literal> �i�i���N���X�� <literal>hashCode()</literal> ��
+ �I�[�o�[���C�h���Ȃ��Ƃ��j
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ���ʎq��getter���\�b�h
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate�� <literal>equals()</literal> �� <literal>hashCode()</literal> ��I�[�o�[���C�h����
+ �i���N���X���o���܂��B
+ </para>
+
+ <para>
+ �f�t�H���g�� <literal>lazy="proxy"</literal> �̑���ɁA <literal>lazy="no-proxy"</literal> ��
+ �I���ƂŁA�^�ϊ��Ɋ֘A����������邱�Ƃ��o���܂��B
+ �������A�r���h���̃o�C�g�R�[�h�g�ݍ��݂��K�v�ɂȂ�A�ǂ̂悤�ȑ���ł����Ă�A
+ �������Ƀv���L�V�̏�������s�����ƂɂȂ�ł��傤�B
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-initialization" revision="1">
+ <title>�R���N�V�����ƃv���L�V�̏�����</title>
+
+ <para>
+ <literal>LazyInitializationException</literal> �́A <literal>Session</literal> �̃X�R�[�v�O����
+ ���������Ă��Ȃ��R���N�V������v���L�V�ɃA�N�Z�X���ꂽ�Ƃ��ɁAHibernate�ɂ���ăX���[����܂��B
+ ���Ȃ킿�A�R���N�V������v���L�V�ւ̎Q�Ƃ��G���e�B�e�B���������ꂽ��Ԃ̎��ł��B
+ </para>
+
+ <para>
+ <literal>Session</literal> ��N���[�Y����O�Ƀv���L�V��R���N�V�����̏�������m����
+ �s�������Ƃ�������܂��B������A <literal>cat.getSex()</literal>
+ �� <literal>cat.getKittens().size()</literal> �Ȃǂ��ɌĂяo�����Ƃŏ������������邱�Ƃ͂ł��܂��B
+ ����������̓R�[�h��ǂސl���������A�ėp�I�ȃR�[�h�Ƃ����_�����s�ւł��B
+ </para>
+
+ <para>
+ static���\�b�h�� <literal>Hibernate.initialize()</literal> �� <literal>Hibernate.isInitialized()</literal>
+ �͒x���������̃R���N�V������v���L�V�����Ƃ��ɕ֗��ȕ��@��A�v���P�[�V�����ɒ��܂��B
+ <literal>Hibernate.initialize(cat)</literal> �́A <literal>Session</literal> ���I�[�v�����Ă�������
+ <literal>cat</literal> �v���L�V�����I�ɏ��������܂��B
+ <literal>Hibernate.initialize( cat.getKittens() )</literal> ��kittens�R���N�V�����ɑ��ē��l��
+ ���ʂ�����܂��B
+ </para>
+
+ <para>
+ �ʂ̑I���Ƃ��āA�K�v�Ȃ��ׂẴR���N�V������v���L�V�����[�h�����܂�
+ <literal>Session</literal> ��I�[�v���ɂ��Ă������@������܂��B�������̃A�v���P�[�V������
+ �A�[�L�e�N�`���ł́A����Hibernate�ɂ��f�[�^�A�N�Z�X��s���R�[�h�ƁA�����g��
+ �R�[�h���قȂ�A�v���P�[�V�����̃��C���[��A�����I�ɈقȂ�v���Z�b�T�̂Ƃ��ɂ́A
+ �R���N�V�����������������Ƃ��� <literal>Session</literal> ���I�[�v�����Ă��邱�Ƃ�
+ �ۏ����肪����܂��B���̖��ɑ��Ă�2�̊�{�I�ȕ��@������܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+
+ Web�x�[�X�̃A�v���P�[�V�����ł́A
+ �r���[�̃����_�����O���������A���N�G�X�g���I����ԍŌ�� <literal>Session</literal>
+ ��N���[�Y���邽�߂ɁA�T�[�u���b�g�t�B���^��g�����Ƃ��ł��܂��i <emphasis>Open Session in View</emphasis>
+ �p�^�[���ł��j�B������A�A�v���P�[�V������Ղ̗�O�����̐��m�������ɏd�v�ɂȂ�܂��B
+ �r���[�̃����_�����O���ɗ�O�����������Ƃ��ł����A���[�U�ɏ������߂�O��
+ <literal>Session</literal> �̃N���[�Y�ƃg�����U�N�V�����̏I����s��
+ ���Ƃ��s���ɂȂ�܂��B
+ Hibernate��Wiki�ɍڂ��Ă���"Open Session in View"�p�^�[���̗��Q�Ƃ��Ă��������B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �r�W�l�X�w���������Ă���A�v���P�[�V�����ł́A�r�W�l�X���W�b�N��
+ Web�w�ŕK�v�ɂȂ邷�ׂẴR���N�V�������O��"����"����K�v������܂��B
+ ����͓���̃��[�X�P�[�X�ŕK�v�ƂȂ�v���[���e�[�V����/Web�w�ɑ��A
+ �r�W�l�X�w�����ׂẴf�[�^���[�h���A���ׂẴf�[�^���������ĕԂ��ׂ���
+ �������Ƃ�Ӗ����Ă��܂��B�ʏ�́A�A�v���P�[�V������Web�w�ŕK�v�ȃR���N�V����
+ ���ꂼ��ɑ��� <literal>Hibernate.initialize()</literal> ��Ăяo����
+ �i���̌Ăяo���̓Z�b�V������N���[�Y����O�ɍs���K�v������܂��j�A
+ Hibernate�N�G���� <literal>FETCH</literal> �߂� <literal>Criteria</literal>
+ �� <literal>FetchMode.JOIN</literal> ��g���ăR���N�V�������ɕ������܂��B
+ ���ʂ� <emphasis>Session Facade</emphasis> �p�^�[���̑����
+ <emphasis>Command</emphasis> �p�^�[����̗p����ق������ȒP�ł��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ����������Ă��Ȃ��R���N�V�����i������͑��̃v���L�V�j�ɃA�N�Z�X����O�ɁA
+ <literal>merge()</literal> �� <literal>lock()</literal> ��g���ĐV����
+ <literal>Session</literal> �ɈȑO�Ƀ��[�h���ꂽ�I�u�W�F�N�g��lj����邱�Ƃ�o���܂��B
+ �A�h�z�b�N�ȃg�����U�N�V�����̃Z�}���e�B�N�X�������̂ŁAHibernate��
+ ��������I�ɍs�킸�A <emphasis>�s���ׂ��ł����܂���</emphasis> �I
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ �傫�ȃR���N�V�����������������͂Ȃ����A�R���N�V�����ɂ��Ă̂Ȃ�炩�̏��i�T�C�Y�̂悤�ȁj
+ ��f�[�^�̃T�u�Z�b�g��K�v�Ƃ��邱�Ƃ�����܂��B
+ </para>
+
+ <para>
+ �R���N�V�����t�B���^��g�����ƂŁA�����������ɃR���N�V�����̃T�C�Y��擾���邱�Ƃ��o���܂��B
+ </para>
+
+ <programlisting><![CDATA[( (Integer) s.createFilter( collection, "select count(*)" ).list().get(0) ).intValue()]]></programlisting>
+
+ <para>
+ <literal>createFilter()</literal> ���\�b�h�́A�R���N�V�����S�̂���������K�v�Ȃ��ɁA�R���N�V������
+ �T�u�Z�b�g�����邽�߂Ɍ��ʓI�Ɏg���܂��B
+ </para>
+
+ <programlisting><![CDATA[s.createFilter( lazyCollection, "").setFirstResult(0).setMaxResults(10).list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-batch">
+ <title>�o�b�`�t�F�b�`�̎g�p</title>
+
+ <para>
+ Hibernate�̓o�b�`�t�F�b�`������I�Ɏg�p�ł��܂��B��̃v���L�V�i������̓R���N�V�����j���A�N�Z�X
+ �����ƁAHibernate�͂������̏��������Ă��Ȃ��v���L�V���[�h���邱�Ƃ��ł��܂��B�o�b�`�t�F�b�`��
+ �x���Z���N�g�t�F�b�`�헪�ɑ���œK���ł��B�o�b�`�t�F�b�`�̒����ɂ͂Q�̕��@������܂��B
+ �N���X���x���ƃR���N�V�������x���ł��B
+ </para>
+
+ <para>
+ �N���X�A�v�f�̃o�b�`�t�F�b�`�͗����ȒP�ł��B���s���̎��̏�ʂ�z�����Ă��������B
+ <literal>Session</literal> �Ƀ��[�h���ꂽ25�� <literal>Cat</literal> �C���X�^���X�����݂��A
+ ���ꂼ��� <literal>Cat</literal> �� <literal>owner</literal> �ł��� <literal>Person</literal> �ւ̊֘A�����܂��B
+ <literal>Person</literal> �N���X�� <literal>lazy="true"</literal> �̃v���L�V�Ń}�b�s���O����Ă��܂��B
+ ��������ׂĂ�Cat�ɑ��ČJ��Ԃ� <literal>getOwner()</literal> ��Ăяo���ƁAHibernate��
+ �f�t�H���g�ł�25��� <literal>SELECT</literal> ����s���Aowner�v���L�V�̕������܂��B
+ ���̐U�镑���� <literal>Person</literal> �̃}�b�s���O�� <literal>batch-size</literal>
+ �̎w��Œ����ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person" batch-size="10">...</class>]]></programlisting>
+
+ <para>
+ Hibernate�̓N�G����R������s����悤�ɂȂ�܂��B�p�^�[����10, 10, 5�ł��B
+ </para>
+
+ <para>
+ �R���N�V�����̃o�b�`�t�F�b�`��L���ɂ��邱�Ƃ��o���܂��B��Ƃ��āA���ꂼ���
+ <literal>Person</literal> �� <literal>Cat</literal> �̒x���R���N�V���������Ă���A
+ 10��Person�� <literal>Sesssion</literal> �Ƀ��[�h���ꂽ�Ƃ���ƁA���ׂĂ�Person��
+ ���ČJ��Ԃ� <literal>getCats()</literal> ��Ăяo�����ƂŁA�v10��� <literal>SELECT</literal>
+ ���������܂��B��� <literal>Person</literal> �̃}�b�s���O�� <literal>cats</literal>
+ �R���N�V�����̃o�b�`�t�F�b�`��L���ɂ���AHibernate�̓R���N�V�����̎��O�t�F�b�`���o���܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <set name="cats" batch-size="3">
+ ...
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ <literal>batch-size</literal> ��3�Ȃ̂ŁAHibernate��4��� <literal>SELECT</literal>
+ ��3�A3�A3�A1���[�h���܂��B�J��Ԃ��ƁA�����̒l�͓���� <literal>Session</literal>
+ �̒��̏���������Ă��Ȃ��R���N�V�����̊��Ґ��Ɉˑ����܂��B
+ </para>
+
+ <para>
+ �R���N�V�����̃o�b�`�t�F�b�`�̓A�C�e���̃l�X�g�����c���[�A ���Ȃ킿�A��\�I�ȕ��i�\�̃p�^�[����
+ ����ꍇ�ɓ��ɗL�p�ł��B�i�������A�ǂݍ��݂������c���[�ł� <emphasis>�l�X�g����set</emphasis>
+ �� <emphasis>��̉������p�X</emphasis> �����悢�I��ɂȂ�܂��B�j
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-subselect">
+ <title>�T�u�Z���N�g�t�F�b�`�̎g�p</title>
+
+ <para>
+ ��̒x���R���N�V������P��l�v���L�V���t�F�b�`����Ȃ�������Ȃ��Ƃ��AHibernate��
+ ����炷�ׂĂ��[�h���A�T�u�Z���N�g�̃I���W�i���N�G�����ēx���s����܂��B�����
+ �o�b�`�t�F�b�`�Ɠ������@�œ����A�������̃��[�h�͍s���܂���B
+ </para>
+
+ <!-- TODO: Write more about this -->
+ <!-- ���������� -->
+ </sect2>
+
+ <sect2 id="performance-fetching-lazyproperties">
+ <title>�x���v���p�e�B�t�F�b�`�̎g�p</title>
+
+ <para>
+ Hibernate3�̓v���p�e�B���Ƃ̒x���t�F�b�`��T�|�[�g���Ă��܂��B���̍œK����@��
+ <emphasis>�O���[�v�̃t�F�b�`</emphasis> �Ƃ��Ă�m���Ă��܂��B����͂قƂ��
+ �v�]����o���@�\�ł��邱�Ƃɒ��ӂ��Ă��������B���ۂɂ͗�ǂݍ��݂̍œK������A
+ �s�ǂݍ��݂̍œK�������ɏd�v�ł��B
+ �������A�N���X�̂������̃v���p�e�B������ǂݍ��ނ��Ƃ́A�����̃e�[�u�������S��̗�����A
+ �f�[�^���f������P�ł��Ȃ��Ȃǂ̋ɒ[�ȏꍇ�ɂ͗L�p�ł��B
+ </para>
+
+ <para>
+ �x���v���p�e�B�ǂݍ��݂�L���ɂ���ɂ́A�Ώۂ̃v���p�e�B�̃}�b�s���O�� <literal>lazy</literal>
+ ������Z�b�g�����������B
+ </para>
+
+ <programlisting><![CDATA[<class name="Document">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name" not-null="true" length="50"/>
+ <property name="summary" not-null="true" length="200" lazy="true"/>
+ <property name="text" not-null="true" length="2000" lazy="true"/>
+</class>]]></programlisting>
+
+ <para>
+ �x���v���p�e�B�ǂݍ��݂̓r���h���̃o�C�g�R�[�h�g�ݍ��݂�K�v�Ƃ��܂��I���
+ �i���N���X�ɑg�ݍ��݂�����Ă��Ȃ��Ȃ�AHibernate�͖ق��Ēx���v���p�e�B�̐ݒ�����āA
+ �����t�F�b�`�ɖ߂��܂��B
+ </para>
+
+ <para>
+ �o�C�g�R�[�h�g�ݍ��݂͈ȉ���Ant�^�X�N��g���Ă��������B
+ </para>
+
+ <programlisting><![CDATA[<target name="instrument" depends="compile">
+ <taskdef name="instrument" classname="org.hibernate.tool.instrument.InstrumentTask">
+ <classpath path="${jar.path}"/>
+ <classpath path="${classes.dir}"/>
+ <classpath refid="lib.class.path"/>
+ </taskdef>
+
+ <instrument verbose="true">
+ <fileset dir="${testclasses.dir}/org/hibernate/auction/model">
+ <include name="*.class"/>
+ </fileset>
+ </instrument>
+</target>]]></programlisting>
+
+ <para>
+ �s�v�ȗ��ǂݍ��܂Ȃ����߂́A�ʂ́i���悢�H�j���@�́A���Ȃ��Ƃ�
+ �ǂݍ��݂݂̂̃g�����U�N�V�����ɂ����ẮAHQL��Criteria�N�G���̎ˉe
+ �@�\��g�����Ƃł��B���̕��@�̓r���h���̃o�C�g�R�[�h�g�ݍ��݂��s�v�ɂȂ�A
+ ���ǂ������@�ł��B
+ </para>
+
+ <para>
+ HQL�� <literal>fetch all properties</literal> ��g�����ƂŁA���ʂǂ����
+ �v���p�e�B�̑����t�F�b�`���O�������邱�Ƃ��o���܂��B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="performance-cache" revision="1">
+ <title>��2���x���L���b�V��</title>
+
+ <para>
+ Hibernate�� <literal>Session</literal> �͉i���f�[�^�̃g�����U�N�V�������x���̃L���b�V���ł��B
+ class-by-class��collection-by-collection���Ƃ́A�N���X�^���x����JVM���x��
+ �i <literal>SessionFactory</literal> ���x���j�̃L���b�V����ݒ肷�邱�Ƃ��o���܂��B
+ �N���X�^�����ꂽ�L���b�V���ɂȂ����Ƃ����o���܂��B���������ӂ��Ă��������B
+ �L���b�V���͑��̃A�v���P�[�V�����ɂ��i���w�̕ύX��
+ �l�����܂���i�L���b�V���f�[�^�����I�Ɋ�����ɂ���ݒ�͏o���܂��j�B
+ </para>
+
+ <para revision="1">
+ Hibernate���g�p����L���b�V�������́A<literal>hibernate.cache.provider_class</literal> �v���p�e�B��
+ <literal>org.hibernate.cache.CacheProvider</literal> ����������N���X����w�肷�邱�ƂŕύX�ł��܂��B
+ Hibernate�͑����̃I�[�v���\�[�X�̃L���b�V���v���o�C�_��r���g�C�������Ŏ����Ă��܂��i��Ƀ��X�g������܂��j�B
+ �����āA�O�ɐ�������悤�ɁA���Ȃ����g���Ǝ��̎������āA�����g�ݍ��ނ��Ƃ�o���܂��B
+ �o�[�W����3.2���O�ł�EhCache���f�t�H���g�̃L���b�V���v���o�C�_�ł��邱�Ƃɒ��ӂ��Ă��������B
+ �o�[�W����3.2�ł͂���͓��Ă͂܂�܂���B
+ </para>
+
+ <table frame="topbot" id="cacheproviders" revision="1">
+ <title>�L���b�V���v���o�C�_</title>
+ <tgroup cols='5' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="3*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>�L���b�V��</entry>
+ <entry>�v���o�C�_�N���X</entry>
+ <entry>�^�C�v</entry>
+ <entry>�N���X�^�Z�[�t</entry>
+ <entry>�N�G���L���b�V���̃T�|�[�g</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Hashtable�i���i�p�Ƃ��ĈӐ}���Ă��܂���j</entry>
+ <entry><literal>org.hibernate.cache.HashtableCacheProvider</literal></entry>
+ <entry>������</entry>
+ <entry></entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry>EHCache</entry>
+ <entry><literal>org.hibernate.cache.EhCacheProvider</literal></entry>
+ <entry>�������A�f�B�X�N</entry>
+ <entry></entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry>OSCache</entry>
+ <entry><literal>org.hibernate.cache.OSCacheProvider</literal></entry>
+ <entry>�������A�f�B�X�N</entry>
+ <entry>yes�i�N���X�^�������j</entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry>SwarmCache</entry>
+ <entry><literal>org.hibernate.cache.SwarmCacheProvider</literal></entry>
+ <entry>�N���X�^�iip�}���`�L���X�g�j</entry>
+ <entry>yes�i�N���X�^�������j</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>JBoss TreeCache</entry>
+ <entry><literal>org.hibernate.cache.TreeCacheProvider</literal></entry>
+ <entry>�N���X�^�iip�}���`�L���X�g�j�A�g�����U�N�V���i��</entry>
+ <entry>yes�i�����j</entry>
+ <entry>yes�i�����������K�v�j</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="performance-cache-mapping" revision="2">
+ <title>�L���b�V���̃}�b�s���O</title>
+
+ <para>
+ �N���X��R���N�V�����̃}�b�s���O�� <literal><cache></literal> �v�f�͈ȉ��̌`���ł��B
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="cache1" coords="2 70"/>
+ <area id="cache2" coords="3 70"/>
+ <area id="cache3" coords="4 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<cache
+ usage="transactional|read-write|nonstrict-read-write|read-only"
+ region="RegionName"
+ include="all|non-lazy"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="cache1">
+ <para>
+ <literal>usage</literal> (required) specifies the caching strategy:
+ <literal>transactional</literal>,
+ <literal>read-write</literal>,
+ <literal>nonstrict-read-write</literal> or
+ <literal>read-only</literal>
+ </para>
+ </callout>
+ <callout arearefs="cache2">
+ <para>
+ <literal>region</literal> (optional, defaults to the class or
+ collection role name) specifies the name of the second level cache
+ region
+ </para>
+ </callout>
+ <callout arearefs="cache3">
+ <para>
+ <literal>include</literal> (optional, defaults to <literal>all</literal>)
+ <literal>non-lazy</literal> specifies that properties of the entity mapped
+ with <literal>lazy="true"</literal> may not be cached when attribute-level
+ lazy fetching is enabled
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ �܂��́i���悢���@�Ƃ��āH�j�A <literal>hibernate.cfg.xml</literal> �� <literal><class-cache></literal>
+ �� <literal><collection-cache></literal> �v�f��w�肷�邱�Ƃ�o���܂��B
+ </para>
+
+ <para>
+ <literal>usage</literal> ������ <emphasis>�L���b�V���̕��헪</emphasis> ��w�肵�܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-cache-readonly">
+ <title>read only�헪</title>
+
+ <para>
+ ����A�v���P�[�V�������ǂݍ��݂̂ݕK�v�ŁA�i���N���X�̃C���X�^���X��ύX���Ȃ��Ȃ�A
+ <literal>read-only</literal> �L���b�V����g�����Ƃ��o���܂��B����͂���Ƃ�P����
+ ����Ƃ�p�t�H�[�}���X�̗ǂ��헪�ł��B�N���X�^�ł̎g�p����S�Ɉ��S�ł��B
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Immutable" mutable="false">
+ <cache usage="read-only"/>
+ ....
+</class>]]></programlisting>
+
+ </sect2>
+
+
+ <sect2 id="performance-cache-readwrite">
+ <title>read/write�헪</title>
+
+ <para>
+ �A�v���P�[�V�������f�[�^��X�V����K�v������Ȃ�A <literal>read-write</literal> �L���b�V�����K������
+ ����܂���B���̃L���b�V���헪�́A�V���A���C�U�u���ȃg�����U�N�V�����������x�����v�������Ȃ�A
+ �����Ďg���ׂ��ł͂���܂���B����L���b�V����JTA���Ŏg����Ȃ�AJTA <literal>TransactionManager</literal>
+ ��擾���邽�߂̕��@���� <literal>hibernate.transaction.manager_lookup_class</literal>
+ �v���p�e�B��w�肵�Ȃ���Ȃ�܂���B���̊��ł́A <literal>Session.close()</literal>
+ �� <literal>Session.disconnect()</literal> ���Ăꂽ�Ƃ��ɁA�m���Ƀg�����U�N�V����������
+ ���Ă��Ȃ���Ȃ�܂���B
+ ����N���X�^�ł��̐헪��g�������Ȃ�A��ƂȂ�L���b�V���̎��������b�N��T�|�[�g
+ ���Ă��邱�Ƃ�ۏ��Ȃ���Ȃ�܂���B
+ �g�ݍ��݂̃L���b�V���v���o�C�_�� <emphasis>�T�|�[�g���Ă��܂���</emphasis> �B
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Cat" .... >
+ <cache usage="read-write"/>
+ ....
+ <set name="kittens" ... >
+ <cache usage="read-write"/>
+ ....
+ </set>
+</class>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-cache-nonstrict">
+ <title>�����ł͂Ȃ�read/write�헪</title>
+
+ <para>
+ �A�v���P�[�V���������܂ɂ����f�[�^��X�V����K�v�͂Ȃ��i���Ȃ킿��̃g�����U�N�V������
+ �����ɓ����A�C�e����X�V���悤�Ƃ��邱�Ƃ͂قƂ�NjN����Ȃ��j�A�����ȃg�����U�N�V����������
+ �v������Ȃ��Ȃ�A <literal>nonstrict-read-write</literal> �L���b�V�����K���������܂���B
+ ����L���b�V����JTA���Ŏg����Ȃ�A <literal>hibernate.transaction.manager_lookup_class</literal>
+ ��w�肵�Ȃ���Ȃ�܂���B���̊��ł́A <literal>Session.close()</literal>
+ �� <literal>Session.disconnect()</literal> ���Ăꂽ�Ƃ��ɁA�m���Ƀg�����U�N�V����������
+ ���Ă��Ȃ���Ȃ�܂���B
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-cache-transactional">
+ <title>transactional�헪</title>
+
+ <para>
+ <literal>transactional</literal> �L���b�V���헪��JBoss TreeCache�̂悤�Ȋ��S�ȃg�����U�N�V���i��
+ �L���b�V���v���o�C�_�̃T�|�[�g����܂��B
+ ���̂悤�ȃL���b�V����JTA���ł̂ݎg�p�\�ŁA <literal>hibernate.transaction.manager_lookup_class</literal>
+ ��w�肵�Ȃ���Ȃ�܂���B
+ </para>
+
+ </sect2>
+
+ <para>
+ ���ׂĂ̓������s���L���b�V���헪��T�|�[�g���Ă���L���b�V���v���o�C�_�͂���܂���B
+ �ȉ��̕\�͂ǂ̃v���o�C�_���ǂ̓������헪�ɑΉ����邩��\���Ă��܂��B
+ </para>
+
+ <table frame="topbot">
+ <title>�������s���L���b�V���헪�̃T�|�[�g</title>
+ <tgroup cols='5' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="1*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>�L���b�V��</entry>
+ <entry>read-only</entry>
+ <entry>�����ł͂Ȃ�read-write</entry>
+ <entry>read-write</entry>
+ <entry>transactional</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Hashtable�i���i�p�Ƃ��ĈӐ}���Ă��܂���j</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>EHCache</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>OSCache</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>SwarmCache</entry>
+ <entry>yes</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>JBoss TreeCache</entry>
+ <entry>yes</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>yes</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="performance-sessioncache" revision="2">
+ <title>�L���b�V���̊Ǘ�</title>
+
+ <para>
+ �I�u�W�F�N�g�� <literal>save()</literal> �A <literal>update()</literal> �A <literal>saveOrUpdate()</literal>
+ �ɓn���Ƃ��A������ <literal>load()</literal> �A <literal>get()</literal> �A <literal>list()</literal> �A
+ <literal>iterate()</literal> �A <literal>scroll()</literal> ��g���ăI�u�W�F�N�g������Ƃ��ɂ͏�ɁA
+ ���̃I�u�W�F�N�g�� <literal>Session</literal> �̓���L���b�V���ɒlj�����܂��B
+ </para>
+ <para>
+ ���� <literal>flush()</literal> ���Ă��ƁA�I�u�W�F�N�g�̏�Ԃ̓f�[�^�x�[�X�Ɠ���������܂��B
+ ������̓������N���邱�Ƃ�]�܂Ȃ��Ƃ���A�c��Ȑ��̃I�u�W�F�N�g�������Ă��ă�����������I��
+ �����K�v������Ƃ��́A <literal>evict()</literal> ���\�b�h��g���Ĉꎟ�L���b�V������
+ �I�u�W�F�N�g��R���N�V������폜���邱�Ƃ��o���܂��B
+ </para>
+
+ <programlisting><![CDATA[ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set
+while ( cats.next() ) {
+ Cat cat = (Cat) cats.get(0);
+ doSomethingWithACat(cat);
+ sess.evict(cat);
+}]]></programlisting>
+
+ <para>
+ <literal>Session</literal> �̓C���X�^���X���Z�b�V�����L���b�V���Ɋ܂܂�邩�ǂ����f���邽�߂�
+ <literal>contains()</literal> ���\�b�h����܂��B
+ </para>
+
+ <para>
+ ���ׂẴI�u�W�F�N�g��Z�b�V�����L���b�V�����犮�S�Ɏ�菜���ɂ́A<literal>Session.clear()</literal>
+ ��Ăяo���Ă��������B
+ </para>
+
+ <para>
+ �L���b�V���̂��߂ɁA <literal>SessionFactory</literal> �ɂ�
+ �C���X�^���X�A�N���X�S�́A�R���N�V�����̃C���X�^���X�A�R���N�V�����S�̂�L���b�V������
+ �폜���邽�߂̃��\�b�h�����ꂼ���`����Ă��܂��B
+ </para>
+
+ <programlisting><![CDATA[sessionFactory.evict(Cat.class, catId); //evict a particular Cat
+sessionFactory.evict(Cat.class); //evict all Cats
+sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
+sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections]]></programlisting>
+
+ <para>
+ <literal>CacheMode</literal> �͓���̃Z�b�V�������L���b�V���Ƃǂ̂悤�ɑ��ݍ�p���邩��
+ �w�肵�܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>CacheMode.NORMAL</literal> - �A�C�e���̓ǂݍ��݂Ə������݂œL���b�V����g���܂�
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.GET</literal> - �ǂݍ��݂͓L���b�V������s���܂����A�f�[�^��
+ �X�V�����ꍇ�����ēL���b�V���ɏ������݂��܂���B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.PUT</literal> - �L���b�V���ɃA�C�e���������݂܂����A�ǂݍ��݂ɂ�
+ �L���b�V����g���܂���B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.REFRESH</literal> - �L���b�V���ɃA�C�e���������݂܂����A�ǂݍ��݂ɂ�
+ �L���b�V����g�킸�A <literal>hibernate.cache.use_minimal_puts</literal>
+ �̉e������ɁA�f�[�^�x�[�X����ǂݍ��ނ��ׂẴA�C�e���̓L���b�V�������I�Ƀ��t���b�V�����܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ �L���b�V���̓�e��N�G���L���b�V���̈���邽�߂ɁA <literal>Statistics</literal> API��
+ �g�����������B
+ </para>
+
+ <programlisting><![CDATA[Map cacheEntries = sessionFactory.getStatistics()
+ .getSecondLevelCacheStatistics(regionName)
+ .getEntries();]]></programlisting>
+
+ <para>
+ ���v����L���ɂ��āA����ɃI�v�V�����Ƃ��āA�L���b�V���G���g����
+ �l����藝��\�Ȍ`���ŕێ����邱�Ƃ�Hibernate�ɋ������܂��B
+ </para>
+
+ <programlisting><![CDATA[hibernate.generate_statistics true
+hibernate.cache.use_structured_entries true]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="performance-querycache" revision="1">
+ <title>�N�G���L���b�V��</title>
+
+ <para>
+ �N�G���̃��U���g�Z�b�g��L���b�V���o���܂��B����͓����p�����[�^�ʼn��x����s�����
+ �N�G���ɑ��Ă̂ݗL�p�ł��B�N�G���L���b�V����g���ɂ́A�܂��ݒ�ŗL���ɂ��Ȃ��Ă͂Ȃ�܂���B
+ </para>
+
+ <programlisting><![CDATA[hibernate.cache.use_query_cache true]]></programlisting>
+
+ <para>
+ ���̐ݒ�͐V���ɓ�̃L���b�V���̈�̍쐬��s���܂��B��̓N�G���̃��U���g�Z�b�g��
+ �L���b�V���i <literal>org.hibernate.cache.StandardQueryCache</literal> �j��ێ����A
+ ���1�̓N�G���\�ȃe�[�u���ւ̍ŐV�̍X�V�^�C���X�^���v
+ �i <literal>org.hibernate.cache.UpdateTimestampsCache</literal> �j��ێ����܂��B
+ �N�G���L���b�V���̓��U���g�Z�b�g�̎��ۂ̗v�f�̏�Ԃ̓L���b�V�����Ȃ����Ƃ�
+ ���ӂ��Ă��������B�L���b�V������͎̂��ʎq�̒l�ƁA�l�^�̌��ʂ݂̂ł��B
+ ���̂��߁A�N�G���L���b�V���͏�ɓL���b�V���ƈꏏ�Ɏg���ׂ��ł��B
+ </para>
+
+ <para>
+ �قƂ�ǂ̃N�G���̓L���b�V���̉��b��Ȃ��̂ŁA�f�t�H���g�ł̓N�G���̓L���b�V������܂���B
+ �L���b�V����L���ɂ���ɂ́A <literal>Query.setCacheable(true)</literal> ��Ăяo���Ă��������B
+ ��������N�G���������̃L���b�V�����ʂ�T���A�N�G�����s���ɂ��̌��ʂ�L���b�V���ɒlj�����
+ �悤�ɂȂ�܂��B
+ </para>
+
+ <para>
+ �N�G���L���b�V���̔j���|���V�[��ׂ������䂵�����Ƃ��́A <literal>Query.setCacheRegion()</literal>
+ ��Ăяo���ē���̃N�G���ɑ���L���b�V���̈��w�肷�邱�Ƃ��o���܂��B
+ </para>
+
+ <programlisting><![CDATA[List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger")
+ .setEntity("blogger", blogger)
+ .setMaxResults(15)
+ .setCacheable(true)
+ .setCacheRegion("frontpages")
+ .list();]]></programlisting>
+
+ <para>
+ �N�G�������g�̃N�G���L���b�V���̈�̃��t���b�V���������Ȃ���Ȃ�Ȃ��Ȃ�A
+ <literal>Query.setCacheMode(CacheMode.REFRESH)</literal> ��Ăяo���ׂ��ł��B�����
+ ���ƂȂ�f�[�^���ʂ̃v���Z�X�ɂ���čX�V���ꂽ��i���Ȃ킿Hibernate��ʂ��čX�V����Ȃ��j�A
+ �A�v���P�[�V�����ɓ���̃N�G�����U���g�Z�b�g��I���ă��t���b�V��������ꍇ�ɓ��ɗL�p�ł��B
+ ����ɗL�p�Ȃ����̕��@�́A <literal>SessionFactory.evictQueries()</literal>
+ �ɂ���ăN�G���L���b�V���̈��������邱�Ƃł��B
+ </para>
+
+ </sect1>
+��14.1
+ <sect1 id="performance-collections">
+ <title>�R���N�V�����̃p�t�H�[�}���X�̗���</title>
+
+ <para>
+ �R���N�V�����̘b��ɂ͂��łɑ����̎��Ԃ�g���܂����B���̐߂ł�
+ �R���N�V���������s���ɂǂ̂悤�ɐU�������ɂ��Ă̘b���2�A3���グ�܂��B
+ </para>
+
+ <sect2 id="performance-collections-taxonomy">
+ <title>����</title>
+
+ <para>Hibernate��3�̊�{�I�ȃR���N�V�����̎�ނ��`���Ă��܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>�l�̃R���N�V����</para>
+ </listitem>
+ <listitem>
+ <para>��Α��֘A</para>
+ </listitem>
+ <listitem>
+ <para>���Α��֘A</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ���̕��ނ͂��܂��܂ȃe�[�u����O���L�[�֘A���ʂ��܂����A���������m��K�v�̂���
+ �֘A���f���ɂ��ĂقƂ�ǂȂɂ�����Ă���܂���B�֘A�\����p�t�H�[�}���X�̓�����
+ ���S�ɗ�����ɂ́AHibernate���R���N�V�����̍s��X�V�A�폜���邽�߂Ɏg����L�[��
+ �\����܂��l���Ȃ���Ȃ�܂���B����͈ȉ��̕��ނ���܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>�C���f�b�N�X�t���R���N�V����</para>
+ </listitem>
+ <listitem>
+ <para>set</para>
+ </listitem>
+ <listitem>
+ <para>bag</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ���ׂẴC���f�b�N�X�t���R���N�V�����imap�Alist�A�z��j�� <literal><key></literal>
+ �� <literal><index></literal> �J��������Ȃ��L�[�����Ă��܂��B���̏ꍇ��
+ �R���N�V�����̍X�V�͔��Ɍ����I�ł��B��L�[�͗L�p�ȃC���f�b�N�X�ɂȂ�AHibernate��
+ ����̍s��X�V�܂��͍폜����Ƃ��ɁA���̍s������I�Ɍ����邱�Ƃ��ł��܂��B
+ </para>
+
+ <para>
+ set�� <literal><key></literal> ����Ȃ��L�[�Ɨv�f�̃J���������Ă��܂��B
+ ����̓R���N�V�����v�f�̂������̌^�ɂ��Ă͌����I�ł͂Ȃ��������܂���B
+ ���ɕ����v�f�A�傫�ȃe�L�X�g�A�o�C�i���t�B�[���h�ł͔�����ł��B�f�[�^�x�[�X��
+ ������L�[�Ɍ����I�ɃC���f�b�N�X��t���邱�Ƃ��ł��Ȃ�����ł��B����A1�Α��⑽�Α��֘A�ɂ����āA
+ ���ɐl�H���ʎq�̏ꍇ�͓������炢�����I�ł��B�i�]�k�F <literal>SchemaExport</literal>
+ �Ŏ��ۂ� <literal><set></literal> �̎�L�[���肽���Ȃ�A���ׂẴJ������
+ <literal>not-null="true"</literal> ��錾���Ȃ���Ȃ�܂���B�j
+ </para>
+
+ <para>
+ <literal><idbag></literal> �}�b�s���O�͑㗝�L�[���`���܂��B���̂���
+ �X�V�͏�ɔ��Ɍ����I�ł��B������A����͍őP�̃P�[�X�ł��B
+ </para>
+
+ <para>
+ bag�͍ň��̃P�[�X�ł��Bbag�͗v�f�̒l�̏d�����\�ŁA�C���f�b�N�X�J���������Ȃ����߁A
+ ��L�[�͒�`����Ȃ��������܂���BHibernate�ɂ͏d�������s���ʂ�����@������܂���B
+ Hibernate�͂��̖��̉��̂��߂ɁA�ύX���������Ƃ��ɂ͏�Ɋ��S�ȍ폜
+ �i��� <literal>DELETE</literal> �ɂ��j��s���A�R���N�V�����̍č쐬��s���܂��B
+ ����͔��ɔ�����I�������܂���B
+ </para>
+
+ <para>
+ 1�Α��֘A�ł́A�u��L�[�v�̓f�[�^�x�[�X�̃e�[�u���̕����I��
+ ��L�[�ł͂Ȃ��������Ȃ����Ƃɒ��ӂ��Ă��������B���������̏ꍇ�ł����A��L�̕��ނ͂܂��L�p�ł��B
+ �iHibernate���R���N�V�����̌X�̍s��ǂ�����āu�����邩�v��\���Ă��܂��B�j
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-collections-mostefficientupdate">
+ <title>�X�V�ɂ���Ƃ�����I�ȃR���N�V���� list�Amap�Aidbag�Aset</title>
+
+ <para>
+ ��ł̋c�_����A�C���f�b�N�X�t���R���N�V�����Ɓi���ʂ́jset�͗v�f�̒lj��A�폜�A
+ �X�V�ł���Ƃ�����I�ȑ��삪�o���邱�Ƃ͖��炩�ł��B
+ </para>
+
+ <para>
+ �قڊԈႢ�Ȃ��A���Α��֘A��l�̃R���N�V�����ɂ����āA�C���f�b�N�X�t���R���N�V������
+ set����D��Ă���_����ȏ゠��܂��B <literal>Set</literal> �͂���
+ �\���̂��߂ɁAHibernate�͗v�f���u�ύX�v���ꂽ�Ƃ��ɍs������ <literal>UPDATE</literal>
+ ���܂���B <literal>Set</literal> �ւ̕ύX�͏�Ɂi�X�̍s�́j<literal>INSERT</literal>
+ �� <literal>DELETE</literal> �ɂ���čs���܂��B�J��Ԃ��܂����A����͈�Α��֘A�ɂ�
+ ���Ă͂܂�܂���B
+ </para>
+
+ <para>
+ �z��͒x���������ł��Ȃ��Ƃ������܂�Ȃ̂ŁA���_�Ƃ��āAlist�Amap�Aidbag������Ƃ�
+ �p�t�H�[�}���X�̗ǂ��iinverse�ł͂Ȃ��j�R���N�V�����^�C�v�ƂȂ�܂��Bset��
+ ����قLjႢ�͂���܂���BHibernate�̃A�v���P�[�V�����ł́Aset�̓R���N�V�����̂���Ƃ�
+ ���ʂ̎�ނƂ��Ċ��҂���܂��Bset�̕\���͊֘A���f���ł͂���Ƃ���R������ł��B
+ </para>
+
+ <para>
+ �������A�悭�f�U�C�����ꂽHibernate�̃h���C�����f���ł́A�ʏ����Ƃ�����R���N�V������
+ ������ <literal>inverse="true"</literal> ��w�肵��1�Α��֘A�ł��B�����̊֘A�ł́A
+ �X�V�͑��Έ�̊֘A�[�ň����A�R���N�V�����̍X�V�p�t�H�[�}���X�̖��͓��Ă͂܂�܂���B
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-collections-mostefficentinverse">
+ <title>inverse�R���N�V�����ɂ���Ƃ�œK��bag��list</title>
+
+ <para>
+ bag�������Ă��܂��O�ɁAbag�i������list��j��set��������ƃp�t�H�[�}���X���ǂ����ʂȃP�[�X��
+ �Љ�܂��B <literal>inverse="true"</literal> �̃R���N�V�����i��ʓI��1�Α��֘A�̎g�����Ȃǁj�ŁA
+ bag�̗v�f�������i�t�F�b�`�j����K�v�Ȃ�bag��list�ɗv�f��lj��ł��܂��I
+ ����� <literal>Collection.add()</literal> �� <literal>Collection.addAll()</literal>
+ ��bag�� <literal>List</literal> �ł͏��true��Ԃ��Ȃ���Ȃ�Ȃ�����ł�
+ �i <literal>Set</literal> �Ƃ͈قȂ�܂��j�B
+ ����͈ȉ��̋��ʏ������葬�����邱�Ƃ��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) sess.load(Parent.class, id);
+Child c = new Child();
+c.setParent(p);
+p.getChildren().add(c); //no need to fetch the collection!
+sess.flush();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-collections-oneshotdelete">
+ <title>�ꊇ�폜</title>
+
+ <para>
+ ���X�A�R���N�V�����̗v�f����폜���邱�Ƃ͋ɂ߂Ĕ�����I�ɂȂ邱�Ƃ�����܂��B
+ Hibernate�͋��ł͂Ȃ��̂ŁA�V������̃R���N�V�����̏ꍇ�i <literal>list.clear()</literal>
+ ��Ăяo�����ꍇ�Ȃǁj�ł͂�����ׂ��łȂ����Ƃ�m���Ă��܂��B���̏ꍇ�́AHibernate��
+ <literal>DELETE</literal> ���s���āA����ł��ׂďI���܂��I
+ </para>
+
+ <para>
+ �T�C�Y20�̃R���N�V�����Ɉ�̗v�f��lj����A���ꂩ���̗v�f��폜����Ƃ��܂��B
+ Hibernate�͈�� <literal>INSERT</literal> ���Ɠ�� <literal>DELETE</literal> ���s���܂�
+ �i�R���N�V������bag�łȂ���j�B����͊m���ɖ]�܂�������ł��B
+ </para>
+
+ <para>
+ �������A18�̗v�f��폜����2��c���A���ꂩ��3�V�����v�f��lj�����Ƃ��܂��B
+ ���̂Ƃ���̕��@������܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ 18�s����폜���āA3�s��lj�����
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �R���N�V�����S�̂�폜�i <literal>DELETE</literal> ��SQL����j���A������5�̗v�f���ׂĂ�
+ �i����j�lj�����
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate�͂��̏ꍇ��2�Ԗڂ̕��@����葬�����낤�Ƃ킩��قnj����͂���܂���B
+ �i������Hibernate�����̂悤�Ɍ������Ƃ�]�܂����Ȃ��ł��傤�B���̂悤�ȐU�镑����
+ �f�[�^�x�[�X�̃g���K�Ȃǂ��������邩�����܂���B�j
+ </para>
+
+ <para>
+ �K���ɂ�A���̃R���N�V������̂āi�܂�Q�Ƃ��߂āj�A���݂̗v�f���ׂĎ��V�����R���N�V������
+ �C���X�^���X��Ԃ����ƂŁA���ł���̐U�镑���i2�Ԗڂ̐헪�j�������邱�Ƃ��o���܂��B
+ ���ɂ���͂ƂĂ�֗��ŋ��͂ł��B
+ </para>
+
+ <para>
+ ������A�ꊇ�폜�� <literal>inverse="true"</literal> ��w�肵���R���N�V�����ɂ͍s���܂���B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="performance-monitoring" revision="1">
+ <title>�p�t�H�[�}���X�̃��j�^�����O</title>
+
+ <para>
+ �œK���̓��j�^�����O��p�t�H�[�}���X�������l���Ȃ���Ώ\���ɍs���܂���B
+ Hibernate�͓�������̂��ׂĂ͈̔͂̐��l����܂��B
+ Hibernate�̓��v���� <literal>SessionFactory</literal> �P�ʂŎ擾�\�ł��B
+ </para>
+
+ <sect2 id="performance-monitoring-sf" revision="2">
+ <title>SessionFactory�̃��j�^�����O</title>
+
+ <para>
+ <literal>SessionFactory</literal> �̃��g���N�X�ɃA�N�Z�X����ɂ�2�̕��@������܂��B
+ �ŏ��̕��@�́A <literal>sessionFactory.getStatistics()</literal> ��Ăяo���A
+ ������ <literal>Statistics</literal> �̓ǂݍ��݂�\����s���܂��B
+ </para>
+
+ <para>
+ <literal>StatisticsService</literal> MBean��L���ɂ��Ă���AHibernate��JMX��g����
+ ���g���N�X�s���邱�Ƃ�ł��܂��B1��MBean���ׂĂ� <literal>SessionFactory</literal>
+ �ɑ��ėL���ɂ��邩�ASessionFactory���ƂɈ��MBean��L���ɂ��邱�Ƃ��o���܂��B
+ �ŏ����̐ݒ��ł���ȉ��̃R�[�h���Ă��������B
+ </para>
+
+ <programlisting><![CDATA[// MBean service registration for a specific SessionFactory
+Hashtable tb = new Hashtable();
+tb.put("type", "statistics");
+tb.put("sessionFactory", "myFinancialApp");
+ObjectName on = new ObjectName("hibernate", tb); // MBean object name
+
+StatisticsService stats = new StatisticsService(); // MBean implementation
+stats.setSessionFactory(sessionFactory); // Bind the stats to a SessionFactory
+server.registerMBean(stats, on); // Register the Mbean on the server]]></programlisting>
+
+
+<programlisting><![CDATA[// MBean service registration for all SessionFactory's
+Hashtable tb = new Hashtable();
+tb.put("type", "statistics");
+tb.put("sessionFactory", "all");
+ObjectName on = new ObjectName("hibernate", tb); // MBean object name
+
+StatisticsService stats = new StatisticsService(); // MBean implementation
+server.registerMBean(stats, on); // Register the MBean on the server]]></programlisting>
+
+ <para>
+ TODO: ����͈Ӗ�������܂���B�ŏ��̃P�[�X�́AMBean�ڕ������Ďg�p���܂��B2�Ԗڂ̃P�[�X�́A
+ �g���O��session factory�������Ă���JNDI����n���Ȃ���Ȃ�܂���B
+ <literal>hibernateStatsBean.setSessionFactoryJNDIName("my/JNDI/Name")</literal> ��g�����������B
+ </para>
+ <para>
+ <literal>SessionFactory</literal> �ɑ��ă��j�^�����O�̊J�n�i�I���j��s�����Ƃ��o���܂��B
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ �ݒ莞�ɂ́A <literal>hibernate.generate_statistics</literal> �� <literal>false</literal> �ɂ��܂�
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>
+ ���s���ɁA <literal>sf.getStatistics().setStatisticsEnabled(true)</literal> �܂���
+ <literal>hibernateStatsBean.setStatisticsEnabled(true)</literal> ��Ăяo���܂�
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ���v�� <literal>clear()</literal> ���\�b�h��g���Ď蓮�Ń��Z�b�g���邱�Ƃ��o���܂��B
+ �T�}���� <literal>logSummary()</literal> ���\�b�h��g����logger�ɑ��邱�Ƃ��o���܂�
+ �iinfo���x���ł��j�B
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-monitoring-metrics" revision="1">
+ <title>���g���N�X</title>
+
+ <para>
+ �����̂�̂�����܂��B���ׂĂ̎g�p�\�ȃJ�E���^�� <literal>Statistics</literal>
+ �C���^�[�t�F�C�X��API�ɏ�����Ă���A3�̕��ނ�����܂��B
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ ���g���N�X�͈�ʓI�� <literal>Session</literal> �̎g�����ƊW���Ă��܂��B
+ �I�[�v�������Z�b�V�����̐���JDBC�R�l�N�V�����Ɗ֘A���Ă���̂Ɠ����ł��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ���g���N�X�͗v�f�A�R���N�V�����A�N�G����L���b�V���ȂǑS�̂�
+ �W���Ă��܂��i�ʖ��̓O���[�o�����g���N�X�ł��j�B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ���g���N�X�̏ڍׂ͓���̃G���e�B�e�B�A�R���N�V�����A�N�G���A�L���b�V���̈�ɊW���Ă��܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ��Ƃ��āA�L���b�V���̃q�b�g�A�q�b�g�~�X��A�v�f�A�R���N�V�����A�N�G���̊����A�N�G���̎��s��
+ �K�v�ȕ��ώ��Ԃ�m�F�ł��܂��B�~���b�̐��l��Java�̋ߎ���邱�Ƃɒ��ӂ��Ă��������B
+ Hibernate��JVM�̐��x�ɐ�������A�v���b�g�t�H�[���ɂ���Ă�10�b�P�ʂł������m�łȂ��������܂���B
+ </para>
+
+ <para>
+ �P����getter�̓O���[�o�����g���N�X�i���Ȃ킿����̃G���e�B�e�B�A�R���N�V�����A�L���b�V���̈�Ȃǂɔ����Ȃ��j
+ �ɃA�N�Z�X���邽�߂Ɏg���܂��B����̃G���e�B�e�B�A�R���N�V�����A�L���b�V���̈�̃��g���N�X�́A
+ �����̖��O��A�N�G����HQL�ASQL�\���ɂ���ăA�N�Z�X���邱�Ƃ��o���܂��B����ɏڂ������́A
+ <literal>Statistics</literal> �A <literal>EntityStatistics</literal> �A <literal>CollectionStatistics</literal>
+ �A <literal>SecondLevelCacheStatistics</literal> �A <literal>QueryStatistics</literal> API��javadoc��
+ �Q�Ƃ��Ă��������B�ȉ��̃R�[�h�͊ȒP�ȗ�ł��B
+ </para>
+
+ <programlisting><![CDATA[Statistics stats = HibernateUtil.sessionFactory.getStatistics();
+
+double queryCacheHitCount = stats.getQueryCacheHitCount();
+double queryCacheMissCount = stats.getQueryCacheMissCount();
+double queryCacheHitRatio =
+ queryCacheHitCount / (queryCacheHitCount + queryCacheMissCount);
+
+log.info("Query Hit ratio:" + queryCacheHitRatio);
+
+EntityStatistics entityStats =
+ stats.getEntityStatistics( Cat.class.getName() );
+long changes =
+ entityStats.getInsertCount()
+ + entityStats.getUpdateCount()
+ + entityStats.getDeleteCount();
+log.info(Cat.class.getName() + " changed " + changes + "times" );]]></programlisting>
+
+ <para>
+ ���ׂẴG���e�B�e�B�A�R���N�V�����A�N�G���A�L���b�V���̈�ɑ��čs���ꍇ�́A
+ <literal>getQueries()</literal> �A <literal>getEntityNames()</literal>�A
+ <literal>getCollectionRoleNames()</literal> �A <literal>getSecondLevelCacheRegionNames()</literal> ���\�b�h��
+ ���ꂼ��̖��O�̃��X�g��擾���邱�Ƃ��o���܂��B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/persistent_classes.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/persistent_classes.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/persistent_classes.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/persistent_classes.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,539 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="persistent-classes" revision="2">
+ <title>�i���N���X</title>
+
+ <para>
+ �i���N���X�̓r�W�l�X��̖��̃G���e�B�e�B�i�Ⴆ�AE�R�}�[�X�A�v���P�[�V�����̌ڋq�⒍���j
+ ���������A�v���P�[�V�����̃N���X�ł��B
+ �i���N���X�̂��ׂẴC���X�^���X���i����Ԃł���ƌ��Ȃ����킯�ł͂���܂���B
+ �C���X�^���X�͋t�Ɉꎞ�I�itransient�j�ł�������A������ԁidetached�j�ł������肷�邩�����܂���B
+ </para>
+
+ <para>
+ Plain Old Java Object (POJO)�v���O���~���O���f���Ƃ��Ă�m����
+ �������̒P���ȃ��[���ɏ]���Ȃ�AHibernate�͍ł�悭�����܂��B
+ �����������̃��[���͓����̂ł͂���܂���B
+ ����Hibernate3�͉i���I�u�W�F�N�g�̐����ɂقƂ�lj��̑O���u���Ă��܂���B
+ �h���C�����f���͑��̕��@�ŕ\�����邱�Ƃ�ł��܂��B
+ �Ⴆ�� <literal>Map</literal> �C���X�^���X�̃c���[��g�����@������܂��B
+ </para>
+
+ <sect1 id="persistent-classes-pojo">
+ <title>�P����POJO�̗�</title>
+
+ <para>
+ �قƂ�ǂ�Java�A�v���P�[�V�����ɂ̓l�R�Ȃ̓�����\������i���N���X���K�v�ł��B
+ </para>
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+import java.util.Date;
+
+public class Cat {
+ private Long id; // identifier
+
+ private Date birthdate;
+ private Color color;
+ private char sex;
+ private float weight;
+ private int litterId;
+
+ private Cat mother;
+ private Set kittens = new HashSet();
+
+ private void setId(Long id) {
+ this.id=id;
+ }
+ public Long getId() {
+ return id;
+ }
+
+ void setBirthdate(Date date) {
+ birthdate = date;
+ }
+ public Date getBirthdate() {
+ return birthdate;
+ }
+
+ void setWeight(float weight) {
+ this.weight = weight;
+ }
+ public float getWeight() {
+ return weight;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+ void setColor(Color color) {
+ this.color = color;
+ }
+
+ void setSex(char sex) {
+ this.sex=sex;
+ }
+ public char getSex() {
+ return sex;
+ }
+
+ void setLitterId(int id) {
+ this.litterId = id;
+ }
+ public int getLitterId() {
+ return litterId;
+ }
+
+ void setMother(Cat mother) {
+ this.mother = mother;
+ }
+ public Cat getMother() {
+ return mother;
+ }
+ void setKittens(Set kittens) {
+ this.kittens = kittens;
+ }
+ public Set getKittens() {
+ return kittens;
+ }
+
+ // addKitten not needed by Hibernate
+ public void addKitten(Cat kitten) {
+ kitten.setMother(this);
+ kitten.setLitterId( kittens.size() );
+ kittens.add(kitten);
+ }
+}]]></programlisting>
+
+ <para>
+ �]���ׂ�4�̃��[��������܂��F
+ </para>
+
+ <sect2 id="persistent-classes-pojo-constructor" revision="1">
+ <title>�����̂Ȃ��R���X�g���N�^���������</title>
+
+ <para>
+ <literal>Cat</literal> �ɂ͈����̂Ȃ��R���X�g���N�^������܂��B
+ Hibernate�� <literal>Constructor.newInstance()</literal> ��g���ĉi���N���X��
+ �C���X�^���X����s����悤�ɁA���ׂẲi���N���X�ɂ̓f�t�H���g�R���X�g���N�^
+ �ipublic�łȂ��Ă�\���܂���j���Ȃ���Ȃ�܂���B
+ Hibernate�̎��s���v���L�V�����̂��߂ɁA���Ȃ��Ƃ� <emphasis>package</emphasis>
+ �̉������f�t�H���g�R���X�g���N�^���������߂��܂��B
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-identifier" revision="2">
+ <title>���ʎq�v���p�e�B��p�ӂ���i�I�v�V�����j</title>
+
+ <para>
+ <literal>Cat</literal> �ɂ� <literal>id</literal> �Ƃ����v���p�e�B������܂��B
+ ���̃v���p�e�B�̓f�[�^�x�[�X�e�[�u���̎�L�[�J�����փ}�b�s���O����܂��B
+ ���̃v���p�e�B�̖��O�͉��ł�\���܂��A�^�͂ǂ̂悤�ȃv���~�e�B�u�^�ł�A
+ �v���~�e�B�u�́u���b�p�[�v�^�ł�A<literal>java.lang.String</literal> ��
+ <literal>java.util.Date</literal> �ł�\���܂���B
+ �i������K�V�[�f�[�^�x�[�X�e�[�u���������L�[���Ȃ�A
+ ���q�ׂ��悤�Ȍ^�̃v���p�e�B�����[�U��`�̃N���X��g�����Ƃ����\�ł��B
+ ��ŕ������ʎq�̐߂��Ă��������B�j
+ </para>
+
+ <para>
+ ���ʎq�v���p�e�B�͌����ɂ̓I�v�V�����ł��B
+ �����ȗ����āAHibernate�ɓ���I�ɃI�u�W�F�N�g�̎��ʎq��ǐՂ����邱�Ƃ͉\�ł��B
+ �������������߂͂��܂���B
+ </para>
+
+ <para>
+ ���ۂɁA���ʎq�v���p�e�B��錾����N���X���������p�\�ȋ@�\������������܂��F
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ �����I�u�W�F�N�g�̘A���I�ȍĒlj��i�J�X�P�[�h�X�V��J�X�P�[�h�}�[�W�j�B
+ <xref linkend="objectstate-transitive"/> ��Q�Ƃ��Ă��������B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.saveOrUpdate()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.merge()</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ �i���N���X�ɂ́A��т������O�̎��ʎq�v���p�e�B���`���邱�Ƃ����߂��܂��B
+ �����null�l�����(�܂�v���~�e�B�u�ł͂Ȃ�)�^��g���������悢�ł��傤�B
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-final">
+ <title>final�N���X�ɂ��Ȃ��i�I�v�V�����j</title>
+ <para>
+ Hibernate�̒��S�I�ȓ����ł��� <emphasis>�v���L�V</emphasis> �́A
+ �i���N���X��final�łȂ����ƁA�܂��̓��\�b�h��S��public�Ő錾���Ă���
+ �C���^�[�t�F�C�X����������Ă��邩�Ɉˑ����Ă��܂��B
+ </para>
+ <para>
+ Hibernate�ŃC���^�[�t�F�C�X��������Ă��Ȃ� <literal>final</literal> �N���X��i�������邱�Ƃ͂ł��܂����A
+ �x���֘A�t�F�b�`�ɑ��ăv���L�V��g�����Ƃ͂ł��Ȃ��Ȃ�܂��B
+ ����̓p�t�H�[�}���X�`���[�j���O�ւ̑I�����߂邱�ƂɂȂ�܂��B
+ </para>
+ <para>
+ final�ł͂Ȃ��N���X�� <literal>public final</literal> ���\�b�h���`���邱�Ƃ����ׂ��ł��B
+ <literal>public final</literal> ���\�b�h���N���X��g��������A
+ <literal>lazy="false"</literal> �Ɛݒ肵�Ė����I�Ƀv���L�V���ɂ��Ȃ���Ȃ�܂���B
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-accessors" revision="2">
+ <title>�i���t�B�[���h�ɑ���A�N�Z�T�ƃ~���[�e�[�^���`����i�I�v�V�����j</title>
+
+ <para>
+ <literal>Cat</literal> �ł͂��ׂẲi���t�B�[���h�ɑ��ăA�N�Z�T���\�b�h���`���Ă��܂��B
+ ���̑�����ORM�c�[���́A�i���C���X�^���X�ϐ��ډi�������܂��B
+ �������̓����[�V���i���X�L�[�}�ƃN���X�̓���\������������ǂ��ƐM���Ă��܂��B
+ �f�t�H���g�ł́AHibernate��JavaBean�X�^�C���̃v���p�e�B��i�������A
+ <literal>getFoo</literal>, <literal>isFoo</literal>, <literal>setFoo</literal>
+ �`���̃��\�b�h����F�����܂��B
+ �������K�v�Ȃ�A����̃v���p�e�B�ɑ��āA���ڂ̃t�B�[���h�A�N�Z�X�ɐ�ւ��邱�Ƃ͉\�ł��B
+ </para>
+
+ <para>
+ �v���p�e�B��public�Ő錾����K�v�� <emphasis>����܂���</emphasis> �B
+ Hibernate�̓f�t�H���g�A<literal>protected</literal> ������� <literal>private</literal>
+ ��get / set�̃y�A���v���p�e�B��i�������邱�Ƃ��ł��܂��B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-inheritance">
+ <title>�p���̎���</title>
+
+ <para>
+ �T�u�N���X��1�Ԗڂ�2�Ԗڂ̃��[������Ȃ���Ȃ�܂���B
+ �T�u�N���X�̓X�[�p�[�N���X <literal>Cat</literal> ���环�ʎq�v���p�e�B��p�����܂��B
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+public class DomesticCat extends Cat {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+ protected void setName(String name) {
+ this.name=name;
+ }
+}]]></programlisting>
+ </sect1>
+
+ <sect1 id="persistent-classes-equalshashcode" revision="1">
+ <title><literal>equals()</literal> �� <literal>hashCode()</literal> �̎���</title>
+
+ <para>
+ �ȉ��̏��̏ꍇ�A
+ <literal>equals()</literal> �� <literal>hashCode()</literal> ���\�b�h��I�[�o�[���C�h���Ȃ���Ȃ�܂���A
+ </para>
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ �i���N���X�̃C���X�^���X�� <literal>Set</literal> �ɒu���ꍇ�B
+ �i����͑��l�̊֘A��\�����邨�����߂̕��@�ł��j
+ <emphasis>���������</emphasis>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �����C���X�^���X��Z�b�V�����֍Ēlj�����ꍇ�B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate�́A�i��ID�i�f�[�^�x�[�X�̍s�j�ƁA����̃Z�b�V�����X�R�[�v���
+ ����ł���JavaID�Ƃ������ł��邱�Ƃ�ۏ��܂��B
+ �ł�����قȂ�Z�b�V�����Ō��������C���X�^���X��g�ݍ��킹��ꍇ�A
+ <literal>Set</literal> �ɈӖ��̂���Z�}���e�B�N�X�������悤�Ǝv���Ă���Ȃ�
+ ������<literal>equals()</literal> �� <literal>hashCode()</literal>
+ ��������Ȃ���Ȃ�܂���B
+ </para>
+
+ <para>
+ �ł�����ȕ��@�́A�����̃I�u�W�F�N�g�̎��ʎq�̒l�̔�r�ɂ���� <literal>equals()</literal>��
+ <literal>hashCode()</literal> �����������@�ł��B
+ �l�������Ȃ�A���҂̓f�[�^�x�[�X�̓����s�łȂ���Ȃ�Ȃ����ߓ������Ȃ�܂��B
+ �i���҂� <literal>Set</literal> �ɒlj�����Ă�A
+ <literal>Set</literal> �ɂ�1�̗v�f�����Ȃ����ƂɂȂ�܂��j
+ �c�O�Ȃ��ƂɁA�������ꂽ���ʎq�ɂ͂��̃A�v���[�`��g�����Ƃ��ł��܂���B
+ Hibernate�͉i�������ꂽ�I�u�W�F�N�g�֎��ʎq�̒l�������邾���ł���A
+ �V�����쐬���ꂽ�C���X�^���X�͂ǂ̂悤�Ȏ��ʎq�̒l������Ă��܂���B
+ ����ɁA�C���X�^���X���Z�[�u����Ă��炸�A���� <literal>Set</literal> �̒��ɂ���A
+ �Z�[�u����ƃI�u�W�F�N�g�֎��ʎq�̒l�������邱�ƂɂȂ�܂��B
+ ��� <literal>equals()</literal> �� <literal>hashCode()</literal> �����ʎq�̒l�Ɋ�Â��Ă���Ȃ�A
+ �n�b�V���R�[�h���ύX������ <literal>Set</literal> �̋K�j���܂��B
+ ���̖��ɂ��Ă̊��S�ȋc�_�́AHibernate�̃E�F�u�T�C�g���Ă��������B
+ �����Hibernate�̖��ł͂Ȃ��A�I�u�W�F�N�g�̓��ꐫ�Ɠ������ɂ��ẮA
+ �ʏ��Java�̃Z�}���e�B�N�X�ł��邱�Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ <emphasis>�r�W�l�X�L�[�̓�����</emphasis> ��g���āA
+ <literal>equals()</literal> �� <literal>hashCode()</literal> ��������邱�Ƃ����߂��܂��B
+ �r�W�l�X�L�[�̓������Ƃ́A<literal>equals()</literal> ���\�b�h���A�r�W�l�X�L�[�A
+ �܂茻���̐��E�ɂ����ăC���X�^���X����肷��L�[�i<emphasis>���R</emphasis> ���L�[�j
+ ��`������v���p�e�B�������r���邱�Ƃ�Ӗ����܂��B
+ </para>
+
+ <programlisting><![CDATA[public class Cat {
+
+ ...
+ public boolean equals(Object other) {
+ if (this == other) return true;
+ if ( !(other instanceof Cat) ) return false;
+
+ final Cat cat = (Cat) other;
+
+ if ( !cat.getLitterId().equals( getLitterId() ) ) return false;
+ if ( !cat.getMother().equals( getMother() ) ) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = getMother().hashCode();
+ result = 29 * result + getLitterId();
+ return result;
+ }
+
+}]]></programlisting>
+
+ <para>
+ �r�W�l�X�L�[�̓f�[�^�x�[�X�̎�L�[���قLj���ł���K�v�͂Ȃ����Ƃɒ��ӂ��Ă�������
+ �i<xref linkend="transactions-basics-identity"/> �����������j�B
+ �X�V�s�ȃv���p�e�B��j�[�N�ȃv���p�e�B�́A�ʏ�r�W�l�X�L�[�̂悢���ł��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-dynamicmodels">
+ <title>���I���f��</title>
+
+ <para>
+ <emphasis>�ȉ��̋@�\�͌��ݎ����i�K�ɂ���ƌ��Ȃ���Ă���A
+ �߂������ύX�����\�������邱�Ƃɒ��ӂ��Ă��������B</emphasis>
+ </para>
+
+ <para>
+ �i���G���e�B�e�B�́A�K��������s����POJO�N���X��JavaBean�I�u�W�F�N�g�ŕ\������K�v�͂���܂���B
+ Hibernate�́i���s���� <literal>Map</literal> �� <literal>Map</literal> ��g���j���I���f���ƁA
+ DOM4J�c���[�Ƃ��ẴG���e�B�e�B�̕\����T�|�[�g���܂��B
+ ���̃A�v���[�`��g���Ɖi���N���X�������A�}�b�s���O�t�@�C�������������ƂɂȂ�܂��B
+ </para>
+
+ <para>
+ �f�t�H���g�ł́AHibernate�͒ʏ��POJO���[�h�œ��삵�܂��B
+ <literal>default_entity_mode</literal> �ݒ�I�v�V������g���āA
+ ����� <literal>SessionFactory</literal> �ɑ���f�t�H���g�̃G���e�B�e�B�\�����[�h��ݒ肷�邱�Ƃ��ł��܂�
+ �i<xref linkend="configuration-optional-properties"/> �����������j�B
+ </para>
+
+ <para>
+ �ȉ��̗�ł� <literal>Map</literal> ��g�����\����Љ�܂��B
+ �܂��}�b�s���O�t�@�C���ŁA�N���X���̑���Ɂi�܂��͂���ɉ����āj
+ <literal>entity-name</literal> ���`���Ȃ���Ȃ�܂���F
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class entity-name="Customer">
+
+ <id name="id"
+ type="long"
+ column="ID">
+ <generator class="sequence"/>
+ </id>
+
+ <property name="name"
+ column="NAME"
+ type="string"/>
+
+ <property name="address"
+ column="ADDRESS"
+ type="string"/>
+
+ <many-to-one name="organization"
+ column="ORGANIZATION_ID"
+ class="Organization"/>
+
+ <bag name="orders"
+ inverse="true"
+ lazy="false"
+ cascade="all">
+ <key column="CUSTOMER_ID"/>
+ <one-to-many class="Order"/>
+ </bag>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ �֘A���^�[�Q�b�g�̃N���X����g���Ē�`���Ă����Ƃ��Ă�A
+ �֘A�̃^�[�Q�b�g�^��POJO�ł͂Ȃ����I�ȃG���e�B�e�B�ł�\��Ȃ����Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ <literal>SessionFactory</literal> �ɑ��ăf�t�H���g�̃G���e�B�e�B���[�h��
+ <literal>dynamic-map</literal> �ɐݒ肵����A
+ ���s���� <literal>Map</literal> �� <literal>Map</literal> ��g�����Ƃ��ł��܂��F
+ </para>
+
+ <programlisting><![CDATA[Session s = openSession();
+Transaction tx = s.beginTransaction();
+Session s = openSession();
+
+// Create a customer
+Map david = new HashMap();
+david.put("name", "David");
+
+// Create an organization
+Map foobar = new HashMap();
+foobar.put("name", "Foobar Inc.");
+
+// Link both
+david.put("organization", foobar);
+
+// Save both
+s.save("Customer", david);
+s.save("Organization", foobar);
+
+tx.commit();
+s.close();]]></programlisting>
+
+ <para>
+ ���I�ȃ}�b�s���O�̗��_�́A�G���e�B�e�B�N���X�̎�����K�v�Ƃ��Ȃ����߁A
+ �v���g�^�C�s���O�ɗv����^�[���A���E���h�^�C���������Ƃ������Ƃł��B
+ �������R���p�C�����̌^�`�F�b�N���Ȃ��̂ŁA���s���ɔ��ɑ����̗�O��������Ȃ���Ȃ�Ȃ��ł��傤�B
+ Hibernate�}�b�s���O�̂������ŁA�f�[�^�x�[�X�X�L�[�}�͗e�Ղɐ��K���ł��A���S�ɂȂ�A
+ ��œK�ȃh���C�����f���̎�����lj����邱�Ƃ��\�ɂȂ�܂��B
+ </para>
+
+ <para>
+ �G���e�B�e�B�\�����[�h�� <literal>Session</literal> ���Ƃɐݒ肷�邱�Ƃ�\�ł��B
+ </para>
+
+ <programlisting><![CDATA[Session dynamicSession = pojoSession.getSession(EntityMode.MAP);
+
+// Create a customer
+Map david = new HashMap();
+david.put("name", "David");
+dynamicSession.save("Customer", david);
+...
+dynamicSession.flush();
+dynamicSession.close()
+...
+// Continue on pojoSession
+]]></programlisting>
+
+
+ <para>
+ <literal>EntityMode</literal> ��g���� <literal>getSession()</literal>
+ �̌Ăяo���� <literal>SessionFactory</literal> �ł͂Ȃ� <literal>Session</literal>
+ API�ɂ��邱�Ƃɒ��ӂ��Ă��������B
+ ���̕��@�ł́A�V���� <literal>Session</literal> �́A�x�[�X�ƂȂ�JDBC�R�l�N�V�����A
+ �g�����U�N�V�����A���̑��̃R���e�L�X�g�����L���܂��B
+ �����2�Ԗڂ� <literal>Session</literal> �ł� <literal>flush()</literal> �� <literal>close()</literal>
+ ��ĂԕK�v���Ȃ��Ƃ������ƁA���̂��߃g�����U�N�V�����ƃR�l�N�V�����̊Ǘ���
+ 1�Ԗڂ̍�ƒP��(Unit of Work)�ɔC���邱�Ƃ��ł���Ƃ������Ƃł��B
+ </para>
+
+ <para>
+ XML�\���̔\�͂ɂ��Ă̂���Ȃ���� <xref linkend="xml"/> �Ō�����܂��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-tuplizers" revision="1">
+ <title>Tuplizer</title>
+
+ <para>
+ <literal>org.hibernate.tuple.Tuplizer</literal> �Ƃ��̃T�u�C���^�[�t�F�C�X�́A
+ �\���� <literal>org.hibernate.EntityMode</literal> �𗘗p���āA
+ �f�[�^�f�Ђ̂���\���̊Ǘ��ɐӔC�����܂��B
+ �^����ꂽ�f�[�^�f�Ђ�f�[�^�\���Ƃ��čl����Ȃ�ATuplizer�͂��̂悤�ȃf�[�^�\����
+ �ǂ̂悤�ɍ쐬���邩��m��A���̂悤�ȃf�[�^�\������ǂ̂悤�ɒl�𒊏o���A
+ �������邩��m���Ă��܂��B
+ �Ⴆ��POJO�G���e�B�e�B���[�h�ł́A�Ή�����Tuplizer�̓R���X�g���N�^��ʂ��āA
+ POJO��ǂ̂悤�ɍ쐬���邩�A��`���ꂽ�v���p�e�B�A�N�Z�T��g���A
+ POJO�v���p�e�B�ɂǂ̂悤�ɃA�N�Z�X���邩��m��܂��B
+ Tuplizer�ɂ͓�̃n�C���x���̌^������܂��B
+ �����́A<literal>org.hibernate.tuple.EntityTuplizer</literal> ��
+ <literal>org.hibernate.tuple.ComponentTuplizer</literal> �C���^�[�t�F�C�X�ŕ\������܂��B
+ <literal>EntityTuplizer</literal> �͏�ŏq�ׂ��悤�ȃG���e�B�e�B�Ɋւ���_��̊Ǘ��ɐӔC�����܂��B
+ ����A<literal>ComponentTuplizer</literal> �̓R���|�[�l���g�Ɋւ���_��̊Ǘ��ɐӔC�����܂��B
+ </para>
+
+ <para>
+ ���[�U�͓Ǝ���Tuplizer�ɍ����ւ��邱�Ƃ�\�ł��B
+ �����炭dynamic-map entity-mode�̍ۂ� <literal>java.util.HashMap</literal> ��g���̂ł͂Ȃ��A
+ <literal>java.util.Map</literal> �̎������K�v�ł��傤�B
+ ������́A�����炭�f�t�H���g�̂�̂ł͂Ȃ��A�ʂ̃v���L�V�����헪�̒�`���K�v�ł��傤�B
+ ���҂Ƃ�A�J�X�^����Tuplizer�������`���邱�ƂŒB������܂��B
+ Tuplizer�̒�`�́A�Ǘ����悤�Ƃ���G���e�B�e�B��R���|�[�l���g�̃}�b�s���O�Ɍ��ѕt�����܂��B
+ �ڋq�G���e�B�e�B�̗�ɖ߂�ƁF
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+ <class entity-name="Customer">
+ <!--
+ Override the dynamic-map entity-mode
+ tuplizer for the customer entity
+ -->
+ <tuplizer entity-mode="dynamic-map"
+ class="CustomMapTuplizerImpl"/>
+
+ <id name="id" type="long" column="ID">
+ <generator class="sequence"/>
+ </id>
+
+ <!-- other properties -->
+ ...
+ </class>
+</hibernate-mapping>
+
+
+public class CustomMapTuplizerImpl
+ extends org.hibernate.tuple.entity.DynamicMapEntityTuplizer {
+ // override the buildInstantiator() method to plug in our custom map...
+ protected final Instantiator buildInstantiator(
+ org.hibernate.mapping.PersistentClass mappingInfo) {
+ return new CustomMapInstantiator( mappingInfo );
+ }
+
+ private static final class CustomMapInstantiator
+ extends org.hibernate.tuple.DynamicMapInstantitor {
+ // override the generateMap() method to return our custom map...
+ protected final Map generateMap() {
+ return new CustomMap();
+ }
+ }
+}]]></programlisting>
+
+
+ </sect1>
+
+ <para>
+ TODO: �v���p�e�B�ƃv���L�V�p�b�P�[�W�̃��[�U�g���t���[�����[�N�������邱��
+ </para>
+
+</chapter>
+
+
Added: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/preface.xml
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/preface.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/preface.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+
+<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+ <preface id="preface" revision="2">
+ <title>�O����</title>
+
+ <para>
+ �����̊�Ɗ��ɂ����āA�I�u�W�F�N�g�w���\�t�g�E�F�A�ƃ����[�V���i���f�[�^�x�[�X�Ɋւ���Ƃ�
+ �ώG�Ŗc��Ȏ��Ԃ�K�v�Ƃ��܂��B
+ Hibernate��Java���̃I�u�W�F�N�g/�����[�V���i���}�b�s���O�c�[���ł��B
+ �I�u�W�F�N�g/�����[�V���i���}�b�s���O�iORM�j�Ƃ́A
+ �I�u�W�F�N�g���f������SQL�x�[�X�X�L�[�}�̃����[�V���i���f�[�^���f���ւƁA
+ �f�[�^�\����}�b�s���O����i�Ή��t����j�Z�p�̂��Ƃł��B
+ </para>
+
+ <para>
+ Hibernate��Java�N���X����f�[�^�x�[�X�e�[�u���ցi������Java�f�[�^�^����SQL�f�[�^�^�ցj
+ �̃}�b�s���O�������邾���ł͂Ȃ��A�f�[�^�̃N�G���ƕ����̎d�g�݂���܂��B
+ ���̂�������SQL��JDBC��g�������Ƃł̃f�[�^�����ɔ�₳��Ă����J�����Ԃ�啝�ɍ팸�ł��܂��B
+ </para>
+
+ <para>
+ Hibernate�̍ŏI�ڕW�́A�f�[�^�̉i�����Ɋւ���ʓI�ȃv���O���~���O��Ƃ�95������J���҂������邱�Ƃł��B
+ Hibernate�̓r�W�l�X���W�b�N�̎����ɃX�g�A�h�v���V�[�W����g��
+ �f�[�^���S�A�v���P�[�V�����ɑ��Ẵx�X�g�\�����[�V�����ł���ɗ��܂�܂���B
+ �I�u�W�F�N�g�w���h���C�����f����Java�x�[�X�̒��ԑw�ł̃r�W�l�X���W�b�N�ɑ��čł��ɗ����܂��B
+ ������Hibernate�̓x���_�ŗL��SQL�R�[�h��팸�܂��̓J�v�Z����������A
+ �\�`������I�u�W�F�N�g�̃O���t�ւƃ��U���g�Z�b�g��ϊ�����Ȃǂ́A
+ ��ʓI�ȃ^�X�N�ɂ�𗧂ł��傤�B
+ </para>
+
+ <para>
+ Hibernate��I�u�W�F�N�g/�����[�V���i���}�b�s���O�A
+ ����ɂ�Java�����߂Ă̕��́A�ȉ��̃X�e�b�v�ɏ]���Ă��������F
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ <xref linkend="tutorial"/> ��ǂ�ł��������B
+ �i�K�I�ɉ����Ă����܂��B
+ �`���[�g���A���̃\�[�X�R�[�h�̓f�B�X�g���r���[�V������
+ <literal>doc/reference/tutorial</literal> �f�B���N�g���Ɋ܂܂�Ă��܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <xref linkend="architecture"/> ��ǂ�ŁAHibernate�����p�\�Ȋ��𗝉��Ă��������B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Hibernate�f�B�X�g���r���[�V������ <literal>eg/</literal> �f�B���N�g�������������B
+ �ȒP�ȃX�^���h�A���[���̃A�v���P�[�V����������܂��B
+ JDBC�h���C�o�� <literal>lib/</literal> �f�B���N�g���ɃR�s�[���āA
+ �����̃f�[�^�x�[�X�ɍ����������l��w�肷��悤�� <literal>etc/hibernate.properties</literal>
+ ��ҏW���Ă��������B
+ �f�B�X�g���r���[�V�����f�B���N�g������A�R�}���h�v�����v�g��
+ <literal>ant eg</literal> �ƃ^�C�v���Ă��������iAnt��g���܂��j�B
+ �܂�Windows���ł� <literal>build eg</literal> �ƃ^�C�v���Ă��������B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ���̃��t�@�����X�h�L�������g����̏�Ƃ��ė��p���Ă��������B
+ �A�v���P�[�V�����v�ɂ��Ă̂���Ȃ����i�K�I�ȃ`���[�g���A����T���Ă���Ȃ�A
+ <emphasis>Java Persistence with Hibernate</emphasis>�ihttp://www.manning.com/bauer2�j
+ �������߂��܂��B
+ �܂�http://caveatemptor.hibernate.org����
+ Java Persistence with Hibernate�̗��̃A�v���P�[�V������_�E�����[�h�ł��܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ FAQ��Hibernate�E�F�u�T�C�g�ɂ���܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �T�[�h�p�[�e�B�̃f���A��A�`���[�g���A����Hibernate�E�F�u�T�C�g�Ƀ����N������܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Hibernate�E�F�u�T�C�g�̃R�~���j�e�B�G���A�́A�f�U�C���p�^�[���₳�܂��܂ȓ����\�����[�V����
+ �iTomcat, JBoss AS, Struts, EJB, ���j�ɂ��Ă̂悢��ł��B
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ ���₪�����Hibernate�E�F�u�T�C�g�̃��[�U�t�H�[�������p���Ă��������B
+ �܂��o�O���|�[�g�ƃt�B�[�`�����N�G�X�g�̂���JIRA�ۑ�ǐՃV�X�e����p�ӂ��Ă��܂��B
+ Hibernate�̊J���ɋ���������A�J���҃��[�����O���X�g�ɎQ�����Ă��������B
+ ���̃h�L�������g���Ȃ��̍��̌��t�ɖ|�����ꍇ�́A
+ �J���҃��[�����O���X�g�Ŏ������ɃR���^�N�g�����Ă��������B
+ </para>
+
+ <para>
+ ���p�J���̃T�|�[�g�A���i�̃T�|�[�g�AHibernate�̃g���[�j���O��JBoss Inc.�����Ă��܂�
+ �ihttp://www.hibernate.org/SupportTraining/�����������j�B
+ Hibernate��Professional Open Source�v���W�F�N�g�A
+ ������JBoss Enterprise Middleware System�iJEMS�j�v���_�N�g�X�C�[�g�̃N���e�B�J���R���|�[�l���g�ł��B
+ </para>
+<!--
+ <sect1 id="preface-s1" revision="-1">
+
+ <title>���{���ɂ���</title>
+
+ <para id="preface-s1-p1" revision="-1">
+ ���̓��{���Hibernate Reference Document�i�ȉ��A���{��Łj�́A
+ Hibernate�v���W�F�N�g�̖|��v���Z�X�Ɋ�Â��č쐬����Ă��܂��B
+ ���{��łȂ�тɌ�����LGPL���C�Z���X�ɏ����܂��B
+ </para>
+
+ <para id="preface-s1-p2" revision="-1">
+ ���{��ł̗��p�ɂ���đ�O�҂���邠����s���v�ɑ��āA
+ �����ҁA�|��҂Ȃ�тɂ��̑g�D�͈�̕ۏ��������˂܂��B
+ ���{��ł͌���܂މ\�������邱�Ƃ�F��������ł����p���������B
+ ��e�̐��m�ȈӖ���c�����邽�߂ɂ́A������ǂނ��Ƃ������߂��܂��B
+ �܂��A������{��łɌ�������ꂽ�ꍇ�́A�|��҂ɂ��A������������K���ł��B
+ ��������e�Ɋւ��Ă̂��₢���킹�ɂ͉������˂܂��̂ŁA���������������B
+ </para>
+
+ <sect2 id="preface-s1-1" revision="-1">
+
+ <title>���{��Ŗ|��҂ɂ���</title>
+
+ <para id="preface-s1-1-p4" revision="-1">
+ ���{��Ńo�[�W����3.2 cr3�̖|��͊�����ЃG�N�T
+ �i<ulink url="http://www.exa-corp.co.jp">�z�[���y�[�W�͂�����</ulink>�j
+ �̈ȉ��̃����o�[�ōs���܂����B
+ �{�ԗ́i6,18,19,21,22,23�͒S���j�A
+ �L�˗T��i�O����,2,5,13,14,24,25�͒S���j�A
+ ���s���l�i7,8,9,10�͒S���j�A
+ �ߐ{�G�j�i12,16,17�͒S���j�A
+ ��֒m���i1,3,11�͒S���j�A
+ �ѓc�_�i�i4,15�͒S���j�A
+ ���Ԍ���i20�͒S���j�A
+ �X����i���r���[�S���j�B
+ �Ȃ���̂��w�E�͖{�ԁA�L�˂܂ł��肢�������܂��B
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/mailaddr.gif" format="GIF" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../shared/images/mailaddr.gif" format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ </para>
+ </sect2>
+ </sect1>
+-->
+ </preface>
\ No newline at end of file
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/query_criteria.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/query_criteria.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/query_criteria.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/query_criteria.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,448 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="querycriteria">
+ <title>Criteria�N�G��</title>
+
+ <para>
+ Hibernate�ɂ́A�����I�Ŋg���\��criteria�N�G��API���p�ӂ���Ă��܂��B
+ </para>
+
+ <sect1 id="querycriteria-creating">
+ <title> <literal>Criteria</literal> �C���X�^���X�̍쐬</title>
+
+ <para>
+ <literal>org.hibernate.Criteria</literal>
+ �C���^�[�t�F�C�X�͓���̉i�����N���X�ɑ���N�G����\�����܂��B
+ <literal>Session</literal> �� <literal>Criteria</literal> �C���X�^���X�̃t�@�N�g���ł��B
+ </para>
+
+ <programlisting><![CDATA[Criteria crit = sess.createCriteria(Cat.class);
+crit.setMaxResults(50);
+List cats = crit.list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-narrowing">
+ <title>���U���g�Z�b�g�̍i����</title>
+
+ <para>
+ <literal>org.hibernate.criterion.Criterion</literal> �C���^�[�t�F�C�X�̃C���X�^���X�́A
+ �ʂ̃N�G���N���C�e���I���i�₢���킹�̔����j��\���܂��B
+ <literal>org.hibernate.criterion.Restrictions</literal>
+ �N���X�́A����g�ݍ��݂� <literal>Criterion</literal>
+ �^��擾���邽�߂̃t�@�N�g�����\�b�h�����Ă��܂��B
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .add( Restrictions.between("weight", minWeight, maxWeight) )
+ .list();]]></programlisting>
+
+ <para>
+ Restriction�i����j�́A�_���I�ɃO���[�v���ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .add( Restrictions.or(
+ Restrictions.eq( "age", new Integer(0) ),
+ Restrictions.isNull("age")
+ ) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
+ .add( Restrictions.disjunction()
+ .add( Restrictions.isNull("age") )
+ .add( Restrictions.eq("age", new Integer(0) ) )
+ .add( Restrictions.eq("age", new Integer(1) ) )
+ .add( Restrictions.eq("age", new Integer(2) ) )
+ ) )
+ .list();]]></programlisting>
+
+ <para>
+ ���X����Criterion�^�i<literal>Restrictions</literal> �̃T�u�N���X�j
+ �͂��Ȃ�͈̔͂ɋy�т܂����A���ɗL�p�Ȃ̂�SQL�ڎw��ł����̂ł��B
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.sqlRestriction("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) )
+ .list();]]></programlisting>
+
+ <para>
+ <literal>{alias}</literal> �Ƃ����v���[�X�z���_�́A
+ �₢���킹����G���e�B�e�B�̍s�̕ʖ��ɂ���Ēu���������܂��B
+ </para>
+
+ <para>
+ criterion��ʂ̎�i�́A
+ <literal>Property</literal> �C���X�^���X����擾���邱�Ƃł��B
+ <literal>Property.forName()</literal> ��Ăяo���āA
+ <literal>Property</literal> �C���X�^���X��쐬�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[
+Property age = Property.forName("age");
+List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.disjunction()
+ .add( age.isNull() )
+ .add( age.eq( new Integer(0) ) )
+ .add( age.eq( new Integer(1) ) )
+ .add( age.eq( new Integer(2) ) )
+ ) )
+ .add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-ordering">
+ <title>���ʂ̐���</title>
+
+ <para>
+ <literal>org.hibernate.criterion.Order</literal>
+ ��g���Č��ʂ���ёւ��邱�Ƃ��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "F%")
+ .addOrder( Order.asc("name") )
+ .addOrder( Order.desc("age") )
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Property.forName("name").like("F%") )
+ .addOrder( Property.forName("name").asc() )
+ .addOrder( Property.forName("age").desc() )
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-associations" revision="2">
+ <title>�֘A</title>
+
+ <para>
+ <literal>createCriteria()</literal> ��g���A�֘A��i�r�Q�[�g���邱�ƂŁA
+ �e�ՂɊW����G���e�B�e�B�ɐ����w��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "F%") )
+ .createCriteria("kittens")
+ .add( Restrictions.like("name", "F%") )
+ .list();]]></programlisting>
+
+ <para>
+ 2�Ԗڂ� <literal>createCriteria()</literal> �́A<literal>kittens</literal>
+ �R���N�V�����̗v�f��Q�Ƃ���V���� <literal>Criteria</literal>
+ �C���X�^���X��Ԃ����Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ �ȉ��̂悤�ȕ��@��A�ɂ��L�p�ł��B
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .createAlias("kittens", "kt")
+ .createAlias("mate", "mt")
+ .add( Restrictions.eqProperty("kt.name", "mt.name") )
+ .list();]]></programlisting>
+
+ <para>
+ �i<literal>createAlias()</literal> �͐V����
+ <literal>Criteria</literal> �C���X�^���X��쐬���܂���B�j
+ </para>
+
+ <para>
+ �O��2�̃N�G���ɂ���ĕԂ���� <literal>Cat</literal>
+ �C���X�^���X�ɂ���ĕێ������kittens�R���N�V�����́A
+ criteria�ɂ���Ď��O�Ƀt�B���^�����O <emphasis>����Ȃ�</emphasis>
+ ���Ƃɒ��ӂ��Ă��������B
+ ���criteria�ɓK������kitten��擾�������Ȃ�A
+ <literal>ResultTransformer</literal> ��g��Ȃ���Ȃ�܂���B
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .createCriteria("kittens", "kt")
+ .add( Restrictions.eq("name", "F%") )
+ .setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP)
+ .list();
+Iterator iter = cats.iterator();
+while ( iter.hasNext() ) {
+ Map map = (Map) iter.next();
+ Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
+ Cat kitten = (Cat) map.get("kt");
+}]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-dynamicfetching" revision="1">
+ <title>�֘A�̓��I�t�F�b�`</title>
+
+ <para>
+ <literal>setFetchMode()</literal> ��g���A
+ ���s���Ɋ֘A�̕������@��w�肵�Ă�悢�ł��B
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .setFetchMode("mate", FetchMode.EAGER)
+ .setFetchMode("kittens", FetchMode.EAGER)
+ .list();]]></programlisting>
+
+ <para>
+ ���̃N�G���͊O�������ɂ�� <literal>mate</literal> ��
+ <literal>kittens</literal> �̗�����t�F�b�`���܂��B
+ ��葽���̏��� <xref linkend="performance-fetching"/> ��Q�Ƃ��Ă��������B
+ </para>
+
+ </sect1>
+
+ <sect1 id="querycriteria-examples">
+ <title>�N�G���̗�</title>
+
+ <para>
+ <literal>org.hibernate.criterion.Example</literal> �N���X�́A
+ �^����ꂽ�C���X�^���X����N�G���N���C�e���I����\�z�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[Cat cat = new Cat();
+cat.setSex('F');
+cat.setColor(Color.BLACK);
+List results = session.createCriteria(Cat.class)
+ .add( Example.create(cat) )
+ .list();]]></programlisting>
+
+ <para>
+ �o�[�W�����v���p�e�B�A���ʎq�A�֘A�͖�������܂��B
+ �f�t�H���g�ł�null�l�̃v���p�e�B�͏��O����܂��B
+ </para>
+
+ <para>
+ �ǂ̂悤�� <literal>Example</literal> ��K�p���邩
+ �������邱�Ƃ��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[Example example = Example.create(cat)
+ .excludeZeroes() //exclude zero valued properties
+ .excludeProperty("color") //exclude the property named "color"
+ .ignoreCase() //perform case insensitive string comparisons
+ .enableLike(); //use like for string comparisons
+List results = session.createCriteria(Cat.class)
+ .add(example)
+ .list();]]></programlisting>
+
+ <para>
+ �֘A�I�u�W�F�N�g��criteria��w�肷�邽�߂ɁAExample��g�����Ƃ�\�ł��B
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .add( Example.create(cat) )
+ .createCriteria("mate")
+ .add( Example.create( cat.getMate() ) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-projection">
+ <title>�ˉe�A�W��A�O���[�v��</title>
+ <para>
+ <literal>org.hibernate.criterion.Projections</literal> �N���X��
+ <literal>Projection</literal> �C���X�^���X�̃t�@�N�g���ł��B
+ <literal>setProjection()</literal> ��Ăяo�����ƂŁA
+ �N�G���Ɏˉe��K�p���܂��B
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.rowCount() )
+ .add( Restrictions.eq("color", Color.BLACK) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount() )
+ .add( Projections.avg("weight") )
+ .add( Projections.max("weight") )
+ .add( Projections.groupProperty("color") )
+ )
+ .list();]]></programlisting>
+
+ <para>
+ �K�v�ł����Ă�Acriteria�N�G���Ɂugroup by�v������K�v�͂���܂���B
+ ������Projection�^�� <emphasis>�O���[�v���ˉe</emphasis> �Ƃ��Ē�`����A
+ SQL�� <literal>group by</literal> �߂ɂ����܂��B
+ </para>
+
+ <para>
+ �C�ӂŎˉe�ɕʖ���t�����邽�߁A�ˉe�����l��restriction��ordering�����Q�Ƃł��܂��B
+ �ʖ������Q�̈قȂ���@�����܂��B
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
+ .addOrder( Order.asc("colr") )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.groupProperty("color").as("colr") )
+ .addOrder( Order.asc("colr") )
+ .list();]]></programlisting>
+
+ <para>
+ <literal>alias()</literal> �� <literal>as()</literal> ���\�b�h�́A
+ Projection�C���X�^���X��ʂ̖��O�� <literal>Projection</literal> �C���X�^���X��
+ ���b�v���邾���ł��B
+ �V���[�g�J�b�g�Ƃ��āA�ˉe��ˉe���X�g�ɒlj�����ۂɁA�ʖ�������܂��B
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount(), "catCountByColor" )
+ .add( Projections.avg("weight"), "avgWeight" )
+ .add( Projections.max("weight"), "maxWeight" )
+ .add( Projections.groupProperty("color"), "color" )
+ )
+ .addOrder( Order.desc("catCountByColor") )
+ .addOrder( Order.desc("avgWeight") )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Domestic.class, "cat")
+ .createAlias("kittens", "kit")
+ .setProjection( Projections.projectionList()
+ .add( Projections.property("cat.name"), "catName" )
+ .add( Projections.property("kit.name"), "kitName" )
+ )
+ .addOrder( Order.asc("catName") )
+ .addOrder( Order.asc("kitName") )
+ .list();]]></programlisting>
+
+ <para>
+ �ˉe�̎��� <literal>Property.forName()</literal> ��g�p�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Property.forName("name") )
+ .add( Property.forName("color").eq(Color.BLACK) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount().as("catCountByColor") )
+ .add( Property.forName("weight").avg().as("avgWeight") )
+ .add( Property.forName("weight").max().as("maxWeight") )
+ .add( Property.forName("color").group().as("color" )
+ )
+ .addOrder( Order.desc("catCountByColor") )
+ .addOrder( Order.desc("avgWeight") )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-detachedqueries">
+ <title>�N�G������уT�u�N�G���̕���</title>
+ <para>
+ <literal>DetachedCriteria</literal> �N���X�ɂ��A
+ �Z�b�V�����X�R�[�v�O�ɃN�G����쐬�ł��܂��B
+ ��ŁA�C�ӂ� <literal>Session</literal> ��g���āA���s�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria query = DetachedCriteria.forClass(Cat.class)
+ .add( Property.forName("sex").eq('F') );
+
+Session session = ....;
+Transaction txn = session.beginTransaction();
+List results = query.getExecutableCriteria(session).setMaxResults(100).list();
+txn.commit();
+session.close();]]></programlisting>
+
+ <para>
+ <literal>DetachedCriteria</literal> �́A�T�u�N�G����\�����邽�߂ɂ�g���܂��B
+ �T�u�N�G����Criterion�C���X�^���X�́A
+ <literal>Subqueries</literal> ������� <literal>Property</literal> ���瓾���܂��B
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)
+ .setProjection( Property.forName("weight").avg() );
+session.createCriteria(Cat.class)
+ .add( Property.forName("weight").gt(avgWeight) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)
+ .setProjection( Property.forName("weight") );
+session.createCriteria(Cat.class)
+ .add( Subqueries.geAll("weight", weights) )
+ .list();]]></programlisting>
+
+ <para>
+ ���݊W������T�u�N�G���ł�����\�ł��B
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")
+ .setProjection( Property.forName("weight").avg() )
+ .add( Property.forName("cat2.sex").eqProperty("cat.sex") );
+session.createCriteria(Cat.class, "cat")
+ .add( Property.forName("weight").gt(avgWeightForSex) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <!--TODO: ResultSetTransformer + aliasing. AliasToBeanTransformer allow returning arbitrary
+ user objects - similar to setResultClass in JDO2. General use of ResultTransformer
+ could also be explained. -->
+
+ <sect1 id="query-criteria-naturalid">
+ <title>���R���ʎq�ɂ��N�G��</title>
+
+ <para>
+ criteria�N�G����܂ނ����Ă��̃N�G���ɂƂ��āA
+ �N�G���L���b�V���͂��܂�������悭�Ȃ��ł��B
+ �Ȃ��Ȃ�A�N�G���L���b�V�����p�ɂɖ����ɂȂ邽�߂ł��B
+ �������Ȃ���A�L���b�V�����ɂ���A���S���Y����œK���ł���
+ ���ʂȃN�G���̎�ނ��P����܂��B
+ �X�V����Ȃ����R�L�[�ɂ�錟���ł��B
+ �������̃A�v���P�[�V�����ł́A���̎�ނ̃N�G�����p�ɂɌ���܂��B
+ ���̂悤�Ȏg�����̂��߂ɁAcriteria API�͓��ʂȑ����܂��B
+ </para>
+
+ <para>
+ �ŏ��ɁA<literal><natural-id></literal> ��g���āA
+ �G���e�B�e�B�̎��R�L�[��}�b�v���Ă��������B
+ �����āA�L���b�V����L���ɂ��܂��B
+ </para>
+
+ <programlisting><![CDATA[<class name="User">
+ <cache usage="read-write"/>
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <natural-id>
+ <property name="name"/>
+ <property name="org"/>
+ </natural-id>
+ <property name="password"/>
+</class>]]></programlisting>
+
+ <para>
+ ���ӁF <emphasis>�ύX�����</emphasis> ���R�L�[���G���e�B�e�B��
+ ���̋@�\��g���̂́A�Ӑ}����Ă��Ȃ��g�����ł��B
+ </para>
+
+ <para>
+ ���ɁAHibernate�N�G���L���b�V����L���ɂ��܂��B
+ </para>
+
+ <para>
+ ����ŁA<literal>Restrictions.naturalId()</literal> �ɂ��A
+ �������I�ȃL���b�V���A���S���Y����g�p�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[session.createCriteria(User.class)
+ .add( Restrictions.naturalId()
+ .set("name", "gavin")
+ .set("org", "hb")
+ ).setCacheable(true)
+ .uniqueResult();]]></programlisting>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/query_hql.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/query_hql.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/query_hql.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/query_hql.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,1131 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="queryhql">
+ <title>HQL: The Hibernate Query Language</title>
+
+ <para>
+ Hibernate��SQL�ɔ��ɂ悭����(�Ӑ}�I�Ɏ�����)���͂Ȗ₢���킹���������Ă��܂��B
+ ������SQL�Ɏ����\���ɘf�킳��Ȃ��ł��������BHQL�͊��S�ɃI�u�W�F�N�g�w���ł���A
+ �p���A�|�����[�t�B�Y���A�֘A�Ƃ������T�O�𗝉��܂��B
+ </para>
+
+ <sect1 id="queryhql-casesensitivity">
+ <title>�啶���Ə������̋��</title>
+
+ <para>
+ �N�G����Java�̃N���X���ƃv���p�e�B�������đ啶���A���������ʂ��܂���B
+ �]���� <literal>SeLeCT</literal> ��
+ <literal>sELEct</literal> �Ɠ����ŁA����
+ <literal>SELECT</literal> �Ƃ�����ł���
+ <literal>net.sf.hibernate.eg.FOO</literal> ��
+ <literal>net.sf.hibernate.eg.Foo</literal> �Ƃ͈Ⴂ�A����
+ <literal>foo.barSet</literal> ��
+ <literal>foo.BARSET</literal> �Ƃ�Ⴂ�܂��B
+ </para>
+
+ <para>
+ ���̃}�j���A���ł͏�������HQL�L�[���[�h��g�p���܂��B
+ �啶���̃L�[���[�h�̃N�G���̕����ǂ݂₷���Ɗ����郆�[�U�[�����Ǝv���܂��B
+ �ł����AJava�R�[�h��ɖ��ߍ��܂ꂽ�Ƃ��ɂ͌��Â炢�Ǝv���܂��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-from">
+ <title>from��</title>
+
+ <para>
+ ����Ƃ�P����Hibernate�N�G���͎��̌`���ł��B
+ </para>
+
+ <programlisting><![CDATA[from eg.Cat]]></programlisting>
+
+ <para>
+ ����͒P���Ɂ@<literal>eg.Cat</literal>�@�N���X�̃C���X�^���X���ׂĕԂ��܂��B
+ �K������N���X����C������i�N���X�Ƀp�b�P�[�W����t����j�K�v�͂���܂���B
+ �Ƃ����̂�A<literal>auto-import</literal> ���f�t�H���g�ɂȂ��Ă��邩��ł��B
+ ���̂��߂قƂ�ǂ̏ꍇ�A���̂悤�ɏ��������ŏ\���ł��B
+ </para>
+
+ <programlisting><![CDATA[from Cat]]></programlisting>
+
+ <para>
+ �قƂ�ǂ̏ꍇ�N�G���̂ق��̕����Ł@<literal>Cat</literal>�@��Q�Ƃ���̂ŁA�ʖ����蓖�Ă�K�v������ł��傤�B
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat]]></programlisting>
+
+ <para>
+ ���̃N�G���ł� <literal>Cat</literal> �C���X�^���X�� <literal>cat</literal>
+ �Ƃ����ʖ���t���Ă��܂��B
+ ���̂��߁A��ł��̃N�G����ŁA���̕ʖ���g�����Ƃ��ł��܂��B
+ <literal>as</literal> �L�[���[�h�̓I�v�V�����ł��B�܂肱�̂悤�ɏ������Ƃ�ł��܂��F
+ </para>
+
+ <programlisting><![CDATA[from Cat cat]]></programlisting>
+
+ <para>
+ ���ρA���邢�̓N���X�����ɂ���đ����̃N���X���o�����邱�Ƃ����܂��B
+ </para>
+
+ <programlisting><![CDATA[from Formula, Parameter]]></programlisting>
+ <programlisting><![CDATA[from Formula as form, Parameter as param]]></programlisting>
+
+ <para>
+ ���[�J���ϐ���Java�̃l�[�~���O��ƈ�v�����A
+ �������ɏ�������g�����N�G���̕ʖ���t���邱�Ƃ͂����K���ł�(�Ⴆ�� <literal>domesticCat</literal> )�B
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-joins" revision="2">
+ <title>�֘A�ƌ���</title>
+
+ <para>
+ �֘A����G���e�B�e�B���邢�͒l�R���N�V�����̗v�f�ɂ�A<literal>����</literal> ��g���ĕʖ����蓖�Ă邱�Ƃ��o���܂��B
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join cat.mate as mate
+ left outer join cat.kittens as kitten]]></programlisting>
+
+ <programlisting><![CDATA[from Cat as cat left join cat.mate.kittens as kittens]]></programlisting>
+
+ <programlisting><![CDATA[from Formula form full join form.parameter param]]></programlisting>
+
+ <para>
+ �T�|�[�g���Ă��錋���̃^�C�v��ANSI SQL�Ɠ����ł��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>inner join</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>left outer join</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>right outer join</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>full join</literal> (�����Ă��̏ꍇ�g���Â炢)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>inner join</literal>�A<literal>left outer join</literal>�A<literal>right outer join</literal>�ɂ͏ȗ��`��g�����Ƃ�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ join cat.mate as mate
+ left join cat.kittens as kitten]]></programlisting>
+
+ <para>
+ HQL�� <literal>with</literal> �L�[���[�h��g���ƁA��������t�������邱�Ƃ��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ left join cat.kittens as kitten
+ with kitten.bodyWeight > 10.0]]></programlisting>
+
+ <para>
+ �����āA�u�t�F�b�`�v�����͊֘A��l�̃R���N�V������e�I�u�W�F�N�g�ƈꏏ��1�x��select��ŏ��������܂��B
+ ����͓��ɃR���N�V�����̏ꍇ�ɗL�p�ł��B����͎�����A�֘A�ƃR���N�V�����ɑ���}�b�s���O��`�t�@�C���̊O��������lazy�������̒�`��㏑�����邱�ƂɂȂ�܂��B
+
+ <xref linkend="performance-fetching"/> �ɂ�葽���̏����܂��B
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join fetch cat.mate
+ left join fetch cat.kittens]]></programlisting>
+
+ <para>
+ �����ɂ��t�F�b�`�͊֘A����I�u�W�F�N�g�� <literal>where</literal> ��(�܂��͑��̂ǂ�Ȑ߂ł�)
+ �Ŏg���Ă͂Ȃ�Ȃ��̂ŁA�ʏ�ʖ����蓖�Ă�K�v������܂���B�܂��֘A�I�u�W�F�N�g�͖₢���킹���ʂƂ���
+ ���ڕԂ���܂���B����ɐe�I�u�W�F�N�g��ʂ��ăA�N�Z�X�ł��܂��B
+ �R���N�V������ċA�I�Ɍ����t�F�b�`����ꍇ�̂݁A�ʖ����K�v�ɂȂ�܂��B
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join fetch cat.mate
+ left join fetch cat.kittens child
+ left join fetch child.kittens]]></programlisting>
+
+ <para>
+ <literal>fetch</literal> �\���� <literal>iterate()</literal>
+ ��g�����N�G���Ăяo���Ŏg�p�ł��Ȃ����Ƃɒ��ӂ��Ă�������
+ �i����� <literal>scroll()</literal> �͎g�p�ł��܂��j�B
+
+ �܂��A�����̑���͌��ʂ̍s�Ɋ�Â��Ă��邽�߁A
+ <literal>fetch</literal> �� <literal>setMaxResults()</literal> �� <literal>setFirstResult()</literal>
+ �ƈꏏ�Ɏg�p���ׂ��ł͂���܂���B
+ �ʏ�eager�ȃR���N�V�����t�F�b�`����Əd�����o�Ă��܂����߁A���Ȃ������҂���悤�ȍs���ɂ͂Ȃ�Ȃ��̂ł��B
+
+ �����Ă܂� <literal>fetch</literal> �́A�A�h�z�b�N�� <literal>with</literal> ����
+ �ꏏ�Ɏg�����Ƃ�ł��܂���B
+ ��̃N�G���ŕ����̃R���N�V���������t�F�b�`���邱�Ƃɂ�蒼�ς�쐬�ł���̂ŁA���̏ꍇ���ӂ��Ă��������B
+ �܂��A�����̃R���N�V�����ɑ��錋���t�F�b�`��bag�}�b�s���O�ɑ��ė\�����ʌ��ʂ����炷���Ƃ�����̂ŁA
+ ���̏ꍇ�̃N�G���̍쐬�ɂ͒��ӂ��Ă��������B
+ �Ō�� <literal>�S�O�������ɂ��t�F�b�`</literal> ��
+ <literal>�E�O�������ɂ��t�F�b�`</literal> �͗L�p�ł͂Ȃ����Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ ����v���p�e�B���x���̒x���t�F�b�`��g���ꍇ�i����I�Ƀo�C�g�R�[�h��������ꍇ�j�A
+ <literal>fetch all properties</literal> ��g�����Ƃ�
+ Hibernate�ɒx���v���p�e�B�𑬂₩�Ɂi�ŏ��̃N�G���Łj�t�F�b�`�����邱�Ƃ��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[from Document fetch all properties order by name]]></programlisting>
+ <programlisting><![CDATA[from Document doc fetch all properties where lower(doc.name) like '%cats%']]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-joins-forms">
+ <title>�����\���̌`��</title>
+
+ <para>
+ HQL�͂Q�̊֘A�����`����T�|�[�g���܂��F<literal>�ÖٓI</literal> �� <literal>�����I</literal>�B
+ </para>
+
+ <para>
+ ����܂ł̃Z�N�V�����ł����������g�����͂��ׂ� <literal>�����I��</literal> �`���ŁA
+ from�߂Ŗ����I��join�L�[���[�h��g���Ă��܂��B
+ ���̌`���������߂��܂��B
+ </para>
+
+ <para>
+ <literal>�ÖٓI</literal> �t�H�[���́Ajoin�L�[���[�h��g���܂���B����ɁA�Q�Ƃ���֘A��
+ �h�b�g�\�L��g���܂��B<literal>�ÖٓI</literal> �����́A���܂��܂�HQL�ɏo�Ă��܂��B
+ <literal>�ÖٓI</literal> �����̌��ʂ́ASQL�X�e�[�g�����g�̓���������ʂł��B
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.mate.name like '%s%']]></programlisting>
+ </sect1>
+
+ <sect1 id="queryhql-select">
+ <title>Select��</title>
+
+ <para>
+ <literal>select</literal> �߂͈ȉ��̂悤�ɂǂ̃I�u�W�F�N�g�Ƒ�����N�G�����U���g�Z�b�g�ɕԂ�����I���܂��B:
+ </para>
+
+ <programlisting><![CDATA[select mate
+from Cat as cat
+ inner join cat.mate as mate]]></programlisting>
+
+ <para>
+ ��L�̃N�G���͑��� <literal>Cat</literal> �� <literal>mate</literal> ��I���܂��B
+ ���ۂɂ͎��̂悤�ɁA���Ȍ��ɕ\���ł��܂��B:
+ </para>
+
+ <programlisting><![CDATA[select cat.mate from Cat cat]]></programlisting>
+
+ <para>
+ �N�G���̓R���|�[�l���g�^�̃v���p�e�B��܂ށA������l�^�̃v���p�e�B��Ԃ��܂��B:
+ </para>
+
+ <programlisting><![CDATA[select cat.name from DomesticCat cat
+where cat.name like 'fri%']]></programlisting>
+
+ <programlisting><![CDATA[select cust.name.firstName from Customer as cust]]></programlisting>
+
+ <para>
+ �N�G���͕����̃I�u�W�F�N�g��(�܂���)�v���p�e�B�� <literal>Object[]</literal> �^�̔z��Ƃ��ĕԂ��܂��B
+ </para>
+
+ <programlisting><![CDATA[select mother, offspr, mate.name
+from DomesticCat as mother
+ inner join mother.mate as mate
+ left outer join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ ������� <literal>List</literal> �Ƃ��āA
+ </para>
+
+ <programlisting><![CDATA[select new list(mother, offspr, mate.name)
+from DomesticCat as mother
+ inner join mother.mate as mate
+ left outer join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ �܂��́A�^�C�v�Z�[�t��Java�I�u�W�F�N�g��Ԃ��܂��B
+ </para>
+
+ <programlisting><![CDATA[select new Family(mother, mate, offspr)
+from DomesticCat as mother
+ join mother.mate as mate
+ left join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ ���邢�� <literal>Family</literal> �N���X���K�ȃR���X�g���N�^�����Ă���Ƃ���Ȃ�A
+ </para>
+
+ <para>
+ select�߂� <literal>as</literal> ��g���ĕʖ�����邱�Ƃ�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n
+from Cat cat]]></programlisting>
+
+ <para>
+ <literal>select new map</literal> �ƈꏏ�Ɏg���Ƃ��ɍł�𗧂��܂��F
+ </para>
+
+ <programlisting><![CDATA[select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n )
+from Cat cat]]></programlisting>
+
+ <para>
+ ���̃N�G���͕ʖ�����select�����l�� <literal>Map</literal> ��Ԃ��܂��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-aggregation">
+ <title>�W���</title>
+
+ <para>
+ HQL�̃N�G���̓v���p�e�B�̏W����̌��ʂ�Ԃ��܂��F
+ </para>
+
+ <programlisting><![CDATA[select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)
+from Cat cat]]></programlisting>
+
+<!-- NO LONGER SUPPORTED
+ <para>
+ Collections may also appear inside aggregate functions in the <literal>select</literal>
+ clause.
+ </para>
+
+ <programlisting><![CDATA[select cat, count( elements(cat.kittens) )
+from Cat cat group by cat]]></programlisting>
+-->
+
+ <para>
+ �T�|�[�g���Ă���W����͈ȉ��̂�̂ł��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>avg(...), sum(...), min(...), max(...)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>count(*)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>count(...), count(distinct ...), count(all...)</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ select�߂ɂ����ĎZ�p����A�A���Ə��F���ꂽSQL����g�����Ƃ��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[select cat.weight + sum(kitten.weight)
+from Cat cat
+ join cat.kittens kitten
+group by cat.id, cat.weight]]></programlisting>
+
+ <programlisting><![CDATA[select firstName||' '||initial||' '||upper(lastName) from Person]]></programlisting>
+
+ <para>
+ SQL�Ɠ����Ӗ����� <literal>distinct</literal> �� <literal>all</literal> �L�[���[�h��g�����Ƃ��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[select distinct cat.name from Cat cat
+
+select count(distinct cat.name), count(cat) from Cat cat]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-polymorphism">
+ <title>�|�����[�t�B�b�N�ȃN�G��</title>
+
+ <para>
+ ���̂悤�ȃN�G���F
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat]]></programlisting>
+
+ <para>
+ <literal>Cat</literal> �C���X�^���X�����ł͂Ȃ��A<literal>DomesticCat</literal>
+ �̂悤�ȃT�u�N���X��Ԃ���܂��BHibernate�N�G���� <emphasis>�ǂ��</emphasis>
+ Java�N���X��C���^�[�t�F�C�X�� <literal>from</literal> �߂ɓ���邱�Ƃ��ł��܂��B
+ �N�G���͂��̃N���X��g�������A������̓C���^�[�t�F�C�X����������S�Ẳi���N���X��Ԃ��܂��B
+ ���̃N�G���͉i���I�u�W�F�N�g���ׂĕԂ��܂�:
+ </para>
+
+ <programlisting><![CDATA[from java.lang.Object o]]></programlisting>
+
+ <para>
+ <literal>Named</literal> �C���^�[�t�F�C�X�͗l�X�ȉi���N���X�ɂ���Ď�������܂��B:
+ </para>
+
+ <programlisting><![CDATA[from Named n, Named m where n.name = m.name]]></programlisting>
+
+ <para>
+ �Ō�̓�̃N�G���́A��ȏ��SQL <literal>SELECT</literal> ��v�����Ă��邱�Ƃɒ��ӂ��Ă��������B
+ ���̂��Ƃ� <literal>order by</literal> �߂����U���g�Z�b�g�S�̂𐳊m�ɂ͐��Ȃ����Ƃ�Ӗ����܂�
+ (����ɂ���́A<literal>Query.scroll()</literal> ��g�p���Ă����̃N�G����ĂԂ��Ƃ��ł��Ȃ����Ƃ�Ӗ����܂��B)�B
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-where">
+ <title>where��</title>
+
+ <para>
+ <literal>where</literal> �߂͕Ԃ����C���X�^���X�̃��X�g��i�邱�Ƃ��ł��܂��B
+ ����ʖ����Ȃ��ꍇ�A���O�Ńv���p�e�B��Q�Ƃ��܂��B
+ </para>
+
+ <programlisting><![CDATA[from Cat where name='Fritz']]></programlisting>
+
+ <para>
+ ����ʖ�������ꍇ�A�C������g���Ă��������B
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.name='Fritz']]></programlisting>
+
+ <para>
+ ���O��'Fritz'�Ƃ��� <literal>Cat</literal> �̃C���X�^���X��Ԃ��܂��B
+ </para>
+
+ <programlisting><![CDATA[select foo
+from Foo foo, Bar bar
+where foo.startDate = bar.date]]></programlisting>
+
+ <para>
+ ���HQL�́A<literal>Foo</literal> �� <literal>startDate</literal> �v���p�e�B�Ɠ�����
+ <literal>date</literal> �v���p�e�B������ <literal>bar</literal> �C���X�^���X�����݂���A
+ ���ׂĂ� <literal>Foo</literal> �C���X�^���X��Ԃ��܂��B
+ �R���p�E���h�p�X���i�Ⴆ�ucat.mate.name�v�j�� <literal>where</literal> �߂���ɋ��͂ɂ��܂��B���ځF
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.mate.name is not null]]></programlisting>
+
+ <para>
+ ���̃N�G���̓e�[�u�������i��������j����SQL�N�G���ɕϊ�����܂��B
+ ���̑���Ɉȉ��̂悤�ɏ����ƁA
+ </para>
+
+ <programlisting><![CDATA[from Foo foo
+where foo.bar.baz.customer.address.city is not null]]></programlisting>
+
+ <para>
+ �����̃N�G����L�q������N�G�����4�̃e�[�u��������K�v�Ƃ���SQL�N�G���ɕϊ�����܂��B
+ </para>
+
+ <para>
+ <literal>=</literal> ���Z�q�͈ȉ��̂悤�ɁA�v���p�e�B�����łȂ��C���X�^���X���r���邽�߂ɂ�g���܂��B�F
+ </para>
+
+ <programlisting><![CDATA[from Cat cat, Cat rival where cat.mate = rival.mate]]></programlisting>
+
+ <programlisting><![CDATA[select cat, mate
+from Cat cat, Cat mate
+where cat.mate = mate]]></programlisting>
+
+ <para>
+ <literal>id</literal> (������)�͓��ʂȃv���p�e�B�ł���A
+ �I�u�W�F�N�g�̃��j�[�N�Ȏ��ʎq��Q�Ƃ��邽�߂Ɏg�p�ł��܂��B(����ɁA���̃v���p�e�B����g�p�ł��܂��B)
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.id = 123
+
+from Cat as cat where cat.mate.id = 69]]></programlisting>
+
+ <para>
+ 2�Ԗڂ̃N�G���͌����I�ł��B�e�[�u���������K�v����܂���I
+ </para>
+
+ <para>
+ �܂��������ʎq�̃v���p�e�B��g�p�ł��܂��B������ <literal>Person</literal> ��
+ <literal>country</literal> �� <literal>medicareNumber</literal> ����Ȃ镡�����ʎq���Ɖ��肵�܂��B
+ </para>
+
+ <programlisting><![CDATA[from bank.Person person
+where person.id.country = 'AU'
+ and person.id.medicareNumber = 123456]]></programlisting>
+
+ <programlisting><![CDATA[from bank.Account account
+where account.owner.id.country = 'AU'
+ and account.owner.id.medicareNumber = 123456]]></programlisting>
+
+ <para>
+ �����x�����܂����A2�Ԗڂ̃N�G���ɂ̓e�[�u���������K�v����܂���B
+ </para>
+
+ <para>
+ ���l�� <literal>class</literal> �͓��ʂȃv���p�e�B�ł���A
+ �|�����[�t�B�b�N�ȉi�����ɂ�����C���X�^���X��discriminator�l�ɃA�N�Z�X���܂��B
+ where�߂ɖ��ߍ��܂ꂽJava�̃N���X���͂���discriminator�l�ɕϊ�����܂��B
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.class = DomesticCat]]></programlisting>
+
+ <para>
+ �܂��R���|�[�l���g�╡�����[�U�^(�܂����̃R���|�[�l���g�̃R���|�[�l���g�Ȃ�)�̃v���p�e�B��w��ł��܂��B
+
+ �����������āi�R���|�[�l���g�̃v���p�e�B�ł͂Ȃ��j�R���|�[�l���g�^�̃v���p�e�B�ŏI������p�X����g��Ȃ��ł��������B
+ �Ⴆ��� <literal>store.owner</literal> �� <literal>address</literal>
+ �R���|�[�l���g���G���e�B�e�B�Ȃ�Έȉ��̂悤�Ȍ��ʂƂȂ�܂��B
+ </para>
+
+ <programlisting><![CDATA[store.owner.address.city // okay
+store.owner.address // error!]]></programlisting>
+
+ <para>
+ "any"�^�͓��ʂȃv���p�e�B�ł��� <literal>id</literal> �� <literal>class</literal> �����A
+ �ȉ��̕��@�Ō�����\�����邱�Ƃ�\�ɂ��܂�(<literal>AuditLog.item</literal> ��
+ <literal><any></literal> �Ń}�b�s���O���ꂽ�v���p�e�B�ł�)�B
+ </para>
+
+ <programlisting><![CDATA[from AuditLog log, Payment payment
+where log.item.class = 'Payment' and log.item.id = payment.id]]></programlisting>
+
+ <para>
+ <literal>log.item.class</literal> �� <literal>payment.class</literal> ��
+ ��L�̃N�G�����őS���قȂ�f�[�^�x�[�X�J�����̒l��Q�Ƃ���Ƃ������Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-expressions">
+ <title>Expressions ��</title>
+
+ <para>
+ SQL�� <literal>where</literal> �߂ŋL�q���邱�Ƃ��o���鎮�̂قƂ�ǂ�HQL�ł�L�q�ł��܂��B:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ �Z�p���Z�q�F<literal>+, -, *, /</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 2����r���Z�q�F<literal>=, >=, <=, <>, !=, like</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �_�����Z�q�F<literal>and, or, not</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �O���[�v������\�����ʁF<literal>( )</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>in</literal>,
+ <literal>not in</literal>,
+ <literal>between</literal>,
+ <literal>is null</literal>,
+ <literal>is not null</literal>,
+ <literal>is empty</literal>,
+ <literal>is not empty</literal>,
+ <literal>member of</literal> and
+ <literal>not member of</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ "�V���v��"��case <literal>case ... when ... then ... else ... end</literal>�A
+ "�T���I"��case <literal>case when ... then ... else ... end</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �X�g�����O�̘A�� <literal>...||...</literal> �܂��� <literal>concat(...,...)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>current_date()</literal>, <literal>current_time()</literal>,
+ <literal>current_timestamp()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>second(...)</literal>, <literal>minute(...)</literal>,
+ <literal>hour(...)</literal>, <literal>day(...)</literal>,
+ <literal>month(...)</literal>, <literal>year(...)</literal>,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ EJB-QL 3.0�Œ�`����Ă�����≉�Z�q: <literal>substring(), trim(),
+ lower(), upper(), length(), locate(), abs(), sqrt(), bit_length()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>coalesce()</literal> �� <literal>nullif()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �����⎞�Ԃ̒l��String�ɃR���o�[�g���� <literal>str()</literal>�j
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ 2�Ԗڂ̈�����Hibernate�^�̖��O�ł��� <literal>cast(... as ...)</literal> ��
+ <literal>extract(... from ...)</literal>�B
+ �������g�p����f�[�^�x�[�X��ANSI <literal>cast()</literal> �� <literal>extract()</literal>
+ ��T�|�[�g����ꍇ�Ɍ���܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ���������C���f�b�N�X�t���̃R���N�V�����̕ʖ��ɓK�p�����HQL��
+ <literal>index()</literal> ���B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �R���N�V�����l�̃p�X������HQL���F <literal>size(), minelement(), maxelement(),
+ minindex(), maxindex()</literal> �B
+ <literal>some, all, exists, any, in</literal> ��g���ďC�����邱�Ƃ��ł�����ʂ�
+ <literal>elements()</literal> �� <literal>indices</literal> ���ƈꏏ�Ɏg���܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>sign()</literal>, <literal>trunc()</literal>, <literal>rtrim()</literal>, <literal>sin()</literal>
+ �̂悤�ȃf�[�^�x�[�X���T�|�[�g����SQL�X�J�����B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ JDBC�X�^�C���̈ʒu�p�����[�^ <literal>?</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ���O�t���p�����[�^: <literal>:name</literal>, <literal>:start_date</literal>, <literal>:x1</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ SQL���e�����F<literal>'foo'</literal>, <literal>69</literal>, <literal>6.66E+2</literal>,
+ <literal>'1970-01-01 10:00:01.0'</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Java�� <literal>public static final</literal> �萔�F<literal>eg.Color.TABBY</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>in</literal> �� <literal>between</literal> �͈ȉ��̂悤�Ɏg�p�ł��܂��B:
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name between 'A' and 'B']]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )]]></programlisting>
+
+ <para>
+ �܂��A�ے�`�ŋL�q���邱�Ƃ�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name not between 'A' and 'B']]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )]]></programlisting>
+
+ <para>
+ ���l�� <literal>is null</literal> �� <literal>is not null</literal> ��null�l��e�X�g���邽�߂Ɏg�p�ł��܂��B
+ </para>
+
+ <para>
+ Hibernate�ݒ�t�@�C����HQL query substitutions���`����Aboolean�l���̒��ŊȒP�Ɏg�p�ł��܁B�F
+ </para>
+
+ <programlisting><![CDATA[<property name="hibernate.query.substitutions">true 1, false 0</property>]]></programlisting>
+
+ <para>
+ �������邱�Ƃʼn��L��HQL��SQL�ɕϊ�����Ƃ��� <literal>true</literal> ,
+ <literal>false</literal> �L�[���[�h�� <literal>1</literal> , <literal>0</literal> �ɒu���������܂��B:
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.alive = true]]></programlisting>
+
+ <para>
+ ���ʂȃv���p�e�B <literal>size</literal>�A�܂��͓��ʂȊ� <literal>size()</literal>
+ ��g���ăR���N�V�����̃T�C�Y��e�X�g�ł��܂��B:
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.kittens.size > 0]]></programlisting>
+
+ <programlisting><![CDATA[from Cat cat where size(cat.kittens) > 0]]></programlisting>
+
+ <para>
+ �C���f�b�N�X�t���̃R���N�V�����ł́A<literal>minindex</literal> �� <literal>maxindex</literal>
+ ����g���āA�C���f�b�N�X�̍ŏ��l�ƍő�l��Q�Ƃł��܂��B
+ ���l�ɁA<literal>minelement</literal> �� <literal>maxelement</literal> ��g���āA
+ ��{�^�̃R���N�V�����v�f�̍ŏ��l�ƍő�l��Q�Ƃł��܂��B
+ </para>
+
+ <programlisting><![CDATA[from Calendar cal where maxelement(cal.holidays) > current_date]]></programlisting>
+
+ <programlisting><![CDATA[from Order order where maxindex(order.items) > 100]]></programlisting>
+
+ <programlisting><![CDATA[from Order order where minelement(order.items) > 10000]]></programlisting>
+
+ <para>
+ �R���N�V�����̗v�f��C���f�b�N�X�̃Z�b�g�i<literal>elements</literal> �� <literal>indices</literal>
+ ���j�A�܂��͕��₢���킹�i��q�j�̌��ʂ�����Ƃ��́A
+ SQL�� <literal>any, some, all, exists, in</literal> ���T�|�[�g����܂��B
+ </para>
+
+ <programlisting><![CDATA[select mother from Cat as mother, Cat as kit
+where kit in elements(foo.kittens)]]></programlisting>
+
+ <programlisting><![CDATA[select p from NameList list, Person p
+where p.name = some elements(list.names)]]></programlisting>
+
+ <programlisting><![CDATA[from Cat cat where exists elements(cat.kittens)]]></programlisting>
+
+ <programlisting><![CDATA[from Player p where 3 > all elements(p.scores)]]></programlisting>
+
+ <programlisting><![CDATA[from Show show where 'fizard' in indices(show.acts)]]></programlisting>
+
+ <para>
+ <literal>size</literal>, <literal>elements</literal>, <literal>indices</literal>,
+ <literal>minindex</literal>, <literal>maxindex</literal>, <literal>minelement</literal>,
+ <literal>maxelement</literal> ��Hibernate3��where�߂����ŗ��p�\�ł��邱�Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ �C���f�b�N�X�t���̃R���N�V�����iarrays, lists, maps�j�̗v�f�́A
+ �C���f�b�N�X�ŎQ�Ƃł��܂��iwhere�ߓ�ł̂݁j�B
+ </para>
+
+ <programlisting><![CDATA[from Order order where order.items[0].id = 1234]]></programlisting>
+
+ <programlisting><![CDATA[select person from Person person, Calendar calendar
+where calendar.holidays['national day'] = person.birthDay
+ and person.nationality.calendar = calendar]]></programlisting>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11]]></programlisting>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ maxindex(order.items) ] = item and order.id = 11]]></programlisting>
+
+ <para>
+ <literal>[]</literal> ����̎��́A�Z�p���ł�\���܂���B
+ </para>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ size(order.items) - 1 ] = item]]></programlisting>
+
+ <para>
+ ��Α��֘A��l�̃R���N�V�����̗v�f�ɑ��ẮAHQL�͑g�ݍ��݂� <literal>index()</literal> ����p�ӂ��Ă��܂��B
+ </para>
+
+ <programlisting><![CDATA[select item, index(item) from Order order
+ join order.items item
+where index(item) < 5]]></programlisting>
+
+ <para>
+ �x�[�X�ƂȂ�f�[�^�x�[�X���T�|�[�g���Ă���X�J���[SQL�����g�p�ł��܂�
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where upper(cat.name) like 'FRI%']]></programlisting>
+
+ <para>
+ ����܂��S�Ă𗝉��Ă��Ȃ��Ȃ�A���̃N�G����SQL�łǂꂾ�������A�ǂ݂Â炭�o���邩�l���Ă��������B:
+
+ </para>
+
+ <programlisting><![CDATA[select cust
+from Product prod,
+ Store store
+ inner join store.customers cust
+where prod.name = 'widget'
+ and store.location.name in ( 'Melbourne', 'Sydney' )
+ and prod = all elements(cust.currentOrder.lineItems)]]></programlisting>
+
+ <para>
+ <emphasis>�q���g:</emphasis> �Ⴆ���̂悤�ɏo���܂��B
+ </para>
+
+ <programlisting><![CDATA[SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order
+FROM customers cust,
+ stores store,
+ locations loc,
+ store_customers sc,
+ product prod
+WHERE prod.name = 'widget'
+ AND store.loc_id = loc.id
+ AND loc.name IN ( 'Melbourne', 'Sydney' )
+ AND sc.store_id = store.id
+ AND sc.cust_id = cust.id
+ AND prod.id = ALL(
+ SELECT item.prod_id
+ FROM line_items item, orders o
+ WHERE item.order_id = o.id
+ AND cust.current_order = o.id
+ )]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-ordering">
+ <title>order by��</title>
+
+ <para>
+ �N�G�����Ԃ�list�́A�Ԃ����N���X��R���|�[�l���g�̔C�ӂ̑����ɂ���ĕ��בւ����܂��B�F
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat
+order by cat.name asc, cat.weight desc, cat.birthdate]]></programlisting>
+
+ <para>
+ �I�v�V������ <literal>asc</literal> �� <literal>desc</literal> �͂��ꂼ�ꏸ�����~���̐�������܂��B
+ </para>
+ </sect1>
+
+ <sect1 id="queryhql-grouping">
+ <title>group by��</title>
+
+ <para>
+ �W��l��Ԃ��N�G���́A�Ԃ����N���X��R���|�[�l���g�̔C�ӂ̃v���p�e�B�ɂ���ăO���[�v���ł��܂��B:
+ </para>
+
+ <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat)
+from Cat cat
+group by cat.color]]></programlisting>
+
+ <programlisting><![CDATA[select foo.id, avg(name), max(name)
+from Foo foo join foo.names name
+group by foo.id]]></programlisting>
+
+ <para>
+ <literal>having</literal> �߂�g���܂��B
+ </para>
+
+ <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat)
+from Cat cat
+group by cat.color
+having cat.color in (eg.Color.TABBY, eg.Color.BLACK)]]></programlisting>
+
+ <para>
+ ����g�p����f�[�^�x�[�X���T�|�[�g���Ă���Ȃ�A
+ <literal>having</literal> �� <literal>order by</literal> �߂�SQL���ƏW������g���܂�
+ �i�Ⴆ��MySQL�ɂ͂���܂���j�B
+ </para>
+
+ <programlisting><![CDATA[select cat
+from Cat cat
+ join cat.kittens kitten
+group by cat
+having avg(kitten.weight) > 100
+order by count(kitten) asc, sum(kitten.weight) desc]]></programlisting>
+
+ <para>
+ <literal>group by</literal> �߂� <literal>order by</literal> �߂�
+ �Z�p����܂ނ��Ƃ��ł��Ȃ����Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-subqueries" revision="2">
+ <title>���₢���킹</title>
+
+ <para>
+ �T�u�Z���N�g��T�|�[�g����f�[�^�x�[�X�̂��߁AHibernate�͕��₢���킹��T�|�[�g���Ă��܂��B
+ ���₢���킹�͊��ʂň͂܂Ȃ���Ȃ�܂���iSQL�̏W����Ăяo���ɂ�鎖�������ł��j�B
+ �֘A���₢���킹(�O���N�G�����̕ʖ���Q�Ƃ��镛�₢���킹�̂���)����������܂��B
+ </para>
+
+ <programlisting><![CDATA[from Cat as fatcat
+where fatcat.weight > (
+ select avg(cat.weight) from DomesticCat cat
+)]]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat as cat
+where cat.name = some (
+ select name.nickName from Name as name
+)]]></programlisting>
+
+ <programlisting><![CDATA[from Cat as cat
+where not exists (
+ from Cat as mate where mate.mate = cat
+)]]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat as cat
+where cat.name not in (
+ select name.nickName from Name as name
+)]]></programlisting>
+
+ <programlisting><![CDATA[select cat.id, (select max(kit.weight) from cat.kitten kit)
+from Cat as cat]]></programlisting>
+
+ <para>
+ HQL���₢���킹�́Aselect�܂���where�߂����Ŏg���邱�Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ select���X�g�ɕ����̎������₢���킹�ɂ́A�^�v����g�����Ƃ��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+where not ( cat.name, cat.color ) in (
+ select cat.name, cat.color from DomesticCat cat
+)]]></programlisting>
+
+ <para>
+ �������̃f�[�^�x�[�X�iOracle��HSQL�ɂ͂���܂���j�ł́A
+ ���̃R���e�L�X�g�ł�^�v�����g���܂��B
+ �Ⴆ�A�N�G���R���|�[�l���g�╡�����[�U�^�ɂ����Ăł��B
+ </para>
+
+ <programlisting><![CDATA[from Person where name = ('Gavin', 'A', 'King')]]></programlisting>
+
+ <para>
+ �����ł����A���璷�ȃN�G���ł��F
+ </para>
+
+ <programlisting><![CDATA[from Person where name.first = 'Gavin' and name.initial = 'A' and name.last = 'King')]]></programlisting>
+
+ <para>
+ ���̂悤�Ȃ��Ƃ������Ȃ��̂ɂ�2�̗��R������܂��F
+ 1�ڂ́A�f�[�^�x�[�X�v���b�g�t�H�[���ԂŊ��S�Ȍ݊����͂Ȃ�����ł��B
+ 2�ڂ́A�N�G�����}�b�s���O�h�L�������g�̃v���p�e�B�̏����Ɉˑ����邩��ł��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-examples">
+ <title>HQL�̗�</title>
+
+ <para>
+ Hibernate�N�G���͔��ɋ��͂ŕ��G�ɂł��܂��B���ہA�N�G������̈З͂�Hibernate�̎�v�ȃZ�[���X�|�C���g�̈�ł��B
+ �����ɍŋ߂̃v���W�F�N�g�Ŏg�p�����N�G���Ɣ��ɂ悭�����Ⴊ����܂��B
+ �قƂ�ǂ̃N�G���͂����̗���ȒP�ɋL�q�ł��邱�Ƃɒ��ӂ��Ă�������!
+ </para>
+
+ <para>
+ �ȉ��̃N�G���͓���̌ڋq�Ɨ^����ꂽ�ŏ��̍��v�l�ɑ��関���������̒���ID�A
+ ���i�̐��A�����̍��v���v�l�Ő��ĕԂ��܂��B
+ ���i���肷��ہA���݂̃J�^���O��g���܂��B���ʂƂ��ĕԂ����SQL�N�G����
+ <literal>ORDER</literal>, <literal>ORDER_LINE</literal>, <literal>PRODUCT</literal>,
+ <literal>CATALOG</literal> ����� <literal>PRICE</literal> �e�[�u���ɑ�4�̓��������
+ (�֘A���Ȃ�)���₢���킹�����܂��B
+ </para>
+
+ <programlisting><![CDATA[select order.id, sum(price.amount), count(item)
+from Order as order
+ join order.lineItems as item
+ join item.product as product,
+ Catalog as catalog
+ join catalog.prices as price
+where order.paid = false
+ and order.customer = :customer
+ and price.product = product
+ and catalog.effectiveDate < sysdate
+ and catalog.effectiveDate >= all (
+ select cat.effectiveDate
+ from Catalog as cat
+ where cat.effectiveDate < sysdate
+ )
+group by order
+having sum(price.amount) > :minAmount
+order by sum(price.amount) desc]]></programlisting>
+
+ <para>
+ ���ċ���ȃN�G���Ȃ̂ł��傤! ���i���͕��₢���킹���܂�g���܂���B���������Ď��̃N�G���͎��ۂɂ͈ȉ��̂悤�ɂȂ�܂��B:
+ </para>
+
+ <programlisting><![CDATA[select order.id, sum(price.amount), count(item)
+from Order as order
+ join order.lineItems as item
+ join item.product as product,
+ Catalog as catalog
+ join catalog.prices as price
+where order.paid = false
+ and order.customer = :customer
+ and price.product = product
+ and catalog = :currentCatalog
+group by order
+having sum(price.amount) > :minAmount
+order by sum(price.amount) desc]]></programlisting>
+
+ <para>
+ ���̃N�G���͊e�X�e�[�^�X�̎x�������𐔂��܂��B���������ׂĂ̎x���������݂̗��p�҂ɂ��
+ �ŐV�̃X�e�[�^�X�ύX�ł��� <literal>AWAITING_APPROVAL</literal> �ł���ꍇ�����܂��B
+ ���̃N�G����2�̓�������� <literal>PAYMENT</literal>, <literal>PAYMENT_STATUS</literal> �����
+ <literal>PAYMENT_STATUS_CHANGE</literal> �e�[�u���ɑ���֘A���₢���킹�������SQL�N�G���ɕϊ�����܂��B
+ </para>
+
+ <programlisting><![CDATA[select count(payment), status.name
+from Payment as payment
+ join payment.currentStatus as status
+ join payment.statusChanges as statusChange
+where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
+ or (
+ statusChange.timeStamp = (
+ select max(change.timeStamp)
+ from PaymentStatusChange change
+ where change.payment = payment
+ )
+ and statusChange.user <> :currentUser
+ )
+group by status.name, status.sortOrder
+order by status.sortOrder]]></programlisting>
+
+ <para>
+ �������set�̑����list�Ƃ��� <literal>statusChanges</literal> �R���N�V������
+ �}�b�s���O�����Ȃ�A�͂邩�ɊȒP�ɃN�G����L�q�ł���ł��傤�B
+ </para>
+
+ <programlisting><![CDATA[select count(payment), status.name
+from Payment as payment
+ join payment.currentStatus as status
+where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
+ or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :currentUser
+group by status.name, status.sortOrder
+order by status.sortOrder]]></programlisting>
+
+ <para>
+ ���̃N�G���͌��݂̃��[�U����������g�D�ɑ���A�J�E���g����і������̎x������
+ ���ׂĕԂ�MS SQL Server
+ �� <literal>isNull()</literal> ����g�p���Ă��܂��B
+ ���̃N�G����3�̓��������1�̊O������ �A
+ ������ <literal>ACCOUNT</literal>, <literal>PAYMENT</literal>, <literal>PAYMENT_STATUS</literal>,
+ <literal>ACCOUNT_TYPE</literal>, <literal>ORGANIZATION</literal> �����
+ <literal>ORG_USER</literal> �e�[�u���ɑ��镛�₢���킹������SQL�ɕϊ�����܂��B
+ </para>
+
+ <programlisting><![CDATA[select account, payment
+from Account as account
+ left outer join account.payments as payment
+where :currentUser in elements(account.holder.users)
+ and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
+order by account.type.sortOrder, account.accountNumber, payment.dueDate]]></programlisting>
+
+ <para>
+ �������̃f�[�^�x�[�X�ɂ��ẮA(�֘A������ꂽ)���₢���킹�̎g�p�����K�v������ł��傤�B
+ </para>
+
+ <programlisting><![CDATA[select account, payment
+from Account as account
+ join account.holder.users as user
+ left outer join account.payments as payment
+where :currentUser = user
+ and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
+order by account.type.sortOrder, account.accountNumber, payment.dueDate]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-bulk" revision="2">
+ <title>��ʂ�UPDATE��DELETE</title>
+
+ <para>
+ HQL�͍��� <literal>update</literal> �� <literal>delete</literal>�A<literal>insert ... select ...</literal>
+ �X�e�[�g�����g��HQL�ɓ���邱�Ƃ�T�|�[�g���Ă��܂��B
+ <xref linkend="batch-direct"/> �ɏڍׂ�����܂��B
+ </para>
+ </sect1>
+
+ <sect1 id="queryhql-tipstricks">
+ <title>Tips & Tricks</title>
+
+ <para>
+ ���ۂɌ��ʂ�Ԃ��Ȃ��Ă�N�G���̌��ʐ��𐔂��邱�Ƃ��ł��܂��B:
+ </para>
+
+ <programlisting><![CDATA[( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue()]]></programlisting>
+
+ <para>
+ �R���N�V�����̃T�C�Y�ɂ�茋�ʂ���בւ��邽�߂ɂ͈ȉ��̃N�G����g�p���܂��B:
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User as usr
+ left join usr.messages as msg
+group by usr.id, usr.name
+order by count(msg)]]></programlisting>
+
+ <para>
+ �g�p���Ă���f�[�^�x�[�X���T�u�Z���N�g��T�|�[�g����ꍇ�A�N�G����where�߂ŃT�C�Y�ɂ��I�����ݒ�ł��܂�:
+ </para>
+
+ <programlisting><![CDATA[from User usr where size(usr.messages) >= 1]]></programlisting>
+
+ <para>
+ �g�p���Ă���f�[�^�x�[�X���T�u�Z���N�g��T�|�[�g���Ȃ��ꍇ�́A���̃N�G����g�p���Ă�������:
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User usr.name
+ join usr.messages msg
+group by usr.id, usr.name
+having count(msg) >= 1]]></programlisting>
+
+ <para>
+ ����������Ă��邹���ŏ�̉��@��message�̌�����
+ �[���� <literal>User</literal> ��Ԃ����Ƃ��ł��Ȃ��Ȃ�A�ȉ��̌`�����g���܂��B
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User as usr
+ left join usr.messages as msg
+group by usr.id, usr.name
+having count(msg) = 0]]></programlisting>
+
+ <para>
+ JavaBean�̃v���p�e�B�́A���O�t���̃N�G���p�����[�^�Ɍ��т��邱�Ƃ��o���܂��B�F
+ </para>
+
+ <programlisting><![CDATA[Query q = s.createQuery("from foo Foo as foo where foo.name=:name and foo.size=:size");
+q.setProperties(fooBean); // fooBean has getName() and getSize()
+List foos = q.list();]]></programlisting>
+
+ <para>
+ �R���N�V�����̓t�B���^�t�� <literal>Query</literal> �C���^�[�t�F�C�X��g�p���邱�ƂŃy�[�W����邱�Ƃ��ł��܂��B:
+ </para>
+
+ <programlisting><![CDATA[Query q = s.createFilter( collection, "" ); // the trivial filter
+q.setMaxResults(PAGE_SIZE);
+q.setFirstResult(PAGE_SIZE * pageNumber);
+List page = q.list();]]></programlisting>
+
+ <para>
+ �R���N�V�����̗v�f�̓N�G���t�B���^��g���āA���בւ���O���[�v�������o���܂��B:
+ </para>
+
+ <programlisting><![CDATA[Collection orderedCollection = s.filter( collection, "order by this.amount" );
+Collection counts = s.filter( collection, "select this.type, count(this) group by this.type" );]]></programlisting>
+
+ <para>
+ �R���N�V���������������ɃR���N�V�����̃T�C�Y�邱�Ƃ��ł��܂��B:
+ </para>
+
+ <programlisting><![CDATA[( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue();]]></programlisting>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/query_sql.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/query_sql.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/query_sql.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/query_sql.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,724 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="querysql" revision="2">
+ <title>�l�C�e�B�uSQL</title>
+
+ <para>�f�[�^�x�[�X�̃l�C�e�B�uSQL������g���ăN�G����\�����邱�Ƃ�ł��܂��B
+ �N�G���q���g��Oracle�� <literal>CONNECT</literal> �L�[���[�h�̂悤�ɁA
+ �f�[�^�x�[�X�Ǝ��̋@�\�𗘗p�������Ƃ��Ɏg���܂��B
+ SQL/JDBC�ڎg�p���Ă���A�v���P�[�V��������Hibernate�ւ̈ڍs��e�Ղɂ��Ă��܂��B</para>
+
+ <para>Hibernate3�ł́A�����A�X�V�A�폜�A�ǂݍ��ݏ����̂悤�Ȃ��ׂĂ�
+ SQL�i�X�g�A�h�v���V�[�W����܂ށj��菑���ł��܂��B</para>
+
+ <sect1 id="querysql-creating" revision="4">
+ <title><literal>SQLQuery</literal> �̎g�p</title>
+
+ <para>�l�C�e�B�u��SQL�N�G���̎��s�� <literal>SQLQuery</literal>
+ �C���^�[�t�F�C�X��ʂ��Đ��䂵�܂��B
+ <literal>SQLQuery</literal> �C���^�[�t�F�C�X��
+ <literal>Session.createSQLQuery()</literal> ��Ăяo���Ď擾���܂��B
+ ����API��g���Ė₢���킹������@��ȉ��Ő�����܂��B</para>
+
+ <sect2>
+ <title>�X�J���[�̃N�G��</title>
+
+ <para>�ł��{�I��SQL�N�G���̓X�J���[�i�l�j�̃��X�g�邱�Ƃł��B</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS").list();
+sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").list();
+]]></programlisting>
+
+ <para>�����͂ǂ����ACATS�e�[�u���̊e�J�����̃X�J���[�l��܂�
+ Object�z��iObject[]�j�̃��X�g��Ԃ��܂��B
+ �Ԃ��X�J���[�l�̎��ۂ̏��Ԃƌ^�𐄒肷�邽�߂ɁA
+ Hibernate��ResultSetMetadata��g�p���܂��B</para>
+
+ <para><literal>ResultSetMetadata</literal> ��g�p����I�[�o�[�w�b�h����邽�߁A
+ ������͒P�ɉ����Ԃ���邩���m�ɂ��邽�߁A<literal>addScalar()</literal>
+ ��g���܂��B</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS")
+ .addScalar("ID", Hibernate.LONG)
+ .addScalar("NAME", Hibernate.STRING)
+ .addScalar("BIRTHDATE", Hibernate.DATE)
+]]></programlisting>
+
+ <para>���̃N�G���Ŏw�肳��Ă����̂��L�Ɏ����܂��B</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL�N�G��������</para>
+ </listitem>
+
+ <listitem>
+ <para>�Ԃ����J�����ƌ^</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>����͂܂�Object�z���Ԃ��܂����A
+ <literal>ResultSetMetdata</literal> ��g�p���܂���B
+ �������A���̑���Ɋ�b�ɂ��郊�U���g�Z�b�g����
+ ID�ANAME�ABIRTHDATE �J�������ꂼ��
+ Long�AString�AShort �Ƃ��Ė����I�Ɏ擾���܂��B
+ ����͂R�̃J������Ԃ��݂̂ł��邱�Ƃ�Ӗ����܂��B
+ ���Ƃ��A�N�G���� <literal>*</literal> ��g�p���A
+ �����R��葽���̃J������Ԃ���Ƃ��Ă�ł��B</para>
+
+ <para>�X�J���[�̌^����Ȃ����Ƃ�ł��܂��B</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS")
+ .addScalar("ID", Hibernate.LONG)
+ .addScalar("NAME")
+ .addScalar("BIRTHDATE")
+]]></programlisting>
+
+ <para>
+ ����͖{���I�ɑO�Ɠ����N�G���ł����A�A
+ NAME �� BIRTHDATE �̌^���߂邽�߂� <literal>ResultSetMetaData</literal>
+ ��g�p���܂��B����AID �̌^�͖����I�Ɏw�肳��Ă��܂��B
+ </para>
+
+ <para>
+ ResultSetMetaData ����Ԃ���� java.sql.Types �� Hibernate �̌^��
+ �}�b�s���O���邱�Ƃ́ADialect �����䂵�܂��B
+ �������ꂽ�^���}�b�s���O����Ă��Ȃ����A���ʂ̌^�����҂�����̂ƈقȂ�ꍇ�A
+ Dialect �� <literal>registerHibernateType</literal> ��Ăяo���A
+ �J�X�^�}�C�Y�ł��܂��B
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>�G���e�B�e�B�̃N�G��</title>
+
+ <para>�����܂ł̃N�G���́A���ׂăX�J���[�l��Ԃ���̂ł����B
+ ��{�I�ɁA���U���g�Z�b�g����u�����H�v�̒l��Ԃ��܂��B
+ �ȍ~�ł́A<literal>addEntity()</literal> �ɂ��A�l�C�e�B�uSQL�N�G������
+ �G���e�B�e�B�I�u�W�F�N�g��擾������@�����܂��B</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT * FROM CATS").addEntity(Cat.class);
+sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").addEntity(Cat.class);
+]]></programlisting>
+
+ <para>���̃N�G���Ŏw�肳��Ă����̂��L�Ɏ����܂��B</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL�N�G��������</para>
+ </listitem>
+
+ <listitem>
+ <para>�N�G�����Ԃ��G���e�B�e�B��SQL�e�[�u���̕ʖ�
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Cat��ID, NAME, BIRTHDATE�̃J������g���ăN���X�Ƀ}�b�s���O�����ꍇ�A
+ ��L�̃N�G���͂ǂ����A�v�f��Cat�G���e�B�e�B�ł��郊�X�g��Ԃ��܂��B</para>
+
+ <para>�G���e�B�e�B��ʂ̃G���e�B�e�B�� <literal>���Έ�</literal> �Ń}�b�s���O���Ă���ꍇ�́A
+ �l�C�e�B�u�N�G������s����ۂɁA���̕ʂ̃G���e�B�e�B��Ԃ����Ƃ�v�����܂��B
+ ����Ȃ���A�f�[�^�x�[�X�ŗL�́ucolumn not found(�J������������܂���)�v�G���[���������܂��B
+ * �\�L��g�p�����ۂ́A�lj��̃J�����������I�ɕԂ���܂����A
+ ���̗�̂悤�ɁA<literal>Dog</literal> �� <literal>���Έ�</literal> �ł��邱�Ƃ�
+ �������邱�Ƃ������͍D�݂܂��B</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE, DOG_ID FROM CATS").addEntity(Cat.class);
+]]></programlisting>
+
+ <para>����ɂ�� cat.getDog() ���������@�\���܂��B</para>
+ </sect2>
+
+ <sect2>
+ <title>�֘A�ƃR���N�V�����̑���</title>
+
+ <para>�v���L�V���������邽�߂̗]���ȏ�������邽�߁A
+ <literal>Dog</literal> �̒��ő��������ł��܂��B
+ ����� <literal>addJoin()</literal> ���\�b�h�ɂ��s���܂��B
+ �֘A������̓R���N�V�����Ɍ����ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT c.ID, NAME, BIRTHDATE, DOG_ID, D_ID, D_NAME FROM CATS c, DOGS d WHERE c.DOG_ID = d.D_ID")
+ .addEntity("cat", Cat.class)
+ .addJoin("cat.dog");
+]]></programlisting>
+
+ <para>���̗�̒��ŁA�Ԃ���� <literal>Cat</literal> �́A
+ �f�[�^�x�[�X�ւ̗]�������Ȃ��ŁA
+ ���S�ɏ��������ꂽ <literal>dog</literal> �v���p�e�B�����܂��B
+ �����Ώۂ̃v���p�e�B�ւ̃p�X��w��ł���悤�ɁA
+ �ʖ��i�ucat�v�j��lj��������Ƃɒ��ӂ��Ă��������B
+ �R���N�V�����̑�������������悤�ɂł��܂��B
+ ���Ƃ��A<literal>Cat</literal> ����Α��� <literal>Dog</literal>
+ �����Ă����ꍇ�A���̂悤�ɂȂ�܂��B</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE, D_ID, D_NAME, CAT_ID FROM CATS c, DOGS d WHERE c.ID = d.CAT_ID")
+ .addEntity("cat", Cat.class)
+ .addJoin("cat.dogs");
+]]></programlisting>
+
+ <para>���݂̂Ƃ���A
+ Hibernate�Ŏg���₷�����邽�߂�SQL�N�G���̊g���Ȃ��ɁA
+ �l�C�e�B�u�N�G���ʼn�����\�ɂ�����E�ɗ��Ă��܂��B
+ �����^�̃G���e�B�e�B���Ԃ��ۂ�A�f�t�H���g�̕ʖ���ŏ\���ł͂Ȃ��ꍇ�ɁA
+ ���͋N����n�߂܂��B
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>�����G���e�B�e�B�̎擾</title>
+
+ <para>�����܂ł́A���U���g�Z�b�g�̃J�������́A
+ �}�b�s���O�t�@�C���Ŏw�肳�ꂽ�J�������Ɠ����ł���Ɖ��肵�Ă��܂����B
+ �����̃e�[�u���������J���������ꍇ�����邽�߁A
+ �����e�[�u����������SQL�N�G���Ŗ��ƂȂ�ꍇ������܂��B</para>
+
+ <para>���L�̂悤�ȁi���s�������ȁj�N�G���ł́A
+ �J�����ʖ��C���W�F�N�V�����icolumn alias injection�j���K�v�ł��B</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT c.*, m.* FROM CATS c, CATS m WHERE c.MOTHER_ID = m.ID")
+ .addEntity("cat", Cat.class)
+ .addEntity("mother", Cat.class)
+]]></programlisting>
+
+ <para>���̃N�G���̈Ӑ}�́A
+ �P�s���ƂɂQ��Cat�C���X�^���X�A�܂�L�Ƃ��̕�e��Ԃ��Ƃ������Ƃł��B
+ �����J�������Ƀ}�b�s���O���邱�Ƃɂ�薼�O���Փ˂��邽�߁A���̃N�G���͎��s���܂��B
+ �x�[�^�x�[�X�ɂ���ẮA�Ԃ����J�����̕ʖ��� "c.ID"�A"c.NAME" �Ȃǂ̌`���ł���A
+ �}�b�s���O�Ŏw�肳�ꂽ�J�����i"ID" �� "NAME"�j�Ɠ������Ȃ����߁A���s���܂��B</para>
+
+
+ <para>���L�̌`���́A�J���������d�����Ă���v�ł��B</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT {cat.*}, {mother.*} FROM CATS c, CATS m WHERE c.MOTHER_ID = m.ID")
+ .addEntity("cat", Cat.class)
+ .addEntity("mother", Cat.class)
+]]></programlisting>
+
+ <para>���̃N�G���Ŏw�肳��Ă����̂��L�Ɏ����܂��B</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL�N�G��������
+ �iHibernate���J�����̕ʖ���}�����邽�߂̃v���[�X�z���_��܂ށj</para>
+ </listitem>
+
+ <listitem>
+ <para>�N�G���ɂ���ĕԂ����G���e�B�e�B</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>��L�Ŏg�p���Ă��� {cat.*} �� {mother.*} �Ƃ����\�L�́A
+ �u���ׂẴv���p�e�B�v��\���ȗ��`�ł��B
+ ����ɁA�����I�ɃJ��������Ă�悢�ł����A
+ ���̏ꍇ�́AHibernate�Ɋe�v���p�e�B�ɑΉ�����SQL�J�����̕ʖ���}��������ׂ��ł��傤�B
+ �J�����̕ʖ��̂��߂̃v���[�X�z���_�́A�e�[�u���̕ʖ��ɂ���ďC�����ꂽ�v���p�e�B���ł��B
+ ���L�̗�ł́A�ʂ̃e�[�u�� cat_log ����
+ �}�b�s���O���^�f�[�^�Œ�`���ꂽ Cat �Ƃ��̕�e�����܂��B
+ ����D�ނȂ�Awhere�߂̒��ł�A�v���p�e�B�̕ʖ���g���܂��B</para>
+
+ <programlisting><![CDATA[String sql = "SELECT ID as {c.id}, NAME as {c.name}, " +
+ "BIRTHDATE as {c.birthDate}, MOTHER_ID as {c.mother}, {mother.*} " +
+ "FROM CAT_LOG c, CAT_LOG m WHERE {c.mother} = c.ID";
+
+List loggedCats = sess.createSQLQuery(sql)
+ .addEntity("cat", Cat.class)
+ .addEntity("mother", Cat.class).list()
+]]></programlisting>
+
+ <sect3 id="querysql-aliasreferences" revision="2">
+ <title>�ʖ��ƃv���p�e�B�̃��t�@�����X</title>
+
+ <para>�����̏ꍇ�A��L�̂悤�ȕʖ��C���W�F�N�V�������K�v�ł��B
+ �������A�����v���p�e�B�A�p�����ʎq�A�R���N�V�����Ȃǂ̂悤��
+ ��蕡�G�ȃ}�b�s���O�Ɗ֘A����N�G�����Ȃ���ł��B
+ �������̕ʖ���g�p���邱�Ƃɂ��AHibernate�͓K�ȕʖ���}���ł��܂��B</para>
+
+ <para>�ʖ��C���W�F�N�V�����Ƃ��Ďg�p�ł����̂��\�Ɏ����܂��B
+ ���ӁF���\�̕ʖ��͈��ł��B
+ ���ꂼ��̕ʖ��͈�ӂł���A�g�p����ۂɂ͂����炭�قȂ閼�O�����܂��B</para>
+
+ <table frame="topbot" id="aliasinjection-summary">
+ <title>�ʖ��ɑ}�����閼�O</title>
+
+ <tgroup cols="3">
+ <colspec colwidth="1*" />
+
+ <colspec colwidth="1*" />
+
+ <colspec colwidth="2.5*" />
+
+ <thead>
+ <row>
+ <entry>���</entry>
+ <entry>�\��</entry>
+ <entry>��</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>�P���ȃv���p�e�B</entry>
+ <entry><literal>{[aliasname].[propertyname]}</literal></entry>
+ <entry><literal>A_NAME as {item.name}</literal></entry>
+ </row>
+ <row>
+ <entry>�����v���p�e�B</entry>
+ <entry><literal>{[aliasname].[componentname].[propertyname]}</literal></entry>
+ <entry><literal>CURRENCY as {item.amount.currency}, VALUE as
+ {item.amount.value}</literal></entry>
+ </row>
+ <row>
+ <entry>�G���e�B�e�B�̃N���X���ʂ���l</entry>
+ <entry><literal>{[aliasname].class}</literal></entry>
+ <entry><literal>DISC as {item.class}</literal></entry>
+ </row>
+ <row>
+ <entry>�G���e�B�e�B�̑S�v���p�e�B</entry>
+ <entry><literal>{[aliasname].*}</literal></entry>
+ <entry><literal>{item.*}</literal></entry>
+ </row>
+ <row>
+ <entry>�R���N�V�����̃L�[</entry>
+ <entry><literal>{[aliasname].key}</literal></entry>
+ <entry><literal>ORGID as {coll.key}</literal></entry>
+ </row>
+ <row>
+ <entry>�R���N�V������ID</entry>
+ <entry><literal>{[aliasname].id}</literal></entry>
+ <entry><literal>EMPID as {coll.id}</literal></entry>
+ </row>
+ <row>
+ <entry>�R���N�V�����̗v�f</entry>
+ <entry><literal>{[aliasname].element}</literal></entry>
+ <entry><literal>XID as {coll.element}</literal></entry>
+ </row>
+ <row>
+ <entry>�R���N�V�����̗v�f�̃v���p�e�B</entry>
+ <entry><literal>{[aliasname].element.[propertyname]}</literal></entry>
+ <entry><literal>NAME as {coll.element.name}</literal></entry>
+ </row>
+ <row>
+ <entry>�R���N�V�����̗v�f�̑S�v���p�e�B</entry>
+ <entry><literal>{[aliasname].element.*}</literal></entry>
+ <entry><literal>{coll.element.*}</literal></entry>
+ </row>
+ <row>
+ <entry>�R���N�V�����̑S�v���p�e�B</entry>
+ <entry><literal>{[aliasname].*}</literal></entry>
+ <entry><literal>{coll.*}</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>�Ǘ�����Ă��Ȃ��G���e�B�e�B�̎擾</title>
+
+ <para>�l�C�e�B�uSQL�N�G���� ResultTransformer ��K�p�ł��܂��B
+ ���L�̂悤�ɁA�Ⴆ�A�Ǘ�����Ă��Ȃ��G���e�B�e�B��Ԃ��܂��B</para>
+
+ <programlisting><![CDATA[sess.createSQLQuery("SELECT NAME, BIRTHDATE FROM CATS")
+ .setResultTransformer(Transformers.aliasToBean(CatDTO.class))]]></programlisting>
+
+ <para>���̃N�G���Ŏw�肳��Ă����̂��L�Ɏ����܂��B</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SQL�N�G��������</para>
+ </listitem>
+
+ <listitem>
+ <para>���ʂ�ϊ��������</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>��L�̃N�G���́A�C���X�^���X�����ANAME �� BIRTHDATE �̒l��
+ �Ή�����v���p�e�B������̓t�B�[���h�ɑ}������ <literal>CatDTO</literal>
+ �̃��X�g��Ԃ��܂��B</para>
+ </sect2>
+
+ <sect2>
+ <title>�p���̐���</title>
+
+ <para>�p���̈ꕔ�Ƃ��ă}�b�s���O���ꂽ�G���e�B�e�B��₢���킹��l�C�e�B�uSQL�N�G���́A
+ �x�[�X�̃N���X�Ƃ��̂��ׂẴT�u�N���X�̃v���p�e�B���ׂĂ�܂܂Ȃ���Ȃ�܂���B</para>
+ </sect2>
+
+ <sect2>
+ <title>�p�����[�^</title>
+
+ <para>�l�C�e�B�uSQL�N�G���́A�ȉ��̂悤�ɁA
+ ���O�t���p�����[�^�i:name�j�Ɠ��l�Ɉʒu�p�����[�^��T�|�[�g���܂��B</para>
+
+ <programlisting><![CDATA[Query query = sess.createSQLQuery("SELECT * FROM CATS WHERE NAME like ?").addEntity(Cat.class);
+List pusList = query.setString(0, "Pus%").list();
+
+query = sess.createSQLQuery("SELECT * FROM CATS WHERE NAME like :name").addEntity(Cat.class);
+List pusList = query.setString("name", "Pus%").list(); ]]></programlisting>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="querysql-namedqueries" revision="3">
+ <title>���O�t��SQL�N�G��</title>
+
+ <para>���O�t��SQL�N�G���̓}�b�s���O�h�L�������g�Œ�`���邱�Ƃ��ł��A
+ ���O�t��HQL�N�G���ƑS���������@�ŌĂԂ��Ƃ��ł��܂��B
+ ���̏ꍇ�A<literal>addEntity()</literal> ��Ăяo���K�v�� <emphasis>�Ȃ�</emphasis> �ł��B</para>
+
+ <programlisting><![CDATA[<sql-query name="persons">
+ <return alias="person" class="eg.Person"/>
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex}
+ FROM PERSON person
+ WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+ <programlisting><![CDATA[List people = sess.getNamedQuery("persons")
+ .setString("namePattern", namePattern)
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ <para>�֘A�������邽�߂ƃR���N�V��������������N�G�����`���邽�߂ɁA���ꂼ��
+ <literal><return-join></literal> �� <literal><load-collection></literal>
+ �v�f��g���܂��B</para>
+
+ <programlisting><![CDATA[<sql-query name="personsWith">
+ <return alias="person" class="eg.Person"/>
+ <return-join alias="address" property="person.mailingAddress"/>
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex},
+ address.STREET AS {address.street},
+ address.CITY AS {address.city},
+ address.STATE AS {address.state},
+ address.ZIP AS {address.zip}
+ FROM PERSON person
+ JOIN ADDRESS address
+ ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
+ WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+ <para>���O�t��SQL�N�G���̓X�J���l��Ԃ����Ƃ�ł��܂��B
+ <literal><return-scalar></literal> �v�f��g���āA
+ ��̕ʖ���Hibernate�̌^��錾���Ȃ���Ȃ�܂���B</para>
+
+ <programlisting><![CDATA[<sql-query name="mySqlQuery">
+ <return-scalar column="name" type="string"/>
+ <return-scalar column="age" type="long"/>
+ SELECT p.NAME AS name,
+ p.AGE AS age,
+ FROM PERSON p WHERE p.NAME LIKE 'Hiber%'
+</sql-query>]]></programlisting>
+
+
+ <para>���U���g�Z�b�g�̃}�b�s���O���� <literal><resultset></literal>
+ �ɊO�o�����邱�Ƃ��ł��܂��B
+ �����̖��O�t���N�G���ōė��p������A<literal>setResultSetMapping()</literal>
+ API��ʂ��čė��p������ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<resultset name="personAddress">
+ <return alias="person" class="eg.Person"/>
+ <return-join alias="address" property="person.mailingAddress"/>
+</resultset>
+
+<sql-query name="personsWith" resultset-ref="personAddress">
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex},
+ address.STREET AS {address.street},
+ address.CITY AS {address.city},
+ address.STATE AS {address.state},
+ address.ZIP AS {address.zip}
+ FROM PERSON person
+ JOIN ADDRESS address
+ ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
+ WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+ <para>����ɁAhbm�t�@�C����̃��U���g�Z�b�g�̃}�b�s���O����
+ ����Java�R�[�h�̒��Ŏg�p�ł��܂��B</para>
+
+ <programlisting><![CDATA[List cats = sess.createSQLQuery(
+ "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id"
+ )
+ .setResultSetMapping("catAndKitten")
+ .list();]]></programlisting>
+
+ <sect2 id="propertyresults">
+ <title>��Ɨ�̕ʖ����I�Ɏw�肷�邽�߂� return-property ��g��</title>
+
+ <para>�ʖ���}�����邽�߂� <literal>{}</literal> �\����g������ɁA
+ <literal><return-property></literal> ��g���A
+ �ǂ̗�̕ʖ���g���̂����ł��܂��B</para>
+
+ <programlisting><![CDATA[<sql-query name="mySqlQuery">
+ <return alias="person" class="eg.Person">
+ <return-property name="name" column="myName"/>
+ <return-property name="age" column="myAge"/>
+ <return-property name="sex" column="mySex"/>
+ </return>
+ SELECT person.NAME AS myName,
+ person.AGE AS myAge,
+ person.SEX AS mySex,
+ FROM PERSON person WHERE person.NAME LIKE :name
+</sql-query>
+]]></programlisting>
+
+ <para><literal><return-property></literal> �͕����̗������܂��B
+ ����́A������̃v���p�e�B���ߍׂ�������ł��Ȃ��Ƃ����A
+ <literal>{}</literal> �\���̐���������܂��B</para>
+
+ <programlisting><![CDATA[<sql-query name="organizationCurrentEmployments">
+ <return alias="emp" class="Employment">
+ <return-property name="salary">
+ <return-column name="VALUE"/>
+ <return-column name="CURRENCY"/>
+ </return-property>
+ <return-property name="endDate" column="myEndDate"/>
+ </return>
+ SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer},
+ STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},
+ REGIONCODE as {emp.regionCode}, EID AS {emp.id}, VALUE, CURRENCY
+ FROM EMPLOYMENT
+ WHERE EMPLOYER = :id AND ENDDATE IS NULL
+ ORDER BY STARTDATE ASC
+</sql-query>]]></programlisting>
+
+ <para>���̗�ł́A�}���̂��߂� <literal>{}</literal> �\���Ƃ�������ɁA
+ <literal><return-property></literal> ��g���Ă��邱�Ƃɒ��ӂ��Ă��������B
+ ��ƃv���p�e�B��ǂ̂悤�ɎQ�Ƃ��邩��I�ׂ܂��B</para>
+
+ <para>�}�b�s���O�� discriminator ���܂܂�Ă���ꍇ�A
+ discriminator �̗��w�肷�邽�߂ɁA<return-discriminator>
+ ��g��Ȃ���Ȃ�܂���B</para>
+ </sect2>
+
+ <sect2 id="sp_query" revision="1">
+ <title>�₢���킹���邽�߂ɃX�g�A�h�v���V�[�W����g��</title>
+
+ <para>Hibernate�̓o�[�W����3����A�X�g�A�h�v���V�[�W���ƃX�g�A�h���o�R�̖₢���킹��
+ �T�|�[�g����܂����B
+ �ȍ~�̕����̑����́A�����ɓ��Ă͂܂�܂��B
+ �X�g�A�h�v���V�[�W����X�g�A�h����Hibernate�Ŏg�����߂ɂ́A
+ 1�Ԗڂ̏o�̓p�����[�^�Ƃ��ă��U���g�Z�b�g��Ԃ��Ȃ���Ȃ�܂���B
+ Oracle 9�i������͂���ȏ�̃o�[�W�����j�̃X�g�A�h�v���V�[�W���̗��ȉ��Ɏ����܂��B</para>
+
+ <programlisting><![CDATA[CREATE OR REPLACE FUNCTION selectAllEmployments
+ RETURN SYS_REFCURSOR
+AS
+ st_cursor SYS_REFCURSOR;
+BEGIN
+ OPEN st_cursor FOR
+ SELECT EMPLOYEE, EMPLOYER,
+ STARTDATE, ENDDATE,
+ REGIONCODE, EID, VALUE, CURRENCY
+ FROM EMPLOYMENT;
+ RETURN st_cursor;
+ END;]]></programlisting>
+
+ <para>Hibernate�ł��̃N�G����g�����߂ɂ́A
+ ���O�t���N�G���Ń}�b�s���O����K�v������܂��B</para>
+
+ <programlisting><![CDATA[<sql-query name="selectAllEmployees_SP" callable="true">
+ <return alias="emp" class="Employment">
+ <return-property name="employee" column="EMPLOYEE"/>
+ <return-property name="employer" column="EMPLOYER"/>
+ <return-property name="startDate" column="STARTDATE"/>
+ <return-property name="endDate" column="ENDDATE"/>
+ <return-property name="regionCode" column="REGIONCODE"/>
+ <return-property name="id" column="EID"/>
+ <return-property name="salary">
+ <return-column name="VALUE"/>
+ <return-column name="CURRENCY"/>
+ </return-property>
+ </return>
+ { ? = call selectAllEmployments() }
+</sql-query>]]></programlisting>
+
+ <para>���ӁF���̂Ƃ���A�X�g�A�h�v���V�[�W���̓X�J���ƃG���e�B�e�B��Ԃ��݂̂ł��B
+ <literal><return-join></literal> �� <literal><load-collection></literal>
+ �̓T�|�[�g����Ă��܂���B</para>
+
+ <sect3 id="querysql-limits-storedprocedures" revision="1">
+ <title>�X�g�A�h�v���V�[�W����g����ł̃��[���Ɛ���</title>
+
+ <para>Hibernate�ŃX�g�A�h�v���V�[�W�������g�����߂ɂ́A
+ ���̃v���V�[�W���͂������̃��[���ɏ�������K�v������܂��B
+ ���[���ɏ������Ă��Ȃ��v���V�[�W���́AHibernate�Ŏg�����Ƃ͂ł��܂���B
+ ����ł�A�������Ă��Ȃ��v���V�[�W����g�������̂ł���A
+ <literal>session.connection()</literal> ��ʂ��Ď��s���Ȃ���Ȃ�܂���B
+ ���[���̓f�[�^�x�[�X���ƂɈقȂ�܂��B
+ �X�g�A�h�v���V�[�W���̃Z�}���e�B�b�N�X�ƃV���^�b�N�X�́A
+ �f�[�^�x�[�X�x���_���ƂɈقȂ邽�߂ł��B</para>
+
+ <para><literal>setFirstResult()/setMaxResults()</literal> ��g���āA
+ �X�g�A�h�v���V�[�W���N�G����y�[�W�������邱�Ƃ͂ł��܂���B</para>
+
+ <para>��������Ăяo�����́A�W���ł���SQL92�ɏ]�����Ƃł��B
+ <literal>{ ? = call functionName(<parameters>) }</literal> ��
+ <literal>{ ? = call procedureName(<parameters>) }</literal> �ł��B
+ �l�C�e�B�u�ȌĂяo���\���̓T�|�[�g����Ă��܂���B</para>
+
+ <para>Oracle�ɂ͉��L�̃��[�����K�p����܂��B</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>���̓��U���g�Z�b�g��Ԃ��Ȃ���Ȃ�܂���B
+ �v���V�[�W���̑������̓��U���g�Z�b�g��Ԃ����߁A
+ <literal>OUT</literal> �łȂ���Ȃ�܂���B
+ Oracle 9��10�ł́A<literal>SYS_REFCURSOR</literal> ��g�����Ƃɂ���Ăł��܂��B
+ Oracle�ł� <literal>REF CURSOR</literal> �^���`����K�v������܂��B
+ Oracle�̕�����Q�Ƃ��Ă��������B</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Sybase��MS SQL�T�[�o�[�ɓK�p����郋�[�����L�Ɏ����܂��B</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>�v���V�[�W���̓��U���g�Z�b�g��Ԃ��Ȃ���Ȃ�܂���B
+ �T�[�o�[�͕����̃��U���g�Z�b�g�ƍX�V�J�E���g��Ԃ��܂����A
+ Hibernate��1�ڂ̃��U���g�Z�b�g������Ԃ����Ƃɒ��ӂ��Ă��������B
+ ���̑��͂��ׂĎ̂Ă��܂��B</para>
+ </listitem>
+
+ <listitem>
+ <para>�v���V�[�W���̒��� <literal>SET NOCOUNT ON</literal> ��L���ɂł���A
+ �����炭�������悭�Ȃ�ł��傤�B
+ �������A����͕K�v���ł͂���܂���B</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 id="querysql-cud">
+ <title>�쐬�A�X�V�A�폜�̂��߂̃J�X�^��SQL</title>
+
+ <para>Hibernate3�͍쐬�A�X�V�A�폜�����̂��߂̃J�X�^��SQL����g�p�ł��܂��B
+ �N���X�ƃR���N�V�����̉i�����@�\�́A�R���t�B�O���[�V�������ɐ������ꂽ������
+ �iinsertsql�Adeletesql�Aupdatesql�Ȃǁj�̃Z�b�g���łɕێ����Ă��܂��B
+ �����̕�������A
+ <literal><sql-insert></literal>�A
+ <literal><sql-delete></literal>�A
+ <literal><sql-update></literal> �Ƃ����}�b�s���O�^�O���D�悳��܂��B</para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ? )</sql-insert>
+ <sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE ID=?</sql-update>
+ <sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete>
+</class>]]></programlisting>
+
+ <para>SQL�ڃf�[�^�x�[�X�Ŏ��s���邽�߁A�D�݂̕������R�Ɏg�p�ł��܂��B
+ �f�[�^�x�[�X�Ǝ���SQL��g���A���R�}�b�s���O�̃|�[�^�r���e�B��������܂��B</para>
+
+ <para><literal>callable</literal> ������Z�b�g����A
+ �X�g�A�h�v���V�[�W����g�p�ł��܂��B</para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <sql-insert callable="true">{call createPerson (?, ?)}</sql-insert>
+ <sql-delete callable="true">{? = call deletePerson (?)}</sql-delete>
+ <sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update>
+</class>]]></programlisting>
+
+ <para>���̂Ƃ���A�ʒu�p�����[�^�̏��Ԃ͂ƂĂ�d�v�ł��B
+ ���Ȃ킿�AHibernate�����҂��鏇���łȂ���Ȃ�܂���B</para>
+
+ <para><literal>org.hiberante.persister.entity</literal> ���x���̃f�o�b�O���O��
+ �L���ɂ��邱�Ƃɂ���āA���҂���鏇�Ԃ�m���߂��܂��B
+ ���̃��x����L���ɂ��邱�Ƃɂ��A�G���e�B�e�B�̍쐬�A�X�V�A�폜�Ȃǂ�
+ �g�p�����ÓI��SQL���o�͂���܂��B
+ �i���҂���鏇����m�F���邽�߂ɂ́AHibernate����������ÓI��SQL��I�[�o�[���C�h����
+ �J�X�^��SQL��}�b�s���O�t�@�C���Ɋ܂߂Ȃ����Ƃ�Y��Ȃ��ł��������B�j</para>
+
+ <para>�X�g�A�h�v���V�[�W���͑}��/�X�V/�폜���ꂽ�s����Ԃ��K�v������܂�
+ �i�ǂݍ��݂̏ꍇ�́A�Ԃ��Ȃ����͕Ԃ������悢�ł��j�B
+ ���s����Hibernate��SQL���̐�����`�F�b�N���邩��ł��B
+ Hibernate�́ACUD�����̂��߂̐��l�̏o�̓p�����[�^�Ƃ��āA
+ SQL���̍ŏ��̃p�����[�^����L�^���܂��B</para>
+
+ <programlisting><![CDATA[CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname IN VARCHAR2)
+ RETURN NUMBER IS
+BEGIN
+
+ update PERSON
+ set
+ NAME = uname,
+ where
+ ID = uid;
+
+ return SQL%ROWCOUNT;
+
+END updatePerson;]]></programlisting>
+ </sect1>
+
+ <sect1 id="querysql-load">
+ <title>���[�h�̂��߂̃J�X�^��SQL</title>
+
+ <para>�G���e�B�e�B��ǂݍ��ނ��߂̓Ǝ���SQL�i�������HQL�j�N�G����錾�ł��܂��B</para>
+
+ <programlisting><![CDATA[<sql-query name="person">
+ <return alias="pers" class="Person" lock-mode="upgrade"/>
+ SELECT NAME AS {pers.name}, ID AS {pers.id}
+ FROM PERSON
+ WHERE ID=?
+ FOR UPDATE
+</sql-query>]]></programlisting>
+
+ <para>����́A�܂��Ɂi�ȑO�c�_�����j���O�t���N�G���̐錾�ł��B
+ ���̖��O�t���N�G����N���X�̃}�b�s���O����Q�Ƃł��܂��B</para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <loader query-ref="person"/>
+</class>]]></programlisting>
+
+
+ <para>����̓X�g�A�h�v���V�[�W���ł�������삵�܂��B</para>
+
+ <para>���̂悤�ɁA�R���N�V�������[�h���邽�߂̃N�G��������`���Ă悢�ł��B</para>
+
+ <programlisting><![CDATA[<set name="employments" inverse="true">
+ <key/>
+ <one-to-many class="Employment"/>
+ <loader query-ref="employments"/>
+</set>]]></programlisting>
+
+ <programlisting><![CDATA[<sql-query name="employments">
+ <load-collection alias="emp" role="Person.employments"/>
+ SELECT {emp.*}
+ FROM EMPLOYMENT emp
+ WHERE EMPLOYER = :id
+ ORDER BY STARTDATE ASC, EMPLOYEE ASC
+</sql-query>]]></programlisting>
+
+ <para>���̂悤�ɁA�����t�F�b�`�ɂ��R���N�V�������[�h����
+ �G���e�B�e�B���[�_�[���`�ł��܂��B</para>
+
+ <programlisting><![CDATA[<sql-query name="person">
+ <return alias="pers" class="Person"/>
+ <return-join alias="emp" property="pers.employments"/>
+ SELECT NAME AS {pers.*}, {emp.*}
+ FROM PERSON pers
+ LEFT OUTER JOIN EMPLOYMENT emp
+ ON pers.ID = emp.PERSON_ID
+ WHERE ID=?
+</sql-query>]]></programlisting>
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/session_api.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/session_api.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/session_api.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/session_api.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,1120 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="objectstate">
+ <title>�I�u�W�F�N�g����</title>
+
+ <para>
+ Hibernate �͊��S�ȃI�u�W�F�N�g/�����[�V���i���}�b�s���O�\�����[�V�����ł���A
+ �f�[�^�x�[�X�Ǘ��V�X�e���̏ڍׂ�J���҂���B�����邾���łȂ��A �I�u�W�F�N�g�� <emphasis>��ԊǗ�</emphasis> ��s���܂��B
+ ����́AJDBC/SQL�i���w�Ɠ����悤��SQL <literal>��</literal> �̊Ǘ��Ƃ͈قȂ�A
+ Java�A�v���P�[�V�����ɂ�����i�����ɑ���A�ƂĂ���R�ȃI�u�W�F�N�g�w���̍l��������܂��B
+ </para>
+
+ <para>
+ ����������AHibernate��p����A�v���P�[�V�����J���҂́A�I�u�W�F�N�g�� <emphasis>���</emphasis> �ɂ��Ă�
+ ��Ɉӎ����ׂ��ł���ASQL���̎��s�ɂ��Ă͕K����������ł͂���܂���B
+ ���̕����́A�ʏ�AHibernate���������A�V�X�e���̃p�t�H�[�}���X��`���[�j���O����Ƃ��ɂ����A ���ɂȂ��Ă��܂��B
+ </para>
+
+ <sect1 id="objectstate-overview">
+ <title>Hibernate�ɂ�����I�u�W�F�N�g�̏��</title>
+
+ <para>
+ Hibernate�͎��̂悤�ȃI�u�W�F�N�g�̏�Ԃ��`���A�T�|�[�g���Ă��܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis> �ꎞ�I(Transient) </emphasis> - <literal>new</literal>
+ ���Z�q��g���� �C���X�^���X�����ꂽ�����ŁA Hibernate�� <literal>Session</literal>
+ �Ɋ֘A�t�����Ă��Ȃ��I�u�W�F�N�g�́A �ꎞ�I(transient)�ł��B
+ ����́A�f�[�^�x�[�X�ɉi���I�ȕ\���������A���ʎq�ƂȂ�l�͊��蓖�Ă��Ă��܂���B
+ �ꎞ�I�ȃC���X�^���X�́A�A�v���P�[�V���������̎Q�Ƃ�ǂ��ɂ�ێ����Ȃ��ꍇ�ɁA �K�x�[�W�R���N�^�ɂ���Ĕj������܂��B
+ �I�u�W�F�N�g��i���I(persistent)�ȏ�Ԃɂ��邽�߂ɂ́AHibernate��
+ <literal>Session</literal> ��g���܂��傤�B
+ �i���̏�ԑJ�ڂɕK�v�ƂȂ�SQL���̔��s�́AHibernate�ɔC���܂��傤�B�j
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>�i���I(Persistent)</emphasis> -
+ �i���I�ȃC���X�^���X�̓f�[�^�x�[�X�� �i���I�ȕ\�������A���ʎq�ƂȂ�l�����Ă��܂��B
+ ����́A�Z�[�u���ꂽ��A���[�h���ꂽ�肷�邩�����܂��A
+ ��`��́A <literal>Session</literal> �̃X�R�[�v�̒��ɑ��݂��Ă��܂��B
+ Hibernate�́A��ƒP�ʁiUnit of work�j�����������Ƃ��ɁA �i����Ԃ̃I�u�W�F�N�g�ɉ�����ꂽ�ύX���o���A
+ �I�u�W�F�N�g�̏�Ԃƃf�[�^�x�[�X�����܂��B �I�u�W�F�N�g��ꎞ�I(transient)�ɂ���Ƃ��́A�J���҂́A���Ƃ�
+ <literal>UPDATE</literal> ���� <literal>DELETE</literal>
+ ������s���܂���B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>����(Detached)</emphasis> - �������ꂽ�C���X�^���X�Ƃ́A�i��������Ă��邪�A
+ ����Ɗ֘A�t���Ă��� <literal>Session</literal> ���N���[�Y����Ă���I�u�W�F�N�g�̂��Ƃł��B
+ ���̃I�u�W�F�N�g�ւ̎Q�Ƃ́A�ˑR�Ƃ��ėL���ł��B
+ �����āA������A�������ꂽ��Ԃɂ���I�u�W�F�N�g�́A�C�����邱�Ƃ����ł��܂��B
+ �������ꂽ�C���X�^���X�́A�����x�i�����������i�����āA���ׂĂ̕ύX��i�����������j�Ƃ��ɁA �V����
+ <literal>Session</literal> �ɍĒlj��ł��܂��B
+ ���̋@�\�́A���[�U���l���鎞�Ԃ�K�v�Ƃ���悤�ȁA�����Ԃɋy�ԍ�ƒP�ʂɑ��� �v���O���~���O���f����\�ɂ��܂��B
+ ��X�́A����� <emphasis>�A�v���P�[�V�����̃g�����U�N�V�����iapplication
+ transactions�j</emphasis> �ƌĂ�ł��܂��B ���Ȃ킿�A���[�U���猩����ƒP�ʂ��Ƃ������Ƃł��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ���ꂩ��A��ԂƏ�ԑJ�ځi�����āA�J�ڂ̂��������ƂȂ�Hibernate�̃��\�b�h�j�ɂ��� �A�ڍׂɏq�ׂ܂��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-makingpersistent" revision="1">
+ <title>�I�u�W�F�N�g��i����Ԃɂ���</title>
+
+ <para>
+ �V�����C���X�^���X�����ꂽ�i���N���X�̃C���X�^���X�́A Hibernate�ł�
+ <emphasis>�ꎞ�I(transient)</emphasis> �ƌ��Ȃ���܂��B
+ �ȉ��̂悤�ɁA�Z�b�V�����Ɗ֘A�Â��邱�ƂŁA�ꎞ�I�ȃC���X�^���X��
+ <emphasis>�i�����(persistent)</emphasis> �ɂł��܂��B
+ </para>
+
+
+ <programlisting><![CDATA[DomesticCat fritz = new DomesticCat();
+fritz.setColor(Color.GINGER);
+fritz.setSex('M');
+fritz.setName("Fritz");
+Long generatedId = (Long) sess.save(fritz);]]></programlisting>
+
+ <para>
+ <literal>Cat</literal> �N���X�̎��ʎq���������������̂ł���A
+ <literal>save()</literal> ���Ă��Ƃ��ɁA ���ʎq����������A <literal>cat</literal>
+ �C���X�^���X�Ɋ��蓖�Ă��܂��B <literal>Cat</literal>
+ �̎��ʎq�������犄�蓖�Ă���i <literal>assigned</literal> ���ʎq���j���A�����L�[�ł���Ȃ�A
+ <literal>save()</literal> ��Ăяo���O�ɁA���ʎq���蓖�ĂȂ���Ȃ�܂���B
+ <literal>save()</literal> �̑���ɁAEJB3 �̏����h���t�g�Œ�`���ꂽ
+ <literal>persist()</literal> ��g�����Ƃ�\�ł��B
+ </para>
+
+ <para>
+ ����ɁA���ʎq������ɂƂ� <literal>save()</literal>
+ ���\�b�h��g���āA ���ʎq���蓖�Ă邱�Ƃ�ł��܂��B
+ </para>
+
+
+ <programlisting><![CDATA[DomesticCat pk = new DomesticCat();
+pk.setColor(Color.TABBY);
+pk.setSex('F');
+pk.setName("PK");
+pk.setKittens( new HashSet() );
+pk.addKitten(fritz);
+sess.save( pk, new Long(1234) );]]></programlisting>
+
+ <para>
+ �i��������I�u�W�F�N�g���֘A�I�u�W�F�N�g�����Ă���ꍇ �i�Ⴆ�A�O�̗�ɂ�����
+ <literal>kittens</literal> �R���N�V�����̂悤�Ɂj�A �O���L�[�J�����ɁA <literal>NOT
+ NULL</literal> �������Ȃ�����́A �����̈�A�̃I�u�W�F�N�g��ǂ�ȏ��Ԃʼni�������Ă���܂��܂���B
+ �O���L�[�����ᔽ���鋰��͂���܂���B �������A <literal>NOT NULL</literal>
+ ������ꍇ�A�Ԉ�������ԂŃI�u�W�F�N�g�� <literal>save()</literal> ���Ă��܂��ƁA
+ ����Ɉᔽ���邩�����܂���B </para>
+
+ <para>
+ �֘A����I�u�W�F�N�g�����I�ɕۑ�����A Hibernate�� <emphasis>�J�ړI�ȉi����(transitive
+ persistence)</emphasis> �@�\�� �g�����Ȃ�A���̂悤�ȏڍׂ�C�ɂ���K�v�͂���܂���B
+ �����āA <literal>NOT NULL</literal> ����̈ᔽ����N����܂���B
+ Hibernate�����ׂĖʓ|��݂Ă���܂��B�J�ړI�ȉi�����́A���̏͂̌㔼�ɏ�����Ă��܂��B </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-loading">
+ <title>�I�u�W�F�N�g�̃��[�h</title>
+
+ <para>
+ �i�������ꂽ�C���X�^���X�̎��ʎq�����炩���ߕ������Ă���Ȃ�A <literal>Session</literal> ��
+ <literal>load()</literal> ���\�b�h��g���āA�����ł��܂��B <literal>load()</literal>
+ �́AClass �I�u�W�F�N�g������ɂƂ�A ���̃N���X�̃C���X�^���X��V���ɐ������A��Ԃ��[�h���܂��B
+ ���̃C���X�^���X�̏�Ԃ́A�i��(persistent)��Ԃł��B </para>
+
+
+ <programlisting><![CDATA[Cat fritz = (Cat) sess.load(Cat.class, generatedId);]]></programlisting>
+
+
+ <programlisting><![CDATA[// you need to wrap primitive identifiers
+long id = 1234;
+DomesticCat pk = (DomesticCat) sess.load( DomesticCat.class, new Long(id) );]]></programlisting>
+ <para>
+ ���邢�́A�ȉ��̂悤�ɁA�����̃C���X�^���X�ɏ�Ԃ��[�h���邱�Ƃ�ł��܂��B </para>
+
+
+ <programlisting><![CDATA[Cat cat = new DomesticCat();
+// load pk's state into cat
+sess.load( cat, new Long(pkId) );
+Set kittens = cat.getKittens();]]></programlisting>
+
+ <para>
+ DB�ɊY������s�������ꍇ�A <literal>load()</literal> �͉s�\�ȗ�O�� �����邱�Ƃɒ��ӂ��܂��傤�B
+ ���̃N���X���v���L�V��g���ă}�b�s���O����Ă���ꍇ�A <literal>load()</literal>
+ �͏���������Ă��Ȃ��v���L�V��Ԃ��A�v���L�V�̃��\�b�h���Ă��܂Ŏ��ۂɂ� �f�[�^�x�[�X�ɃA�N�Z�X���܂���B
+ ����A���ۂɃf�[�^�x�[�X���烍�[�h�����ɁA�I�u�W�F�N�g�ɑ���֘A���肽���ꍇ�A ���̐U�镑���͂ƂĂ�𗧂��܂��B
+ <literal>batch-size</literal> ���N���X�}�b�s���O�ɒ�`����Ă���Ȃ�A
+ �����̃C���X�^���X��ꊇ�Ń��[�h���邱�Ƃ��\�ł��B </para>
+
+ <para>
+ �Y������s�����݂��邱�Ƃ�m�M�ł��Ȃ��ꍇ�́A <literal>get()</literal> ���\�b�h��g���ׂ��ł��B
+ ����́A�f�[�^�x�[�X�ɂ����ɃA�N�Z�X���A�Y������s�������ꍇ��null��Ԃ��܂��B </para>
+
+
+ <programlisting><![CDATA[Cat cat = (Cat) sess.get(Cat.class, id);
+if (cat==null) {
+ cat = new Cat();
+ sess.save(cat, id);
+}
+return cat;]]></programlisting>
+
+ <para>
+ <literal>LockMode</literal> ��g���A
+ <literal>SELECT ... FOR UPDATE</literal>�Ƃ���SQL�� �g���ăI�u�W�F�N�g���[�h���邱�Ƃ��ł��܂��B
+ �ڍׂȏ��́AAPI�h�L�������g��Q�Ƃ��Ă��������B </para>
+
+
+ <programlisting><![CDATA[Cat cat = (Cat) sess.get(Cat.class, id, LockMode.UPGRADE);]]></programlisting>
+
+ <para>
+ �֘A�ɑ���J�X�P�[�h���@�Ƃ���
+ <literal>lock</literal> �� <literal>all</literal> ��
+ �w�肵�Ȃ�����A�֘A����C���X�^���X��܂܂��R���N�V������ <literal>FOR UPDATE</literal> �ŕ���
+ <emphasis>����Ȃ�</emphasis> ���Ƃɒ��ӂ��܂��傤�B </para>
+
+ <para>
+ <literal>refresh()</literal> ���\�b�h��g�����ƂŁA�ǂ�ȂƂ��ł�A�I�u�W�F�N�g�₻�̃R���N�V������
+ �����[�h���邱�Ƃ��ł��܂��B �f�[�^�x�[�X�̃g���K���e�[�u����X�V�����ۂɁA
+ ���̃e�[�u���ɑΉ�����I�u�W�F�N�g�̃v���p�e�B������ꍇ�A���̃��\�b�h����ɗ����܂��B </para>
+
+
+ <programlisting><![CDATA[sess.save(cat);
+sess.flush(); //force the SQL INSERT
+sess.refresh(cat); //re-read the state (after the trigger executes)]]></programlisting>
+ <para>
+ ��Ȗ��́A������̓_�Ɋւ����̂ł��B����́AHibernate���f�[�^�x�[�X����A
+ �ǂ̂��炢�̗ʂ�����̂��ƁA�ǂ̂��炢�̐���SQL�� <literal>SELECT</literal> �����g����̂��ł��B
+ ����́A <emphasis>�t�F�b�`�̐헪</emphasis> �ɂ��܂��B����ɂ��ẮA<xref linkend="performance-fetching"/> �Ő�����Ă��܂��B </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-querying" revision="1">
+ <title>�N�G��</title>
+
+ <para>
+ �T�������I�u�W�F�N�g�̎��ʎq��������Ȃ��ꍇ�́A�N�G�����K�v�ɂȂ�܂��B
+ Hibernate�͎g���₷���ċ��͂ȃI�u�W�F�N�g�w���̃N�G������ (HQL)��T�|�[�g���Ă��܂��B
+ �v���O�����ɂ���ăN�G�����쐬�ł���悤�ɁAHibernate�͐�����ꂽCriteria��Example�N�G���@�\(QBC��QBE�j��
+ �T�|�[�g���Ă��܂��BResultSet��I�u�W�F�N�g�ɕϊ�����Hibernate�̃I�v�V�����@�\��g�����ƂŁA
+ �f�[�^�x�[�X�̃l�C�e�B�u��SQL�ŃN�G����\�����邱�Ƃ�ł��܂��B </para>
+
+ <sect2 id="objectstate-querying-executing" revision="1">
+ <title>�N�G���̎��s</title>
+
+ <para>
+ HQL��l�C�e�B�u��SQL�N�G���́A <literal>org.hibernate.Query</literal>
+ �̃C���X�^���X�Ƃ��ĕ\������܂��B ���̃C���^�t�F�[�X�́A�p�����[�^�o�C���f�B���O��ResultSet�̃n���h�����O��
+ �N�G���̎��s��s�����\�b�h��p�ӂ��Ă��܂��B �ʏ�A <literal>Query</literal> �́A�ȉ��Ɏ����悤�ɁA
+ ���̎��_�� <literal>Session</literal> ��g���Ď擾���܂��B </para>
+
+
+ <programlisting><![CDATA[List cats = session.createQuery(
+ "from Cat as cat where cat.birthdate < ?")
+ .setDate(0, date)
+ .list();
+
+List mothers = session.createQuery(
+ "select mother from Cat as cat join cat.mother as mother where cat.name = ?")
+ .setString(0, name)
+ .list();
+
+List kittens = session.createQuery(
+ "from Cat as cat where cat.mother = ?")
+ .setEntity(0, pk)
+ .list();
+
+Cat mother = (Cat) session.createQuery(
+ "select cat.mother from Cat as cat where cat = ?")
+ .setEntity(0, izi)
+ .uniqueResult();]]
+
+Query mothersWithKittens = (Cat) session.createQuery(
+ "select mother from Cat as mother left join fetch mother.kittens");
+Set uniqueMothers = new HashSet(mothersWithKittens.list());
+
+ ]]></programlisting>
+
+ <para>
+ �N�G���́A���ʁA <literal>list()</literal> ��Ăяo�����Ƃɂ���Ď��s����܂��B
+ �N�G���̌��ʂ́A��������ɂ���R���N�V�����ɂ��ׂă��[�h����܂��B
+ �N�G���ɂ���ĕ������ꂽ�G���e�B�e�B�̃C���X�^���X�́A�i����Ԃł��B
+ ����A�N�G����������1�̃C���X�^���X��Ԃ��ƕ������Ă���Ȃ�A
+ <literal>uniqueResult()</literal> ���\�b�h�������葁�����@�ł��B
+ �����t�F�b�`�𗘗p�����N�G���̏ꍇ�A�ӂ��A����ꂽ�R���N�V�����ɂ́A
+ ���[�g�̃I�u�W�F�N�g���d�����Ċ܂܂�Ă��܂�
+ �i�������A���[�g�����R���N�V�����͏�����(���[�h�j����Ă��܂��j�B
+ ���̏d���� <literal>Set</literal> ��g���Ď�菜�����Ƃ��ł��܂��B</para>
+
+ <sect3 id="objectstate-querying-executing-iterate">
+ <title>���ʂ�C�e���[�g����</title>
+
+ <para>
+ ���X�A <literal>iterate()</literal> ���\�b�h��g���ăN�G������s���邱�ƂŁA
+ ���ǂ��p�t�H�[�}���X�邱�Ƃ��ł��܂��B ����́A�ʏ�A�N�G���ɂ���ē���ꂽ���ۂ̃G���e�B�e�B�̃C���X�^���X���A
+ ���łɃZ�b�V�����܂��͓L���b�V���ɑ��݂��邱�Ƃ����҂ł���ꍇ�����ł��B
+ ����炪�A�܂��L���b�V������Ă��Ȃ��Ȃ�A <literal>iterate()</literal> �́A
+ <literal>list()</literal> ����x���A�ȒP�ȃN�G���ɑ��Ă�����̃f�[�^�x�[�X�A�N�Z�X��
+ �K�v�Ƃ��܂��B���̃A�N�Z�X�Ƃ́A���ʎq������擾���邽�߂̍ŏ���select�P��ƁA
+ ���ۂ̃C���X�^���X���������邽�߂Ɍォ��s��n���select�̂��Ƃł��B </para>
+
+
+ <programlisting><![CDATA[// fetch ids
+Iterator iter = sess.createQuery("from eg.Qux q order by q.likeliness").iterate();
+while ( iter.hasNext() ) {
+ Qux qux = (Qux) iter.next(); // fetch the object
+ // something we couldnt express in the query
+ if ( qux.calculateComplicatedAlgorithm() ) {
+ // delete the current instance
+ iter.remove();
+ // dont need to process the rest
+ break;
+ }
+}]]></programlisting>
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-tuples">
+ <title>�I�u�W�F�N�g�̑g�ituple�j��Ԃ��N�G��</title>
+ <para>
+ Hibernate�̃N�G���ł́A���X�A�I�u�W�F�N�g�̑g��Ԃ����Ƃ�����܂��B ���̏ꍇ�́A�e�^�v���͔z��Ƃ��ĕԂ���܂��B
+ </para>
+
+
+ <programlisting><![CDATA[Iterator kittensAndMothers = sess.createQuery(
+ "select kitten, mother from Cat kitten join kitten.mother mother")
+ .list()
+ .iterator();
+
+while ( kittensAndMothers.hasNext() ) {
+ Object[] tuple = (Object[]) kittensAndMothers.next();
+ Cat kitten = (Cat) tuple[0];
+ Cat mother = (Cat) tuple[1];
+ ....
+}]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-scalar" revision="1">
+ <title>�X�J���[�̌���</title>
+
+ <para>
+ �N�G���ł́A <literal>select</literal> �߂ŃN���X�̃v���p�e�B��w��ł��܂��B
+ SQL�̏W������ĂԂ��Ƃ�ł��܂��B�v���p�e�B��W�����́A
+ �i�i����Ԃ̃G���e�B�e�B�ł͂Ȃ��j�u�X�J���[�l�v�ł���ƌ��Ȃ���܂��B </para>
+
+
+ <programlisting><![CDATA[Iterator results = sess.createQuery(
+ "select cat.color, min(cat.birthdate), count(cat) from Cat cat " +
+ "group by cat.color")
+ .list()
+ .iterator();
+
+while ( results.hasNext() ) {
+ Object[] row = (Object[]) results.next();
+ Color type = (Color) row[0];
+ Date oldest = (Date) row[1];
+ Integer count = (Integer) row[2];
+ .....
+}]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-parameters">
+ <title>�p�����[�^�̃o�C���h</title>
+
+ <para>
+ <literal>Query</literal>
+ �́A���O�t���̃p�����[�^��JDBC�X�^�C���� <literal>?</literal>
+ �p�����[�^�ɒl��o�C���h���邽�߂̃��\�b�h�����Ă��܂��B
+ <emphasis>JDBC�Ƃ͈Ⴂ�AHibernate�̓p�����[�^�Ƀ[������ԍ���U���Ă����܂��B</emphasis>
+ ���O�t���̃p�����[�^�Ƃ́A�N�G��������̂Ȃ��ɂ��� <literal>:name</literal> �`���̎��ʎq�ł��B
+ ���O�t���p�����[�^�̗��_�͎��̒ʂ�ł��B </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para> ���O�t���p�����[�^�́A�N�G��������ɓo�ꂷ�鏇�ԂƖ��W�ł� </para>
+ </listitem>
+ <listitem>
+ <para> �����N�G����ɕ�����o�ꂷ�邱�Ƃ��ł��܂� </para>
+ </listitem>
+ <listitem>
+ <para> �������g�������܂� </para>
+ </listitem>
+ </itemizedlist>
+
+
+ <programlisting><![CDATA[//named parameter (preferred)
+Query q = sess.createQuery("from DomesticCat cat where cat.name = :name");
+q.setString("name", "Fritz");
+Iterator cats = q.iterate();]]></programlisting>
+
+
+ <programlisting><![CDATA[//positional parameter
+Query q = sess.createQuery("from DomesticCat cat where cat.name = ?");
+q.setString(0, "Izi");
+Iterator cats = q.iterate();]]></programlisting>
+
+
+ <programlisting><![CDATA[//named parameter list
+List names = new ArrayList();
+names.add("Izi");
+names.add("Fritz");
+Query q = sess.createQuery("from DomesticCat cat where cat.name in (:namesList)");
+q.setParameterList("namesList", names);
+List cats = q.list();]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-pagination">
+ <title>�y�[�W����
+ </title>
+
+ <para>
+ ResultSet�ɐ����i�����������ő�s���╜���������ŏ��̍s�j�������K�v������A
+ �ȉ��̂悤�ɁA <literal>Query</literal> �C���^�[�t�F�C�X�̃��\�b�h��g���܂��B </para>
+
+
+ <programlisting><![CDATA[Query q = sess.createQuery("from DomesticCat cat");
+q.setFirstResult(20);
+q.setMaxResults(10);
+List cats = q.list();]]></programlisting>
+
+ <para> �����t���̃N�G����DBMS�̃l�C�e�B�u��SQL�ɕϊ�������@��AHibernate�͒m���Ă��܂��B
+ </para>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-scrolling">
+ <title>�X�N���[���\�ȃC�e���[�V����</title>
+
+ <para>
+ JDBC�h���C�o���X�N���[���\�� <literal>ResultSet</literal> ��T�|�[�g������A
+ <literal>Query</literal>
+ �C���^�[�t�F�C�X��g���āA <literal>ScrollableResults</literal> �I�u�W�F�N�g��
+ �擾�ł��܂��B�����g���ƁA�N�G���̌��ʂɑ��ď_��Ƀi�r�Q�[�V�����ł��܂��B </para>
+
+
+ <programlisting><![CDATA[Query q = sess.createQuery("select cat.name, cat from DomesticCat cat " +
+ "order by cat.name");
+ScrollableResults cats = q.scroll();
+if ( cats.first() ) {
+
+ // find the first name on each page of an alphabetical list of cats by name
+ firstNamesOfPages = new ArrayList();
+ do {
+ String name = cats.getString(0);
+ firstNamesOfPages.add(name);
+ }
+ while ( cats.scroll(PAGE_SIZE) );
+
+ // Now get the first page of cats
+ pageOfCats = new ArrayList();
+ cats.beforeFirst();
+ int i=0;
+ while( ( PAGE_SIZE > i++ ) && cats.next() ) pageOfCats.add( cats.get(1) );
+
+}
+cats.close()]]></programlisting>
+
+ <para>
+ ���̋@�\�ɂ̓I�[�v����Ԃ̃f�[�^�x�[�X�R�l�N�V�������K�v�ł��邱�Ƃɒ��ӂ��Ă��������B
+ ����A�I�t���C���̃y�[�W�����@�\���K�v�ł���A <literal>setMaxResult()</literal> /
+ <literal>setFirstResult()</literal> ��g���܂��傤�B </para>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-named" revision="1">
+ <title>���O�t���N�G���̊O�o��</title>
+
+ <para>
+ �}�b�s���O�h�L�������g�ɖ��O�t���̃N�G�����`���邱�Ƃ��ł��܂��B
+ �i�}�[�N�A�b�v�Ɖ�߂���镶�����N�G���Ɋ܂܂��Ȃ�A <literal>CDATA</literal> �Z�N�V������
+ �g�����Ƃ�Y��Ȃ��悤�ɂ��܂��傤�B�j </para>
+
+
+ <programlisting><![CDATA[<query name="ByNameAndMaximumWeight"><![CDATA[
+ from eg.DomesticCat as cat
+ where cat.name = ?
+ and cat.weight > ?
+] ]></query>]]></programlisting>
+
+ <para>�p�����[�^�̃o�C���f�B���O�Ǝ��s�́A�ȉ��̂悤�ȃv���O�����ōs���܂��B </para>
+
+
+ <programlisting><![CDATA[Query q = sess.getNamedQuery("ByNameAndMaximumWeight");
+q.setString(0, name);
+q.setInt(1, minWeight);
+List cats = q.list();]]></programlisting>
+
+ <para> ���ۂ̃v���O�����R�[�h�́A�g����N�G������Ɉˑ����Ă��Ȃ����Ƃɒ��ӂ��܂��傤�B
+ ���^�f�[�^�ɂ́A�l�C�e�B�uSQL�N�G�����`���邱�Ƃ�ł��܂��B �܂��A�����̃N�G����}�b�s���O�t�@�C���Ɉڂ����ƂŁA
+ Hibernate�Ɉڍs���邱�Ƃ�ł��܂��B </para>
+ <para>
+ <literal><hibernate-mapping></literal> �̒��̃N�G����`�́A�N�G���ɑ���
+ ���j�[�N�Ȗ��O���K�v�Ȃ��Ƃɂ���ӂ��Ă��������B����ɑ��āA <literal><class></literal> �̒���
+ �N�G����`�́A�N���X�̊��S���薼���O�ɕt������̂ŁA�����I�Ƀ��j�[�N�Ȗ��O�ɂȂ�܂��B
+ ��F <literal>eg.Cat.ByNameAndMaximumWeight</literal>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="objectstate-filtering" revision="1">
+ <title>�R���N�V�����̃t�B���^�����O</title>
+ <para> �R���N�V���� <emphasis>�t�B���^</emphasis> �́A�i��������Ă���R���N�V������z��ɓK�p�����
+ ����ȃ^�C�v�̃N�G���ł��B���̃N�G��������ł́A�R���N�V�����̂��̎��_�ł̗v�f��Ӗ�����
+ <literal>this</literal> ��g���܂��B </para>
+
+
+ <programlisting><![CDATA[Collection blackKittens = session.createFilter(
+ pk.getKittens(),
+ "where this.color = ?")
+ .setParameter( Color.BLACK, Hibernate.custom(ColorUserType.class) )
+ .list()
+);]]></programlisting>
+
+ <para> �Ԃ����R���N�V������Bag�Ƃ݂Ȃ���܂��B�����āA����͂�Ƃ̃R���N�V�����̃R�s�[�ɂȂ�܂��B
+ ���̃R���N�V�����͏C������܂���i����́A"filter"�Ƃ������O�̈Ӗ��Ƃ͈قȂ�܂����A ���҂���铮���Ƃ͈�v���Ă��܂��j�B
+ </para>
+
+ <para> �t�B���^�ɂ� <literal>from</literal>
+ �߂��s�v�ł��邱�ƂɋC�Â��ł��傤�i�K�v�Ȃ�A�����Ƃ�\�ł����j�B �t�B���^�́A�R���N�V�����̗v�f���̂�Ԃ��č\���܂���B
+ </para>
+
+
+ <programlisting><![CDATA[Collection blackKittenMates = session.createFilter(
+ pk.getKittens(),
+ "select this.mate where this.color = eg.Color.BLACK.intValue")
+ .list();]]></programlisting>
+
+ <para> �N�G����܂܂Ȃ��t�B���^���ɗ����܂��B
+ �Ⴆ�A���ɑ傫�ȃR���N�V�����̕����W�����[�h���邽�߂Ɏg���܂��B </para>
+
+
+ <programlisting><![CDATA[Collection tenKittens = session.createFilter(
+ mother.getKittens(), "")
+ .setFirstResult(0).setMaxResults(10)
+ .list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="objecstate-querying-criteria" revision="1">
+ <title>�N���C�e���A�̃N�G��</title>
+
+ <para> HQL�͔��ɋ��͂ł����A�N�G��������������A�I�u�W�F�N�g�w����API��g����
+ ���I�ɃN�G���������D�ފJ���҂���܂��B �����������ꍇ�̂��߂ɁAHibernate�͒����I��
+ <literal>Criteria</literal> �N�G��API����Ă��܂��B </para>
+
+
+ <programlisting><![CDATA[Criteria crit = session.createCriteria(Cat.class);
+crit.add( Restrictions.eq( "color", eg.Color.BLACK ) );
+crit.setMaxResults(10);
+List cats = crit.list();]]></programlisting>
+
+ <para> <literal>Criteria</literal> ��
+ <literal>Example</literal> API�̏ڍׂ́A <xref linkend="querycriteria"/>
+ �ɏq�ׂ��Ă��܂��B </para>
+
+ </sect2>
+
+ <sect2 id="objectstate-querying-nativesql" revision="2">
+ <title>�l�C�e�B�uSQL�̃N�G��</title>
+
+ <para>
+ <literal>createSQLQuery()</literal> ��g���āASQL�ŃN�G����\�����邱�Ƃ�ł��܂��B
+ �����āAHibernate�ɁAResultSet ����I�u�W�F�N�g�ւ̃}�b�s���O��܂����܂��B
+ <literal>session.connection()</literal> ��Ăׂǂ�ȂƂ��ł�A���ځAJDBC
+ <literal>Connection</literal> ��g�p�ł��邱�Ƃ�o���Ă����܂��傤�B ����AHibernate
+ API��g���̂ł���A���L�̂悤��SQL�̕ʖ����ʂł�����Ȃ���Ȃ�܂���B </para>
+
+ <programlisting><![CDATA[List cats = session.createSQLQuery("SELECT {cat.*} FROM CAT {cat} WHERE ROWNUM<10")
+ .addEntity("cat", Cat.class)
+.list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = session.createSQLQuery(
+ "SELECT {cat}.ID AS {cat.id}, {cat}.SEX AS {cat.sex}, " +
+ "{cat}.MATE AS {cat.mate}, {cat}.SUBCLASS AS {cat.class}, ... " +
+ "FROM CAT {cat} WHERE ROWNUM<10")
+ .addEntity("cat", Cat.class)
+.list()]]></programlisting>
+
+ <para>
+ SQL�N�G���́AHibernate�N�G���Ɠ����悤�ɁA���O�t���̃p�����[�^�ƈʒu�p�����[�^�����Ƃ��ł��܂��B
+ Hibernate�ɂ�����l�C�e�B�u��SQL�N�G���̏ڍׂɂ��ẮA <xref linkend="querysql"/>
+ ��Q�Ƃ��Ă��������B </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="objectstate-modifying" revision="1">
+ <title>�i���I�u�W�F�N�g�̏C��</title>
+
+ <para>
+ <emphasis>�������̉i���C���X�^���X</emphasis>
+ �i��F <literal>Session</literal> �ɂ���āA
+ ���[�h�A�Z�[�u�A�쐬�A�N�G�����ꂽ�I�u�W�F�N�g�j�́A�A�v���P�[�V�����ɑ��삳��܂��B
+ ���̍ۂɕύX���ꂽ�i����Ԃ́A <literal>Session</literal> �� <emphasis>�t���b�V��</emphasis>
+ �����Ƃ��ɁA�i��������܂��i����́A���̏͂̌㔼�ŏq�ׂĂ��܂��j�B
+ �ύX��i�������邽�߂ɁA����ȃ��\�b�h�i <literal>update()</literal>
+ �̂悤�Ȃ�́B����́A�ʂ̖ړI�Ŏg�p���܂��j�� �ĂԕK�v�͂���܂���B �I�u�W�F�N�g�̏�Ԃ�X�V�����ԊȒP�ȕ��@�́A�I�u�W�F�N�g��
+ <literal>load()</literal> ���A <literal>Session</literal>
+ ��I�[�v���ɂ��Ă���ԂɁA���ڑ��삷�邱�Ƃł��B </para>
+
+
+ <programlisting><![CDATA[DomesticCat cat = (DomesticCat) sess.load( Cat.class, new Long(69) );
+cat.setName("PK");
+sess.flush(); // changes to cat are automatically detected and persisted
+]]></programlisting>
+
+ <para>
+ �i�I�u�W�F�N�g���[�h���邽�߂́jSQL�� <literal>SELECT</literal> �Ɓi�X�V���ꂽ��Ԃ�i�������邽�߂́j
+ SQL�� <literal>UPDATE</literal> �������Z�b�V�����ŕK�v�ƂȂ�̂ŁA���̃v���O���~���O���f���́A
+ �����������Ȃ�ꍇ������܂��B
+ ���̂��߁AHibernate�͕ʂ̕��@��p�ӂ��Ă��܂��B����́A�C���X�^���X������idetached�j���@�ł��B </para>
+
+ <para>
+ <emphasis>Hibernate�́A <literal>UPDATE</literal> ����
+ <literal>DELETE</literal> ���ڎ��s����API��p�ӂ��Ă��܂���B
+ Hibernate�́A <emphasis>��ԊǗ�</emphasis> �T�[�r�X�ł���A�g����SQL
+ <emphasis>��</emphasis> �̂��Ƃ�J���҂��l����K�v�͂���܂���B
+ JDBC��SQL������s���銮����API�ł���A <literal>session.connection()</literal>
+ ��ĂԂ��Ƃ� ���ł�AJDBC <literal>Connection</literal> ��J���҂͎擾�ł��܂��B
+ ����ɁA��ʂ̃f�[�^����̍l�����́A�I�����C���g�����U�N�V�������������A�v���P�[�V������
+ �I�u�W�F�N�g/�����[�V���i���}�b�s���O�ƏՓ˂��܂��B
+ �������AHibernate�̍���̃o�[�W�����ł́A��ʃf�[�^����������ʂȋ@�\����邩�����܂���B
+ �o�b�`����ɗ��p�ł��邢�����̍H�v�ɂ��ẮA <xref linkend="batch"/> ��Q�Ƃ��Ă��������B </emphasis>
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-detached" revision="2">
+ <title>�����I�u�W�F�N�g�̏C��</title>
+
+ <para>
+ �����̃A�v���P�[�V�����ł͎��̂��Ƃ��K�v�ɂȂ�܂��B
+ ����́A����g�����U�N�V�����ŃI�u�W�F�N�g�����A���삷�邽�߂ɂ����UI�w�ɑ���A
+ ���̌�ɁA�V�����g�����U�N�V�����ŕύX��Z�[�u����Ƃ��������Ƃł��B
+ ���s���̍������ŁA���̃^�C�v�̃A�v���[�`��g���A�v���P�[�V�����ł́A "���Ԃ̒���"
+ ��ƒP�ʂ̊u������ۏ��邽�߂ɁA�o�[�W�����f�[�^���ʏ�g���܂��B </para>
+
+ <para>
+ Hibernate�́A <literal>Session.update()</literal> ��
+ <literal>Session.merge()</literal> ���\�b�h��
+ �g���āA�����C���X�^���X��Ēlj����邱�ƂŁA���̃��f���ɑΉ����܂��B </para>
+
+
+ <programlisting><![CDATA[// in the first session
+Cat cat = (Cat) firstSession.load(Cat.class, catId);
+Cat potentialMate = new Cat();
+firstSession.save(potentialMate);
+
+// in a higher layer of the application
+cat.setMate(potentialMate);
+
+// later, in a new session
+secondSession.update(cat); // update cat
+secondSession.update(mate); // update mate]]></programlisting>
+
+ <para>
+ ���ʎq<literal>catId</literal> ���� <literal>Cat</literal> ���A����
+ <literal>secondSession</literal> �Ń��[�h����Ă����ꍇ�́A�Ēlj����悤�Ƃ����Ƃ��ɁA��O���������܂��B
+ </para>
+
+ <para>
+ �������ʎq���i���C���X�^���X��Z�b�V���������ɕێ����Ă��Ȃ����Ƃ�
+ �m�M�ł���Ȃ� <literal>update()</literal> ��g���܂��傤�B
+ �����āA�Z�b�V�����̏�Ԃ�l�����ɁA�ǂ�ȏꍇ�ł�ύX��}�[�W�������ꍇ�́A <literal>merge()</literal>
+ ��g���܂��傤�B ���Ȃ킿�A�����I�u�W�F�N�g�̍Ēlj����삪�A�ŏ��Ɏ��s����邱�Ƃ�m���ɂ��邽�߂ɁA �ʏ��
+ <literal>update()</literal> ���V�����Z�b�V�����̂Ȃ��ōŏ��ɌĂ�郁�\�b�h�ɂȂ�܂��B </para>
+
+ <para>
+ �����C���X�^���X���瓞�B�\�ȁA�����C���X�^���X��A�v���P�[�V�����͌ʂ� <literal>update()</literal>
+ ���ׂ��ł��B����́A���̏�Ԃ�X�V�������ꍇ�� <emphasis>����</emphasis> �܂��B
+ <emphasis>�J�ړI�ȉi����</emphasis> ��g���A���������ł��܂��B <xref
+ linkend="objectstate-transitive"/> ��Q�Ƃ��Ă��������B </para>
+
+ <para>
+ ���\�b�h�ł�܂��A�V�����Z�b�V�����ɃI�u�W�F�N�g��Ċ֘A�t���ł��܂��B �������A�����C���X�^���X�͖��C���łȂ���Ȃ�܂���B
+ </para>
+
+
+ <programlisting><![CDATA[//just reassociate:
+sess.lock(fritz, LockMode.NONE);
+//do a version check, then reassociate:
+sess.lock(izi, LockMode.READ);
+//do a version check, using SELECT ... FOR UPDATE, then reassociate:
+sess.lock(pk, LockMode.UPGRADE);]]></programlisting>
+
+ <para>
+ <literal>lock()</literal> �́A���܂��܂�
+ <literal>LockMode</literal> �ƂƂ�Ɏg�����Ƃ��ł��܂��B
+ �ڍׂ́AAPI�h�L�������g�ƃg�����U�N�V���������̏͂�Q�Ƃ��Ă��������B
+ �Ēlj��̂Ƃ��ɂ����A <literal>lock()</literal> ���g����킯�ł͂���܂���B </para>
+
+ <para>
+ ���Ԃ̒�����ƒP�ʂ́A���̑��̃��f���́A<xref linked="transactions-optimistic"/> �ŏq�ׂĂ��܂��B </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-saveorupdate">
+ <title>�����I�ȏ�Ԍ��o</title>
+
+ <para>
+ Hibernate�̃��[�U�͎���2�̃P�[�X�̂ǂ���ɂ�g����ėp�I�ȃ��\�b�h��v�����Ă��܂����B
+ ����́A�V�������ʎq�����Ĉꎞ�I�ȃC���X�^���X��Z�[�u���邱�ƂƁA
+ ���̎��_�̎��ʎq�Ɗ֘A�Â��Ă��镪���C���X�^���X��X�V/�Ēlj����邱�Ƃ̂ł��郁�\�b�h�ł��B
+ <literal>saveOrUpdate()</literal> �͂��̂悤�ȋ@�\������������\�b�h�ł��B </para>
+
+
+ <programlisting><![CDATA[// in the first session
+Cat cat = (Cat) firstSession.load(Cat.class, catID);
+
+// in a higher tier of the application
+Cat mate = new Cat();
+cat.setMate(mate);
+
+// later, in a new session
+secondSession.saveOrUpdate(cat); // update existing state (cat has a non-null id)
+secondSession.saveOrUpdate(mate); // save the new instance (mate has a null id)]]></programlisting>
+
+ <para>
+ <literal>saveOrUpdate()</literal> �̎g�p���@�ƈӖ��́A
+ �V�������[�U�ɂƂ��č��������������܂���B
+ �܂����ɁA����Z�b�V�����Ŏg�p�����C���X�^���X��ʂ̐V�����Z�b�V�����Ŏg�����Ƃ��Ȃ�����A
+ <literal>update()</literal> �� <literal>saveOrUpdate()</literal> ��
+ <literal>merge()</literal> ��g���K�v�͂���܂���B
+ �A�v���P�[�V�����S�̂�ʂ��āA�����̃��\�b�h��S���g��Ȃ����Ƃ����܂��B </para>
+
+ <para>
+ �ʏ�A <literal>update()</literal> �� <literal>saveOrUpdate()</literal>
+ �͎��̃V�i���I�� �g���܂��B </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>�A�v���P�[�V�������ŏ��̃Z�b�V�����ŃI�u�W�F�N�g���[�h���܂��B </para>
+ </listitem>
+ <listitem>
+ <para>�I�u�W�F�N�g��UI�w�ɑ����܂��B </para>
+ </listitem>
+ <listitem>
+ <para>�I�u�W�F�N�g�ɑ��ĕύX���������܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para> �I�u�W�F�N�g���r�W�l�X���W�b�N�w�ɑ����܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ �A�v���P�[�V�����́A2�Ԗڂ̃Z�b�V������ <literal>update()</literal>
+ ��ĂԂ��ƂŁA�����̕ύX��i�������܂��B </para>
+ </listitem>
+ </itemizedlist>
+
+ <para> <literal>saveOrUpdate()</literal> �͈ȉ��̂��Ƃ�s���܂��B </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>�I�u�W�F�N�g�����̃Z�b�V�����ŁA���łɉi��������Ă���A������܂���B </para>
+ </listitem>
+ <listitem>
+ <para>
+ ���̃Z�b�V�����Ɋ֘A�Â��Ă���ʂ̃I�u�W�F�N�g���������ʎq�����Ă���Ȃ�A ��O�𓊂��܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ �I�u�W�F�N�g�̎��ʎq���l�����Ȃ��Ȃ�A <literal>save()</literal> ���܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ �I�u�W�F�N�g�̎��ʎq���l�����A���̒l���V���ɃC���X�^���X�����ꂽ�I�u�W�F�N�g�̂��߂̒l�ł���ꍇ�A ���̃I�u�W�F�N�g��
+ <literal>save()</literal> ���܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ �I�u�W�F�N�g���i <literal><version></literal> ��
+ <literal><timestamp></literal> �ɂ���āj
+ �o�[�W�����Â�����Ă��āA�o�[�W�����̃v���p�e�B���l�����A
+ ���̒l���V�����C���X�^���X�����ꂽ�I�u�W�F�N�g�̂��߂̒l�ł���ꍇ�A ���̃I�u�W�F�N�g��
+ <literal>save()</literal> ���܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ �����łȂ��ꍇ�́A���̃I�u�W�F�N�g�� <literal>update()</literal> ���܂��B </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ �����āA <literal>merge()</literal> �͈ȉ��̂悤�ɂƂĂ�قȂ�܂��B </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ �������ʎq���i�����C���X�^���X�����̎��_�ŃZ�b�V�����Ɗ֘A�t���Ă���Ȃ�A
+ �����Ŏ�����I�u�W�F�N�g�̏�Ԃ�i�����C���X�^���X�ɃR�s�[���܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ �i�����C���X�^���X�����̎��_�ŃZ�b�V�����Ɋ֘A�t���Ă��Ȃ��Ȃ�A
+ �f�[�^�x�[�X���炻����[�h���邩�A���邢�́A�V�����i�����C���X�^���X��쐬���܂��B </para>
+ </listitem>
+ <listitem>
+ <para>�i�����C���X�^���X���Ԃ���܂��B </para>
+ </listitem>
+ <listitem>
+ <para> �����Ƃ��ė^�����C���X�^���X�̓Z�b�V�����Ɗ֘A�����܂���B ����́A������Ԃ̂܂܂ł��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 id="objectstate-deleting" revision="1">
+ <title>�i���I�u�W�F�N�g�̍폜</title>
+
+ <para>
+ <literal>Session.delete()</literal>
+ �̓I�u�W�F�N�g�̏�Ԃ�f�[�^�x�[�X����폜���܂��B ������A�폜�����I�u�W�F�N�g��A�v���P�[�V�������ێ������܂܂ł�悢�ł��B
+ ���̂��߁A <literal>delete()</literal> �͉i���C���X�^���X��ꎞ�I�ɂ����̂ƍl����̂���Ԃł��B </para>
+
+ <programlisting><![CDATA[sess.delete(cat);]]></programlisting>
+
+ <para>
+ �O���L�[����Ɉᔽ���郊�X�N��Ȃ��A�D���ȏ��ԂŃI�u�W�F�N�g��폜���邱�Ƃ��ł��܂��B
+ �������A�Ԉ�������ԂŃI�u�W�F�N�g��폜����ƁA�O���L�[�J������ <literal>NOT NULL</literal>
+ ����Ɉᔽ����\��������܂��B �Ⴆ�A�e�I�u�W�F�N�g��폜�����Ƃ��ɁA�q���I�u�W�F�N�g��폜���Y�ꂽ�ꍇ�ł��B </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-replicating" revision="1">
+ <title>�قȂ��̃f�[�^�X�g�A�Ԃł̃I�u�W�F�N�g�̃��v���P�[�V����</title>
+
+ <para>
+ �i���C���X�^���X�̃O���t��ʂ̃f�[�^�X�g�A�ɉi��������ꍇ�ɁA
+ ���ʎq�̒l��Đ��������ɂ��ނƕ֗��ȏꍇ������܂��B </para>
+
+
+ <programlisting><![CDATA[//retrieve a cat from one database
+Session session1 = factory1.openSession();
+Transaction tx1 = session1.beginTransaction();
+Cat cat = session1.get(Cat.class, catId);
+tx1.commit();
+session1.close();
+
+//reconcile with a second database
+Session session2 = factory2.openSession();
+Transaction tx2 = session2.beginTransaction();
+session2.replicate(cat, ReplicationMode.LATEST_VERSION);
+tx2.commit();
+session2.close();]]></programlisting>
+
+ <para>
+ ���v���P�[�V������̃f�[�^�x�[�X�ɍs�����ɂ���ꍇ�A <literal>replicate()</literal>
+ ���Փ˂�ǂ̂悤�Ɉ������� <literal>ReplicationMode</literal> �Ŏw�肵�܂��B </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>ReplicationMode.IGNORE</literal> -
+ �������ʎq���s���f�[�^�x�[�X�ɑ��݂���Ȃ�A ���̃I�u�W�F�N�g�����܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.OVERWRITE</literal> - �������ʎq�������̍s��
+ ���ׂď㏑�����܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.EXCEPTION</literal> -
+ �������ʎq���s���f�[�^�x�[�X�ɑ��݂���Ȃ�A ��O�𓊂��܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.LATEST_VERSION</literal> -
+ �s�ɕۑ�����Ă���o�[�W�����ԍ����A �����̃I�u�W�F�N�g�̃o�[�W�����ԍ����Â��Ȃ�A���̍s��㏑�����܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ���̂悤�ȃP�[�X�ŁA���̋@�\��g�p���܂��B �قȂ�f�[�^�x�[�X�C���X�^���X�ɓ����ꂽ�f�[�^�̓����A
+ ���i�X�V���ɂ�����V�X�e���ݒ���̍X�V�A��ACID�g�����U�N�V�����̂Ȃ��ʼn�����ꂽ�ύX�̃��[���o�b�N�Ȃǂł��B </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-flushing">
+ <title>�Z�b�V�����̃t���b�V��</title>
+
+ <para>
+ JDBC�R�l�N�V�����̏�Ԃƃ�������̃I�u�W�F�N�g�̏�Ԃ������邽�߂ɕK�v��
+ SQL���� <literal>Session</literal> �����s���邱�Ƃ��Ƃ��ǂ�����܂��B ���̏���
+ <emphasis>flush</emphasis> �́A�f�t�H���g�ł͎��̂Ƃ��ɋN����܂��B </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para> �N�G������s����O </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>org.hibernate.Transaction.commit()</literal> ����s�����Ƃ�
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.flush()</literal> ����s�����Ƃ� </para>
+ </listitem>
+ </itemizedlist>
+
+ <para> SQL���͈ȉ��̏��ԂŔ��s����܂��B
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ ���ׂẴG���e�B�e�B�̑}���B����́A <literal>Session.save()</literal> ��g���ăZ�[�u����
+ �I�u�W�F�N�g�̏��Ɏ��s���Ă����܂��B </para>
+ </listitem>
+ <listitem>
+ <para> ���ׂẴG���e�B�e�B�̍X�V </para>
+ </listitem>
+ <listitem>
+ <para> ���ׂẴR���N�V�����̍폜 </para>
+ </listitem>
+ <listitem>
+ <para>
+ ���ׂẴR���N�V�����̗v�f�ɑ���폜�A�X�V�A�}�� </para>
+ </listitem>
+ <listitem>
+ <para>���ׂẴR���N�V�����̑}�� </para>
+ </listitem>
+ <listitem>
+ <para>
+ ���ׂẴG���e�B�e�B�̍폜�B����́A<literal>Session.delete()</literal> ��g����
+ �폜�����I�u�W�F�N�g�̏��Ɏ��s���Ă����܂��B </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ (�P��O������܂��B <literal>native</literal> ID ������g�����I�u�W�F�N�g�́A
+ ����炪�Z�[�u���ꂽ�Ƃ��ɑ}������܂��B�j </para>
+
+ <para>
+ �����I��
+ <literal>flush()</literal> ����Ƃ������āA <emphasis>����</emphasis>
+ <literal>Session</literal> ��JDBC��R�[������̂��ɂ���
+ ��ΓI�ȕۏ͂���܂���B�������A����炪���s����� <emphasis>����</emphasis> ������ �ۏ���܂��B
+ �܂��AHibernate �́A <literal>Query.list(..)</literal> ���Â��f�[�^��Ԉ�����f�[�^�Ԃ��Ȃ����Ƃ�
+ �ۏ��Ă��܂��B </para>
+
+ <para>
+ �t���b�V�����p�ɂɋN����Ȃ��悤�Ƀf�t�H���g�̐U�镑����ς��邱�Ƃ��ł��܂��B <literal>FlushMode</literal>
+ �N���X��3�̈قȂ郂�[�h���`���܂��B ����́A�R�~�b�g���ɂ����t���b�V�����郂�[�h �iHibernate��
+ <literal>Transaction</literal> API���g����ꍇ�����ł��j�A
+ ����̂������������Ɋ�Â��Ď����Ńt���b�V�����郂�[�h�A <literal>flush()</literal>
+ �������I�ɌĂ�Ȃ�����t���b�V�����Ȃ����[�h�̂R�ł��B �Ō�̃��[�h�́A��ƒP�ʂ������Ԃɋy�ԏꍇ�ɖ�ɗ����܂� ( <xref
+ linkend="transactions-optimistic-longsession"/> ��Q�Ƃ��Ă�������)�B
+ </para>
+
+
+ <programlisting><![CDATA[sess = sf.openSession();
+Transaction tx = sess.beginTransaction();
+sess.setFlushMode(FlushMode.COMMIT); // allow queries to return stale state
+
+Cat izi = (Cat) sess.load(Cat.class, id);
+izi.setName(iznizi);
+
+// might return stale data
+sess.find("from Cat as cat left outer join cat.kittens kitten");
+
+// change to izi is not flushed!
+...
+tx.commit(); // flush occurs
+sess.close();]]></programlisting>
+
+ <para>�t���b�V���̂Ƃ��A��O���������邩�����܂���B
+ �i�Ⴆ�ADML���삪�����ᔽ����悤�ȏꍇ�ł��B�j
+ ��O�����𗝉��邽�߂ɂ́AHibernate�̃g�����U�N�V�����̐U�镑���𗝉���K�v�����邽�߁A <xref
+ linkend="transactions"/> �Ő�����܂��B </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-transitive" revision="1">
+ <title>�A���I�ȉi����</title>
+
+ <para>
+ �X�̃I�u�W�F�N�g��Z�[�u������A�폜������A�Ēlj������肷�邱�Ƃ�
+ ���Ȃ�ʓ|�ł��B���ɁA�֘A����I�u�W�F�N�g�����悤�ȏꍇ�ɂ͍ۗ����܂��B �悭����̂́A�e�q�W�����P�[�X�ł��B
+ �ȉ��̗��l���Ă݂܂��傤�B </para>
+
+ <para>
+ ����A�e�q�W�̎q���l�^�Ȃ�i�Ⴆ�A�Z���╶����̃R���N�V�����j�A
+ �����̃��C�t�T�C�N���͐e�Ɉˑ����Ă���A�֗��ȏ�ԕω���"�J�X�P�[�h"��g�����߂ɁA �lj��̍�Ƃ͕K�v�͂���܂���B
+ �e���Z�[�u���ꂽ�Ƃ��A�l�^�̎q�I�u�W�F�N�g������悤�ɃZ�[�u����܂����A �e���폜���ꂽ�Ƃ��́A�q��폜����܂��B���̑��̑��������ł��B
+ �R���N�V��������1�̎q��폜����悤�ȑ���ł���܂������܂��B ���Ȃ킿�AHibernate�͂��̍폜������o����ƁA
+ �l�^�̃I�u�W�F�N�g�͎Q�Ƃ��L�ł��Ȃ��̂ŁA�f�[�^�x�[�X���炻�̎q����폜���܂��B </para>
+
+ <para>�����ŁA�e�Ǝq���l�^�łȂ��G���e�B�e�B�ł���Ƃ��ē����V�i���I��l���Ă݂܂��傤�B
+ �i�Ⴆ�A�J�e�S���[�ƕi�ڂ̊W��e�Ǝq�̔L�̊W�ł��B�j �G���e�B�e�B�́A���ꎩ�g�����C�t�T�C�N�������A�Q�Ƃ̋��L��T�|�[�g���܂��B
+ �i���̂��߁A�R���N�V��������G���e�B�e�B��폜���邱�Ƃ́A �G���e�B�e�B���g�̍폜��Ӗ����܂���B�j
+ �܂��A�G���e�B�e�B�́A�f�t�H���g�ł́A�֘A���鑼�̃G���e�B�e�B�� ��Ԃ�J�X�P�[�h���邱�Ƃ͂���܂���B Hibernate��
+ <emphasis>���B�\���ɂ��i����</emphasis> ��f�t�H���g�ł͎��s���܂���B </para>
+
+ <para>
+ Hibernate��Session�̊�{����i <literal>persist(), merge(), saveOrUpdate(),
+ delete(), lock(), refresh(), evict(), replicate()</literal> ���܂܂�܂��j�ɑ��āA
+ ���ꂼ��ɑΉ�����J�X�P�[�h�X�^�C��������܂��B ���ꂼ��̃J�X�P�[�h�X�^�C���ɂ́A <literal>create, merge,
+ save-update, delete, lock, refresh, evict, replicate</literal>
+ �Ƃ������O�����Ă��܂��B ����A�֘A�ɉ����ăJ�X�P�[�h�����������삪����Ȃ�A�}�b�s���O�t�@�C���ɂ����w�肵�Ȃ���Ȃ�܂���B
+ �Ⴆ�A�ȉ��̂悤�ɂ��܂��B </para>
+
+
+ <programlisting><![CDATA[<one-to-one name="person" cascade="persist"/>]]></programlisting>
+
+ <para> �J�X�P�[�h�X�^�C���́A�g�ݍ��킹�邱�Ƃ��ł��܂��B </para>
+
+
+ <programlisting><![CDATA[<one-to-one name="person" cascade="persist,delete,lock"/>]]></programlisting>
+
+ <para>
+ <emphasis>���ׂĂ�</emphasis>
+ �����֘A�ɉ����ăJ�X�P�[�h����悤�w�肷��Ƃ��́A <literal>cascade="all"</literal> ��g���܂��B
+ �f�t�H���g�� <literal>cascade="none"</literal> �́A�ǂ̑����J�X�P�[�h���Ȃ����Ƃ�Ӗ����܂��B
+ </para>
+
+ <para>
+ ����ȃJ�X�P�[�h�X�^�C��
+ <literal>delete-orphan</literal> �́A��Α��֘A�ɂ��� �K�p�ł��܂��B
+ ����́A�֘A����폜���ꂽ�q���̃I�u�W�F�N�g�ɑ��āA <literal>delete()</literal>
+ ���삪�K�p����邱�Ƃ�Ӗ����܂��B </para>
+
+ <para>�������߁F </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ ���ʁA <literal><many-to-one></literal> ��
+ <literal><many-to-many></literal> �֘A�ɑ��ẮA
+ �J�X�P�[�h��ݒ肷��Ӗ��͂���܂���B <literal><one-to-one></literal> ��
+ <literal><one-to-many></literal> �֘A�ɑ��ẮA
+ �J�X�P�[�h����ɗ����Ƃ�����܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ �q���I�u�W�F�N�g�̎������e�I�u�W�F�N�g�̎����ɐ������Ȃ�A
+ <literal>cascade="all,delete-orphan"</literal> ��w�肵�A �q���I�u�W�F�N�g��
+ <emphasis>���C�t�T�C�N���I�u�W�F�N�g</emphasis> �ɂ��܂��B </para>
+ </listitem>
+ <listitem>
+ <para> .
+ ����ȊO�̏ꍇ�́A�J�X�P�[�h�͂قƂ�ǕK�v�Ȃ��ł��傤�B
+ �������A�����g�����U�N�V�����̂Ȃ��Őe�Ǝq���ꏏ�ɓ��삷�邱�Ƃ������Ǝv���A
+ �����炩�̃R�[�h������Ԃ�Ȃ������̂ł���A
+ <literal>cascade="persist,merge,save-update"</literal>
+ ��g�����Ƃ�l���܂��傤�B </para>
+ </listitem>
+ </itemizedlist>
+
+ <para> <literal>cascade="all"</literal> �Ń}�b�s���O�����֘A�i�P�l�֘A��R���N�V�����j�́A
+ <emphasis>�e�q</emphasis> �X�^�C���̊֘A�ƃ}�[�N����܂��B
+ ����́A�e�̃Z�[�u/�X�V/�폜���A�q�̃Z�[�u/�X�V/�폜������N�����W�̂��Ƃł��B </para>
+
+ <para>
+ ����ɁA�i�������ꂽ�e���q��P�ɎQ�Ƃ��Ă��邾���ŁA�q�̃Z�[�u/�X�V������N�����܂��B
+ �������A���̃��^�t�@�[�͕s���S�ł��B�e����Q�Ƃ���Ȃ��Ȃ����q�́A�����I�ɍ폜 <emphasis>����܂���</emphasis> �B
+ �������A <literal>cascade="delete-orphan"</literal> �Ń}�b�s���O���ꂽ
+ <literal><one-to-many></literal> �֘A�� �����Ăł��B
+ �e�q�W�̃J�X�P�[�h����̐��m�ȈӖ��͈ȉ��̂悤�ɂȂ�܂��B </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ �e��
+ <literal>persist()</literal> �ɓn���ꂽ�Ȃ�A ���ׂĂ̎q��
+ <literal>persist()</literal> �ɓn����܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>merge()</literal> �ɓn���ꂽ�Ȃ�A ���ׂĂ̎q��
+ <literal>merge()</literal> �ɓn����܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ �e�� <literal>save()</literal>
+ �A <literal>update()</literal>
+ �A <literal>saveOrUpdate()</literal> �ɓn���ꂽ�Ȃ�A���ׂĂ̎q��
+ <literal>saveOrUpdate()</literal> �ɓn����܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ �ꎞ�I�܂��͕�����Ԃ̎q���A�i�������ꂽ�e�ɎQ�Ƃ��ꂽ�Ȃ�A
+ <literal>saveOrUpdate()</literal> �ɓn����܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ �e���폜���ꂽ�Ȃ�A���ׂĂ̎q�́A <literal>delete()</literal> �ɓn����܂��B </para>
+ </listitem>
+ <listitem>
+ <para>
+ �q���i�������ꂽ�e����Q�Ƃ���Ȃ��Ȃ����Ƃ��́A <emphasis>���ɉ���N����܂���</emphasis> �B
+ ����āA�A�v���P�[�V�������K�v�ł���A�����I�ɍ폜����K�v������܂��B
+ �������A <literal>cascade="delete-orphan"</literal> �̏ꍇ�����܂��B
+ ���̏ꍇ�A�u�e�̂Ȃ��v�q�͍폜����܂��B </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ �Ō�ɁA����̃J�X�P�[�h���I�u�W�F�N�g�O���t�ɓK�p�����̂́A <emphasis>�R�[��������</emphasis>
+ ���邢�́A <emphasis>flush������</emphasis> �ł��邱�Ƃɒ��ӂ��Ă��������B
+ ���ׂĂ̑���́A���̑��삪���s���ꂽ�Ƃ��ɁA���B�\�Ȋ֘A����G���e�B�e�B�ɑ���
+ �J�X�P�[�h���\�Ȃ�J�X�P�[�h���܂��B
+ �������A <literal>save-upate</literal> ��
+ <literal>delete-orphan</literal> �́A <literal>Session</literal>
+ ��flush���Ă���ԂɁA ���ׂĂ̓��B�\�Ȋ֘A����G���e�B�e�B�ɓ`�d���܂��B</para>
+ </sect1>
+
+ <sect1 id="objectstate-metadata">
+ <title>���^�f�[�^�̎g�p</title>
+
+ <para>
+ Hibernate�́A���ׂẴG���e�B�e�B�ƒl�^�̔��Ƀ��b�`�ȃ��^���x���̃��f����K�v�Ƃ��܂��B
+ �Ƃ��ǂ��A���̃��f���̓A�v���P�[�V�����ɂƂ��ĂƂĂ��ɗ����܂��B
+ �Ⴆ�A�A�v���P�[�V�����́AHibernate�̃��^�f�[�^��g���āA"����" �f�B�[�v�R�s�[�A���S���Y����
+ �����ł��邩����܂���B���̃A���S���Y���Ƃ́A�ǂ̃I�u�W�F�N�g���R�s�[�����ׂ����i��F�ς̒l�^�j��
+ �ǂ̃I�u�W�F�N�g�̓R�s�[����Ȃ��ׂ����i��F�s�ςȒl�^��\�Ȃ�֘A����G���e�B�e�B�j�� ���f�ł����̂ł��B </para>
+
+
+ <para>
+ Hibernate��<literal>ClassMetadata</literal>
+ ��<literal>CollectionMetadata</literal> �C���^�t�F�[�X��
+ <literal>Type</literal> �K�w��ʂ��ă��^�f�[�^����J���܂��B
+ ���^�f�[�^�C���^�[�t�F�C�X�̃C���X�^���X�́A <literal>SessionFactory</literal> ���瓾���܂��B
+ </para>
+
+
+ <programlisting><![CDATA[Cat fritz = ......;
+ClassMetadata catMeta = sessionfactory.getClassMetadata(Cat.class);
+
+Object[] propertyValues = catMeta.getPropertyValues(fritz);
+String[] propertyNames = catMeta.getPropertyNames();
+Type[] propertyTypes = catMeta.getPropertyTypes();
+
+// get a Map of all properties which are not collections or associations
+Map namedValues = new HashMap();
+for ( int i=0; i<propertyNames.length; i++ ) {
+ if ( !propertyTypes[i].isEntityType() && !propertyTypes[i].isCollectionType() ) {
+ namedValues.put( propertyNames[i], propertyValues[i] );
+ }
+}]]></programlisting>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/toolset_guide.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/toolset_guide.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/toolset_guide.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/toolset_guide.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,634 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="toolsetguide" revision="2">
+ <title>Toolset Guide
+
+ �c�[���Z�b�g�K�C�h
+ </title>
+
+ <para>
+ Hibernate��g�������E���h�g���b�v�G���W�j�A�����O�́A
+ Eclipse�v���O�C����R�}���h���C���c�[���A������Ant�^�X�N��g�����Ƃʼn\�ł��B
+ </para>
+
+ <para>
+ <emphasis>Hibernate Tools</emphasis> �͌��݁A�����f�[�^�x�[�X�̃��o�[�X�G���W�j�A�����O��Ant�^�X�N�ɉ����āAEclipseIDE�̃v���O�C����܂݂܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem><para>
+ <emphasis>�}�b�s���O�G�f�B�^:</emphasis>
+ Hibernate��XML�}�b�s���O�t�@�C���p�̃G�f�B�^�ŁA
+ �����⊮�ƍ\�������\����T�|�[�g���Ă��܂��B�N���X����v���p�e�B/�t�B�[���h���ɑ��鎩���⊮��T�|�[�g���A
+ �ʏ��XML�G�f�B�^������͂ł��B
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Console:</emphasis>
+ �R���\�[���̓G�N���v�X�̐V�����r���[�ł��B
+ �R���\�[���R���t�B�M�����[�V�����̃c���[�I�[�o�[�r���[�ɉ����āA�i���N���X�Ƃ��̊֘A�̑��ݍ�p�r���[������܂��B
+ �f�[�^�x�[�X��HQL����s���A���ʂڃG�N���v�X��Ō��邱�Ƃ��ł��܂��B
+ </para></listitem>
+ <listitem><para>
+ <emphasis>�J���E�B�U�[�h</emphasis>
+ Hibernate��Eclipse�c�[���͂������̃E�B�U�[�h����܂��B
+ �E�B�U�[�h��g����Hibernate�̐ݒ�t�@�C��(cfg.xml)���₭����������A
+ �����̃f�[�^�x�[�X�X�L�[�}��POJO�̃\�[�X�t�@�C����Hibernate�̃}�b�s���O�t�@�C���ւƁA
+ ���S�Ƀ��o�[�X�G���W�j�A�����O���邱�Ƃ��ł��܂��B
+ ���o�[�X�G���W�j�A�����O�E�B�U�[�h�̓J�X�^�}�C�Y�\�ȃe���v���[�g��T�|�[�g���܂��B
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Ant Tasks:</emphasis>
+ </para></listitem>
+
+ </itemizedlist>
+
+ <para>
+ ���ڂ������� <emphasis>Hibernate Tools</emphasis> �p�b�P�[�W�Ƃ��̃h�L�������g��Q�Ƃ��Ă��������B
+ </para>
+
+ <para>
+ �������AHibernate�̃��C���p�b�P�[�W�� <emphasis>SchemaExport</emphasis> �A
+ �ʖ� <literal>hbm2ddl</literal> ��܂݂܂�(Hibernate��ŃI���U�t���C�Ŏg�p�ł��܂�)�B
+ </para>
+
+ <sect1 id="toolsetguide-s1" revision="2">
+ <title>�X�L�[�}�̎�������</title>
+
+ <para>
+ DDL��Hibernate���[�e�B���e�B�ɂ��}�b�s���O�t�@�C�����琶�����邱�Ƃ��ł��܂��B
+ �������ꂽ�X�L�[�}�̓G���e�B�e�B��R���N�V�����̃e�[�u���ɑ���Q�Ɛ���������(��L�[�ƊO���L�[)��܂݂܂��B
+ �e�[�u���ƃV�[�P���X�̓}�b�s���O���鎯�ʎq�W�F�l���[�^�ɑ��Đ�������܂��B
+ </para>
+
+ <para>
+ DDL�̓x���_�[�ˑ��Ȃ̂ŁA���̃c�[����g���Ƃ��́A<literal>hibernate.dialect</literal>
+ �v���p�e�B��SQL�� <literal>����</literal> ��w�� <emphasis>���Ȃ���Ȃ�܂���</emphasis> �B
+ </para>
+
+ <para>
+ �܂��A���������X�L�[�}����P����悤�ɁA�}�b�s���O�t�@�C����J�X�^�}�C�Y���Ă��������B
+ </para>
+
+ <sect2 id="toolsetguide-s1-2" revision="3">
+ <title>�X�L�[�}�̃J�X�^�}�C�Y</title>
+
+ <para>
+ ������Hibernate�̃}�b�s���O�v�f�ł́A�I�v�V������ <literal>length</literal> �Ƃ������̑������`���Ă��܂��B
+ ���̑����ŃJ��������ݒ肷�邱�Ƃ��ł��܂�(�܂���NUMERIC/DECIMAL�^�̃f�[�^�̐��x��ݒ�ł��܂�)�B
+ </para>
+
+ <para>
+ <literal>not-null</literal> �����i�e�[�u���̃J������ <literal>NOT NULL</literal> ���������j��
+ <literal>unique</literal> �����i�e�[�u���̃J������ <literal>UNIQUE</literal> ���������j���ݒ�ł���^�O�����܂��B
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="bar" column="barId" not-null="true"/>]]></programlisting>
+
+ <programlisting><![CDATA[<element column="serialNumber" type="long" not-null="true" unique="true"/>]]></programlisting>
+
+ <para>
+ <literal>unique-key</literal> �����̓J������O���[�v�����Ĉ�̃L�[����ɂ��邽�߂Ɏg���܂��B
+ ���݁A<literal>unique-key</literal> �����Ŏw�肳�ꂽ�l�͐���̎w��ɂ� <emphasis>�g��ꂸ</emphasis> �A
+ �}�b�s���O�t�@�C���ŃJ������O���[�v�����邱�Ƃɂ̂ݎg���܂��B
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="org" column="orgId" unique-key="OrgEmployeeId"/>
+<property name="employeeId" unique-key="OrgEmployeeId"/>]]></programlisting>
+
+
+
+ <para>
+ <literal>index</literal> �����̓}�b�s���O����J������g���Đ��������C���f�b�N�X�̖��O��w�肵�܂��B
+ �����J������P�̃C���f�b�N�X�ɃO���[�v���ł��܂��B�P�ɁA�����C���f�b�N�X����w�肷�邾���ł��B
+ </para>
+
+<programlisting><![CDATA[<property name="lastName" index="CustName"/>
+<property name="firstName" index="CustName"/>]]></programlisting>
+
+ <para>
+ <literal>foreign-key</literal> �����́A�������ꂽ�O���L�[����̖��O��I�[�o�[���C�h���邽�߂Ɏg�p�ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="bar" column="barId" foreign-key="FKFooBar"/>]]></programlisting>
+
+ <para>
+ �����̃}�b�s���O�v�f�́A�q <literal><column></literal> �v�f��L�q�ł��܂��B����͕����J�����^�̃}�b�s���O�ɂ͓��ɗL�p�ł��B
+ </para>
+
+ <programlisting><![CDATA[<property name="name" type="my.customtypes.Name"/>
+ <column name="last" not-null="true" index="bar_idx" length="30"/>
+ <column name="first" not-null="true" index="bar_idx" length="20"/>
+ <column name="initial"/>
+</property>]]></programlisting>
+
+ <para>
+ <literal>default</literal> �����̓J�����̃f�t�H���g�l��w�肵�܂�
+ (�}�b�s���O�����N���X�̐V�����C���X�^���X��ۑ�����O�ɁA
+ �}�b�s���O�����v���p�e�B�֓����l�������ׂ��ł�)�B
+ </para>
+
+ <programlisting><![CDATA[<property name="credits" type="integer" insert="false">
+ <column name="credits" default="10"/>
+</property>]]></programlisting>
+
+ <programlisting><![CDATA[<version name="version" type="integer" insert="false">
+ <column name="version" default="0"/>
+</property>]]></programlisting>
+
+ <para>
+ <literal>sql-type</literal> �����ŁA�f�t�H���g��Hibernate�^����SQL�̃f�[�^�^�ւ̃}�b�s���O��I�[�o�[���C�h�ł��܂��B
+ </para>
+
+
+ <programlisting><![CDATA[<property name="balance" type="float">
+ <column name="balance" sql-type="decimal(13,3)"/>
+</property>]]></programlisting>
+
+
+ <para>
+ <literal>check</literal> �����Ń`�F�b�N�����w�肷�邱�Ƃ��ł��܂��B
+ </para>
+
+ <programlisting><![CDATA[<property name="foo" type="integer">
+ <column name="foo" check="foo > 10"/>
+</property>]]></programlisting>
+
+ <programlisting><![CDATA[<class name="Foo" table="foos" check="bar < 100.0">
+ ...
+ <property name="bar" type="float"/>
+</class>]]></programlisting>
+
+
+ <table frame="topbot" id="schemattributes-summary" revision="2">
+ <title>�܂Ƃ�</title>
+ <tgroup cols="3">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>����</entry>
+ <entry>�l</entry>
+ <entry>���</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>length</literal></entry>
+ <entry>���l</entry>
+ <entry>�J�����̒���</entry>
+ </row>
+
+ <row>
+ <entry><literal>precision</literal></entry>
+ <entry>���l</entry>
+ <entry>�J������DECIMAL�^�̐��x�iprecision�j</entry>
+ </row>
+
+ <row>
+ <entry><literal>scale</literal></entry>
+ <entry>���l</entry>
+ <entry>�J������DECIMAL�^�̃X�P�[���iscale�j</entry>
+ </row>
+
+ <row>
+ <entry><literal>not-null</literal></entry>
+ <entry><literal>true|false</literal></entry>
+ <entry>�J������null�l����Ȃ����Ƃ�w�肵�܂�
+ </entry>
+ </row>
+ <row>
+ <entry><literal>unique</literal></entry>
+ <entry><literal>true|false</literal></entry>
+ <entry>�J���������j�[�N��������Ƃ�w�肵�܂�
+ </entry>
+ </row>
+ <row>
+ <entry><literal>index</literal></entry>
+ <entry><literal>�C���f�b�N�X��</literal> </entry>
+ <entry>(�����J������)�C���f�b�N�X�̖��O��w�肵�܂�
+ </entry>
+ </row>
+ <row>
+ <entry><literal>unique-key</literal></entry>
+ <entry><literal>���j�[�N�L�[��</literal></entry>
+ <entry>�����J�����̃��j�[�N����̖��O��w�肵�܂�
+ </entry>
+ </row>
+ <row>
+ <entry><literal>foreign-key</literal></entry>
+ <entry><literal>�O���L�[��</literal></entry>
+ <entry>
+ <one-to-one>�A<many-to-one>�A<many-to-many>�}�b�s���O�v�f��g���āA
+ �֘A�ɑ��������ꂽ�O���L�[����̖��O��w�肵�܂��B
+ <literal>SchemaExport</literal> �� <literal>inverse="true"</literal> ����l�����Ȃ����Ƃɒ��ӂ��Ă��������B
+ </entry>
+ </row>
+ <row>
+ <entry><literal>sql-type</literal></entry>
+ <entry><literal>SQL�̃J�����^</literal></entry>
+
+ <entry>
+ �f�t�H���g�̃J�����^��I�[�o�[���C�h���܂�( <literal><column></literal> �v�f�̑����̂�)
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>default</literal></entry>
+ <entry>SQL��</entry>
+
+ <entry>
+ �J�����̃f�t�H���g�l��w�肵�܂�
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>check</literal></entry>
+ <entry>SQL��</entry>
+
+ <entry>
+ �J�������e�[�u����SQL�̃`�F�b�N�����쐬���܂�
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <literal><comment></literal> �v�f�Ő�������X�L�[�}�ɃR�����g��w�肷�邱�Ƃ��ł��܂��B
+
+ </para>
+
+ <programlisting><![CDATA[<class name="Customer" table="CurCust">
+ <comment>Current customers only</comment>
+ ...
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[<property name="balance">
+ <column name="bal">
+ <comment>Balance in USD</comment>
+ </column>
+</property>]]></programlisting>
+
+ <para>
+ ����ɂ��A��������DDL�� <literal>comment on table</literal> �� <literal>comment on column</literal> ����������܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-3" revision="2">
+ <title>�c�[���̎��s</title>
+
+ <para>
+ <literal>SchemaExport</literal> �͕W���o�͂ɑ���DDL�X�N���v�g�����o���ADDL������s���������܂��B
+ </para>
+
+ <para>
+ <literal>java -cp </literal> <emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaExport</literal> <emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title> <literal>SchemaExport</literal> Command Line Options
+
+ <literal>SchemaExport</literal> �̃R�}���h���C���I�v�V����
+ </title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>�I�v�V����</entry>
+ <entry>���</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry> <literal>--quiet</literal> </entry>
+ <entry>�X�N���v�g��W���o�͂ɏo�͂��܂���</entry>
+ </row>
+ <row>
+ <entry> <literal>--drop</literal> </entry>
+ <entry>�e�[�u���̍폜������s���܂�</entry>
+ </row>
+
+ <row>
+ <entry> <literal>--create</literal> </entry>
+ <entry>�e�[�u���̐����݂̂�s���܂��B
+ </entry>
+ </row>
+
+ <row>
+ <entry> <literal>--text</literal> </entry>
+ <entry>�f�[�^�x�[�X�ɃG�N�X�|�[�g���܂���</entry>
+ </row>
+ <row>
+ <entry> <literal>--output=my_schema.ddl</literal> </entry>
+ <entry> DDL�X�N���v�g��t�@�C���ɏo�͂��܂�</entry>
+ </row>
+
+ <row>
+ <entry> <literal>--naming=eg.MyNamingStrategy</literal> </entry>
+ <entry> <literal>NamingStrategy</literal> ��I���܂�
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>--config=hibernate.cfg.xml</literal> </entry>
+ <entry>XML�t�@�C������Hibernate�̒�`����ǂݍ��݂܂�</entry>
+ </row>
+ <row>
+ <entry> <literal>--properties=hibernate.properties</literal> </entry>
+ <entry>�t�@�C������f�[�^�x�[�X�v���p�e�B��ǂݍ��݂܂�</entry>
+ </row>
+ <row>
+ <entry> <literal>--format</literal> </entry>
+ <entry>�X�N���v�g��ɐ�������SQL��ǂ݂₷���悤�Ƀt�H�[�}�b�g���܂�</entry>
+ </row>
+ <row>
+ <entry> <literal>--delimiter=x</literal> </entry>
+ <entry>�X�N���v�g�̍s��蕶����ݒ肵�܂�</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ �A�v���P�[�V������ <literal>SchemaExport</literal> ��g�ݍ��ނ��Ƃ�ł��܂��F
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaExport(cfg).create(false, true);]]></programlisting>
+
+ </sect2>
+
+
+ <sect2 id="toolsetguide-s1-4">
+ <title>�v���p�e�B</title>
+
+ <para>
+ ���̂悤�ɁA�f�[�^�x�[�X�̃v���p�e�B��w�肷�邱�Ƃ��ł��܂��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>-D</literal> <emphasis><property></emphasis> ��g���āA�V�X�e���v���p�e�B�Ƃ���
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal>hibernate.properties</literal> �t�@�C�����
+ </para>
+ </listitem>
+ <listitem>
+ <para> <literal>--properties</literal> ��g���Ďw�肵���v���p�e�B�t�@�C�����
+
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ �K�v�ȃv���p�e�B�͈ȉ��̂�̂ł��F
+ </para>
+
+ <table frame="topbot">
+ <title>SchemaExport�R�l�N�V�����v���p�e�B</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>�v���p�e�B��
+ </entry>
+ <entry>���
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry> <literal>hibernate.connection.driver_class</literal> </entry>
+ <entry>jdbc�̃h���C�o�[�N���X
+ </entry>
+ </row>
+ <row>
+ <entry> <literal>hibernate.connection.url</literal> </entry>
+ <entry>jdbc��url
+ </entry>
+ </row>
+ <row>
+ <entry> <literal>hibernate.connection.username</literal> </entry>
+ <entry>�f�[�^�x�[�X�̃��[�U
+ </entry>
+ </row>
+ <row>
+ <entry> <literal>hibernate.connection.password</literal> </entry>
+ <entry>���[�U�p�X���[�h
+ </entry>
+ </row>
+ <row>
+ <entry> <literal>hibernate.dialect</literal> </entry>
+ <entry>�f�[�^�x�[�X����
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-5">
+ <title>Ant��g�p����</title>
+
+ <para>
+ Ant�̃r���h�X�N���v�g���� <literal>SchemaExport</literal> ��Ăяo�����Ƃ��ł��܂��B:
+ </para>
+
+ <programlisting><![CDATA[<target name="schemaexport">
+ <taskdef name="schemaexport"
+ classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
+ classpathref="class.path"/>
+
+ <schemaexport
+ properties="hibernate.properties"
+ quiet="no"
+ text="no"
+ drop="no"
+ delimiter=";"
+ output="schema-export.sql">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemaexport>
+</target>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-6" revision="2">
+ <title>�C���N�������^���ȃX�L�[�}�X�V
+ </title>
+
+ <para>
+ <literal>SchemaUpdate</literal> �c�[���͊����̃X�L�[�}��C���N�������^���ɍX�V���܂��B
+ <literal>SchemaUpdate</literal> ��JDBC�̃��^�f�[�^API�ɋ����ˑ����܂��B
+ ���̂��߁A���ׂĂ�JDBC�h���C�o�ł��܂������Ƃ͌���Ȃ����Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ <literal>java -cp </literal> <emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaUpdate</literal> <emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title> <literal>SchemaUpdate</literal> �̃R�}���h���C����I�v�V����</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>�I�v�V����</entry>
+ <entry>���</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry> <literal>--quiet</literal> </entry>
+ <entry>�W���o�͂ɃX�N���v�g��o�͂��܂���</entry>
+ </row>
+
+ <row>
+ <entry> <literal>--text</literal> </entry>
+ <entry>�f�[�^�x�[�X�ɃX�N���v�g��G�N�X�|�[�g���܂���
+ </entry>
+ </row>
+ <row>
+ <entry> <literal>--naming=eg.MyNamingStrategy</literal> </entry>
+ <entry><literal>NamingStrategy</literal> ��I���܂��B
+ </entry>
+ </row>
+
+ <row>
+ <entry> <literal>--properties=hibernate.properties</literal> </entry>
+ <entry>�t�@�C������f�[�^�x�[�X�v���p�e�B��ǂݍ��݂܂�
+ </entry>
+ </row>
+
+ <row>
+ <entry> <literal>--config=hibernate.cfg.xml</literal> </entry>
+ <entry><literal>.cfg.xml</literal> �t�@�C����w�肵�܂�
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ �A�v���P�[�V������ <literal>SchemaUpdate</literal> ��g�ݍ��ނ��Ƃ��ł��܂��B�F
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaUpdate(cfg).execute(false);]]></programlisting>
+
+ </sect2>
+
+
+ <sect2 id="toolsetguide-s1-7">
+ <title>�C���N�������^���ȃX�L�[�}�X�V�ɑ���Ant�̎g�p</title>
+
+ <para>
+ Ant�X�N���v�g���� <literal>SchemaUpdate</literal> ��Ăяo�����Ƃ��ł��܂��F
+ </para>
+
+ <programlisting><![CDATA[<target name="schemaupdate">
+ <taskdef name="schemaupdate"
+ classname="org.hibernate.tool.hbm2ddl.SchemaUpdateTask"
+ classpathref="class.path"/>
+
+ <schemaupdate
+ properties="hibernate.properties"
+ quiet="no">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemaupdate>
+</target>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-8" revision="1">
+ <title>Schema validation</title>
+
+ <para>
+ <literal>SchemaValidator</literal> �c�[���́A�����̃f�[�^�x�[�X�X�L�[�}�ƍ쐬�����}�b�s���O�h�L�������g��"��v����"���Ƃ����܂��B <literal>SchemaValidator</literal> ��JDBC�̃��^�f�[�^API�ɋ����ˑ����邱�Ƃɒ��ӂ��Ă��������B���̂��߁A���ׂĂ�JDBC�h���C�o�[�ō쓮�����̂ł͂���܂���B���̃c�[���̓e�X�g���ɔ��ɗL�p�ł��B
+ </para>
+
+ <para>
+ <literal>java -cp </literal> <emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaValidator</literal> <emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title> <literal>SchemaValidator</literal> �̃R�}���h���C���E�I�v�V����
+ </title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>�I�v�V����</entry>
+ <entry>���</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry> <literal>--naming=eg.MyNamingStrategy</literal> </entry>
+ <entry><literal>NamingStrategy</literal> ��I���܂�
+ </entry>
+ </row>
+ <row>
+ <entry> <literal>--properties=hibernate.properties</literal> </entry>
+ <entry>�t�@�C������f�[�^�x�[�X�̃v���p�e�B��ǂݍ��݂܂�
+ </entry>
+ </row>
+ <row>
+ <entry> <literal>--config=hibernate.cfg.xml</literal> </entry>
+ <entry><literal>.cfg.xml</literal> �t�@�C����w�肵�܂�
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <literal>SchemaValidator</literal> ��A�v���P�[�V�����ɑg�ݍ��ނ��Ƃ��o���܂�:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaValidator(cfg).validate();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-9">
+ <title>�X�L�[�}�̃o���f�[�V������Ant��g�p���܂�</title>
+
+ <para>
+ Ant�X�N���v�g���� <literal>SchemaValidator</literal> ��Ăяo���܂�:
+ </para>
+
+ <programlisting><![CDATA[<target name="schemavalidate">
+ <taskdef name="schemavalidator"
+ classname="org.hibernate.tool.hbm2ddl.SchemaValidatorTask"
+ classpathref="class.path"/>
+
+ <schemavalidator
+ properties="hibernate.properties">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemavalidator>
+</target>]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/transactions.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/transactions.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/transactions.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/transactions.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,1276 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="transactions" revision="2">
+ <title>�g�����U�N�V�����ƕ��s��</title>
+
+ <para>
+ Hibernate�Ɠ������s����ɂ��čł�d�v�ȓ_�́A�e�Ղɗ���ł��邱�Ƃł��B
+ Hibernate�͐V���ȃ��b�N�̐U�镑����lj����Ă��炸�A����JDBC�R�l�N�V������JTA���\�[�X��g�p���܂��B
+ JDBC�AANSI�A����уf�[�^�x�[�X�Ǘ��V�X�e���iDBMS�j�̃g�����U�N�V���������̎d�l��
+ �������Ԃ����ĕ����邱�Ƃ����������܂��B
+ </para>
+
+ <para>
+ Hibernate�̓�������̃I�u�W�F�N�g���b�N���܂���B
+ �A�v���P�[�V�����́A�f�[�^�x�[�X�g�����U�N�V�����̕������x����
+ ��`�����U�镑������҂ł��܂��B
+ �g�����U�N�V�����X�R�[�v�̃L���b�V���ł���� <literal>Session</literal> �̂��A�ŁA
+ ���ʎq��N�G���ɂ�茟�������G���e�B�e�B�̓��s�[�^�u�����[�h�ɂȂ�܂�
+ �i�X�J���[�l��Ԃ��悤�ȃ��|�[�g�N�G���͈Ⴂ�܂��j�B
+ </para>
+
+ <para>
+ �o�[�W���j���O�ɂ�鎩���I�Ȋy�ϓI�������s����ɉ����āA
+ <literal>SELECT FOR UPDATE</literal> ����g�p���āA
+ �s��ߊϓI���b�N���邽�߂́i�}�C�i�[�ȁjAPI����܂��B
+ �y�ϓI�������s����Ƃ���API�ɂ��ẮA���̏͂̌�̂ق��ŋc�_���܂��B
+ </para>
+
+ <para>
+ �f�[�^�x�[�X�g�����U�N�V�����Ⓑ���Θb�iconversation�A�����O�g�����U�N�V�����j�����łȂ��A
+ <literal>Configuration</literal>�A<literal>SessionFactory</literal>�A�����
+ <literal>Session</literal>
+ �Ƃ������x��Hibernate���s���������s����̋c�_��n�߂܂��B
+ </para>
+
+ <sect1 id="transactions-basics" revision="1">
+ <title>session�X�R�[�v��transaction�X�R�[�v</title>
+
+ <para>
+ <literal>SessionFactory</literal> �͐������邱�Ƃ������ŁA
+ �X���b�h�Z�[�t�ȃI�u�W�F�N�g�ł��B
+ ����āA�A�v���P�[�V�����̂��ׂẴX���b�h�ŋ��L���ׂ��ł��B
+ �ʏ�A�A�v���P�[�V�����̋N�����ɁA
+ <literal>Configuration</literal> �C���X�^���X����P�x�����������܂��B
+ </para>
+
+ <para>
+ <literal>Session</literal> �͍����ł͂Ȃ��A�X���b�h�Z�[�t�ȃI�u�W�F�N�g�ł����܂���B
+ ����āA�P�̗v����P�̑Θb�A�P�̍�ƒP�ʁiunit of work�j�ɑ��ĂP�x�����g���A
+ ���̌�Ŏ̂Ă�ׂ��ł��B
+ <literal>Session</literal> �͕K�v�ɂȂ�܂ŁA
+ JDBC <literal>Connection</literal>�i������� <literal>DataSource</literal>�j��l�����܂���B
+ �䂦�ɁA���ۂɎg�p����Ƃ��܂Ń��\�[�X�����܂���B
+ </para>
+
+ <para>
+ ���̏��������邽�߂ɁA �f�[�^�x�[�X�g�����U�N�V�����ɂ��Ă�l���Ȃ���Ȃ�܂���B
+ �f�[�^�x�[�X��̃��b�N�̋������Ȃ����邽�߂ɁA
+ �f�[�^�x�[�X�g�����U�N�V�����͉\�Ȍ���Z������ׂ��ł��B
+ �����f�[�^�x�[�X�g�����U�N�V�����́A�A�v���P�[�V�����̍���������s����j�Q���܂��B
+ �䂦�ɁA���[�U�[���l���Ă���ԁi��ƒP�ʂ���������܂Łj�f�[�^�x�[�X�g�����U�N�V������
+ �J�����܂܂ɂ���̂́A�����Ă��̏ꍇ�悢�v�Ƃ͂����܂���B
+ </para>
+
+ <para>
+ ��ƒP�ʂƂ����X�R�[�v�Ƃ͉��ł��傤���H
+ �P��Hibernate <literal>Session</literal> �́A
+ �������̃f�[�^�x�[�X�g�����U�N�V������܂����邱�Ƃ��ł���ł��傤���H
+ �܂��́A�X�R�[�v�ƈ�Έ�̊W�ł��傤���H
+ ���� <literal>Session</literal> ��J���A����ׂ��ł��傤���H
+ �����āA�f�[�^�x�[�X�g�����U�N�V�������E��ǂ̂悤�ɕ�����̂ł��傤���H
+ </para>
+
+ <sect2 id="transactions-basics-uow" revision="1">
+ <title>��ƒP�ʁiUnit of work�j</title>
+
+ <para>
+ �P�ڂ́A<emphasis>session-per-operation</emphasis> �A���`�p�^�[����g���Ă͂����܂���B
+ ���Ȃ킿�A�P�̃X���b�h�̒��ŁA�P���ȃf�[�^�x�[�X�Ăяo���̂��т�
+ <literal>Session</literal> ��J���āA���Ă͂����܂���I
+ ������A�f�[�^�x�[�X�g�����U�N�V�����ɂ��Ă���l�ł��B
+ �A�v���P�[�V�������̃f�[�^�x�[�X�Ăяo���́A
+ �v�悳�ꂽ�V�[�P���X�iplanned sequence�j��g���A
+ �A�g�~�b�N�ȍ�ƒP�ʂɕ��ނ���܂��B
+ �i�P��SQL�����ƂɃR�~�b�g���鎩���R�~�b�g���A
+ �g���Ȃ��Ƃ����Ӗ��ł���邱�Ƃɒ��ӂ��Ă��������B
+ �����R�~�b�g�́ASQL�R���\�[���ŃA�h�z�b�N�ȍ�Ƃ���ۂɎg����̂ł��B
+ Hibernate�͒����Ɏ����R�~�b�g���[�h���ɂ��܂��B
+ ������́A�A�v���P�[�V�����T�[�o�[�����������邱�Ƃ���҂��܂��B�j
+ �f�[�^�x�[�X�g�����U�N�V�����̓I�v�V�����ł͂���܂���B
+ �f�[�^�x�[�X�Ƃ̂��ׂĂ̒ʐM�́A�f�[�^�̓ǂݍ��݂ł����Ă�A�������݂ł����Ă�A
+ �g�����U�N�V�����̒��ōs��Ȃ���Ȃ�܂���B
+ �������ƁA�f�[�^�ǂݍ��݂ɑ��āA�����R�~�b�g�͔���ׂ��ł��B
+ �Ȃ��Ȃ�A�����̏����ȃg�����U�N�V�����́A���m�ɒ�`���ꂽ�P�̍�ƒP�ʂƔ�ׂāA
+ �p�t�H�[�}���X���悭�Ȃ邱�Ƃ͂���܂���B
+ ��҂͕ێ琫��g�������肷����Ă��܂��B
+ </para>
+
+ <para>
+ �}���`���[�U�[�̃N���C�A���g�^�T�[�o�[�A�v���P�[�V�����̒��ŁA
+ �ł�悭�g����p�^�[���́A<emphasis>session-per-request</emphasis> �ł��B
+ ���̃��f���̒��ł́A
+ �N���C�A���g����iHibernate�i�����w�����삷��j�T�[�o�[�փ��N�G�X�g�������A
+ �V����Hibernate <literal>Session</literal> ���J����܂��B
+ �����āA���̍�ƒP�ʂ̒��ł��ׂẴf�[�^�x�[�X���������s����܂��B
+ ��Ƃ����������i�����āA�N���C�A���g�ւ̃��X�|���X�������ł����j���_�ŁA
+ session ��t���b�V�����A���܂��B
+ �N���C�A���g�̗v���������邽�߂ɁA�P�̃f�[�^�x�[�X�g�����U�N�V������g�p����ł��傤�B
+ <literal>Session</literal> ��J���A����ۂɁA
+ �f�[�^�x�[�X�g�����U�N�V������J�n���A�R�~�b�g���܂��B
+ ��̊W�͈�Έ�ł��B
+ ���̃��f���͑����̃A�v���P�[�V�����Ɋ��S�ɓK�����܂��B
+ </para>
+
+ <para>
+ �ȍ~�̎����Ƀ`�������W���Ă��������B
+ <literal>Session</literal> �����A�g�����U�N�V�����𐳊m�ɊJ�n���A�I��点�邾���łȂ��A
+ �f�[�^�A�N�Z�X�������₷������K�v������܂��B
+ ���N�G�X�g���T�[�o�[�Ƀq�b�g�����ۂƁA���X�|���X�𑗐M����O�ɁA���s�����interceptor
+ �i�Ⴆ�A<literal>ServletFilter</literal>�j��g���āA��ƒP�ʂ̋��E���������̂����z�I�ł��B
+ <literal>ThreadLocal</literal> �ϐ���g���āA
+ ���N�G�X�g��������X���b�h�� <literal>Session</literal> ���т��邱�Ƃ𐄏����܂��B
+ ����ɂ��A�X���b�h��Ŏ��s����邷�ׂẴR�[�h�ŁA
+ �istatic�ϐ��ɃA�N�Z�X����悤�Ɂj�ȒP�� <literal>Session</literal> �ɃA�N�Z�X�ł���悤�ɂȂ�܂��B
+ �I�����f�[�^�x�[�X�g�����U�N�V�������E�̋@�\����ŁA<literal>ThreadLocal</literal>
+ �ϐ��̒��Ƀg�����U�N�V�����R���e�L�X�g��ێ����邩�����܂���B
+ ���̎����p�^�[���́A<emphasis>ThreadLocal Session</emphasis> �����
+ <emphasis>Open Session in View</emphasis> �Ƃ������O�Œm���Ă��܂��B
+ �{�h�L�������g�Ő�Ɍ����� <literal>HibernateUtil</literal> �w���p�[�N���X��g�����邱�ƂŁA
+ ���̃p�^�[����e�ՂɎ����ł��܂��B
+ ������Ainterceptor �����������@�����A����Z�b�g�A�b�v����K�v������܂��B
+ Hibernate��Web�T�C�g�ɂ���tips�Ɨ��Q�Ƃ��Ă��������B
+ </para>
+
+ <para>
+ �ȍ~�̎����Ƀ`�������W���Ă��������B
+ Hibernate�͒P���Ȃ��̃p�^�[���̂��߂ɁA�\�ߑg�ݍ��܂ꂽ
+ �ucurrent session�v�̊Ǘ�����܂��B
+ �T�[�o�[���N�G�X�g��������ۂ̓g�����U�N�V������J�n���Ȃ���Ȃ�܂���B
+ �����āA���X�|���X��N���C�A���g�ɑ��M����O�Ƀg�����U�N�V������I��点�܂��B
+ �D���ȕ��@�Ŏ����ł��܂��B��ʓI�ȉ���� <literal>ServletFilter</literal> ��
+ �T�[�r�X���\�b�h��|�C���g�J�b�g����AOP�C���^�[�Z�v�^�[�A
+ proxy/interception �R���e�i�ł��B
+ EJB�R���e�i��EJB�Z�b�V�����r�[����g�����U�N�V�������E�Ƃ���
+ �A�X�y�N�g��N���X�J�b�g��������̕W���I�ȕ��@�ł��iCMT�ɂ��錾�I�j�B
+ �v���O�����ɂ��g�����U�N�V�������E��g���ƌ��߂��ꍇ�A
+ �ȒP�Ɏg�����߁A�݊����̂���R�[�h�ɂ��邽�߂ɁA
+ ���̏͂̌�̂ق��ɂ���Hibernate <literal>Transaction</literal> API�̂ق����悢�ł��B
+ </para>
+
+ <para>
+ �A�v���P�[�V�����̃R�[�h�́A�K�v�ȂƂ��ɂǂ��ł�A����ł�A
+ �P�� <literal>sessionFactory.getCurrentSession()</literal> ��Ăяo��������
+ �u���݂̃Z�b�V�����v�ɃA�N�Z�X�ł��܂��B
+ ���݂̃f�[�^�x�[�X�g�����U�N�V�����ւ� <literal>�Z�b�V����</literal> ���Ɏ擾���܂��B
+ ���\�[�X�E���[�J���Ȋ��A�������JTA����\�����Ȃ���Ȃ�܂���
+ �i<xref linkend="architecture-current-session"/> ��Q�Ƃ��Ă��������j�B
+ </para>
+
+ <para>
+ �Ƃ��ǂ��A�u�r���[��`�悷��v�܂� <literal>�Z�b�V����</literal>
+ �ƃf�[�^�x�[�X�g�����U�N�V�����̃X�R�[�v��g������ƕ֗��Ȃ��Ƃ�����܂��B
+ ����́A�v���̏����ƕ`��̃t�F�[�Y���Ă���
+ �T�[�u���b�g�A�v���P�[�V�����ɂ����ē��ɖ𗧂��܂��B
+ �Ǝ��̃C���^�[�Z�v�^���������A
+ �r���[��`�悷��܂Ńf�[�^�x�[�X�g�����U�N�V������g������̂͊ȒP�ł��B
+ �������A�R���e�i�Ǘ��g�����U�N�V������EJB�ɗ���ꍇ�́A�ȒP�ɂ͂ł��܂���B
+ �Ȃ��Ȃ�A�r���[�̕`���J�n����O�ɁAEJB�̃��\�b�h�����^�[�������ۂɁA
+ �g�����U�N�V�������������邽�߂ł��B
+ ���� <emphasis>Open Session in View</emphasis> �p�^�[���Ɋ֘A����q���g�Ɨ�ɂ��ẮA
+ Hibernate��Web�T�C�g��t�H�[������Q�Ƃ��Ă��������B
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-basics-apptx" revision="1">
+ <title>�����Θb</title>
+
+ <para>
+ session-per-request�p�^�[���́A��ƒP�ʂ�v����ۂɖ𗧂l���Ƃ��������ł͂���܂���B
+ �����̃r�W�l�X�v���Z�X�́A���[�U�[�Ƃ̈�A�̑��ݍ�p�S�̂�v�����܂��B
+ ���̑��ݍ�p�ɂ́A�f�[�^�x�[�X�A�N�Z�X���܂܂�܂��B
+
+ Web�ƃG���^�[�v���C�Y�A�v���P�[�V�����ł́A�f�[�^�x�[�X�g�����U�N�V������
+ ���[�U�Ƃ̑��ݍ�p�ɂ܂œn�邱�Ƃ͋�����܂���B
+
+ ���̗��悭�l���Ă݂Ă��������B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ �_�C�A���O�̍ŏ��̉�ʂ��J���A�X�� <literal>Session</literal>
+ �ƃf�[�^�x�[�X�g�����U�N�V�����̒��Ń��[�h���ꂽ�f�[�^���[�U�[�Ɍ����܂��B
+ ���[�U�[�̓I�u�W�F�N�g���R�ɏC���ł��܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 5����Ƀ��[�U�[�́uSave�v��N���b�N���A�C�����i���������̂���҂��܂��B
+ �܂��A���̏���ҏW�����͎̂����P�l�����ŁA
+ �C���̃R���t���N�g�͔������Ȃ��Ɗ��҂��܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ ���̍�ƒP�ʂ�i���[�U�[�̎��_�Łj������ <emphasis>�Θb</emphasis>
+ �i������́A<emphasis>�A�v���P�[�V�����g�����U�N�V����</emphasis> �j�ƌĂт܂��B
+ �A�v���P�[�V�����ɂ�������������@�͂�������܂��B
+ </para>
+
+ <para>
+ �ŏ��Ɏv���������́A���[�U�[���l���Ă���ԁA<literal>Session</literal>
+ �ƃf�[�^�x�[�X�g�����U�N�V������J�����܂܂ɂ��Ă������Ƃł��B
+ �����ɏC�����ꂸ�A�����ƌ��q�����ۏ����悤�ɁA
+ �f�[�^�x�[�X��̃��b�N�͕ێ������܂܂ɂ��܂��B
+ ������A����̓A���`�p�^�[���ł��B
+ �Ȃ��Ȃ�A���b�N�̋�������������ƁA
+ �A�v���P�[�V�������������[�U�[���ɉ����ăX�P�[���A�b�v�ł��Ȃ��Ȃ邩��ł��B
+ </para>
+
+ <para>
+ ���炩�ɁA�Θb��������邽�߂ɂ́A
+ �������̃f�[�^�x�[�X�g�����U�N�V������g�p����ׂ��ł��B
+ ���̏ꍇ�A�r�W�l�X�v���Z�X�̕�����ێ����邱�Ƃ́A
+ �A�v���P�[�V�����w�̐Ӗ��̂P�ɂȂ�܂��B
+ �P�̑Θb�́A
+ �ʏ킢�����̃f�[�^�x�[�X�g�����U�N�V�����ɋy�т܂��B
+ �f�[�^�x�[�X�g�����U�N�V�����̂P�̂݁i�Ō�̂P�j���X�V�����f�[�^��ۑ����A
+ ���̓f�[�^��ǂނ����ł���A����̓A�g�~�b�N�ł�
+ �i�Ⴆ�A�������̗v���^������J��Ԃ��E�B�U�[�h�`���̃_�C�A���O�j�B
+ ����͕������A���������ق����ȒP�ł��B
+ Hibernate�̋@�\��g���̂ł���A���ɊȒP�ł��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>�����o�[�W���j���O</emphasis>
+ - Hibernate�͎����I�Ɋy�ϓI�������s���䂪�ł��܂��B
+ ���[�U�[���l���Ă���Ԃɓ����ɏC�����������ꍇ�A�����I�Ɍ��o�ł��܂��B
+ �ʏ�A�Θb�̏I�����Ƀ`�F�b�N���邾���ł��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>�����iDetached�j�I�u�W�F�N�g</emphasis> - ���łɋc�_����
+ <emphasis>session-per-request</emphasis> �p�^�[����g���ƌ��肵���ꍇ�A
+ ���[�h���ꂽ���ׂẴC���X�^���X�́A���[�U���l���Ă���Ԃ́A
+ �Z�b�V�������番�����ꂽ��ԂɂȂ�܂��B
+ �I�u�W�F�N�g��Z�b�V�����ɍĒlj����A�C����i�����ł��܂��B
+ ����� <emphasis>session-per-request-with-detached-objects</emphasis>
+ �p�^�[���ƌĂт܂��B
+ �����o�[�W���j���O��g�����ƂŁA�����ɍs����C�����ł��܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>�g���i������́A�����j�Z�b�V����</emphasis>
+ - Hibernate�� <literal>Session</literal> �́A
+ �f�[�^�x�[�X�g�����U�N�V������R�~�b�g������A
+ ���Ō��т��Ă���JDBC�R�l�N�V������ؒf�ł��܂��B
+ �����āA�N���C�A���g����̐V�����v�������������ۂɁA�Đڑ��ł��܂��B
+ ���̃p�^�[���́A<emphasis>session-per-conversation</emphasis>
+ �Ƃ������Œm���Ă���A�I�u�W�F�N�g��Z�b�V�����֍Ēlj����邱�Ƃ����s�v�ɂ��܂��B
+ �����o�[�W���j���O��g�����ƂŁA�����ɍs����C�����ł��܂��B
+
+ �ʏ� <literal>Session</literal> �����I�Ƀt���b�V���������A
+ �����I�Ƀt���b�V�����܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <emphasis>session-per-request-with-detached-objects</emphasis> ��
+ <emphasis>session-per-conversation</emphasis> �̂Q�́A
+ ���_�ƌ��_�����Ă��܂��B
+ ����ɂ��ẮA���̏͂̌�̂ق��ŁA�y�ϓI�������s����̕����̒��ŋc�_���܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-basics-identity">
+ <title>�I�u�W�F�N�g���ʎq��l����</title>
+
+ <para>
+ �A�v���P�[�V�����́A�Q�̈قȂ� <literal>Session</literal> ����
+ �����i����Ԃɓ����ɃA�N�Z�X�ł��܂��B
+ �������A�Q�� <literal>Session</literal> �C���X�^���X��
+ �i�����N���X�̂P�̃C���X�^���X���L���邱�Ƃ͂ł��܂���B
+ �䂦�ɁA���ʎq�ɂ͂Q�̈قȂ�T�O������Ƃ������ƂɂȂ�܂��B
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>�f�[�^�x�[�X���ʎq</term>
+ <listitem>
+ <para>
+ <literal>foo.getId().equals( bar.getId() )</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>JVM���ʎq</term>
+ <listitem>
+ <para>
+ <literal>foo==bar</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ <emphasis>�X��</emphasis> <literal>Session</literal> �ɒlj����ꂽ�I�u�W�F�N�g�ɂƂ���
+ �i���Ȃ킿�A�P�� <literal>Session</literal> �̃X�R�[�v�̒��ł́j�A�Q�̊T�O�͓����ł��B
+ �f�[�^�x�[�X���ꐫ��JVM���ꐫ����v���邱�Ƃ�AHibernate���ۏ��܂��B
+ �������A�A�v���P�[�V�������Q�̈قȂ�Z�b�V��������
+ �u�����v�i�i�������ʎq�́j�r�W�l�X�I�u�W�F�N�g�ɓ����ɃA�N�Z�X�������A
+ �Q�̃C���X�^���X�͎��ۂɁiJVM���ʎq���j�u�قȂ�v�܂��B
+ �y�ϓI�A�v���[�`�ɂ���āA�i�����o�[�W���j���O�́j�t���b�V���^�R�~�b�g����
+ �R���t���N�g��������܂��B
+ </para>
+
+ <para>
+ ���̃A�v���[�`�ł́AHibernate�ƃf�[�^�x�[�X�ɓ������s�ɂ��Ă̐S�z���c��܂��B
+ ����ŁA�ō��̃X�P�[���r���e�B������܂��B
+ �Ȃ��Ȃ�A�P�X���b�h�̍�ƒP�ʂ̒��ň�Ӑ����ۏ����A
+ �����ȃ��b�N�⓯�������s�v�ɂȂ邽�߂ł��B
+ <literal>Session</literal> ���ƂɂP�̃X���b�h��\��t�������A
+ �A�v���P�[�V�����̓r�W�l�X�I�u�W�F�N�g��synchronize����K�v�͂���܂���B
+ <literal>Session</literal> ��ł́A�A�v���P�[�V�����̓I�u�W�F�N�g���r���邽�߂ɁA
+ <literal>==</literal> ����S�Ɏg�p�ł��܂��B
+ </para>
+
+ <para>
+ ����ǂ�A<literal>Session</literal> �̊O�� <literal>==</literal>
+ ��g���A�v���P�[�V�����́A�\�����Ȃ����ʂɑ������܂��B
+ ����͗\�����Ȃ��ꏊ�ŋN���肦�܂��B
+ �Ⴆ�A�Q�̕����C���X�^���X�� <literal>Set</literal> ��
+ put�����Ƃ��Ȃǂł��B
+ �����Ƃ�����f�[�^�x�[�X���ʎq�����܂��i���Ȃ킿�A�����s��\���܂��j�B
+ �������A������Ԃ̃C���X�^���X��JVM���ʎq�͓��R�ۏ���܂���B
+ �J���҂́A�i�����N���X�� <literal>equals()</literal> �� <literal>hashCode()</literal>
+ ���\�b�h��I�[�o�[���C�h���A�I�u�W�F�N�g�������̊T�O��������ׂ��ł��B
+ �x�����P����܂��B�������̎����Ƀf�[�^�x�[�X���ʎq��g��Ȃ��ł��������B
+ ���j�[�N�ȁi���ʂ͕s�ς́j�����̑g�ݍ��킹�ł���r�W�l�X�L�[��g���Ă��������B
+ ����A�ꎞ�I�u�W�F�N�g���i�������ꂽ�ꍇ�A�f�[�^�x�[�X���ʎq���ς��܂��B
+ �ꎞ�I�u�W�F�N�g��i�ʏ핪���C���X�^���X�Ƌ��Ɂj <literal>Set</literal>
+ �ɕێ�����ꍇ�A�n�b�V���R�[�h���ς��Ƃ������Ƃ́A<literal>Set</literal>
+ �̌_���j��Ƃ������Ƃł��B
+ �r�W�l�X�L�[�̂��߂̑����́A�f�[�^�x�[�X�̎�L�[�قLj��肷�ׂ��ł͂Ȃ��ł��B
+ �I�u�W�F�N�g������ <literal>Set</literal> �̒��ɂ���Ԃ����A�����ۏ��ׂ��ł��B
+ ���̖��̂��O��I�ȋc�_�́AHibernate��Web�T�C�g��Q�Ƃ��Ă��������B
+ �܂��A�����Hibernate�̖��ł͂Ȃ��A�P��Java�I�u�W�F�N�g�̎��ʎq�ⓙ������
+ �ǂ̂悤�Ɏ������ׂ����Ƃ������Ƃł��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-basics-issues">
+ <title>��ʓI�Ȗ��</title>
+
+ <para>
+ <emphasis>session-per-user-session</emphasis> ��
+ <emphasis>session-per-application</emphasis> �A���`�p�^�[��
+ �͎g���Ă͂����܂���i������A�܂�ɗ�O������܂��j�B
+ ���ӁF���L�̖��̂������́A���������p�^�[���Ƃ��Ă�o�����܂��B
+ �v���肷��O�ɁA���̈Ӗ��𗝉���悤�ɂ��Ă��������B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>Session</literal> �̓X���b�h�Z�[�t�ł͂���܂���B
+ HTTP���N�G�X�g�A�Z�b�V����Bean�ASwing���[�J�[�̂悤�ɁA
+ �������s���\�Ȃ�̂� <literal>Session</literal> �C���X�^���X���L����ƁA
+ ������Ԃ�����N�����܂��B
+ �i��ŋc�_����j<literal>HttpSession</literal> �̒���
+ Hibernate <literal>Session</literal> ��ێ�����ꍇ�A
+ HttpSession�ւ̃A�N�Z�X�������邱�Ƃ�l�����ׂ��ł��B
+ ����Ȃ���A���[�U�[���\�����������[�h��N���b�N����ƁA
+ �����ɑ���Q�̃X���b�h�̒��ŁA���� <literal>Session</literal> ���g���܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Hibernate����O�𓊂����ꍇ�́A�f�[�^�x�[�X�g�����U�N�V�������[���o�b�N���A
+ ������ <literal>Session</literal> �����ׂ��ł��i�ڍׂ��ŋc�_���܂��j�B
+ <literal>Session</literal> ���A�v���P�[�V�����Ɍ��ѕt�����Ă���̂ł���A
+ �A�v���P�[�V�������~���ׂ��ł��B
+ �f�[�^�x�[�X�g�����U�N�V�������[���o�b�N����A�r�W�l�X�I�u�W�F�N�g��
+ �g�����U�N�V������J�n�����Ƃ��̏�Ԃɖ߂�܂���B
+ ����́A�f�[�^�x�[�X�̏�Ԃƃr�W�l�X�I�u�W�F�N�g�͓������Ă��Ȃ����Ƃ�Ӗ����܂��B
+ �ʏ킱��͖��ɂȂ�܂���B
+ �Ȃ��Ȃ�A��O�͉ł��Ȃ�����ł��B
+ �Ƃɂ������[���o�b�N������ɂ�蒼���ׂ��ł��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session</literal> �͉i���ipersistent�j��Ԃ̂��ׂẴI�u�W�F�N�g��
+ �L���b�V�����܂��iHibernate�͊Ď����A�_�[�e�B��Ԃ��`�F�b�N���܂��j�B
+ ����́A�����ԃZ�b�V������J�����܂܂ɂ��邩�A
+ ���ɑ����̃f�[�^���[�h�������邩�����ꍇ�́A
+ OutOfMemoryException����������܂Ŗ����ɑ傫���Ȃ邱�Ƃ�Ӗ����܂��B
+ ����̂P�́A<literal>Session</literal> �L���b�V����Ǘ����邽�߂ɁA
+ <literal>clear()</literal> �� <literal>evict()</literal> ��ĂԂ��Ƃł��B
+ �������A�傫�ȃf�[�^��������K�v������Ȃ�A
+ ���Ԃ�X�g�A�h�v���V�[�W����l������ׂ��ł��傤�B
+ �������̉���́A<xref linkend="batch"/> �ŏЉ��Ă��܂��B
+ ���[�U�[�Z�b�V�����̊ԁA<literal>Session</literal> ��J�����܂܂ɂ���Ƃ������Ƃ́A
+ �f�[�^���V�N�łȂ��Ȃ�m���������Ȃ邱�Ƃ�Ӗ����܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="transactions-demarcation">
+ <title>�f�[�^�x�[�X�g�����U�N�V�������E</title>
+
+ <para>
+ �f�[�^�x�[�X�i������̓V�X�e���j�g�����U�N�V�����̋��E�́A��ɕK�v�ł��B
+ �f�[�^�x�[�X�g�����U�N�V�����̊O�ŁA�f�[�^�x�[�X�Ƃ̒ʐM�͋N���܂���
+ �i����͎����R�~�b�g���[�h�Ɋ���Ă��鑽���̊J���҂��������邩�����܂���j�B
+ �ǂݍ��ނ����̑���ɂł�A������m�ȃg�����U�N�V�������E��g�p���Ă��������B
+ �������x���ƃf�[�^�x�[�X�̔\�͎���ŁA����͕K�v�Ȃ��������܂��A
+ ��Ƀg�����U�N�V�������E���I�Ɏw�肵�Ă�A�}�C�i�X�ʂ͑S������܂���B
+
+ �m���ɁA�P�̃f�[�^�x�[�X�g�����U�N�V�����͑����̏����ȃg�����U�N�V�������
+ �i�f�[�^�̓ǂݍ��݂ł����Ă�j�p�t�H�[�}���X��������Ă��܂��B
+ </para>
+
+ <para>
+ J2EE���ɊǗ�����Ă��Ȃ����
+ �i���Ȃ킿�A�X�^���h�A�����A�P����Web��Swing�A�v���P�[�V�����j�ł�A
+ �Ǘ����ꂽ��Ԃł�AHibernate�A�v���P�[�V��������s�ł��܂��B
+ �Ǘ�����Ă��Ȃ����ł́AHiberante���f�[�^�x�[�X�̃R�l�N�V�����v�[������܂��B
+ �A�v���P�[�V�����J���҂́A�g�����U�N�V�������E��蓮�Őݒ肵�Ȃ���Ȃ�܂���B
+ ����������ƁA�f�[�^�x�[�X�g�����U�N�V�����̊J�n�A�R�~�b�g�A���[���o�b�N��
+ �J���Ҏ��g���ݒ肷��K�v������Ƃ������Ƃł��B
+
+ �ʏ�A�Ǘ����ꂽ���ł́A�R���e�i�Ǘ��ɂ��g�����U�N�V�����iCMT�j������܂��B
+ �Ⴆ�A�Z�b�V����Bean�̃f�v���C�����g�f�B�X�N���v�^�Ő錾�I�ɒ�`���A
+ �g�����U�N�V������g�ݗ��Ă܂��B
+ �v���O�����ɂ��g�����U�N�V�������E�͂���K�v����܂���B
+ </para>
+
+ <para>
+ �������Ȃ���A�Ǘ�����Ă��Ȃ����\�[�X�E���[�J���Ȋ���
+ JTA�Ɉˑ������V�X�e���iCMT�ł͂Ȃ�BMT�j�̗����ɁA
+ �i�����w��|�[�^�u���ɕۂ̂́A�����Ζ]�܂������Ƃł��B
+
+ �f�v���C���̃l�C�e�B�u�̃g�����U�N�V�����V�X�e����Ăяo��
+ <literal>Transaction</literal> �Ƃ������b�p�[API��Hibernate�����܂��B
+ ����API��g�����͔C�ӂł����ACMT�̃Z�b�V����Bean��g��Ȃ��̂ł���A�g�����Ƃ����������܂��B
+ </para>
+
+ <para>
+ �ʏ�A<literal>Session</literal> �I���́A�S�̈قȂ�t�F�[�Y��܂݂܂��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ �Z�b�V�����̃t���b�V��
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �g�����U�N�V�����̃R�~�b�g
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ �Z�b�V�����̃N���[�Y
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ��O�̃n���h�����O
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ �Z�b�V�����̃t���b�V���ɂ��ẮA�O�̂ق��ł��łɋc�_���܂����B
+ �Ǘ����ꂽ���ƊǗ�����Ă��Ȃ����̗����ɂ��āA
+ �g�����U�N�V�������E�Ɨ�O�n���h�����O�����Əڂ������Ă����܂��傤�B
+ </para>
+
+
+ <sect2 id="transactions-demarcation-nonmanaged" revision="2">
+ <title>�Ǘ�����Ă��Ȃ���</title>
+
+ <para>
+ Hibernate�i�����w��Ǘ�����Ă��Ȃ����Ŏ�������ꍇ�́A
+
+ �ʏ�P���ȃR�l�N�V�����v�[���i���Ȃ킿DataSource�ł͂Ȃ��j�ɂ���āA
+ �f�[�^�x�[�X�R�l�N�V�����𐧌䂵�܂��B
+ Hibernate�͂��̃R�l�N�V�����v�[������K�v�ȃR�l�N�V������擾���܂��B
+
+ �Z�b�V�����^�g�����U�N�V��������̃C�f�B�I���͎��̂悤�ɂȂ�܂��B
+ </para>
+
+ <programlisting><![CDATA[// Non-managed environment idiom
+Session sess = factory.openSession();
+Transaction tx = null;
+try {
+ tx = sess.beginTransaction();
+
+ // do some work
+ ...
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ if (tx != null) tx.rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>
+ �����I�� <literal>Session</literal> �� <literal>flush()</literal> ��Ăяo���ׂ��ł͂Ȃ��A
+ <literal>commit()</literal> ��Ăяo�����Ƃɂ��A�����I�ɓ��������������s����܂�
+ �i�Z�b�V������ <xref linkend="objectstate-flushing">FlushMode</xref> �Ɉˑ����Ă���j�B
+
+ <literal>close()</literal> ��Ăяo�����Ƃɂ��A�Z�b�V�����̏I���m�ɂ��܂��B
+ <literal>close()</literal> ���ÖٓI�ɍs����Ȃ��Ƃ́A
+ �Z�b�V������JDBC�R�l�N�V������J�����邱�Ƃł��B
+
+ ��L��Java�R�[�h�̓|�[�^�u���ł���A�Ǘ�����Ă��Ȃ�����JTA���̗����Ŏ��s�ł��܂��B
+ </para>
+
+ <para>
+ ���K�����̂������́AHibernate�ɗ\�ߑg�ݍ��܂�Ă���
+ �ucurrent session�v�R���e�L�X�g�Ǘ��ł��B
+ ���t�Ő�������艺�L�����ق��������ł��傤�B
+ </para>
+
+ <programlisting><![CDATA[// Non-managed environment idiom with getCurrentSession()
+try {
+ factory.getCurrentSession().beginTransaction();
+
+ // do some work
+ ...
+
+ factory.getCurrentSession().getTransaction().commit();
+}
+catch (RuntimeException e) {
+ factory.getCurrentSession().getTransaction().rollback();
+ throw e; // or display error message
+}]]></programlisting>
+
+ <para>
+ ���K�̃A�v���P�[�V�����̒��ł́A���̂悤�ȃR�[�h�̐�[�����Č��Ȃ��ł��傤�B
+ �v���I�ȁi�V�X�e���j��O�́A��Ɂu�ŏ�ʁv�ŃL���b�`���ׂ��ł��B
+ ����������A�i�i�����w�ŁjHibernate�Ăяo������s����R�[�h�ƁA
+ <literal>RuntimeException</literal> �𐧌䂷��
+ �i�ʏ�̓N���[���A�b�v�ƏI���̂ݍs�����Ƃ��ł���j�R�[�h�́A�ʁX�̑w�̒��ɂ���܂��B
+ Hibernate�ɂ��J�����g�R���e�L�X�g�Ǘ��́A���̐v���Ȃ�P���ɂ��܂��B
+ �K�v�Ȃ̂́A<literal>SessionFactory</literal> �ɃA�N�Z�X���邱�Ƃ����ł��B
+ ��O�����́A���̏͂̌�̂ق��ŋc�_���܂��B
+ </para>
+
+ <para>
+ ���ӁF�i�f�t�H���g�ł����j
+ <literal>org.hibernate.transaction.JDBCTransactionFactory</literal>
+ ��I����ׂ��ł��B
+ ��2�̗p��Ƃ��ẮA
+ <literal>hibernate.current_session_context_class</literal> ��
+ <literal>"thread"</literal> �Ƃ���Ƃ悢�ł��傤�B
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-jta" revision="3">
+ <title>JTA��g�p����</title>
+
+ <para>
+ �i�����w��A�v���P�[�V�����T�[�o�[�i�Ⴆ�AEJB�Z�b�V����Bean�̔w��j�Ŏ��s����ꍇ�A
+ Hibernate����擾���邷�ׂẴf�[�^�\�[�X�R�l�N�V�����́A
+ �����I�ɃO���[�o��JTA�g�����U�N�V�����̈ꕔ�ɂȂ�܂��B
+
+ EJB��g�킸�ɁA�X�^���h�A������JTA���������邱�Ƃ�ł��܂��B
+ JTA�����̂��߂ɁAHibernate�͂Q�̐헪����܂��B
+ </para>
+
+ <para>
+ Bean�Ǘ��g�����U�N�V�����iBMT�j��g���A<literal>Transaction</literal> API��g���ꍇ�A
+ Hibernate�̓A�v���P�[�V�����T�[�o�[��BMT�g�����U�N�V�����̊J�n�ƏI�������܂��B
+ ���Ȃ킿�A�g�����U�N�V�����Ǘ��̃R�[�h�́A�Ǘ�����Ȃ����Ɠ����ɂȂ�܂��B
+ </para>
+
+ <programlisting><![CDATA[// BMT idiom
+Session sess = factory.openSession();
+Transaction tx = null;
+try {
+ tx = sess.beginTransaction();
+
+ // do some work
+ ...
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ if (tx != null) tx.rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>
+ �g�����U�N�V�������E�Ƃ��� <literal>Session</literal> ��g�������ꍇ�A
+ �ȒP�ɃR���e�L�X�g��`�d����@�\�ł��� <literal>getCurrentSession()</literal> ������̂ŁA
+ JTA�� <literal>UserTransaction</literal> API�ڎg�p���ׂ��ł��傤�B
+ </para>
+
+ <programlisting><![CDATA[// BMT idiom with getCurrentSession()
+try {
+ UserTransaction tx = (UserTransaction)new InitialContext()
+ .lookup("java:comp/UserTransaction");
+
+ tx.begin();
+
+ // Do some work on Session bound to transaction
+ factory.getCurrentSession().load(...);
+ factory.getCurrentSession().persist(...);
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ tx.rollback();
+ throw e; // or display error message
+}]]></programlisting>
+
+ <para>
+ CMT�ł́A�g�����U�N�V�������E��Z�b�V����Bean�̃f�v���C�����g�f�B�X�N���v�^�Œ�`���A
+ �v���O�����ł͍s���܂���B
+ �䂦�ɁA�R�[�h�͎��̂悤�ɏ��Ȃ��Ȃ�܂��B
+ </para>
+
+ <programlisting><![CDATA[// CMT idiom
+ Session sess = factory.getCurrentSession();
+
+ // do some work
+ ...
+]]></programlisting>
+
+ <para>
+ CMT/EJB�̒��ł́A��Ƀ��[���o�b�N�������I�Ɏ��{����܂��B
+ �Ȃ��Ȃ�A�Z�b�V�����r�[���̃��\�b�h�ɂ�蓊����ꂽ���䂳��Ă��Ȃ�
+ <literal>RuntimeException</literal> �́A�O���[�o���g�����U�N�V������
+ ���[���o�b�N����悤�ɃR���e�i�ɓ`���邽�߂ł��B
+ <emphasis>����́ABMT�������CMT�Ƃ��������Hibernate <literal>Transaction</literal>
+ API��g���K�v�͏�����Ȃ��Ƃ����Ӗ��ł��B</emphasis>
+ </para>
+
+ <para>
+ Hibernate�̃g�����U�N�V�����t�@�N�g����ݒ肷��ۂɁA
+ JTA�ڎg���iBMT�́j�ꍇ�� <literal>org.hibernate.transaction.JTATransactionFactory</literal> ��A
+ CMT�Z�b�V�����r�[���̒��ł� <literal>org.hibernate.transaction.CMTTransactionFactory</literal> ��
+ �I���ׂ����Ƃ������Ƃɒ��ӂ��Ă��������B
+ <literal>hibernate.transaction.manager_lookup_class</literal>
+ ��Z�b�g���邱�Ƃ�v���o���Ă��������B
+ �Ȃ��A<literal>hibernate.current_session_context_class</literal> �́A
+ �Z�b�g���Ȃ����i����݊��j�A<literal>"jta"</literal> ��Z�b�g���Ă��������B
+ </para>
+
+ <para>
+ <literal>getCurrentSession()</literal> �I�y���[�V�����́AJTA���ł͂P�̌��_�����܂��B
+
+ �f�t�H���g�Ŏg���� <literal>after_statement</literal> �R�l�N�V���������[�X���[�h��g�p�����ŁA
+ �x�����P����܂��B
+
+ JTA�d�l�̋��Ȑ���̂��߂ɁA
+ <literal>scroll()</literal> �܂��� <literal>iterate()</literal> ���Ԃ����A
+ �����Ă��Ȃ� <literal>ScrollableResults</literal> �܂��� <literal>Iterator</literal>
+ �C���X�^���X��Hibernate�������I�ɃN���[���A�b�v���邱�Ƃ͂ł��܂���B
+
+ <literal>finally</literal> �u���b�N�̒��ŁA
+ <literal>ScrollableResults.close()</literal> �܂���
+ <literal>Hibernate.close(Iterator)</literal> ���I�ɌĂяo���āA
+ ���ɐ��f�[�^�x�[�X�J�[�\������ <emphasis>���Ȃ���Ȃ�܂���</emphasis>�B
+
+ �i������A�����̃A�v���P�[�V�����ł́AJTA��CMT�R�[�h�� <literal>scroll()</literal>
+ �� <literal>iterate()</literal> �̎g�p�����̂͗e�Ղł��B�j
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-exceptions">
+ <title>��O�n���h�����O</title>
+
+ <para>
+ <literal>Session</literal> ����O�i<literal>SQLException</literal>��܂ށj�𓊂����ꍇ�A
+ �����ɁA�f�[�^�x�[�X�g�����U�N�V�������[���o�b�N���A<literal>Session.close()</literal>
+ ��ĂсA<literal>Session</literal> �C���X�^���X��j�����ׂ��ł��B
+ <literal>Session</literal> �̂������̃��\�b�h�́A
+ �Z�b�V�����̏�Ԃ� <emphasis>���������܂�</emphasis> �ɂ��܂��B
+ Hibernate����������O��A�ł����̂Ƃ��Ĉ������Ƃ͂ł��܂���B
+ <literal>finally</literal> �u���b�N�̒��� <literal>close()</literal> ��Ă�ŁA
+ <literal>Session</literal> ��m���ɕ��Ă��������B
+ </para>
+
+ <para>
+ <literal>HibernateException</literal> �́AHibernate�i�����w�̒��Ŕ������鑽���̃G���[��
+ ���b�v����A��������Ȃ���O�ł��iHibernate�̌Â��o�[�W�����͈Ⴂ�܂����j�B
+ �������̈ӌ��́A�A�v���P�[�V�����J���҂ɉs�\�ȗ�O��
+ ���w�ŃL���b�`���邱�Ƃ��v���ׂ��ł͂Ȃ��Ƃ������Ƃł��B
+ �����̃V�X�e���ł́A��������Ȃ���O�ƒv���I�ȗ�O�́A
+ �R�[���X�^�b�N�̍ŏ��̃t���[���̂P�i�Ⴆ�A�ŏ�ʂ̑w�Łj�Ńn���h�����O���A
+ �G���[���b�Z�[�W��A�v���P�[�V�������[�U�[�ɕ\�����܂�
+ �i������́A���̓K�ȏ�������{���܂��j�B
+ Hibernate�́A<literal>HibernateException</literal> �ȊO�̌�������Ȃ���O��
+ �����邱�Ƃɒ��ӂ��Ă��������B
+ ������܂��A�s�\�ł���A�K�ȏ�������{���ׂ��ł��B
+ </para>
+
+ <para>
+ Hibernate�́A�f�[�^�x�[�X�Ƃ̑Θb���ɓ�����ꂽ <literal>SQLException</literal> ��
+ <literal>JDBCException</literal> �Ń��b�v���܂��B
+ ���́A��O����Ӗ��̂��� <literal>JDBCException</literal> �̃T�u�N���X��
+ �ϊ����悤�Ǝ��݂܂��B
+ ���� <literal>SQLException</literal> �́A<literal>JDBCException.getCause()</literal>
+ �ɂ�肢�ł�����܂��B
+ Hibernate�́A<literal>SessionFactory</literal> �ɒlj�����Ă���
+ <literal>SQLExceptionConverter</literal> ��g���A<literal>SQLException</literal> ��
+ �K���� <literal>JDBCException</literal> �T�u�N���X�ɕϊ����܂��B
+ �f�t�H���g�ł́A<literal>SQLExceptionConverter</literal> �͐ݒ肳��Ă���SQL�����ɂ��
+ ��`����܂��B
+ ����ŁA�Ǝ��̎����ɍ����ւ��邱�Ƃ�ł��܂�
+ �i�ڍׂ́A<literal>SQLExceptionConverterFactory</literal> �N���X��Javadoc��Q�Ƃ��Ă��������j�B
+ �W���I�� <literal>JDBCException</literal> �̃T�u�^�C�v���L�Ɏ����܂��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>JDBCConnectionException</literal> -
+ ��b�ƂȂ�JDBC�ʐM�̃G���[��\���܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>SQLGrammarException</literal> -
+ ���s����SQL�̕��@������͍\���̖���\���܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ConstraintViolationException</literal> -
+ ���炩�̌`���̊��S������ᔽ��\���܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockAcquisitionException</literal> -
+ �v�����ꂽ�������{����̂ɕK�v�ȃ��b�N���x����ۂ̃G���[��\���܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>GenericJDBCException</literal> -
+ ���̃J�e�S���Ɉ�v���Ȃ�������ʓI�ȗ�O�ł��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-timeout">
+ <title>�g�����U�N�V�����̃^�C���A�E�g</title>
+
+ <para>
+ EJB�̂悤�ȊǗ����ꂽ�������邫��߂ďd�v�ȓ����̂P�́A
+ �g�����U�N�V�����̃^�C���A�E�g�ł��B
+ ����͊Ǘ�����Ă��Ȃ��R�[�h�ɂ͒ł��܂���B
+ �g�����U�N�V�����^�C���A�E�g�́A�s�i�s�ȃg�����U�N�V������
+ ���[�U�[�Ƀ��X�|���X��Ԃ��Ȃ��܂܁A�������Ƀ��\�[�X��g�������Ȃ�
+ ���Ƃ�ۏႵ�܂��B
+ �Ǘ����ꂽ���iJTA�j�̊O�ł́AHibernate�͂��̋@�\��t���ɒł��܂���B
+ �������Ȃ���AHibernate�͎��̂悤�ȃf�[�^�A�N�Z�X����̐��䂭�炢�͂ł��܂��B
+ �f�[�^�x�[�X���x���̃f�b�h���b�N��傫�ȃ��U���g�Z�b�g��Ԃ��N�G����
+ ��`���ꂽ�^�C���A�E�g�ɂ���Ċm���ɐ������܂��B
+ �Ǘ����ꂽ���ł́AHibernate�̓g�����U�N�V�����^�C���A�E�g��JTA�ɈϏ����܂��B
+ ���̋@�\�́AHibernate�� <literal>Transaction</literal> �I�u�W�F�N�g��
+ ����Ē��ۉ�����Ă��܂��B
+ </para>
+
+ <programlisting><![CDATA[
+Session sess = factory.openSession();
+try {
+ //set transaction timeout to 3 seconds
+ sess.getTransaction().setTimeout(3);
+ sess.getTransaction().begin();
+
+ // do some work
+ ...
+
+ sess.getTransaction().commit()
+}
+catch (RuntimeException e) {
+ sess.getTransaction().rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>
+ CMT�r�[���̒��ł� <literal>setTimeout()</literal> ��
+ �Ăяo���Ȃ����Ƃɒ��ӂ��Ă��������B
+ �g�����U�N�V�����^�C���A�E�g�͐錾�I�ɒ�`�����ׂ��ł��B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="transactions-optimistic">
+ <title>�y�ϓI�������s����</title>
+
+ <para>
+ �������ƍ����X�P�[���r���e�B�̗������������A�v���[�`�́A
+ �o�[�W���j���O��g�����y�ϓI�������s����݂̂ł��B
+ �X�V�̏Փ˂����邽�߂Ɂi����сA�X�V��������̂�h�����߂Ɂj�A
+ �o�[�W�����ԍ�������̓^�C���X�^���v��g���āA�o�[�W������`�F�b�N���܂��B
+ Hibernate�́A�y�ϓI�������s��s���A�v���P�[�V�����R�[�h�������߂�
+ �A�v���[�`��R���܂��B
+ �������������郆�[�X�P�[�X�́A�����Θb�����܂����A
+ �o�[�W�����`�F�b�N�͂܂��P�̃f�[�^�x�[�X�g�����U�N�V�����̒��ōX�V�������Ƃ�h��
+ ���_������Ă��܂��B
+ </para>
+
+ <sect2 id="transactions-optimistic-manual">
+ <title>�A�v���P�[�V�����ɂ��o�[�W�����`�F�b�N</title>
+
+ <para>
+ Hibernate�ɂقƂ�Ǐ����Ă��킸�Ɏ�������P�[�X�ł��B
+ �f�[�^�x�[�X�Ƃ̂����́A���ꂼ��V���� <literal>Session</literal> �̒��ŋN����܂��B
+ �J���҂́A���ׂẲi�����C���X�^���X�𑀍삷��O�ɁA
+ �f�[�^�x�[�X����ēǂݍ��݂���Ӗ�������܂��B
+ ���̃A�v���[�`�ł́A�Θb�g�����U�N�V�����̕������邽�߂ɁA
+ �A�v���P�[�V�������g���o�[�W�����`�F�b�N��s���K�v������܂��B
+ ���̃A�v���[�`�́A�f�[�^�x�[�X�A�N�Z�X�̒��ł́A�ł������ł��B
+ �G���e�B�e�BEJB�ƍł���Ă���A�v���[�`�ł��B
+ </para>
+
+ <programlisting><![CDATA[// foo is an instance loaded by a previous Session
+session = factory.openSession();
+Transaction t = session.beginTransaction();
+
+int oldVersion = foo.getVersion();
+session.load( foo, foo.getKey() ); // load the current state
+if ( oldVersion != foo.getVersion() ) throw new StaleObjectStateException();
+foo.setProperty("bar");
+
+t.commit();
+session.close();]]></programlisting>
+
+ <para>
+ <literal><version></literal> ��g���āA<literal>version</literal>
+ �v���p�e�B��}�b�s���O���܂��B
+ Hibernate�́A�G���e�B�e�B���_�[�e�B�ł���ꍇ�A�t���b�V�����A
+ ���̊Ԃ� <literal>version</literal> �v���p�e�B�����I�ɃC���N�������g���܂��B
+ </para>
+
+ <para>
+ ������A�f�[�^�̕����Ⴂ���ʼn^�p���Ă���A�o�[�W�����`�F�b�N���s�v�Ȃ�A
+ ���̃A�v���[�`��g���A�o�[�W�����`�F�b�N��X�L�b�v���邾���ł��B
+ ���̏ꍇ�́A�����Θb�ɂ́A
+ <emphasis>�u�Ō�ɃR�~�b�g������̂����v</emphasis> ���f�t�H���g�̐헪�ł��傤�B
+ ���̃A�v���[�`�́A�A�v���P�[�V�����̃��[�U�[���������邩�����Ȃ����Ƃ�
+ �S�ɗ��߂Ēu���Ă��������B����́A�G���[���b�Z�[�W�⋣�������ύX��}�[�W����@�
+ �Ȃ��܂܁A�X�V�����o�����邽�߂ł��B
+ </para>
+
+ <para>
+ �m���ɁA�}�j���A���ɂ��o�[�W�����`�F�b�N�́A���ׂȋV�������Ŏ��s�ł��܂����A
+ �����̃A�v���P�[�V�����ɂƂ��Ď��p�I�ł͂���܂���B
+ �����A�P�̃C���X�^���X�����łȂ��A
+ �C�����ꂽ�I�u�W�F�N�g�̊��S�ȃO���t��`�F�b�N���Ȃ���Ȃ�܂���B
+ Hibernate�́A�v�p���_�C���Ƃ��āA�g�� <literal>Session</literal> ��
+ �������ꂽ�C���X�^���X�����I�Ƀo�[�W�����`�F�b�N���܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-longsession">
+ <title>�g���Z�b�V�����Ǝ����o�[�W���j���O</title>
+
+ <para>
+ �P�� <literal>Session</literal> �C���X�^���X�Ƃ��̉i�����C���X�^���X�́A
+ <emphasis>session-per-conversation</emphasis> �Ƃ��Ēm����A
+ �Θb�S�̂Ŏg���܂��B
+ Hibernate�̓t���b�V������ۂɁA�C���X�^���X�̃o�[�W������`�F�b�N���܂��B
+ �����ɏC�����ꂽ���Ƃ��o����ƁA��O�𓊂��܂��B
+ ���̗�O��L���b�`���Ĉ����̂́A�J���҂̐ӔC�ł�
+ �i��ʓI�ȑI���́A�ύX��}�[�W���邩�Â��Ȃ��f�[�^�Ńr�W�l�X�Θb��
+ �ăX�^�[�g����@����[�U�[�ɒ��邱�Ƃł��j�B
+ </para>
+
+ <para>
+ ���[�U�[�̑Θb��҂��Ă���Ƃ��́A
+ <literal>Session</literal> ���b�ƂȂ�JDBC�R�l�N�V��������藣���܂��B
+ ���̃A�v���[�`�́A�f�[�^�x�[�X�A�N�Z�X�̒��ł́A�ł�����I�ł��B
+ �A�v���P�[�V�����́A�o�[�W�����`�F�b�N�╪�����ꂽ�C���X�^���X��Ēlj����邱��
+ �ɊS���K�v�͂���܂���B�܂��A������f�[�^�x�[�X�g�����U�N�V�����̒���
+ �C���X�^���X��ēǂݍ��݂���K�v�͂���܂���B
+ </para>
+
+ <programlisting><![CDATA[// foo is an instance loaded earlier by the old session
+Transaction t = session.beginTransaction(); // Obtain a new JDBC connection, start transaction
+
+foo.setProperty("bar");
+
+session.flush(); // Only for last transaction in conversation
+t.commit(); // Also return JDBC connection
+session.close(); // Only for last transaction in conversation]]></programlisting>
+
+ <para>
+ <literal>foo</literal> �I�u�W�F�N�g�́A�������[�h���� <literal>Session</literal>
+ ��܂��m���Ă��܂��B
+ �Â��Z�b�V�����̏�ŐV�����f�[�^�x�[�X�g�����U�N�V������J�n���邱�ƂŁA
+ �V�����R�l�N�V������擾���A���̃Z�b�V�������ĊJ����܂��B
+ �f�[�^�x�[�X�g�����U�N�V������R�~�b�g���邱�ƂŁA
+ �Z�b�V��������JDBC�R�l�N�V������ؒf���A�R�l�N�V������v�[���ɕԂ��܂��B
+ �Đڑ�������A�X�V���Ă��Ȃ��f�[�^�̃o�[�W�����`�F�b�N�������邽�߂ɁA
+ ���̃g�����U�N�V�����ɂ��X�V����Ă��邩�����Ȃ��I�u�W�F�N�g�Ɋւ��āA
+ <literal>LockMode.READ</literal> ����� <literal>Session.lock()</literal>
+ ��Ăяo�����Ƃ��ł��܂��B
+ �X�V���� <emphasis>����</emphasis> �f�[�^���b�N����K�v�͂���܂���B
+
+ �ʏ�A�g�� <literal>Session</literal> �� <literal>FlushMode.MANUAL</literal>
+ ��Z�b�g���܂��B
+ �Ō�̃f�[�^�x�[�X�g�����U�N�V�����̎����ł̂݁A
+ �Θb�̒��ŕύX���ꂽ���ׂĂ���ۂɉi���������邽�߂ł��B
+ �䂦�ɁA�Ō�̃f�[�^�x�[�X�g�����U�N�V�����̂� <literal>flush()</literal>
+ �I�y���[�V������܂݂܂��B�����āA�Θb��I��点�邽�߂ɁA
+ �Z�b�V������ <literal>close()</literal> ���܂��B
+ </para>
+
+ <para>
+ ���[�U�[���l�����ɁA�i�[���邱�Ƃ��ł��Ȃ����炢 <literal>Session</literal>
+ ���傫���̂ł���A���̃p�^�[���͖�肪����܂��B
+ �Ⴆ�A<literal>HttpSession</literal> �͉\�Ȍ��菬�����ۂׂ��ł��B
+ <literal>Session</literal> �́i�����I�Ɂj�P���L���b�V���ł����A
+ ���[�h�����I�u�W�F�N�g���ׂĕێ����܂��B
+ �����炭�A���N�G�X�g�^���X�|���X�̃T�C�N��������ł���A���̐헪���g���܂��B
+
+ �P�̑Θb�̂��߂����� <literal>Session</literal> ��g���ׂ��ł��B
+ �Ȃ��Ȃ�A�����ɐV�N�łȂ��f�[�^�����߂ł��B
+ </para>
+
+ <para>
+ �iHibernate�̈ȑO�̃o�[�W�����́A�����I�� <literal>Session</literal> ��
+ �ؒf�ƍĐڑ����K�v���������Ƃɒ��ӂ��Ă��������B
+ �����̃��\�b�h�͔��ɂȂ�܂����B
+ �Ȃ��Ȃ�A�g�����U�N�V�����̊J�n�ƏI���͓������ʂ����邽�߂ł��B�j
+ </para>
+
+ <para>
+ �ؒf���� <literal>Session</literal> ��i�����w�̋߂��ŕێ����ׂ��ł��邱�Ƃ�
+ ���ӂ��Ă��������B
+ ����������ƁA�R�w���̒��� <literal>Session</literal> ��ێ����邽�߂ɁA
+ EJB�X�e�[�g�t���Z�b�V����Bean��g�����������B
+ <literal>HttpSession</literal> �Ɋi�[���邽�߂ɁAWeb�w�ɓ]�����Ȃ��ł�������
+ �i�ʂ̑w�ւ̃V���A���C�Y����Ȃ��ł��������j�B
+ </para>
+
+ <para>
+ �g���Z�b�V�����p�^�[���i������́A<emphasis>session-per-conversation</emphasis>�j�́A
+ �����I�ȃJ�����g�Z�b�V�����R���e�L�X�g�Ǘ�����{���������B
+ ���̂��߂ɁA���Ȃ��� <literal>CurrentSessionContext</literal> �̎�����������K�v������܂��B
+ Hibernate Wiki�ɂ�����Q�Ƃ��Ă��������B
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-detached">
+ <title>�f�^�b�`���ꂽ�I�u�W�F�N�g�Ǝ����o�[�W���j���O</title>
+
+ <para>
+ �V���� <literal>Session</literal>�ɂ��A�i�����X�g�A�i�F�c�a�j�Ƃ̑Θb���������܂��B
+ �܂�����A�����i�����C���X�^���X���A�f�[�^�x�[�X�Ƃ̑Θb���Ƃɍė��p����܂��B
+ �A�v���P�[�V�����́A���X�͑��� <literal>Session</literal> �Ń��[�h����A
+ �f�^�b�`���ꂽ�C���X�^���X�̏�Ԃ𑀍삵�܂��B
+ �����āA<literal>Session.update()</literal> ������́A<literal>Session.saveOrUpdate()</literal>�A
+ <literal>Session.merge()</literal> ��g���āA�����̃C���X�^���X��Ēlj����܂��B
+ </para>
+
+ <programlisting><![CDATA[// foo is an instance loaded by a previous Session
+foo.setProperty("bar");
+session = factory.openSession();
+Transaction t = session.beginTransaction();
+session.saveOrUpdate(foo); // Use merge() if "foo" might have been loaded already
+t.commit();
+session.close();]]></programlisting>
+
+ <para>
+ ���̏ꍇ���͂�AHibernate�̓t���b�V������ۂɁA�C���X�^���X�̃o�[�W������`�F�b�N���܂��B
+ �X�V�̋��������������ꍇ�ɂ́A��O�𓊂��܂��B
+ </para>
+
+ <para>
+ �I�u�W�F�N�g���C������Ă��Ȃ����Ƃ�m�M���Ă���ꍇ�́A
+ <literal>update()</literal> �̑���ɁA<literal>LockMode.READ</literal> ��g���āA
+ <literal>lock()</literal> ��Ăяo�����Ƃ�ł��܂�
+ �i���ׂẴL���b�V����I�A�o�[�W�����`�F�b�N����{���܂��j�B
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-customizing">
+ <title>�����o�[�W���j���O�̃J�X�^�}�C�Y</title>
+
+ <para>
+ �}�b�s���O�� <literal>optimistic-lock</literal> ������ <literal>false</literal>
+ ��ݒ肷�邱�Ƃɂ��A����̃v���p�e�B��R���N�V�����̂��߂�
+ �����o�[�W�����C���N�������g���ɂł��܂��B
+ �v���p�e�B���_�[�e�B�ł����Ă�A�o�[�W������C���N�������g���܂���B
+ </para>
+
+ <para>
+ ���K�V�[�̃f�[�^�x�[�X�X�L�[�}�́A�����ΌŒ�I�ł���A�ύX�ł��܂���B
+ �܂��́A���̃A�v���P�[�V�����������f�[�^�x�[�X�ɃA�N�Z�X���Ȃ���Ȃ炸�A
+ ���̃A�v���P�[�V�����̓o�[�W�����ԍ���^�C���X�^���v�������삷����@��m��܂���B
+ �ǂ���̏ꍇ��A�e�[�u���̓���̃J�����Ăɂ��āA�o�[�W���j���O��s���܂���B
+ �o�[�W������^�C���X�^���v�̃v���p�e�B��}�b�s���O�����ɁA�o�[�W�����`�F�b�N�����邽�߂ɁA
+ <literal><class></literal> �}�b�s���O�� <literal>optimistic-lock="all"</literal> ��
+ �w�肵�Ă��������B
+ �s�̂��ׂẴt�B�[���h�̏�Ԃ��r����悤�ɂȂ�܂��B
+ ����́AHibernate���Â���ԂƐV������Ԃ��r�ł���ꍇ�ɁA
+ ���_�I�ɓ��삷�邾���ł��邱�Ƃɒ��ӂ��Ă��������B
+ �Ⴆ�Asession-per-request-with-detached-objects �ł͂Ȃ��A
+ �P�̒��� <literal>Session</literal> ��g���ꍇ�ł��B
+ </para>
+
+ <para>
+ �Ƃ��ǂ��A�s��ꂽ�ύX���d�Ȃ�Ȃ�����A�����ɍs��ꂽ�ύX�����邱�Ƃ��ł��܂��B
+ <literal><class></literal> �}�b�s���O�� <literal>optimistic-lock="dirty"</literal>
+ ��ݒ肵���ꍇ�A�t���b�V������ۂɁAHibernate�̓_�[�e�B�t�B�[���h�݂̂��r���܂��B
+ </para>
+
+ <para>
+ ��p�̃o�[�W�����^�^�C���X�^���v�̃J������g���ꍇ�A
+ ������͂��ׂā^�_�[�e�B�̃t�B�[���h���r����ꍇ�ǂ���ł����Ă�A
+ Hibernate�̓G���e�B�e�B���Ƃ�1�� <literal>UPDATE</literal> ����
+ �i�K�� <literal>WHERE</literal> �߂Ƌ��Ɂj�g���A
+ �o�[�W�����`�F�b�N�Ə��̍X�V��s���܂��B
+ �֘A����G���e�B�e�B�̍Ēlj���J�X�P�[�h���邽�߂ɁA
+ �A���I�ȉi������g�p�����ꍇ�A�s�K�v�ȍX�V����s���邩�����܂���B
+ ����͒ʏ���ɂȂ�܂���B
+ �������A���������C���X�^���X��ύX���Ă��Ȃ��Ƃ�A
+ �f�[�^�x�[�X�� <emphasis>on update</emphasis> �g���K�[�����s����邩�����܂���B
+ <literal><class></literal> �}�b�s���O��
+ <literal>select-before-update="true"</literal> ��ݒ肷�邱�Ƃɂ���āA
+ ���̐U�镑����J�X�^�}�C�Y�ł��܂��B
+ �m���ɕύX���ꂽ����m�F���邽�߂ɁA�s��X�V����O�ɁA
+ �K���C���X�^���X�� <literal>SELECT</literal> ���܂��B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="transactions-locking">
+ <title>�ߊϓI���b�N</title>
+
+ <para>
+ ���[�U�����b�N�헪�ɔY�ނ̂ɑ����̎��Ԃ��₷���Ƃ�Ӑ}���Ă��܂���B
+ �ʏ�́AJDBC�R�l�N�V�����ɕ������x����w�肵�A
+ �P�Ƀf�[�^�x�[�X�ɂ��ׂĂ̎d��������Ώ\���ł��B
+ �������Ȃ���A���x�ȃ��[�U�́A�r���I�ȔߊϓI���b�N��l�����邱�Ƃ��A
+ �V�����g�����U�N�V�������J�n�����ۂɃ��b�N��Ċl�����邱�Ƃ�
+ �Ƃ��ǂ��]�ނ������܂���B
+ </para>
+
+ <para>
+ Hibernate�͂���f�[�^�x�[�X�̃��b�N�̎d�g�݂�g���܂��B
+ ��������̃I�u�W�F�N�g�����ă��b�N���܂���I
+ </para>
+
+ <para>
+ <literal>LockMode</literal> �N���X�́AHibernate���l���ł���قȂ郍�b�N���x�����`���܂��B
+ �ȉ��̎d�g�݂ɂ��A���b�N��l���ł��܂��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>LockMode.WRITE</literal> �́A
+ Hibernate���s��X�V������͑}������ۂɎ����I�ɓ����܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.UPGRADE</literal> �́A
+ �f�[�^�x�[�X�ŃT�|�[�g����Ă��镶�@ <literal>SELECT ... FOR UPDATE</literal>
+ ��g�����A�����I�ȃ��[�U�[�v���ɂ�蓾���邩�����܂���B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.UPGRADE_NOWAIT</literal> �́A
+ Oracle �� <literal>SELECT ... FOR UPDATE NOWAIT</literal> ��g�����A
+ �����I�ȃ��[�U�[�v���ɂ�蓾���邩�����܂���B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.READ</literal> �́A
+ Repeatable Read�������Serializable�̕������x���ŁA�f�[�^��ǂۂɎ����I�ɓ����܂��B
+ �����炭�A�����I�ȃ��[�U�[�v���ɂ��A�Ď擾����܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.NONE</literal> �́A���b�N���Ȃ����Ƃ�\���܂��B
+ <literal>Transaction</literal> �̏I���ɁA
+ ���ׂẴI�u�W�F�N�g�͂��̃��b�N���[�h�ɐ�ւ��܂��B
+ <literal>update()</literal> �� <literal>saveOrUpdate()</literal> ��Ăяo�����Ƃɂ���āA
+ �Z�b�V�����Ɋ֘A�t����ꂽ�I�u�W�F�N�g��A���̃��b�N���[�h�ŏo�����܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ �u�����I�ȃ��[�U�[�v���v�Ƃ́A���L�̕��@�̂P�Ō����\���܂��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>LockMode</literal> ��w�肵�� <literal>Session.load()</literal> �̌Ăяo���B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.lock()</literal> �̌Ăяo���B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Query.setLockMode()</literal> �̌Ăяo���B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>UPGRADE</literal> ������� <literal>UPGRADE_NOWAIT</literal> ���w�肳�ꂽ
+ <literal>Session.load()</literal> ���Ăяo����A
+ ���v�����ꂽ�I�u�W�F�N�g���Z�b�V�����ɂ���Ă܂����[�h����Ă��Ȃ������ꍇ�́A
+ <literal>SELECT ... FOR UPDATE</literal> ��g���āA�I�u�W�F�N�g�����[�h����܂��B
+ <literal>load()</literal> �ŌĂяo���ꂽ�I�u�W�F�N�g���A
+ �v������Ă����萧�������Ȃ����b�N�ł��łɃ��[�h����Ă����ꍇ�́A
+ Hibernate�͂��̃I�u�W�F�N�g�̂��߂ɁA<literal>lock()</literal> ��Ăяo���܂��B
+ </para>
+
+ <para>
+ �w�肳�ꂽ���b�N���[�h�� <literal>READ</literal> ������́A<literal>UPGRADE</literal>�A
+ <literal>UPGRADE_NOWAIT</literal> �������ꍇ�A<literal>Session.lock()</literal>
+ �́A�o�[�W�����ԍ��̃`�F�b�N����{���܂��B
+ �i<literal>UPGRADE</literal> ������� <literal>UPGRADE_NOWAIT</literal> �̏ꍇ�A
+ <literal>SELECT ... FOR UPDATE</literal> ���g���܂��B�j
+ </para>
+
+ <para>
+ �f�[�^�x�[�X���v�����ꂽ���b�N���[�h��T�|�[�g���Ă��Ȃ��ꍇ�A
+ Hibernate�́i��O�𓊂������ɁA�j�K�ȑ���̃��[�h��g���܂��B
+ ����́A�A�v���P�[�V�������|�[�^�u���ł��邱�Ƃ�ۏ��܂��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="transactions-connection-release">
+ <title>�R�l�N�V�����J�����[�h</title>
+
+ <para>
+ Hibernate�̃��K�V�[�i2.x�j��JDBC�R�l�N�V�����Ǘ��Ɋւ���U�镑���́A
+ �ŏ��ɕK�v�Ƃ����ۂ� <literal>Session</literal> ���R�l�N�V������Ƃ�����̂ł����B
+ �����āA�Z�b�V������������܂ŁA���̃R�l�N�V������ێ����܂����B
+ Hibernate 3.x�́A�Z�b�V������JDBC�R�l�N�V������ǂ̂悤�ɐ��䂷�邩��`����
+ �R�l�N�V�����J�����[�h�Ƃ����T�O�����܂����B
+ �ȍ~�̋c�_�́A�\�����ꂽ <literal>ConnectionProvider</literal> ��ʂ��Ē����
+ �R�l�N�V�����ɓK�ł��邱�Ƃɒ��ӂ��Ă��������B
+ �قȂ�J�����[�h�́A<literal>org.hibernate.ConnectionReleaseMode</literal> ��
+ ���ꂽ�l�ɂ��m�F����܂��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>ON_CLOSE</literal> - �{���I�ɏ�L�ŏq�ׂ����K�V�[�̐U�镑���ł��B
+ Hibernate�Z�b�V�����͍ŏ���JDBC�A�N�Z�X����s����K�v������ۂɃR�l�N�V�����܂��B
+ �����āA�Z�b�V������������܂ŁA�R�l�N�V������ێ����܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>AFTER_TRANSACTION</literal> -
+ <literal>org.hibernate.Transaction</literal> ������������A
+ �R�l�N�V������J�����܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>AFTER_STATEMENT</literal> �i�ϋɓI�ȊJ���Ƃ�Ă��j -
+ ���ׂẴX�e�[�g�����g�����ꂼ����s���ꂽ��A�R�l�N�V�������J������܂��B
+ �X�e�[�g�����g���Z�b�V�����Ɋ֘A���郊�\�[�X��J�����܂܂ɂ���ꍇ�́A
+ ���̐ϋɓI�ȊJ���̓X�L�b�v����܂��B
+ ���̂Ƃ���A���ꂪ�N����̂� <literal>org.hibernate.ScrollableResults</literal>
+ ���g����ꍇ�݂̂ł��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ �R���t�B�O���[�V�����p�����[�^�� <literal>hibernate.connection.release_mode</literal>
+ �́A�g�p����J�����[�h��w�肷�邽�߂Ɏg���܂��B
+ �w��ł���l�͎��̒ʂ�ł��B
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>auto</literal> �i�f�t�H���g�j - �����I�����
+ <literal>org.hibernate.transaction.TransactionFactory.getDefaultReleaseMode()</literal>
+ ���\�b�h�ɂ���ĕԂ����J�����[�h�ɈϏ�����܂��B
+ ���̃��\�b�h�́A
+ JTATransactionFactory�ɂ�ConnectionReleaseMode.AFTER_STATEMENT��Ԃ��A
+ JDBCTransactionFactory�ɂ�ConnectionReleaseMode.AFTER_TRANSACTION��Ԃ��܂��B
+ ���̃f�t�H���g�̐U�镑����ς��Ă��܂�����������������܂���B
+ ����́A���̐ݒ�l�������ŋN�����Q�́A
+ ���[�U�R�[�h�̒��Ńo�O��Ԉ�������ɂȂ�₷������ł��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>on_close</literal> - ConnectionReleaseMode.ON_CLOSE��g���܂��B
+ ���̐ݒ�͌���݊��̂��߂Ɏc����Ă��܂����A�g��Ȃ����Ƃ������߂܂��B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>after_transaction</literal> - ConnectionReleaseMode.AFTER_TRANSACTION��g���܂��B
+ ���̐ݒ��JTA���̒��ł͎g���ׂ��ł͂���܂���B
+ ConnectionReleaseMode.AFTER_TRANSACTION��w�肵�A�����R�~�b�g���[�h�̒��ł́A
+ �J�����[�h��AFTER_STATEMENT�ł��邩�̂悤�ɁA�R�l�N�V�����͊J������邱�Ƃɒ��ӂ��Ă��������B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>after_statement</literal> - ConnectionReleaseMode.AFTER_STATEMENT��g���܂��B
+ ����ɁA�ݒ肳�ꂽ <literal>ConnectionProvider</literal> �́A
+ ���̐ݒ� (<literal>supportsAggressiveRelease()</literal>) ��T�|�[�g���邩�ǂ���
+ �ׂ邽�߂Ɏg�p���܂��B
+ ��������łȂ��ꍇ�A�J�����[�h��ConnectionReleaseMode.AFTER_TRANSACTION
+ �Ƀ��Z�b�g����܂��B
+ ���̐ݒ�͎��̊��ł݈̂��S�ł��B
+ ����́A<literal>ConnectionProvider.getConnection()</literal> ��Ăяo�����т�
+ ��ՂƂȂ�JDBC�R�l�N�V������������̂�擾�ł��邩�A
+ �����R�l�N�V�����������邱�Ƃ����ƂȂ�Ȃ������R�~�b�g���̒��ł��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/tutorial.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/tutorial.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/tutorial.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/tutorial.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,1600 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="tutorial">
+ <title>Hibernate�̓���</title>
+
+ <sect1 id="tutorial-intro" revision="1">
+ <title>�O����</title>
+
+ <para>
+ ���̏͂�Hibernate���߂Ďg�����[�U�����̓���I�ȃ`���[�g���A���ł��B
+ �C���������f�[�^�x�[�X��g���ȒP�ȃR�}���h���C���A�v���P�[�V��������n�߁A
+ �����킩��₷�������ŊJ����i�߂܂��B
+ </para>
+
+ <para>
+ ���̃`���[�g���A����Hibernate���߂Ďg�����[�U��z�肵�Ă��܂����A
+ ������ɂ�Java��SQL�ɂ��Ă̒m�����K�v�ł��B
+ �����Michael Gloegl�̎�ɂ��`���[�g���A�����~���ɂ��Ă��܂����A
+ �����ŃT�[�h�p�[�e�B���C�u�����ƌ����Ă���̂́AJDK 1.4��5.0�p�̂�̂ł��B
+ JDK 1.3�𗘗p����̂ł���Α��̃��C�u�������K�v�������܂���B
+ </para>
+
+ <para>
+ �`���[�g���A���̃\�[�X�R�[�h��Hibernate�f�B�X�g���r���[�V������
+ <literal>doc/reference/tutorial/</literal> �ɂ���܂��B
+ </para>
+
+ </sect1>
+
+ <sect1 id="tutorial-firstapp" revision="2">
+ <title>�p�[�g1 - ���߂Ă�Hibernate�A�v���P�[�V����</title>
+
+ <para>
+ �ŏ��ɃR���\�[���x�[�X�̊ȒP��Hibernate�A�v���P�[�V������쐬���܂��B
+ Java�f�[�^�x�[�X�iHSQL DB�j�𗘗p����̂ŁA
+ �f�[�^�x�[�X�T�[�o��C���X�g�[������K�v�͂���܂���B
+ </para>
+
+ <para>
+ ���ɏ����ȃf�[�^�x�[�X�A�v���P�[�V�������K�v���Ƃ��܂��傤�B
+ ���̃A�v���P�[�V�����ɂ͏o�Ȃ������C�x���g�ƁA
+ ���̃C�x���g�̃z�X�g�ɂ��Ă̏���i�[�����̂Ƃ��܂��B
+ </para>
+
+ <para>
+ �܂��ŏ��ɂ��邱�Ƃ͊J���p�̃f�B���N�g����Z�b�g�A�b�v���āA
+ �K�v�ƂȂ邷�ׂĂ�Java���C�u������z�u���邱�Ƃł��B
+ Hibernate�E�F�u�T�C�g����Hibernate�f�B�X�g���r���[�V������_�E�����[�h�����������B
+ �t�@�C����𓀂��� <literal>/lib</literal> �ɂ���K�v�ȃ��C�u�����̂��ׂĂ�A
+ �V�����J���p�f�B���N�g���� <literal>/lib</literal> �f�B���N�g���ɔz�u���Ă��������B
+ ���̂悤�ɂȂ��Ă���͂��ł��F
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ antlr.jar
+ cglib.jar
+ asm.jar
+ asm-attrs.jars
+ commons-collections.jar
+ commons-logging.jar
+ hibernate3.jar
+ jta.jar
+ dom4j.jar
+ log4j.jar ]]></programlisting>
+
+ <para>
+ ���ꂪ <emphasis>�{�h�L�������g���M���_�ł�</emphasis> Hibernate�̕K�v�Œ���̃��C�u�����ł�
+ �i���C���A�[�J�C�u��hibernate3.jar��R�s�[���Ă��邱�Ƃɒ��ӂ��Ă��������j�B
+ Hibernate�̃o�[�W�����ɂ���Ă͂���ɕK�v�ȃ��C�u������A�s�v�ȃ��C�u���������邩�����܂���B
+ Hibernate�f�B�X�g���r���[�V������ <literal>lib/</literal> �f�B���N�g���ɂ���
+ <literal>README.txt</literal> �t�@�C�������������B
+ �K�{�܂��̓I�v�V�����̃T�[�h�p�[�e�B���C�u�����ɂ��Ă̏���ڂ��Ă��܂�
+ �i����Log4j�͕K�{�ł͂���܂��A�����̊J���҂��D��ł��܂��j�B
+ </para>
+
+ <para>
+ ���Ƀf�[�^�x�[�X�Ɋi�[����C�x���g��\���N���X��쐬���܂��B
+ </para>
+
+ <sect2 id="tutorial-firstapp-firstclass" revision="1">
+ <title>�ŏ��̃N���X</title>
+
+ <para>
+ �ŏ��̉i���N���X�́A�v���p�e�B���������V���v����JavaBean�ł��F
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+import java.util.Date;
+
+public class Event {
+ private Long id;
+
+ private String title;
+ private Date date;
+
+ public Event() {}
+
+ public Long getId() {
+ return id;
+ }
+
+ private void setId(Long id) {
+ this.id = id;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}]]></programlisting>
+
+ <para>
+ �����̂Ƃ���A���̃N���X�̓t�B�[���h��private�̉��������Ă���̂Ɠ����ɁA
+ JavaBean�W���̃Q�b�^�[�A�Z�b�^�[���\�b�h�̖����K��ɏ]���Ă��܂��B
+ ���̂悤�Ȑv�͐�������Ă��܂����K�{�ł͂���܂���B
+ �A�N�Z�T���\�b�h��݂���̂̓��t�@�N�^�����O��l�����挒���̂��߂ŁA
+ Hibernate�̓t�B�[���h�ɒ��ڃA�N�Z�X���邱�Ƃ�\�ł��B
+ �����̂Ȃ��R���X�g���N�^�́A���t���N�V�����ł��̃N���X�̃C���X�^���X��쐬���邽�߂�
+ �K�v�ł��B
+ </para>
+
+ <para>
+ <literal>id</literal> �v���p�e�B�́A�������̃C�x���g�ɑ��郆�j�[�N�Ȏ��ʎq�̒l��ێ����܂��B
+ Hibernate�̊��S�ȋ@�\��g��������A���ׂẲi���G���e�B�e�B�N���X
+ �i����قǏd�v�ł͂Ȃ��ˑ��N���X�Ƃ�����̂����܂��j
+ �ɂ��̂悤�Ȏ��ʎq�v���p�e�B���K�v�ɂȂ�܂��B
+ ������قƂ�ǂ̃A�v���P�[�V�����i����web�A�v���P�[�V�����j�ł́A
+ ���ʎq�ŃI�u�W�F�N�g���ʂ���K�v�����邽�߁A����͐����Ƃ�����������ł���ƍl����ׂ��ł��B
+ �������ʏ�I�u�W�F�N�g��ID�𑀍삷��悤�Ȃ��Ƃ͂��܂���B
+ ���̂��߃Z�b�^�[���\�b�h��private�ɂ���ׂ��ł��B
+ Hibernate�������I�u�W�F�N�g���Z�[�u���ꂽ�Ƃ��Ɏ��ʎq�֒l�������܂��B
+ Hibernate���ipublic, private, protected�j�t�B�[���h�ɒ��ڃA�N�Z�X�ł���̂Ɠ��l�ɁA
+ public, private, protected�̃A�N�Z�T���\�b�h�ɃA�N�Z�X�ł���Ƃ������Ƃ��킩��ł��傤�B
+ �I��͂��Ȃ��ɔC����Ă���̂ŁA���Ȃ��̃A�v���P�[�V�����̐v�ɍ��킹�邱�Ƃ��ł��܂��B
+ </para>
+
+ <para>
+ �����̂Ȃ��R���X�g���N�^�͂��ׂẲi���N���X�ɕK�{�ł��B
+ �����Hibernate��Java�̃��t���N�V������g���āA�I�u�W�F�N�g��쐬���Ȃ���Ȃ�Ȃ����߂ł��B
+ �R���X�g���N�^��private�ɂ��邱�Ƃ͉\�ł����A
+ ���s���̃v���L�V�����ƁA�o�C�g�R�[�h����Ȃ��̌����I�ȃf�[�^�̒��o�ɂ́A
+ package�������K�v�ł��B
+ </para>
+
+ <para>
+ �J���t�H���_�� <literal>src</literal> �Ƃ����f�B���N�g���̓K�ȃp�b�P�[�W�ɁA
+ ����Java�\�[�X�t�@�C����z�u�����������B
+ ���̎��_�Ńf�B���N�g���͈ȉ��̂悤�ɂȂ��Ă���͂��ł��F
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java]]></programlisting>
+
+ <para>
+ ���̃X�e�b�v�ł́AHibernate�ɂ��̉i���N���X�̏������܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-mapping" revision="1">
+ <title>�}�b�s���O�t�@�C��</title>
+
+ <para>
+ Hibernate�́A�ǂ̂悤�ɉi���N���X�̃I�u�W�F�N�g���[�h���i�[����悢����m��K�v������܂��B
+ ������Hibernate�}�b�s���O�t�@�C�����o�ꂵ�܂��B
+ �}�b�s���O�t�@�C���́A�f�[�^�x�[�X��̂ǂ̃e�[�u���ɃA�N�Z�X���Ȃ���Ȃ�Ȃ����A
+ ���̃e�[�u���̂ǂ̃J������g���ׂ�����AHibernate�ɋ����܂��B
+ </para>
+
+ <para>
+ �}�b�s���O�t�@�C���̊�{�I�ȍ\���͂��̂悤�ɂȂ�܂��F
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping>
+[...]
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Hibernate DTD�����ɐ������Ă��邱�Ƃɒ��ڂ��Ă��������B
+ ����DTD�́A�G�f�B�^��IDE�ł�XML�}�b�s���O�v�f�Ƒ����̃I�[�g�R���v���[�V�����@�\�ɗ��p�ł��܂��B
+ �܂�DTD�t�@�C����e�L�X�g�G�f�B�^�ŊJ���Ă݂Ă��������B
+ �Ƃ����̂�A���ׂĂ̗v�f�Ƒ�����T�ς��A
+ �R�����g��f�t�H���g�̒l����ɂ͈�ԊȒP�ȕ��@������ł��B
+ Hibernate�́Aweb����DTD�t�@�C�����[�h�����ɁA
+ �܂��A�v���P�[�V�����̃N���X�p�X���炱���T���o�����Ƃ��邱�Ƃɒ��ӂ��Ă��������B
+ DTD�t�@�C����Hibernate�f�B�X�g���r���[�V������ <literal>src/</literal>
+ �f�B���N�g���Ɠ��l�A<literal>hibernate3.jar</literal> �ɂ�܂܂�Ă��܂��B
+ </para>
+
+ <para>
+ �ȍ~�̗�ł̓R�[�h��Z�����邽�߂�DTD�錾��ȗ����܂��B
+ ���R�ł�������̓I�v�V�����ł͂���܂���B
+ </para>
+
+ <para>
+ 2�� <literal>hibernate-mapping</literal> �^�O�̊Ԃ�
+ <literal>class</literal> �v�f��܂߂Ă��������B
+ ���ׂẲi���G���e�B�e�B�N���X�i�O�����܂����A
+ �t�@�[�X�g�N���X�̃G���e�B�e�B�ł͂Ȃ��ˑ��N���X�Ƃ�����̂���قǓo�ꂵ�܂��j
+ ��SQL�f�[�^�x�[�X��̃e�[�u���ւ̂��̂悤�ȃ}�b�s���O��K�v�Ƃ��܂��B
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ ����܂Ŏ������́A<literal>Event</literal> �N���X�̃I�u�W�F�N�g��
+ <literal>EVENTS</literal> �e�[�u���ɑ��āA�ǂ̂悤�ɉi���������胍�[�h�����肷��̂���
+ Hibernate�ɋ����Ă��܂����B�����ČX�̃C���X�^���X�̓e�[�u���̍s�Ƃ��ĕ\������܂��B
+ ����ł͈��������e�[�u���̎�L�[�ɑ��郆�j�[�N�Ȏ��ʎq�v���p�e�B��}�b�s���O���Ă����܂��B
+ ����ɁA���̎��ʎq�̈����ɋC��g�������Ȃ������̂Ɠ��l�ɁA
+ �㗝�̎�L�[�J�����ɑ���Hibernate�̎��ʎq�����헪��ݒ肵�܂��B
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+ <id name="id" column="EVENT_ID">
+ <generator class="native"/>
+ </id>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>id</literal> �v�f�͎��ʎq�v���p�e�B�̐錾�ł���A
+ <literal>name="id"</literal> ��Java�v���p�e�B�̖��O��錾���܂��B
+ Hibernate�͂��̃v���p�e�B�փA�N�Z�X���邽�߂ɃQ�b�^�[�A�Z�b�^�[���\�b�h��g���܂��B
+ �J���������ł� <literal>EVENTS</literal> �e�[�u���̂ǂ̃J�������L�[�Ƃ��Ďg���̂���
+ Hibernate�ɋ����܂��B
+ ����q�ɂȂ��Ă��� <literal>generator</literal> �v�f�́A���ʎq�����鎞�̐헪��w�肵�܂��B
+ �i���̗�ł� <literal>native</literal> ��p���܂����j�B
+ ���̗v�f�́A�ݒ肵���f�[�^�x�[�X�idialect�j�ɑ���ŗǂȎ��ʎq�����헪��I�肷���̂ł��B
+ Hibernate�́A�A�v���P�[�V�����Œl���蓖�Ă�헪�i������͓Ǝ��Ɋg�������헪�j�Ɠ��l�ɁA
+ �O���[�o���Ƀ��j�[�N�Ȓl��f�[�^�x�[�X�ɐ���������헪��T�|�[�g���Ă��܂��B
+ </para>
+
+ <para>
+ �Ō�ɃN���X�̉i���v���p�e�B�̐錾��}�b�s���O�t�@�C���Ɋ܂߂܂��B
+ �f�t�H���g�ł́A�N���X�̃v���p�e�B�͉i���ƌ��Ȃ���܂���F
+ </para>
+
+ <programlisting><![CDATA[
+<hibernate-mapping>
+
+ <class name="events.Event" table="EVENTS">
+ <id name="id" column="EVENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="date" type="timestamp" column="EVENT_DATE"/>
+ <property name="title"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>id</literal> �v�f�̏ꍇ�Ɠ��l�ɁA <literal>property</literal> �v�f��
+ <literal>name</literal> �����ŁA�ǂ̃Q�b�^�[�ƃZ�b�^�[���\�b�h��g���ׂ�����Hibernate�ɋ����܂��B
+ ���̗�ł́AHibernate�� <literal>getDate()/setDate()</literal> �� <literal>getTitle()/setTitle()</literal> ��
+ �T���܂��B
+ </para>
+
+ <para>
+ �Ȃ� <literal>date</literal> �v���p�e�B�̃}�b�s���O�ɂ� <literal>column</literal>
+ ����������A<literal>title</literal> �v���p�e�B�ɂ͂Ȃ��̂ł��傤���H
+ <literal>column</literal> �������Ȃ���AHibernate�̓v���p�e�B����J�������Ƃ��Ďg���܂��B
+ ����� <literal>title</literal> �ł͏�肭�s���܂��B
+ ������ <literal>date</literal> �͂قƂ�ǂ̃f�[�^�x�[�X�ŗ\���Ȃ̂ŁA
+ �Ⴄ���O�Ń}�b�s���O���������悢�̂ł��B
+ </para>
+
+ <para>
+ ���ɋ����[���̂� <literal>title</literal> �}�b�s���O�� <literal>type</literal>
+ �����������Ă���_�ł��B
+ �}�b�s���O�t�@�C���Ő錾���Ďg��type�́A���킩�肩�����܂���Java�̃f�[�^�^�ł͂���܂���B
+ SQL�f�[�^�x�[�X�̌^�ł����܂���B
+ ����� <emphasis>Hibernate�}�b�s���O�^</emphasis> �ƌĂ��A
+ Java����SQL�f�[�^�̌^�ւ܂���SQL����Java�f�[�^�^�֖|��R���o�[�^�ł��B
+ �J��Ԃ��ɂȂ�܂����AHibernate�� <literal>type</literal> �������}�b�s���O�t�@�C����ɂȂ���A
+ �������R���o�[�W�����ƃ}�b�s���O�^�����ʼn����悤�Ƃ��܂��B
+ �iJava�N���X�̃��t���N�V������g�����j���̎������m�́A
+ �ꍇ�ɂ���Ă͂��Ȃ������҂܂��͕K�v�Ƃ���f�t�H���g�l�ɂȂ�Ȃ��������܂���B
+ <literal>date</literal> �v���p�e�B�̏ꍇ�������ł����B
+ Hibernate�͂��́i <literal>java.util.Date</literal> �́j�v���p�e�B��
+ SQL�� <literal>date</literal> , <literal>timestamp</literal> ,
+ <literal>time</literal> �̂����A�ǂ̃J�����Ƀ}�b�s���O����ׂ��Ȃ̂��킩��܂���B
+ <literal>timestamp</literal> �R���o�[�^�Ńv���p�e�B��}�b�s���O���邱�Ƃɂ��A���S�ȓ�����ۑ����܂��B
+ </para>
+
+ <para>
+ ���̃}�b�s���O�t�@�C���́A<literal>Event.hbm.xml</literal> �Ƃ��� <literal>Event</literal>
+ Java�N���X�\�[�X�t�@�C���̂����ׂɃZ�[�u����ׂ��ł��B
+ �}�b�s���O�t�@�C���̖������@�͔C�ӂł����A<literal>hbm.xml</literal>
+ �T�t�B�b�N�X��Hibernate�̊J���҂̃R�~���j�e�B��ł̏K���ƂȂ��Ă��܂��B
+ ���݃f�B���N�g���\���͂��̂悤�ɂȂ��Ă���͂��ł��F
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java
+ Event.hbm.xml]]></programlisting>
+
+ <para>
+ Hibernate�̎�v�Ȑݒ�𑱂��܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-configuration" revision="2">
+ <title>Hibernate�̐ݒ�</title>
+
+ <para>
+ �����܂łʼni���N���X�ƃ}�b�s���O�t�@�C���������܂����B���ꂩ��Hibernate�̐ݒ��s���܂����A
+ ���̑O�Ƀf�[�^�x�[�X���K�v�ł��B
+ HSQL DB��Java�x�[�X�̃C��������SQL DBMS�ł���AHSQL DB�E�F�u�T�C�g����_�E�����[�h�ł��܂��B
+ ���ۂɂ̓_�E�����[�h�������� <literal>hsqldb.jar</literal> �������K�v�ł��B
+ ���̃t�@�C����J���t�H���_�� <literal>lib/</literal> �f�B���N�g���ɔz�u���Ă��������B
+ </para>
+
+ <para>
+ <literal>data</literal> �Ƃ����f�B���N�g����J���f�B���N�g���̃��[�g�ɍ쐬���Ă��������B
+ HSQL DB�͂����Ƀf�[�^�t�@�C����i�[���܂��B
+ ���̃f�[�^�f�B���N�g���ɂ����� <literal>java -classpath lib/hsqldb.jar org.hsqldb.Server</literal> ����s���A
+ �f�[�^�x�[�X��N���������������B
+ ����̊J�n�ƁATCP/IP�\�P�b�g�̃o�C���h���m�F�ł��܂��B
+ ��قǍ쐬����A�v���P�[�V�����͂����ɐڑ����܂��B
+ ������̃`���[�g���A�����Ƀf�[�^�x�[�X��������������A
+ HSQL DB��V���b�g�_�E�����āi��ƃE�B���h�E�� <literal>CTRL + C</literal> �����܂��j
+ <literal>data/</literal> �f�B���N�g����̃t�@�C����S�ď���������A
+ HSQL DB��ċN�����܂��B
+ </para>
+
+ <para>
+ Hibernate�̓A�v���P�[�V�����̃f�[�^�x�[�X�ɐڑ�����w�Ȃ̂ŁA
+ �R�l�N�V�����̏�K�v�ɂȂ�܂��B
+ �R�l�N�V������JDBC�R�l�N�V�����v�[����ʂ��čs���܂����A�����ݒ肷��K�v������܂��B
+ Hibernate�f�B�X�g���r���[�V�����ɂ͂������̃I�[�v���\�[�X��JDBC�R�l�N�V�����v�[���c�[�����܂܂�Ă��܂����A
+ ���̃`���[�g���A���ł�Hibernate�ɑg�ݍ��܂ꂽ�R�l�N�V�����v�[����g���܂��B
+ ������i���x���̕i���̃T�[�h�p�[�e�BJDBC�R�l�N�V�����v�[���\�t�g�E�F�A��g��������A
+ �N���X�p�X�ɕK�v�ȃ��C�u������R�s�[���āA�قȂ�R�l�N�V�����v�[����ݒ肵�Ȃ����
+ �Ȃ�Ȃ����Ƃɒ��ӂ��Ă��������B
+ </para>
+
+ <para>
+ Hibernate�̐ݒ�ł́A�P���� <literal>hibernate.properties</literal> �t�@�C���A
+ �����菭���������Ă��� <literal>hibernate.cfg.xml</literal> �t�@�C���A
+ �܂��͊��S�Ƀv���O������ŃZ�b�g�A�b�v������@�����p�ł��܂��B
+ �قƂ�ǂ̃��[�U���D�ނ̂�XML�ݒ�t�@�C���ł��F
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <session-factory>
+
+ <!-- Database connection settings -->
+ <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
+ <property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
+ <property name="connection.username">sa</property>
+ <property name="connection.password"></property>
+
+ <!-- JDBC connection pool (use the built-in) -->
+ <property name="connection.pool_size">1</property>
+
+ <!-- SQL dialect -->
+ <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
+
+ <!-- Enable Hibernate's automatic session context management -->
+ <property name="current_session_context_class">thread</property>
+
+ <!-- Disable the second-level cache -->
+ <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
+
+ <!-- Echo all executed SQL to stdout -->
+ <property name="show_sql">true</property>
+
+ <!-- Drop and re-create the database schema on startup -->
+ <property name="hbm2ddl.auto">create</property>
+
+ <mapping resource="events/Event.hbm.xml"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ ����XML�̐ݒ肪�قȂ�DTD��g�����Ƃɒ��ӂ��Ă��������B
+ ����̃f�[�^�x�[�X����O���[�o���t�@�N�g���ł���Hibernate��
+ <literal>SessionFactory</literal> ��ݒ肵�܂��B
+ ��������̃f�[�^�x�[�X������ꍇ�ɂ́A
+ �i�X�^�[�g�A�b�v��ȒP�ɂ��邽�߁j�ʏ킢�����̐ݒ�t�@�C����ŁA
+ �������� <literal><session-factory></literal> ��g���ݒ�ɂ��Ă��������B
+ </para>
+
+ <para>
+ �ŏ���4�� <literal>property</literal> �v�f��JDBC�R�l�N�V�����ɕK�v�Ȑݒ��܂�ł��܂��B
+ dialect�Ƃ������O�� <literal>property</literal> �v�f�́AHibernate��������������SQL������w�肵�܂��B
+ �i���I�ȃR���e�L�X�g�ɑ���Hibernate�̃Z�b�V�����̎����Ǘ��́A��̗�ł����ɂ킩��悤�ɁA��ɗ����Ƃł��傤�B
+ <literal>hbm2ddl.auto</literal> �I�v�V�����̓f�[�^�x�[�X�X�L�[�}�̎���������on�ɂ��܂��B
+ ����͒��ڃf�[�^�x�[�X�ɑ��Đ�������܂��B
+ ���R�iconfig�I�v�V������폜���ājoff�ɂ�����A
+ <literal>SchemaExport</literal> �Ƃ���Ant�^�X�N�̏������ăt�@�C���Ƀ��_�C���N�g������ł��܂��B
+ �Ō�ɉi���N���X�̂��߂̃}�b�s���O�t�@�C����ݒ�ɒlj����܂��B
+ </para>
+
+ <para>
+ ���̃t�@�C����\�[�X�f�B���N�g���ɃR�s�[���Ă��������B
+ ����Ƃ���̓N���X�p�X�̃��[�g�ɂ��邱�ƂɂȂ�܂��B
+ Hibernate�́A�X�^�[�g�A�b�v���ɃN���X�p�X�̃��[�g�� <literal>hibernate.cfg.xml</literal>
+ �Ƃ����t�@�C�������I�ɒT���܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-ant" revision="1">
+ <title>Ant�ɂ��r���h</title>
+
+ <para>
+ ����ł�Ant��g���ă`���[�g���A����r���h���܂��傤�B
+ ����ɂ�Ant���C���X�g�[������Ă��Ȃ���Ȃ�܂���B
+ <ulink url="http://ant.apache.org/bindownload.cgi">Ant�_�E�����[�h�y�[�W</ulink>
+ ����_�E�����[�h�����������B
+ Ant�̃C���X�g�[�����@�͂����ł͐�����܂���̂ŁA
+ <ulink url="http://ant.apache.org/manual/index.html">Ant�}�j���A��</ulink>
+ ��Q�Ƃ��Ă��������B
+ Ant��C���X�g�[������A�r���h�t�@�C���̍쐬��J�n�ł��܂��B
+ ���̃t�@�C���� <literal>build.xml</literal> �ƌĂ�A�J���f�B���N�g���ɒ��ڔz�u���܂��B
+ </para>
+
+ <para>
+ ��{�I�ȃr���h�t�@�C���͂��̂悤�ɂȂ�܂��F
+ </para>
+
+ <programlisting><![CDATA[<project name="hibernate-tutorial" default="compile">
+
+ <property name="sourcedir" value="${basedir}/src"/>
+ <property name="targetdir" value="${basedir}/bin"/>
+ <property name="librarydir" value="${basedir}/lib"/>
+
+ <path id="libraries">
+ <fileset dir="${librarydir}">
+ <include name="*.jar"/>
+ </fileset>
+ </path>
+
+ <target name="clean">
+ <delete dir="${targetdir}"/>
+ <mkdir dir="${targetdir}"/>
+ </target>
+
+ <target name="compile" depends="clean, copy-resources">
+ <javac srcdir="${sourcedir}"
+ destdir="${targetdir}"
+ classpathref="libraries"/>
+ </target>
+
+ <target name="copy-resources">
+ <copy todir="${targetdir}">
+ <fileset dir="${sourcedir}">
+ <exclude name="**/*.java"/>
+ </fileset>
+ </copy>
+ </target>
+
+</project>]]></programlisting>
+
+ <para>
+ ����� <literal>.jar</literal> �ŏI���lib�f�B���N�g���̂��ׂẴt�@�C����A
+ �R���p�C���Ɏg�p����N���X�p�X�ɒlj����邱�Ƃ�Ant�ɋ����܂��B
+ �܂��AJava�\�[�X�t�@�C���łȂ����ׂẴt�@�C����^�[�Q�b�g�f�B���N�g���ɃR�s�[����Ƃ������Ƃł����܂��B
+ �Ⴆ�ΐݒ�t�@�C����Hibernate�}�b�s���O�t�@�C���Ȃǂł��B
+ ��Ant����s����ƁA���̂悤�ȏo�͂�����͂��ł��F
+ </para>
+
+ <programlisting><![CDATA[C:\hibernateTutorial\>ant
+Buildfile: build.xml
+
+copy-resources:
+ [copy] Copying 2 files to C:\hibernateTutorial\bin
+
+compile:
+ [javac] Compiling 1 source file to C:\hibernateTutorial\bin
+
+BUILD SUCCESSFUL
+Total time: 1 second ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-helpers" revision="3">
+ <title>�X�^�[�g�A�b�v�ƃw���p</title>
+
+ <para>
+ ���� <literal>Event</literal> �I�u�W�F�N�g���[�h������i�[�����肷�鏀�����ł��܂����B
+ �������܂��̓C���t���X�g���N�`���̃R�[�h�����āA�Z�b�g�A�b�v��������K�v������܂��B
+ �܂���Hibernate��X�^�[�g�A�b�v���Ȃ���Ȃ�܂���B
+ ���̃X�^�[�g�A�b�v�ɂ́A�O���[�o���� <literal>SessionFactory</literal> �I�u�W�F�N�g�����āA
+ �����A�v���P�[�V�����̃R�[�h�ŃA�N�Z�X���₷���ꏊ�Ɋi�[���邱�Ƃ��܂܂�܂��B
+ <literal>SessionFactory</literal> �͐V���� <literal>Session</literal> ��I�[�v�����邱�Ƃ��ł��܂��B
+ <literal>Session</literal> �̓V���O���X���b�h�̍�ƒP��(Unit of Work)��\�����܂��B
+ ����ɑ�<literal>SessionFactory</literal> �̓X���b�h�Z�[�t�̃O���[�o���I�u�W�F�N�g�ł���A
+ ��x�����C���X�^���X������܂��B
+ </para>
+
+ <para>
+ �����ŃX�^�[�g�A�b�v��s���A �֗��� <literal>SessionFactory</literal> �փA�N�Z�X����
+ <literal>HibernateUtil</literal> �w���p�N���X��쐬���܂��B
+ �������Ă݂܂��傤�F
+ </para>
+
+ <programlisting><![CDATA[package util;
+
+import org.hibernate.*;
+import org.hibernate.cfg.*;
+
+public class HibernateUtil {
+
+ private static final SessionFactory sessionFactory;
+
+ static {
+ try {
+ // Create the SessionFactory from hibernate.cfg.xml
+ sessionFactory = new Configuration().configure().buildSessionFactory();
+ } catch (Throwable ex) {
+ // Make sure you log the exception, as it might be swallowed
+ System.err.println("Initial SessionFactory creation failed." + ex);
+ throw new ExceptionInInitializerError(ex);
+ }
+ }
+
+ public static SessionFactory getSessionFactory() {
+ return sessionFactory;
+ }
+
+}]]></programlisting>
+
+ <para>
+ ���̃N���X�͐ÓI�������u���b�N�i�N���X�����[�h�����Ƃ���JVM�ɂ���Ĉ�x�����Ă��j
+ �ŃO���[�o���� <literal>SessionFactory</literal> �����邾���ł͂Ȃ��A
+ �ÓI�V���O���g���̎g�p��B�����܂��B
+ �A�v���P�[�V�����T�[�o�[��JNDI���� <literal>SessionFactory</literal> ��
+ ���b�N�A�b�v����̂Ɠ��l�ł��B
+ </para>
+
+ <para>
+ �ݒ�t�@�C����� <literal>SessionFactory</literal> �ɖ��O��^����ƁA
+ Hibernate�� <literal>SessionFactory</literal> �\�z���JNDI�ɑ��o�C���h��s�����Ƃ��܂��B
+ ���̃R�[�h���S�ɔr�����邽�߂ɂ́A
+ JMX�f�v���C�����g�𗘗p����
+ JMX�𗘗p�ł���R���e�i��C���X�^���X�����A
+ <literal>HibernateService</literal> ��JNDI�փo�C���h���邱�Ƃ�ł��܂��B
+ �����̍��x�ȃI�v�V�����́AHibernate�̃��t�@�����X�h�L�������g�Ő������Ă��܂��B
+ </para>
+
+ <para>
+ <literal>HibernateUtil.java</literal> ��J���\�[�X�f�B���N�g���ɂ��� <literal>events</literal> �p�b�P�[�W��
+ �ׂɔz�u���Ă��������B
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java
+ Event.hbm.xml
+ +util
+ HibernateUtil.java
+ hibernate.cfg.xml
++data
+build.xml]]></programlisting>
+
+ <para>
+ ����͖��Ȃ��ăR���p�C���ł���͂��ł��B
+ �Ō�Ƀ��M���O�V�X�e����ݒ肷��K�v������܂��B
+ Hibernate��commons logging��g�����߁ALog4j��JDK 1.4 logging�̑I�����K�v������܂���B
+ �قƂ�ǂ̊J���҂��D�ނ̂�Log4j�ł��B
+ Hibernate�f�B�X�g���r���[�V�����i��<literal>etc/</literal> �f�B���N�g���j����
+ <literal>log4j.properties</literal> ���Ȃ��� <literal>src</literal> �f�B���N�g�����
+ <literal>hibernate.cfg.xml</literal> �ׂ̗ɃR�s�[���Ă��������B
+ �ݒ����āA�璷�ȏo�͂��悯��ΐݒ��ύX���Ă��������B
+ �f�t�H���g�ł�Hibernate�̃X�^�[�g�A�b�v���b�Z�[�W�������W���o�͂ɕ\������܂��B
+ </para>
+
+ <para>
+ �`���[�g���A���̃C���t���͊��S�ł��B
+ Hibernate��g���Ď��ۂ̍�Ƃ��鏀���������܂����B
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-workingpersistence" revision="4">
+ <title>�I�u�W�F�N�g�̃��[�h�Ɗi�[</title>
+
+ <para>
+ ���ɃI�u�W�F�N�g�̃��[�h�Ɗi�[��Hibernate��g�����Ƃ��ł��܂��B
+ <literal>main()</literal> ���\�b�h���� <literal>EventManager</literal>
+ �N���X�����܂��F
+ </para>
+
+ <programlisting><![CDATA[package events;
+import org.hibernate.Session;
+
+import java.util.Date;
+
+import util.HibernateUtil;
+
+public class EventManager {
+
+ public static void main(String[] args) {
+ EventManager mgr = new EventManager();
+
+ if (args[0].equals("store")) {
+ mgr.createAndStoreEvent("My Event", new Date());
+ }
+
+ HibernateUtil.getSessionFactory().close();
+ }
+
+ private void createAndStoreEvent(String title, Date theDate) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+ session.beginTransaction();
+
+ Event theEvent = new Event();
+ theEvent.setTitle(title);
+ theEvent.setDate(theDate);
+
+ session.save(theEvent);
+
+ session.getTransaction().commit();
+ }
+
+}]]></programlisting>
+
+ <para>
+ �V���� <literal>Event</literal> �I�u�W�F�N�g�����A�����Hibernate�ɓn���܂��B
+ ���ł�Hibernate��SQL�������A�f�[�^�x�[�X�� <literal>INSERT</literal> ����s���܂��B
+ ���s�O�� <literal>Session</literal> �� <literal>Transaction</literal>
+ ��������R�[�h��m�F�����������B
+ </para>
+
+ <para>
+ <literal>Session</literal> ��1�̍�ƒP��(Unit of Work)�ł��B
+ �����̊ԁA�b��ȒP�ɂ��邽�߂ɁA
+ <literal>Session</literal> �� <literal>Transaction</literal> �̑Ή����Έ�Ɖ��肵�܂��B
+ �g�p���Ă���g�����U�N�V�����E�V�X�e���i���̃P�[�X�ł�JTA�Ƌ����ł���P����JDBC�j����R�[�h��ی삷�邽�߂ɁA
+ Hibernate <literal>Session</literal> ��ŗ��p�\�� <literal>Transaction</literal> API��g�p���܂��B
+ </para>
+
+ <para>
+ <literal>sessionFactory.getCurrentSession()</literal> �͂Ȃɂ���̂ł��傤���H
+ �܂��A�������� <literal>SessionFactory</literal> ��擾���ێ������
+ �i <literal>HibernateUtil</literal> �̂������ŊȒP�ł��j�A���̃��\�b�h���x�ł�A
+ �ǂ�����ł�Ăяo�����Ƃ��o���܂��B
+ <literal>getCurrentSession()</literal> ���\�b�h�͏�Ɂu���݂́v��ƒP��(Unit of Work)��Ԃ��܂��B
+ <literal>hibernate.cfg.xml</literal> �̂��̋@�\�̐ݒ�ŁA"thread"��w�肵�����Ƃ�v���o���Ă��������B
+ ���̂��ߌ��݂̍�ƒP�ʂ̃X�R�[�v�́A���̃A�v���P�[�V��������s���錻�݂�Java�X���b�h�ł��B
+ ����������őS�Ăł͂���܂���B
+ <literal>Session</literal> �͍ŏ��ɕK�v�ƂȂ����Ƃ��A�܂�ŏ��� <literal>getCurrentSession()</literal> ��
+ �Ăꂽ�Ƃ��ɊJ�n���܂��B
+ ���̂Ƃ�Hibernate�ɂ�茻�݂̃X���b�h�Ɍ��ѕt�����܂��B
+ �g�����U�N�V�������I���i�R�~�b�g������̓��[���o�b�N�j�����Ƃ��A
+ Hibernate��X���b�h���� <literal>Session</literal> ��藣���A�N���[�Y���܂��B
+ �Ă� <literal>getCurrentSession()</literal> ��ĂԂƁA
+ �V���� <literal>Session</literal> ��擾���ĐV������ƒP�ʂ�X�^�[�g�ł��܂��B
+ ���� <emphasis>thread-bound</emphasis> �v���O���~���O�E���f����Hibernate�𗘗p�����ōł�l�C������܂��B
+ </para>
+
+ <para>
+ �g�����U�N�V�����̈����Ƌ��E�̏ڂ������ɂ��ẮA
+ <xref linkend="transactions"/> �����������B
+ ���̗�ł̓G���[������[���o�b�N��������܂��B
+ </para>
+
+ <para>
+ ���̍ŏ��̃��[�`������s����ɂ́AAnt�̃r���h�t�@�C���ɌĂяo���\�ȃ^�[�Q�b�g��
+ �lj����Ȃ���Ȃ�܂���F
+ </para>
+
+ <programlisting><![CDATA[<target name="run" depends="compile">
+ <java fork="true" classname="events.EventManager" classpathref="libraries">
+ <classpath path="${targetdir}"/>
+ <arg value="${action}"/>
+ </java>
+</target>]]></programlisting>
+
+ <para>
+ <literal>action</literal> �����̒l�́A�^�[�Q�b�g��ĂԂƂ��ɃR�}���h���C���Őݒ肵�܂��F
+ </para>
+
+ <programlisting><![CDATA[C:\hibernateTutorial\>ant run -Daction=store]]></programlisting>
+
+ <para>
+ �R���p�C������ƁAHibernate���X�^�[�g���A���Ȃ��̐ݒ�ɂ��܂����A
+ �����̃��O�o�͂�����͂��ł��B
+ ���̍Ō�ɂ͈ȉ��̍s������ł��傤�F
+ </para>
+
+ <programlisting><![CDATA[[java] Hibernate: insert into EVENTS (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)]]></programlisting>
+
+ <para>
+ �����Hibernate�����s���� <literal>INSERT</literal> �ŁA
+ �N�G�X�`�����}�[�N��JDBC�o�C���h�p�����[�^��\���Ă��܂��B
+ �����Ƃ��ăo�C���h�����l���邽�߁A���邢�̓��O�̏璷�����炷���߂ɂ́A
+ <literal>log4j.properties</literal> ��`�F�b�N�����������B
+ </para>
+
+ <para>
+ ����ł͓����悤�Ɋi�[���ꂽ�C�x���g�̈ꗗ���悤�Ǝv���܂��B
+ ���̂��߃��C�����\�b�h�ɃI�v�V������lj����܂��F
+ </para>
+
+ <programlisting><![CDATA[if (args[0].equals("store")) {
+ mgr.createAndStoreEvent("My Event", new Date());
+}
+else if (args[0].equals("list")) {
+ List events = mgr.listEvents();
+ for (int i = 0; i < events.size(); i++) {
+ Event theEvent = (Event) events.get(i);
+ System.out.println("Event: " + theEvent.getTitle() +
+ " Time: " + theEvent.getDate());
+ }
+}]]></programlisting>
+
+ <para>
+ �V���� <literal>listEvents()���\�b�h</literal> ��lj����܂��B
+ </para>
+
+ <programlisting><![CDATA[private List listEvents() {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+ session.beginTransaction();
+
+ List result = session.createQuery("from Event").list();
+
+ session.getTransaction().commit();
+
+ return result;
+}]]></programlisting>
+
+ <para>
+ �����ł��邱�Ƃ́A�f�[�^�x�[�X���瑶�݂��邷�ׂĂ� <literal>Event</literal>
+ �I�u�W�F�N�g���[�h����HQL (Hibernate Query Language) �N�G����g�����Ƃł��B
+ Hibernate�͓K��SQL�����A�����f�[�^�x�[�X�ɑ���A
+ ���̃f�[�^��g���� <literal>Event</literal> �I�u�W�F�N�g�����܂��B
+ ���RHQL�ł���ɕ��G�ȃN�G����쐬�ł��܂��B
+ </para>
+
+ <para>
+ �ȉ��̃X�e�b�v�ŁA���ׂĂ̎��s�ƃe�X�g��s���܂��B
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ hbm2ddl��ʂ��O�Ƀf�[�^�x�[�X�̃f�[�^��쐬���A�f�[�^�x�[�X�X�L�[�}�����邽�߂ɁA
+ <literal>ant run -Daction=store</literal> ����s�����������B
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ���� <literal>hibernate.cfg.xml</literal> �t�@�C���̃v���p�e�B��R�����g�A�E�g����hbm2ddl���ɂ��Ă��������B
+ �ʏ�͌p���I�ɒP�̃e�X�g���Ă���Ԃ�hbm2ddl��L���ɂ��Ă����̂ł����A
+ ����ȊO�̏ꍇ��hbm2ddl��N������Ɗi�[���Ă������S�Ẵf�[�^�� <emphasis>�h���b�v</emphasis> ����ł��傤�B
+ �ݒ�� <literal>create</literal> �ɂ���ƁA���ʂƂ���
+ �uSessionFactory�����̍ہA�X�L�[�}����S�Ẵe�[�u����h���b�v���čč쐬����v�Ƃ����ݒ�ɂȂ�܂��B
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ �� <literal>-Daction=list</literal> �Ǝw�肵��Ant��ĂԂƁA
+ ����܂Ŋi�[�����C�x���g��������͂��ł��B
+ <literal>store</literal> �A�N�V�����𐔉�ȏ�ĂԂ��Ƃ�\�ł��B
+ </para>
+
+ <para>
+ ���ӁF���߂�Hibernate�ɐG���l�X�̑����������Ŏ��s���邽�߁A<emphasis>Table not found</emphasis> �G���[���b�Z�[�W��
+ �ւ��鎿������I�Ɍ������܂��B
+ ��������L�̃X�e�b�v�ɏ]���Ahbm2ddl���ŏ��Ɏ��s���ꂽ�Ƃ��Ƀf�[�^�x�[�X�X�L�[�}��쐬���A
+ ���̌�̎��s�ɂ����Ă���̃X�L�[�}��g�p����̂ŁA���͋N����Ȃ��ł��傤�B
+ �}�b�s���O��f�[�^�x�[�X�X�L�[�}��ύX�����Ƃ��́A�����xhbm2ddl��L���ɂ��Ă��������B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="tutorial-associations">
+ <title>�p�[�g2 - �֘A�̃}�b�s���O</title>
+
+ <para>
+ �i���G���e�B�e�B�N���X��e�[�u���Ƀ}�b�s���O���܂����B
+ ����ɂ��̏�ɂ������̃N���X�̊֘A��lj����܂��傤�B
+ �܂����߂ɃA�v���P�[�V�����ɐl�X��lj����A�ނ炪�Q������C�x���g�̃��X�g��i�[���܂��B
+ </para>
+
+ <sect2 id="tutorial-associations-mappinguser" revision="1">
+ <title>Person�N���X�̃}�b�s���O</title>
+
+ <para>
+ �ŏ��� <literal>Person</literal> �N���X�͒P���ł��F
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+public class Person {
+
+ private Long id;
+ private int age;
+ private String firstname;
+ private String lastname;
+
+ public Person() {}
+
+ // Accessor methods for all properties, private setter for 'id'
+
+}]]></programlisting>
+
+ <para>
+ <literal>Person.hbm.xml</literal> �Ƃ����V�����}�b�s���O�t�@�C����쐬���Ă�������
+ �i�t�@�C���̍ŏ���DTD�ւ̎Q�Ƃ�Y�ꂸ�ɓ���Ă��������j�F
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="native"/>
+ </id>
+ <property name="age"/>
+ <property name="firstname"/>
+ <property name="lastname"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ �Ō��Hibernate�̐ݒ�ɐV�����}�b�s���O��lj����Ă��������F
+ </para>
+
+ <programlisting><![CDATA[<mapping resource="events/Event.hbm.xml"/>
+<mapping resource="events/Person.hbm.xml"/>]]></programlisting>
+
+ <para>
+ ����ł͂����2�̃G���e�B�e�B�Ԃ̊֘A��쐬���܂��B
+ �l�X���C�x���g�ɎQ���ł��A�C�x���g���Q���҂��͖̂��炩�ł��B
+ ����Ȃ���Ȃ�Ȃ��v�̖��́A�����A���d�x�A�R���N�V�����̐U�镑���ł��B
+ </para>
+ </sect2>
+
+ <sect2 id="tutorial-associations-unidirset" revision="3">
+ <title>�P����Set�x�[�X�֘A</title>
+
+ <para>
+ �C�x���g�̃R���N�V������ <literal>Person</literal> �N���X�ɒlj����܂��B
+ �������Ă����ƁA�����I�ȃN�G���A�܂�킴�킴<literal>aPerson.getEvents()</literal>��Ăяo�����ɁA
+ ����̐l�ɕR�t���C�x���g��ȒP�Ƀi�r�Q�[�g���邱�Ƃ��ł��܂��B
+ ��������Java�̃R���N�V�����A<literal>Set</literal> ��g���܂��B
+ �R���N�V�����͏d���v�f�����Ȃ����A���Ԃ͎������ɂ͈Ӗ����Ȃ�����ł��B
+ </para>
+
+ <para>
+ <literal>Set</literal> �Ŏ��������P�����A���l�֘A���K�v�ł��B
+ Java�N���X��ɑΉ�����R�[�h�����ă}�b�s���O���܂��傤�F
+ </para>
+
+ <programlisting><![CDATA[public class Person {
+
+ private Set events = new HashSet();
+
+ public Set getEvents() {
+ return events;
+ }
+
+ public void setEvents(Set events) {
+ this.events = events;
+ }
+}]]></programlisting>
+
+ <para>
+ ���̊֘A��}�b�s���O����O�ɁA���Α��ɂ��čl���Ă��������B
+ ���炩�Ȃ��Ƃł����A���͂����P�����ɂ��������ł��B
+ �t�ɁA <literal>Event</literal> ���ɂ�ʂ̃R���N�V�������邱�Ƃ�ł��܂��B
+ �Ⴆ�� <literal>anEvent.getParticipants()</literal> �̂悤�ɁA
+ �o�����Ƀi�r�Q�[�g��������A�������邱�Ƃ�ł��܂��B
+ ����͋@�\�I�ɂ݂ĕK�v�ł͂���܂���B
+ ����̃C�x���g�ɊW����f�[�^��擾���閾�m�ȃN�G����A���ł���s���邱�Ƃ��o���܂����B
+ ���̐v�̑I��͊J���҂ɔC����Ă��āA���̋c�_�ɂ�薾�炩�Ȃ̂͊֘A�̑��d�x�ł��B
+ �܂藼����u���v�l�ɂ���A <emphasis>���Α�</emphasis> �ƌĂ��֘A�ł��B
+ ���̂���Hibernate��many-to-many�}�b�s���O��g���܂��F
+ </para>
+
+ <programlisting><![CDATA[<class name="events.Person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="native"/>
+ </id>
+ <property name="age"/>
+ <property name="firstname"/>
+ <property name="lastname"/>
+
+ <set name="events" table="PERSON_EVENT">
+ <key column="PERSON_ID"/>
+ <many-to-many column="EVENT_ID" class="events.Event"/>
+ </set>
+
+</class>]]></programlisting>
+
+ <para>
+ Hibernate�͂���Ƃ������ނ̃R���N�V�����}�b�s���O��T�|�[�g���Ă��܂����A
+ �ł��ʓI�Ȃ�̂� <literal><set></literal> �ł��B
+ ���Α��֘A�i�܂��� <emphasis>n:m</emphasis> �G���e�B�e�B�����[�V�����V�b�v�j�ɂ́A
+ �֘A�e�[�u�����K�v�ł��B
+ ���̃e�[�u���̂��ꂼ��̍s�́A�l�ƃC�x���g�Ԃ̃����N��\�����܂��B
+ �e�[�u������ <literal>set</literal> �v�f�� <literal>table</literal> �����Őݒ肵�܂��B
+ �l���̊֘A�̎��ʎq�J�������� <literal><key></literal> �v�f�ŁA
+ �C�x���g���̃J�������� <literal><many-to-many></literal> �� <literal>column</literal>
+ �����Œ�`���܂��B
+ Hibernate�ɃR���N�V�����̃I�u�W�F�N�g�̃N���X
+ �i���m�ɂ́A�Q�Ƃ̃R���N�V�����̔��Α��̃N���X�j�����Ȃ���Ȃ�܂���B
+ </para>
+
+ <para>
+ ���̂��߂��̃}�b�s���O�̃f�[�^�x�[�X�X�L�[�}�͈ȉ��̂悤�ɂȂ�܂��B�F
+ </para>
+
+ <programlisting><![CDATA[
+ _____________ __________________
+ | | | | _____________
+ | EVENTS | | PERSON_EVENT | | |
+ |_____________| |__________________| | PERSON |
+ | | | | |_____________|
+ | *EVENT_ID | <--> | *EVENT_ID | | |
+ | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID |
+ | TITLE | |__________________| | AGE |
+ |_____________| | FIRSTNAME |
+ | LASTNAME |
+ |_____________|
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-working" revision="2">
+ <title>�֘A������</title>
+
+ <para>
+ <literal>EventManager</literal> �̐V�������\�b�h�Ől�X�ƃC�x���g��ꏏ�ɂ��܂��傤�F
+ </para>
+
+ <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session.load(Person.class, personId);
+ Event anEvent = (Event) session.load(Event.class, eventId);
+
+ aPerson.getEvents().add(anEvent);
+
+ session.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ <literal>Person</literal> �� <literal>Event</literal> ���[�h������A
+ ���ʂ̃R���N�V�������\�b�h��g���ĒP���ɂ��̃R���N�V������C�����Ă��������B
+ �����̂Ƃ��� <literal>update()</literal> �� <literal>save()</literal>
+ �̖����I�ȌĂяo���͂���܂���B
+ Hibernate�́A�C�����ꂽ���Ƃɂ��X�V����K�v�̂���R���N�V���������I�Ɍ��m���܂��B
+ ����� <emphasis>�����_�[�e�B�`�F�b�N</emphasis> �ƌĂ�A
+ �I�u�W�F�N�g�̖��O��date�v���p�e�B��C�����邱�ƂŎ������Ƃ�\�ł��B
+ ����炪 <emphasis>�i��</emphasis> ��Ԃɂ������A
+ �܂�����Hibernate <literal>Session</literal> �Ƀo�C���h����Ă������
+ �i�Ⴆ��ƒP��(Unit of Work)�̒��ŒP�Ƀ��[�h�܂��̓Z�[�u���ꂽ�j�A
+ Hibernate�͂ǂ�ȕύX����j�^�[���A�x����������(write-behind)��SQL����s���܂��B
+ �ʏ�A��ƒP��(Unit of Work)�̍Ō�ɂ����s����f�[�^�x�[�X�ƃ������̏�Ԃ������鏈���́A
+ <emphasis>�t���b�V��</emphasis> �ƌĂ�܂��B
+ ���̃R�[�h�ł́A��ƒP��(Unit of Work)�̓f�[�^�x�[�X�g�����U�N�V�����̃R�~�b�g�i������̓��[���o�b�N�j�ŏI�����܂��B
+ ����́A <literal>CurrentSessionContext</literal> �N���X�ɑ��� <literal>thread</literal> ��ݒ肵�����߂ł��B
+ </para>
+
+ <para>
+ �قȂ��ƒP��(Unit of Work)�Ől�X�ƃC�x���g���[�h���邱�Ƃ���R�ł��܂��B
+ �����łȂ���A�i����ԂɂȂ��Ƃ��i�ȑO�ɉi���ł������Ȃ�A���̏�Ԃ� <emphasis>�����idetached�j</emphasis>
+ �ƌĂт܂��j�A <literal>Session</literal> �̊O���ŃI�u�W�F�N�g��C�����܂��B
+ ���������Ƃ��ɂ̓R���N�V������ύX���邱�Ƃ�\�ł��F
+ </para>
+
+ <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session
+ .createQuery("select p from Person p left join fetch p.events where p.id = :pid")
+ .setParameter("pid", personId)
+ .uniqueResult(); // Eager fetch the collection so we can use it detached
+
+ Event anEvent = (Event) session.load(Event.class, eventId);
+
+ session.getTransaction().commit();
+
+ // End of first unit of work
+
+ aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached
+
+ // Begin second unit of work
+
+ Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
+ session2.beginTransaction();
+
+ session2.update(aPerson); // Reattachment of aPerson
+
+ session2.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ <literal>update</literal> �̌Ăяo���͕����I�u�W�F�N�g��Ăщi�������܂��B
+ ����́A�V������ƒP��(Unit of Work)�Ƀo�C���h����ƌ�����ł��傤�B
+ ���̂��ߕ����̊Ԃɉ�����ꂽ�ǂ̂悤�ȏC����f�[�^�x�[�X�ɃZ�[�u�ł��܂��B
+ �G���e�B�e�B�I�u�W�F�N�g�̃R���N�V�����ւ̏C���i�lj���폜�j����l�ɃZ�[�u�ł��܂��B
+ </para>
+
+ <para>
+ ����͍��͂��܂�g���݂�������܂��A
+ �����̃A�v���P�[�V�����̐v�ɑg�ݍ��ނ��Ƃ��ł���d�v�ȃR���Z�v�g�ł��B
+ ����ł͂��̃G�N�T�T�C�Y�̍Ō�ɁA
+ <literal>EventManager</literal> �̃��C�����\�b�h�ɐV�����A�N�V������lj�����
+ �R�}���h���C������Ăяo���Ă݂܂��傤�B
+ �l��C�x���g�̎��ʎq���K�v�Ȃ�A <literal>save()</literal> ���\�b�h���Ԃ��Ă���܂�
+ �i�ꍇ�ɂ���Ă͎��ʎq��Ԃ����߂Ƀ��\�b�h��C������K�v�����邩�����܂���j�B
+ </para>
+
+ <programlisting><![CDATA[else if (args[0].equals("addpersontoevent")) {
+ Long eventId = mgr.createAndStoreEvent("My Event", new Date());
+ Long personId = mgr.createAndStorePerson("Foo", "Bar");
+ mgr.addPersonToEvent(personId, eventId);
+ System.out.println("Added person " + personId + " to event " + eventId);
+}]]></programlisting>
+
+ <para>
+ ����͓����悤�ɏd�v��2�̃N���X�A�܂�2�̃G���e�B�e�B�Ԃ̊֘A�̗�ł����B
+ �O�ɏq�ׂ��悤�ɁA�T�^�I�ȃ��f���ɂ́A���ʁu��r�I�d�v�ł͂Ȃ��v���̃N���X�ƌ^������܂��B
+ ����܂łɌ����悤�� <literal>int</literal> �� <literal>String</literal> �̂悤�Ȃ�̂ł��B
+ ���̂悤�ȃN���X�� <emphasis>�l�^</emphasis> �ƌ����܂��B
+ ���̃C���X�^���X�͓���̃G���e�B�e�B�� <emphasis>�ˑ�</emphasis> ���܂��B
+ ���̌^�̃C���X�^���X�͓Ǝ���ID�����܂��A
+ �G���e�B�e�B�Ԃŋ��L����邱�Ƃ����܂���
+ �i�t�@�[�X�g�l�[���������������Ƃ��Ă�A2�l�̐l�͓��� <literal>firstname</literal>
+ �I�u�W�F�N�g��Q�Ƃ��܂���j�B
+ �l�^�͂�����JDK��Ɍ�����܂����A���ꂾ���ł͂Ȃ�
+ �i���ہAHibernate�A�v���P�[�V�����ɂ����Ă��ׂĂ�JDK�N���X�͒l�^�ƌ��Ȃ��܂��j�A
+ �Ⴆ�� <literal>Address</literal> �� <literal>MonetaryAmount</literal>
+ �̂悤�ȓƎ��̈ˑ��N���X�������Ƃ�ł��܂��B
+ </para>
+
+ <para>
+ �l�^�̃R���N�V������v���邱�Ƃ�ł��܂��B
+ ����͑��̃G���e�B�e�B�ւ̎Q�Ƃ̃R���N�V�����Ƃ͊T�O�I�ɔ��ɈقȂ�܂����A
+ Java�ł͂قƂ�Ǔ����悤�Ɍ����܂��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-valuecollections">
+ <title>�l�̃R���N�V����</title>
+
+ <para>
+ �l�^�I�u�W�F�N�g�̃R���N�V������ <literal>Person</literal> �G���e�B�e�B�֒lj����܂��B
+ E���[���A�h���X��i�[�������̂ł����A<literal>String</literal> �^��g���Ă���̂ŁA
+ �R���N�V�����͍Ă� <literal>Set</literal> �ł��F
+ </para>
+ <programlisting><![CDATA[private Set emailAddresses = new HashSet();
+
+public Set getEmailAddresses() {
+ return emailAddresses;
+}
+
+public void setEmailAddresses(Set emailAddresses) {
+ this.emailAddresses = emailAddresses;
+}]]></programlisting>
+
+ <para>
+ ���� <literal>Set</literal> �̃}�b�s���O�ł��F
+ </para>
+
+ <programlisting><![CDATA[<set name="emailAddresses" table="PERSON_EMAIL_ADDR">
+ <key column="PERSON_ID"/>
+ <element type="string" column="EMAIL_ADDR"/>
+</set>]]></programlisting>
+
+ <para>
+ �O�̃}�b�s���O�Ɣ�ׂĈႤ�̂� <literal>element</literal> �̕����ł����A
+ Hibernate�ɂ��̃R���N�V���������̃G���e�B�e�B�ւ̎Q�Ƃ�܂܂��A
+ <literal>String</literal> �^�̗v�f�̃R���N�V������܂ނ��Ƃ����܂��B
+ �i�������̖��O(string)��Hibernate�̃}�b�s���O�^�܂��̓R���o�[�^�ł���Ƃ������Ƃł��j�B
+ �J��Ԃ��܂����A<literal>set</literal> �v�f�� <literal>table</literal> �����́A
+ �R���N�V�����̂��߂̃e�[�u������w�肵�܂��B
+ <literal>key</literal> �v�f�̓R���N�V�����e�[�u���̊O���L�[�J���������`���܂��B
+ <literal>element</literal> �v�f�� <literal>column</literal> ������ <literal>String</literal>
+ �̒l�����ۂɊi�[�����J�����̖��O���`���܂��B
+ </para>
+
+ <para>
+ �X�V�����X�L�[�}�����������F
+ </para>
+
+ <programlisting><![CDATA[
+ _____________ __________________
+ | | | | _____________
+ | EVENTS | | PERSON_EVENT | | | ___________________
+ |_____________| |__________________| | PERSON | | |
+ | | | | |_____________| | PERSON_EMAIL_ADDR |
+ | *EVENT_ID | <--> | *EVENT_ID | | | |___________________|
+ | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID | <--> | *PERSON_ID |
+ | TITLE | |__________________| | AGE | | *EMAIL_ADDR |
+ |_____________| | FIRSTNAME | |___________________|
+ | LASTNAME |
+ |_____________|
+ ]]></programlisting>
+
+ <para>
+ �R���N�V�����e�[�u���̎�L�[�́A���ۂ͗����̃J������g���������L�[�ł��邱�Ƃ��킩��܂��B
+ ����͐l���Ƃ�E���[���A�h���X���d���ł��Ȃ��Ƃ������ƂŁA
+ Java��set�ɗv�������Z�}���e�B�N�X���̂�̂ł��B
+ </para>
+
+ <para>
+ �ȑO�l�ƃC�x���g��֘A�Â����Ƃ��ƑS�������悤�ɁA
+ ���⎎���ɃR���N�V�����ɗv�f��lj����邱�Ƃ��ł���悤�ɂȂ�܂����B
+ �����Ƃ�Java�ł͓����R�[�h�ł��B
+ </para>
+
+ <programlisting><![CDATA[private void addEmailToPerson(Long personId, String emailAddress) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session.load(Person.class, personId);
+
+ // The getEmailAddresses() might trigger a lazy load of the collection
+ aPerson.getEmailAddresses().add(emailAddress);
+
+ session.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ ����A�R���N�V�����̏������� <emphasis>fetch</emphasis> �N�G����g�p���܂���ł����B
+ ���̂��߁Agetter���\�b�h�̌Ăяo���ɂ���ăR���N�V�������������邽�߂�SELECT��
+ ���s�����̂ŁA�R���N�V�����ɗv�f��lj��ł��܂��B
+ SQL�̃��O��Ď����āA�����t�F�b�`��g���čœK�����Ă��������B
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-bidirectional" revision="1">
+ <title>�o�����֘A</title>
+
+ <para>
+ ���ɑo�����֘A��}�b�s���O���܂��B
+ Java�ŗ�������l�ƃC�x���g�̊֘A�삳���܂��B
+ ������A�f�[�^�x�[�X�X�L�[�}�͕ς��܂��A���d�x�͑��Α��̂܂܂ł��B
+ �����[�V���i���f�[�^�x�[�X�̓l�b�g���[�N�v���O���~���O�������_��Ȃ̂ŁA
+ �i�r�Q�[�V�����̕����̂悤�Ȃ�̂�K�v�Ƃ��܂���B
+ �f�[�^�͂�����̕��@�Ō����蕜���ł���Ƃ������Ƃł��B
+ </para>
+
+ <para>
+ �܂� <literal>Event</literal> �C�x���g�N���X�ɎQ���҂̃R���N�V������lj����܂��F
+ </para>
+
+ <programlisting><![CDATA[private Set participants = new HashSet();
+
+public Set getParticipants() {
+ return participants;
+}
+
+public void setParticipants(Set participants) {
+ this.participants = participants;
+}]]></programlisting>
+
+ <para>
+ ����ł� <literal>Event.hbm.xml</literal> �Ŋ֘A�̂����瑤��}�b�s���O���Ă��������B
+ </para>
+
+ <programlisting><![CDATA[<set name="participants" table="PERSON_EVENT" inverse="true">
+ <key column="EVENT_ID"/>
+ <many-to-many column="PERSON_ID" class="events.Person"/>
+</set>]]></programlisting>
+
+ <para>
+ �����̂Ƃ���A������̃}�b�s���O�h�L�������g(XML�t�@�C��)�ł�A���ʂ� <literal>set</literal>
+ �}�b�s���O��g���Ă��܂��B
+ <literal>key</literal> �� <literal>many-to-many</literal> �̃J���������A
+ �����̃}�b�s���O�h�L�������g�œ���ւ��ɂȂ��Ă��邱�Ƃɒ��ڂ��Ă��������B
+ �����ōł�d�v�Ȓlj����ڂ́A <literal>Event</literal> �̃R���N�V�����}�b�s���O�� <literal>set</literal>
+ �v�f�ɂ��� <literal>inverse="true"</literal> �����ł��B
+ </para>
+
+ <para>
+ ���̎w��̈Ӗ��́A2�̊Ԃ̃G���e�B�e�B�Ԃ̃����N�ɂ��Ă̏���T���K�v������Ƃ��A
+ Hibernate�͔��Α��̃G���e�B�e�B�A�܂� <literal>Person</literal> �N���X����T���Ƃ������Ƃł��B
+ ��x2�̃G���e�B�e�B�Ԃ̑o���������N���ǂ̂悤�ɍ쐬����邩���킩��A
+ ����𗝉��邱�Ƃ͂ƂĂ�ȒP�ł��B
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-usingbidir">
+ <title>�o���������N�̓���</title>
+
+ <para>
+ �܂��AHibernate���ʏ��Java�̃Z�}���e�B�N�X�ɉe����y�ڂ��Ȃ����Ƃ�S�ɗ��߂Ă����Ă��������B
+ �������́A�P�����̗�Ƃ��Ăǂ̂悤�� <literal>Person</literal> �� <literal>Event</literal>
+ �̊Ԃ̃����N��쐬�����ł��傤���H
+ <literal>Person</literal> �̃C���X�^���X�̃C�x���g�ւ̎Q�Ƃ̃R���N�V������
+ <literal>Event</literal> �̃C���X�^���X��lj����܂����B
+ ���̂��߂��̃����N��o�����ɂ�������A
+ ������O�ł������Α��ɂ�������Ƃ��Ȃ���Ȃ�܂���B
+ <literal>Event</literal> �̃R���N�V������ <literal>Person</literal> �ւ�
+ �Q�Ƃ�lj�����Ƃ������Ƃł��B
+ ���́u�����Ń����N��ݒ肷�邱�Ɓv�͐�ɕK�v�Ȃ̂ŁA�����ĖY��Ȃ��ł��������B
+ </para>
+
+ <para>
+ �����̊J���҂͐T�d�Ƀv���O��������̂ŁA
+ �G���e�B�e�B�̗����ɐ������֘A��ݒ肷�郊���N�Ǘ����\�b�h��쐬���܂��B
+ �Ⴆ�� <literal>Person</literal> �ł͈ȉ��̂悤�ɂȂ�܂��B�F
+ </para>
+
+ <programlisting><![CDATA[protected Set getEvents() {
+ return events;
+}
+
+protected void setEvents(Set events) {
+ this.events = events;
+}
+
+public void addToEvent(Event event) {
+ this.getEvents().add(event);
+ event.getParticipants().add(this);
+}
+
+public void removeFromEvent(Event event) {
+ this.getEvents().remove(event);
+ event.getParticipants().remove(this);
+}]]></programlisting>
+
+ <para>
+ �R���N�V�����̃Q�b�g�ƃZ�b�g���\�b�h������protected�ɂȂ��Ă��邱�Ƃɒ��ӂ��Ă��������B
+ ����͓����p�b�P�[�W�̃N���X��T�u�N���X�̃��\�b�h�͈ˑR�A�N�Z�X���\�ł����A
+ �i�قƂ�ǁj���̃p�b�P�[�W�O�̂ǂ̃N���X�ł���ڂ��̃R���N�V������䖳���ɂ��邱�Ƃ�h���܂��B
+ �����炭���Α��̃R���N�V�����ɂ�������Ƃ������������ł��傤�B
+ </para>
+
+ <para>
+ <literal>inverse</literal> �}�b�s���O�����Ƃ͂����������ł��傤���H
+ �J���҂�Java�ɂƂ��ẮA�o���������N�͒P�ɗ����̎Q�Ƃ𐳂����ݒ肷��Ƃ������Ƃł��B
+ ������Hibernate�́i����ᔽ����邽�߂ɁjSQL�� <literal>INSERT</literal> �� <literal>UPDATE</literal>
+ ���𐳊m�ɕύX���邽�߂̏\���ȏ������Ă��Ȃ��̂ŁA
+ �o�����֘A�v���p�e�B�������߂̉��炩�̏�����K�v�Ƃ��܂��B
+ �֘A�̕Б��� <literal>inverse</literal> �ɐݒ肷�邱�ƂŁAHibernate�͊�{�I�ɂ͐ݒ肵���������A
+ ���Α��� <emphasis>��</emphasis> �Ƃ��čl���܂��B
+ ���ꂾ���ŁAHibernate�͕������i�r�Q�[�V�������f����SQL�f�[�^�x�[�X�X�L�[�}�֕ϊ�����Ƃ���
+ ���ׂĂ̖��ɂ��܂��Ώ��ł��܂��B
+ �o���Ă����Ȃ���Ȃ�Ȃ����[���͊ȒP�ł��B
+ �o�����֘A�͕K���Б��� <literal>inverse</literal> �ɂ���K�v������Ƃ������Ƃł��B
+ ��Α��֘A�ł͂���͑����łȂ���Ȃ�܂���B
+ ���Α��֘A�ł͂ǂ��瑤�ł�\���܂���B�ǂ���ł�Ⴂ�͂���܂���B
+ </para>
+
+ </sect2>
+
+ <para>
+ �ł͂��������Web�A�v���P�[�V�����ɂ��Ă݂܂��傤�B
+ </para>
+
+ </sect1>
+
+ <sect1 id="tutorial-webapp">
+ <title>�p�[�g3 - EventManager Web�A�v���P�[�V����</title>
+
+ <para>
+ Hibernate��Web�A�v���P�[�V�����́A�X�^���h�A���[���̃A�v���P�[�V�����̂悤��
+ <literal>Session</literal> �� <literal>Transaction</literal> ��g�p���܂��B
+ �������������̈�ʓI�ȃp�^�[�����𗧂��܂��B
+ ������ <literal>EventManagerServlet</literal> ��쐬���܂��B���̃T�[�u���b�g�́A
+ �f�[�^�x�[�X�Ɋi�[�����S�ẴC�x���g���X�g�ɂł��A�����HTML�t�H�[������V�����C�x���g����͂ł����̂ł��B
+ </para>
+
+ <sect2 id="tutorial-webapp-servlet" revision="1">
+ <title>��{�I��Servlet�̋L�q</title>
+
+ <para>
+ �V�����N���X��A�\�[�X�f�B���N�g���� <literal>events</literal> �p�b�P�[�W�ɍ쐬���Ă��������B
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+// Imports
+
+public class EventManagerServlet extends HttpServlet {
+
+ // Servlet code
+}]]></programlisting>
+
+ <para>
+ Servlet��HTTP�� <literal>GET</literal> ���N�G�X�g�݂̂�������̂ŁA
+ <literal>doGet()</literal> ��������܂��B
+ </para>
+
+ <programlisting><![CDATA[protected void doGet(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+
+ SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");
+
+ try {
+ // Begin unit of work
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().beginTransaction();
+
+ // Process request and render page...
+
+ // End unit of work
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().getTransaction().commit();
+
+ } catch (Exception ex) {
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().getTransaction().rollback();
+ throw new ServletException(ex);
+ }
+
+}]]></programlisting>
+
+ <para>
+ ����� <emphasis>session-per-request</emphasis> �Ƃ����p�^�[���ł��B
+ Servlet�����N�G�X�g����ƁA <literal>SessionFactory</literal> ��
+ <literal>getCurrentSession()</literal> �̍ŏ��̌Ăяo���ŁA
+ Hibernate�̐V���� <literal>Session</literal> ���J����܂��B
+ ���̂Ƃ��f�[�^�x�[�X�g�����U�N�V�������J�n����܂��B
+ �f�[�^�̓ǂݏ����Ɋւ�炸�A���ׂẴf�[�^�A�N�Z�X�̓g�����U�N�V������ōs���܂��B
+ �i�A�v���P�[�V������ł̓I�[�g�R�~�b�g���[�h��g�p���܂���j�B
+ </para>
+
+ <para>
+ ���ɁA���N�G�X�g�̃A�N�V�����͏�������A���X�|���X�ł���HTML���`�悳��܂��B
+ ����ɂ��Ă͂����ɐ�����܂��B
+ </para>
+
+ <para>
+ �Ō�Ƀ��N�G�X�g�̏�����HTML�`�悪���������Ƃ��ɁA��ƒP��(Unit of Work)��I�����܂��B
+ ���������`�撆�ɖ�肪���������ꍇ�Aexception���������ăf�[�^�x�[�X�g�����U�N�V�������[���o�b�N���܂��B
+ ����� <literal>session-per-request</literal> �p�^�[�����������܂��B
+ �S�ẴT�[�u���b�g�Ƀg�����U�N�V�������E�̃R�[�h��������ɁA�T�[�u���b�g�t�B���^�ɋL�q���邱�Ƃ�\�ł��B
+ <emphasis>Open Session in View</emphasis> �ƌĂ�邱�̃p�^�[���ɂ��ẮA
+ Hibernate��Web�T�C�g��Wiki��Q�Ƃ��Ă��������B
+ �T�[�u���b�g�ł͂Ȃ�JSP��HTML�`����悤�Ƃ���ƁA�����ɂ��̃p�^�[���ɂ��Ă̏�K�v�ɂȂ�ł��傤�B
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-webapp-processing" revision="1">
+ <title>�����ƕ`��</title>
+
+ <para>
+ �ł́A���N�G�X�g�̏����ƃy�[�W�̕`���������܂��B
+ </para>
+
+<programlisting><![CDATA[// Write HTML header
+PrintWriter out = response.getWriter();
+out.println("<html><head><title>Event Manager</title></head><body>");
+
+// Handle actions
+if ( "store".equals(request.getParameter("action")) ) {
+
+ String eventTitle = request.getParameter("eventTitle");
+ String eventDate = request.getParameter("eventDate");
+
+ if ( "".equals(eventTitle) || "".equals(eventDate) ) {
+ out.println("<b><i>Please enter event title and date.</i></b>");
+ } else {
+ createAndStoreEvent(eventTitle, dateFormatter.parse(eventDate));
+ out.println("<b><i>Added event.</i></b>");
+ }
+}
+
+// Print page
+printEventForm(out);
+listEvents(out, dateFormatter);
+
+// Write HTML footer
+out.println("</body></html>");
+out.flush();
+out.close();]]></programlisting>
+
+ <para>
+ Java��HTML�����݂���R�[�f�B���O�X�^�C���́A��蕡�G�ȃA�v���P�[�V�����ɂ͓K���Ă��Ȃ��ł��傤
+ �i���̃`���[�g���A���ł́A��{�I��Hibernate�̃R���Z�v�g�����Ă��邾���ł��邱�Ƃ�o���Ă����Ă��������j�B
+ ���̃R�[�h��HTML�̃w�b�_�[�ƃt�b�^�[�̋L�q�ł��B
+ ���̃y�[�W�ɂ́A�C�x���g����͂���HTML�t�H�[���ƁA�f�[�^�x�[�X�ɂ���S�ẴC�x���g�̃��X�g���\������܂��B
+ �ŏ��̃��\�b�h�͂����P����HTML�o�͂ł��B
+ </para>
+
+ <programlisting><![CDATA[private void printEventForm(PrintWriter out) {
+ out.println("<h2>Add new event:</h2>");
+ out.println("<form>");
+ out.println("Title: <input name='eventTitle' length='50'/><br/>");
+ out.println("Date (e.g. 24.12.2009): <input name='eventDate' length='10'/><br/>");
+ out.println("<input type='submit' name='action' value='store'/>");
+ out.println("</form>");
+}]]></programlisting>
+
+ <para>
+ <literal>listEvents()</literal> ���\�b�h�́A���݂̃X���b�h�Ɍ��т�
+ Hibernate�� <literal>Session</literal> ��g�p���āA�N�G������s���܂��B
+ </para>
+
+ <programlisting><![CDATA[private void listEvents(PrintWriter out, SimpleDateFormat dateFormatter) {
+
+ List result = HibernateUtil.getSessionFactory()
+ .getCurrentSession().createCriteria(Event.class).list();
+ if (result.size() > 0) {
+ out.println("<h2>Events in database:</h2>");
+ out.println("<table border='1'>");
+ out.println("<tr>");
+ out.println("<th>Event title</th>");
+ out.println("<th>Event date</th>");
+ out.println("</tr>");
+ for (Iterator it = result.iterator(); it.hasNext();) {
+ Event event = (Event) it.next();
+ out.println("<tr>");
+ out.println("<td>" + event.getTitle() + "</td>");
+ out.println("<td>" + dateFormatter.format(event.getDate()) + "</td>");
+ out.println("</tr>");
+ }
+ out.println("</table>");
+ }
+}]]></programlisting>
+
+ <para>
+ �Ō�ɁA <literal>store</literal> �A�N�V������ <literal>createAndStoreEvent()</literal> ���\�b�h��
+ �Ăяo���܂��B���̃��\�b�h�ł���݂̃X���b�h�� <literal>Session</literal> �𗘗p���܂��B
+ </para>
+
+ <programlisting><![CDATA[protected void createAndStoreEvent(String title, Date theDate) {
+ Event theEvent = new Event();
+ theEvent.setTitle(title);
+ theEvent.setDate(theDate);
+
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().save(theEvent);
+}]]></programlisting>
+
+ <para>
+ ����ŃT�[�u���b�g�̊����ł��B
+ �T�[�u���b�g�ւ̃��N�G�X�g�́A��� <literal>Session</literal> ��
+ <literal>Transaction</literal> �ŏ��������ł��傤�B
+ �ŏ��̃X�^���h�A���[���̃A�v���P�[�V�����̂悤�ɁA
+ Hibernate�͎����I�ɂ����̃I�u�W�F�N�g����s����X���b�h�Ɍ��ѕt���邱�Ƃ��ł��܂��B
+ ����ɂ��A�J���҂����R�ɃR�[�h���C���[�����ł��A
+ �D���ȕ��@�� <literal>SessionFactory</literal> �ւ̃A�N�Z�X���ł���悤�ɂȂ�܂��B
+ �ʏ�A�J���҂͂�������ꂽ�f�U�C����g�p���āA�f�[�^�A�N�Z�X�̃R�[�h��
+ �f�[�^�A�N�Z�X�I�u�W�F�N�g�Ɉړ�����ł��傤�iDAO�p�^�[���j�B
+ ��葽���̗�́AHibernate��Wiki��Q�Ƃ��Ă��������B
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-webapp-deploy">
+ <title>�f�v���C�ƃe�X�g</title>
+
+ <para>
+ ���̃A�v���P�[�V�����̃f�v���C�̂��߂ɁAWeb�A�[�J�C�u�iWAR�j��쐬���Ă��������B
+ �ȉ���Ant�^�[�Q�b�g�� <literal>build.xml</literal> �ɉ����Ă��������B
+ </para>
+
+<programlisting><![CDATA[<target name="war" depends="compile">
+ <war destfile="hibernate-tutorial.war" webxml="web.xml">
+ <lib dir="${librarydir}">
+ <exclude name="jsdk*.jar"/>
+ </lib>
+
+ <classes dir="${targetdir}"/>
+ </war>
+</target>]]></programlisting>
+
+ <para>
+ ���̃^�[�Q�b�g�� <literal>hibernate-tutorial.war</literal> �Ƃ����t�@�C����
+ �v���W�F�N�g�f�B���N�g���ɍ쐬���܂��B
+ ���̃t�@�C���͂��ׂẴ��C�u������ <literal>web.xml</literal> �L�q�q��܂�ł���A
+ �v���W�F�N�g�̃x�[�X�f�B���N�g���ɒu����邱�Ƃ���҂���܂��B
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4"
+ xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+ <servlet>
+ <servlet-name>Event Manager</servlet-name>
+ <servlet-class>events.EventManagerServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Event Manager</servlet-name>
+ <url-pattern>/eventmanager</url-pattern>
+ </servlet-mapping>
+</web-app>]]></programlisting>
+
+ <para>
+ Web�A�v���P�[�V�����̃R���p�C���ƃf�v���C�̑O�ɁA <literal>jsdk.jar</literal> �Ƃ���
+ �lj��̃��C�u�������K�v�Ȃ��Ƃɒ��ӂ��Ă��������B
+ �����Java�T�[�u���b�g�̊J���L�b�g�ł��B
+ ����܂����̃��C�u���������Ă��Ȃ��Ȃ�ASun�̃E�F�u�T�C�g�œ��肵�āA
+ ���C�u�����f�B���N�g���ɃR�s�[���Ă��������B
+ �������A����̓R���p�C���ɂ̂ݎg�p����AWAR�p�b�P�[�W����͏��O����܂��B
+ </para>
+
+ <para>
+ �r���h�ƃf�v���C�̂��߂ɁA�v���W�F�N�g�f�B���N�g���� <literal>ant war</literal> ��Ăяo���A
+ <literal>hibernate-tutorial.war</literal> �t�@�C����Tomcat�� <literal>webapp</literal>
+ �f�B���N�g���ɃR�s�[���Ă��������B
+ �܂�Tomcat��C���X�g�[�����Ă��Ȃ���A�_�E�����[�h���āA�ȉ��̃C���X�g�[���K�C�h�ɏ]���Ă��������B
+ �������A���̃A�v���P�[�V�����̃f�v���C���邽�߂ɁATomcat�̐ݒ��ύX����K�v�͂���܂���B
+ </para>
+
+ <para>
+ ��x�f�v���C����Tomcat��N������A <literal>http://localhost:8080/hibernate-tutorial/eventmanager</literal> ��
+ �A�v���P�[�V�����ւ̃A�N�Z�X���\�ł��B
+ �ŏ��̃��N�G�X�g���쐬�����T�[�u���b�g�ɓn�����Ƃ��ɁATomcat�̃��O��
+ Hibernate�̏�����������m�F���Ă�������
+ �i <literal>HibernateUtil</literal> ��̐ÓI�������u���b�N���Ă�Ă��܂��j�B
+ �܂��Aexception�����������Ȃ�ڍׂ�m�F���Ă��������B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="tutorial-summary" revision="1">
+ <title>�v��</title>
+
+ <para>
+ ���̃`���[�g���A���ł́A�ȒP�ȃX�^���h�A���[����Hibernate�A�v���P�[�V������
+ ���K�͂�Web�A�v���P�[�V�����������߂̊�{��Љ�܂����B
+ </para>
+
+ <para>
+ ���Hibernate�Ɏ��M������A���t�@�����X�h�L�������g�̖ڎ��ɖڂ�ʂ��āA
+ �ʔ��������Ǝv���g�s�b�N��T���Ă��������B
+ �ł�p�ɂɎ��₪����̂́A�g�����U�N�V���������i<xref linkend="transactions"/>�j�A
+ �t�F�b�`�̃p�t�H�[�}���X�i<xref linkend="performance"/>�j�A
+ API�̎g�����i<xref linkend="objectstate"/>�j�ƃN�G��
+ �i<xref linkend="objectstate-querying"/>�j�ł��B
+ </para>
+
+ <para>
+ ����Ɂi���ʂȁj�`���[�g���A�����K�v�Ȃ�AHibernate�E�F�u�T�C�g��Y�ꂸ�Ƀ`�F�b�N���Ă��������B
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/content/xml.xml (from rev 14075, core/trunk/documentation/manual/ja-JP/src/main/docbook/modules/xml.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/content/xml.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/content/xml.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,299 @@
+<?xml version="1.0" encoding="Shift_JIS"?>
+<chapter id="xml">
+ <title>XML�}�b�s���O</title>
+
+ <para><emphasis>XML�}�b�s���O��Hibernate3.0�ł͎����I�ȋ@�\�ł���A���Ɋ����I�ɊJ�����ł��B</emphasis></para>
+
+ <sect1 id="xml-intro" revision="1">
+ <title>XML�f�[�^�ł̍��</title>
+
+ <para>
+ Hibernate�ł͉i������POJO��g���č�Ƃ���̂Ƃقړ����悤�Ȃ����ŁA
+ �i������XML�f�[�^��g���č�Ƃł��܂��B
+ </para>
+
+ <para>
+ Hibernate��XML�c���[�𑀍삷�邽�߂�API�Ƃ���dom4j��T�|�[�g���Ă��܂��B
+ �f�[�^�x�[�X����dom4j�̃c���[������N�G���������Ƃ��ł��A
+ �c���[�ɑ��čs�����C���͎����I�Ƀf�[�^�x�[�X�Ɠ�������܂��B
+
+ �܂�XML�h�L�������g��擾���邱�Ƃ��ł��Adom4j��g���ăh�L�������g��p�[�X���A
+ Hibernate�̔C�ӂ̊�{�����g���ăf�[�^�x�[�X�֏������ނ��Ƃ��ł��܂��B�F
+ �܂�A<literal>persist(), saveOrUpdate(), merge(), delete(), replicate()</literal>
+ ����ł�(�}�[�W�͂܂��T�|�[�g���Ă��܂���)�B
+
+ </para>
+
+ <para>
+ �f�[�^�̃C���|�[�g/�G�N�X�|�[�g�A
+ JMS�ɂ��G���e�B�e�B�f�[�^�̊O������SOAP�AXSLT�x�[�X�̃��|�[�g�ȂǁA
+ ���̋@�\�ɂ͑����̗p�r������܂��B
+ </para>
+
+ <para>
+ �P��̃}�b�s���O�́A�N���X�̃v���p�e�B��XML�h�L�������g�̃m�[�h��
+ �����Ƀf�[�^�x�[�X�փ}�b�s���O���邽�߂Ɏg�����Ƃ��ł��܂��B
+ �܂��}�b�s���O����N���X���Ȃ���A
+ XML������}�b�s���O���邽�߂Ɏg�����Ƃ��ł��܂��B
+
+ </para>
+
+ <sect2 id="xml-intro-mapping">
+ <title>XML�ƃN���X�̃}�b�s���O���Ɏw�肷��</title>
+
+ <para>
+ �����POJO��XML���Ƀ}�b�s���O�����ł��B�F
+ </para>
+
+ <programlisting><![CDATA[<class name="Account"
+ table="ACCOUNTS"
+ node="account">
+
+ <id name="accountId"
+ column="ACCOUNT_ID"
+ node="@id"/>
+
+ <many-to-one name="customer"
+ column="CUSTOMER_ID"
+ node="customer/@id"
+ embed-xml="false"/>
+
+ <property name="balance"
+ column="BALANCE"
+ node="balance"/>
+
+ ...
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="xml-onlyxml">
+ <title>XML�}�b�s���O������w�肷��</title>
+
+ <para>
+ �����POJO�N���X���Ȃ��}�b�s���O�̗�ł��B�F
+ </para>
+
+ <programlisting><![CDATA[<class entity-name="Account"
+ table="ACCOUNTS"
+ node="account">
+
+ <id name="id"
+ column="ACCOUNT_ID"
+ node="@id"
+ type="string"/>
+
+ <many-to-one name="customerId"
+ column="CUSTOMER_ID"
+ node="customer/@id"
+ embed-xml="false"
+ entity-name="Customer"/>
+
+ <property name="balance"
+ column="BALANCE"
+ node="balance"
+ type="big_decimal"/>
+
+ ...
+
+</class>]]></programlisting>
+
+ <para>
+ ���̃}�b�s���O�ɂ��Adom4j�c���[���A
+ �v���p�e�B��/�l�̑g�̃O���t�ijava�� <literal>Map</literal>�j�Ƃ���
+ �f�[�^�ɃA�N�Z�X�ł��܂��B
+
+ �v���p�e�B�̖��O�́AHQL�N�G���[��ŎQ�Ƃł��鏃���Ș_���\���ł��B
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="xml-mapping" revision="1">
+ <title>XML�}�b�s���O�̃��^�f�[�^</title>
+
+ <para>
+ ������Hibernate�̃}�b�s���O�v�f�́@<literal>node</literal>�@�������g�p�ł��܂��B
+ ����ɂ��XML�����̖��O��v���p�e�B��G���e�B�e�B�f�[�^��ێ�����v�f��w��ł��܂��B
+ <literal>node</literal>�@�����̃t�H�[�}�b�g�͈ȉ��̒���1�łȂ���Ȃ�܂���B�F
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>"element-name"</literal> - �w�肵��XML�v�f�փ}�b�s���O���܂�
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>"@attribute-name"</literal> - �w�肵��XML�����փ}�b�s���O���܂�
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>"."</literal> -�@�e�v�f�փ}�b�s���O���܂�
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>"element-name/@attribute-name"</literal> -
+ �w�肵���G�������g�̎w�肵�������փ}�b�s���O���܂�
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ �R���N�V�����ƒP��̒l�̊֘A�ɑ��āA
+ ���܂��� <literal>embed-xml</literal> ����������܂��B
+ �f�t�H���g�� <literal>embed-xml="true"</literal> �Ɛݒ肵���ꍇ�A
+ �֘A����G���e�B�e�B(�l�^�̃R���N�V����)��XML�c���[�́A
+ ���ڊ֘A���L����G���e�B�e�B��XML�c���[��ɖ��ߍ��܂�܂��B
+ ���ɁA<literal>embed-xml="false"</literal> �Ɛݒ肵���ꍇ�A
+ �Q�Ƃ���鎯�ʎq�̒l���������d�x�P���̊֘A�ɑ���XML�Ɍ���A
+ �P���ɃR���N�V�����͂܂���������Ȃ��Ȃ�܂��B
+ </para>
+
+ <para>
+ ���܂�ɑ����̊֘A�ɑ���
+ <literal>embed-xml="true"</literal> �Ƃ����܂܂ɂ���̂͒��ӂ��ׂ��ł��B
+ XML�͏z���܂������܂���B
+ </para>
+
+ <programlisting><![CDATA[<class name="Customer"
+ table="CUSTOMER"
+ node="customer">
+
+ <id name="id"
+ column="CUST_ID"
+ node="@id"/>
+
+ <map name="accounts"
+ node="."
+ embed-xml="true">
+ <key column="CUSTOMER_ID"
+ not-null="true"/>
+ <map-key column="SHORT_DESC"
+ node="@short-desc"
+ type="string"/>
+ <one-to-many entity-name="Account"
+ embed-xml="false"
+ node="account"/>
+ </map>
+
+ <component name="name"
+ node="name">
+ <property name="firstName"
+ node="first-name"/>
+ <property name="initial"
+ node="initial"/>
+ <property name="lastName"
+ node="last-name"/>
+ </component>
+
+ ...
+
+</class>]]></programlisting>
+
+ <para>
+ ���̗�ł́A���ۂ�account�̃f�[�^�ł͂Ȃ��A
+ account��id�̃R���N�V�����ߍ��ނ��Ƃɂ��܂����B
+ ������HQL�N�G���ł��F
+ </para>
+
+ <programlisting><![CDATA[from Customer c left join fetch c.accounts where c.lastName like :lastName]]></programlisting>
+
+ <para>
+ ���̂悤�ȃf�[�^�Z�b�g��Ԃ��ł��傤
+ </para>
+
+ <programlisting><![CDATA[<customer id="123456789">
+ <account short-desc="Savings">987632567</account>
+ <account short-desc="Credit Card">985612323</account>
+ <name>
+ <first-name>Gavin</first-name>
+ <initial>A</initial>
+ <last-name>King</last-name>
+ </name>
+ ...
+</customer>]]></programlisting>
+
+ <para>
+ <literal><one-to-many></literal> �}�b�s���O��
+ <literal>embed-xml="true"</literal> �Ɛݒ肵���ꍇ�A
+ �f�[�^�͂��̂悤�ɂȂ�ł��傤�B
+ </para>
+
+ <programlisting><![CDATA[<customer id="123456789">
+ <account id="987632567" short-desc="Savings">
+ <customer id="123456789"/>
+ <balance>100.29</balance>
+ </account>
+ <account id="985612323" short-desc="Credit Card">
+ <customer id="123456789"/>
+ <balance>-2370.34</balance>
+ </account>
+ <name>
+ <first-name>Gavin</first-name>
+ <initial>A</initial>
+ <last-name>King</last-name>
+ </name>
+ ...
+</customer>]]></programlisting>
+
+ </sect1>
+
+
+ <sect1 id="xml-manipulation" revision="1">
+ <title>XML�f�[�^����</title>
+
+ <para>
+ XML�h�L�������g��A�A�v���P�[�V������ōēǂݍ��݂�X�V���Ă݂܂��傤�B
+ �ȉ��ł�dom4j�̃Z�b�V������擾���邱�Ƃōs���܂��B�F
+ </para>
+
+ <programlisting><![CDATA[Document doc = ....;
+
+Session session = factory.openSession();
+Session dom4jSession = session.getSession(EntityMode.DOM4J);
+Transaction tx = session.beginTransaction();
+
+List results = dom4jSession
+ .createQuery("from Customer c left join fetch c.accounts where c.lastName like :lastName")
+ .list();
+for ( int i=0; i<results.size(); i++ ) {
+ //add the customer data to the XML document
+ Element customer = (Element) results.get(i);
+ doc.getRootElement().add(customer);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <programlisting><![CDATA[Session session = factory.openSession();
+Session dom4jSession = session.getSession(EntityMode.DOM4J);
+Transaction tx = session.beginTransaction();
+
+Element cust = (Element) dom4jSession.get("Customer", customerId);
+for ( int i=0; i<results.size(); i++ ) {
+ Element customer = (Element) results.get(i);
+ //change the customer name in the XML and database
+ Element name = customer.element("name");
+ name.element("first-name").setText(firstName);
+ name.element("initial").setText(initial);
+ name.element("last-name").setText(lastName);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ XML�x�[�X�̃f�[�^�̃C���|�[�g/�G�N�X�|�[�g��������邽�߂ɁA
+ Hibernate�� <literal>replicate()</literal> ������̋@�\���т���̂�
+ �ɂ߂ėL���ł��B
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/AuthorWork.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/AuthorWork.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/AuthorWork.zargo (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/AuthorWork.zargo)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/CustomerOrderProduct.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/CustomerOrderProduct.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/CustomerOrderProduct.zargo (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/CustomerOrderProduct.zargo)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/EmployerEmployee.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/EmployerEmployee.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/EmployerEmployee.zargo (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/EmployerEmployee.zargo)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/full_cream.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/full_cream.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/full_cream.svg (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/full_cream.svg)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/images/full_cream.svg (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/images/full_cream.svg 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,429 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="354.331"
+ height="336.614"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,5.25349)"
+ style="font-size:12;"
+ id="g659">
+ <rect
+ width="212.257"
+ height="57.2441"
+ x="17.9576"
+ y="100.132"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ transform="matrix(0.743454,0,0,0.482981,6.46949,52.2178)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <rect
+ width="325.86"
+ height="63.6537"
+ x="17.4083"
+ y="15.194"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="325.86"
+ height="63.6537"
+ x="13.6713"
+ y="12.4966"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ <g
+ transform="matrix(1.14345,0,0,0.729078,-1.67818,105.325)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <text
+ x="170.824753"
+ y="58.402939"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="170.824997"
+ y="58.402901"
+ id="tspan360">
+Application</tspan>
+ </text>
+ <text
+ x="178.076340"
+ y="364.281433"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="178.076004"
+ y="364.281006"
+ id="tspan421">
+Database</tspan>
+ </text>
+ <text
+ x="68.605331"
+ y="138.524582"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="68.605301"
+ y="138.524994"
+ id="tspan384">
+SessionFactory</tspan>
+ </text>
+ <rect
+ width="67.0014"
+ height="101.35"
+ x="196.927"
+ y="89.2389"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect387" />
+ <rect
+ width="67.0014"
+ height="101.35"
+ x="194.633"
+ y="86.4389"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect388" />
+ <text
+ x="249.108841"
+ y="173.885559"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text389">
+ <tspan
+ x="249.108994"
+ y="173.886002"
+ id="tspan392">
+Session</tspan>
+ </text>
+ <rect
+ width="73.0355"
+ height="101.35"
+ x="270.995"
+ y="90.0018"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect395" />
+ <rect
+ width="73.0355"
+ height="101.35"
+ x="267.869"
+ y="87.2018"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect396" />
+ <text
+ x="328.593658"
+ y="174.715622"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text397">
+ <tspan
+ x="328.593994"
+ y="174.716003"
+ id="tspan563">
+Transaction</tspan>
+ </text>
+ <g
+ transform="matrix(0.29544,0,0,0.397877,9.70533,103.96)"
+ style="font-size:12;"
+ id="g565">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect566" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect567" />
+ </g>
+ <text
+ x="25.592752"
+ y="204.497803"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:10;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text568">
+ <tspan
+ x="25.592800"
+ y="204.498001"
+ id="tspan662">
+TransactionFactory</tspan>
+ </text>
+ <g
+ transform="matrix(0.298082,0,0,0.397877,99.6898,103.96)"
+ style="font-size:12;"
+ id="g573">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect574" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect575" />
+ </g>
+ <text
+ x="134.030670"
+ y="205.532791"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:10;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text576">
+ <tspan
+ x="134.031006"
+ y="205.533005"
+ id="tspan664">
+ConnectionProvider</tspan>
+ </text>
+ <g
+ transform="matrix(1.14345,0,0,0.729078,-1.67818,38.9539)"
+ style="font-size:12;"
+ id="g587">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect588" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect589" />
+ </g>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="25.6196"
+ y="206.028"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect594" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="24.4229"
+ y="204.135"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect595" />
+ <text
+ x="85.575645"
+ y="282.300354"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text596">
+ <tspan
+ x="85.575600"
+ y="282.299988"
+ id="tspan607">
+JNDI</tspan>
+ </text>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="236.937"
+ y="206.791"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect610" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="235.741"
+ y="204.898"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect611" />
+ <text
+ x="342.093201"
+ y="283.226410"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text612">
+ <tspan
+ x="342.092987"
+ y="283.226013"
+ id="tspan621">
+JTA</tspan>
+ </text>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="130.134"
+ y="206.791"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect616" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="128.937"
+ y="204.898"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect617" />
+ <text
+ x="212.445343"
+ y="283.226410"
+ transform="scale(0.823795,0.823795)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text618">
+ <tspan
+ x="212.445007"
+ y="283.226013"
+ id="tspan623">
+JDBC</tspan>
+ </text>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,6.19341)"
+ style="font-size:12;"
+ id="g637">
+ <g
+ transform="matrix(0.499515,0,0,0.415467,-0.237339,5.61339)"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="33.749969"
+ y="50.589706"
+ style="font-size:11;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="33.750000"
+ y="50.589699"
+ id="tspan635">
+Transient Objects</tspan>
+ </text>
+ </g>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,5.25349)"
+ style="font-size:12;"
+ id="g644">
+ <g
+ transform="matrix(0.297486,0,0,0.516482,230.251,36.9178)"
+ id="g364">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect365" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect366" />
+ </g>
+ <text
+ x="277.123230"
+ y="85.155571"
+ style="font-size:11;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text367">
+ <tspan
+ x="277.122986"
+ y="85.155602"
+ id="tspan631">
+Persistent</tspan>
+ <tspan
+ x="277.122986"
+ y="96.155602"
+ id="tspan633">
+Objects</tspan>
+ </text>
+ </g>
+</svg>
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/hibernate_logo_a.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/hibernate_logo_a.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/lite.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/lite.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/lite.svg (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/lite.svg)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/images/lite.svg (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/images/lite.svg 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,334 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="318.898"
+ height="248.031"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <rect
+ width="291.837"
+ height="57.0074"
+ x="17.3169"
+ y="18.646"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="291.837"
+ height="57.0074"
+ x="13.9703"
+ y="16.2302"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ <g
+ transform="matrix(0.326107,0,0,0.765831,9.59261,8.98517)"
+ style="font-size:12;"
+ id="g161">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <g
+ transform="matrix(1.02406,0,0,0.652953,0.223384,39.9254)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <g
+ transform="matrix(0.449834,0,0,0.338463,-3.15909,9.73319)"
+ style="font-size:12;"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="302.277679"
+ y="65.943230"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="302.277954"
+ y="65.943184"
+ id="tspan360">
+Application</tspan>
+ </text>
+ <text
+ x="36.235924"
+ y="63.796055"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:14;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="36.235950"
+ y="63.796051"
+ id="tspan427">
+Transient Objects</tspan>
+ </text>
+ <text
+ x="180.416245"
+ y="290.543701"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="180.415939"
+ y="290.543549"
+ id="tspan421">
+Database</tspan>
+ </text>
+ <text
+ x="25.037701"
+ y="179.154755"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="25.037655"
+ y="179.154648"
+ id="tspan384">
+SessionFactory</tspan>
+ </text>
+ <g
+ transform="matrix(0.252763,0,0,0.765831,109.104,8.98517)"
+ style="font-size:12;"
+ id="g386">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect387" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect388" />
+ </g>
+ <g
+ transform="matrix(0.297394,0,0,0.572692,101.502,21.6359)"
+ style="font-size:12;"
+ id="g364">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect365" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect366" />
+ </g>
+ <text
+ x="202.746506"
+ y="102.992203"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:14;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text367">
+ <tspan
+ x="202.746948"
+ y="102.992249"
+ id="tspan423">
+Persistent</tspan>
+ <tspan
+ x="202.746948"
+ y="116.992355"
+ id="tspan425">
+Objects</tspan>
+ </text>
+ <text
+ x="174.458496"
+ y="180.080795"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text389">
+ <tspan
+ x="174.458618"
+ y="180.080338"
+ id="tspan392">
+Session</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,188.675,8.98517)"
+ style="font-size:12;"
+ id="g394">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect395" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect396" />
+ </g>
+ <text
+ x="260.413269"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text397">
+ <tspan
+ x="260.412964"
+ y="179.154343"
+ id="tspan400">
+JDBC</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,229.156,8.98517)"
+ style="font-size:12;"
+ id="g405">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect406" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect407" />
+ </g>
+ <text
+ x="320.606903"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text408">
+ <tspan
+ x="320.606964"
+ y="179.154343"
+ id="tspan417">
+JNDI</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,269.281,8.98517)"
+ style="font-size:12;"
+ id="g411">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect412" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect413" />
+ </g>
+ <text
+ x="377.096313"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+ style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text414">
+ <tspan
+ x="377.096008"
+ y="179.154999"
+ id="tspan145">
+JTA</tspan>
+ </text>
+</svg>
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/overview.png (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/overview.png)
===================================================================
(Binary files differ)
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/images/overview.svg (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/images/overview.svg)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/images/overview.svg (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/images/overview.svg 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,250 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="248.031"
+ height="248.031"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,-3.02123)"
+ style="font-size:12;"
+ id="g158">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="17.3527"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="15.3883"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,3.04452)"
+ style="font-size:12;"
+ id="g161">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,8.0993)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.543505,2.59104,21.1103)"
+ style="font-size:12;"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="105.392174"
+ y="56.568123"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="105.392273"
+ y="56.568146"
+ id="tspan186">
+Application</tspan>
+ </text>
+ <text
+ x="81.820183"
+ y="103.149330"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:20;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="81.820213"
+ y="103.149727"
+ id="tspan206">
+Persistent Objects</tspan>
+ </text>
+ <text
+ x="111.548180"
+ y="278.927887"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="111.547874"
+ y="278.927551"
+ id="tspan200">
+Database</tspan>
+ </text>
+ <text
+ x="94.436180"
+ y="153.805740"
+ transform="scale(0.771934,0.771934)"
+ style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="94.436180"
+ y="153.805740"
+ id="tspan221">
+HIBERNATE</tspan>
+ </text>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,2.59083,1.02261)"
+ style="font-size:12;"
+ id="g254">
+ <g
+ transform="translate(4.58374,2.61928)"
+ id="g176">
+ <g
+ transform="matrix(0.571429,0,0,0.67347,-10.6174,117.093)"
+ id="g170">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect171" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect172" />
+ </g>
+ <g
+ transform="matrix(0.571429,0,0,0.67347,138.682,117.093)"
+ id="g173">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect174" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect175" />
+ </g>
+ </g>
+ <text
+ x="47.259438"
+ y="182.367538"
+ style="font-weight:bold;stroke-width:1pt;font-family:Courier;"
+ id="text191">
+ <tspan
+ x="47.259399"
+ y="182.367996"
+ id="tspan212">
+hibernate.</tspan>
+ <tspan
+ x="47.259399"
+ y="194.367996"
+ id="tspan214">
+properties</tspan>
+ </text>
+ <text
+ x="198.523010"
+ y="188.260941"
+ style="font-weight:normal;stroke-width:1pt;font-family:helvetica;"
+ id="text194">
+ <tspan
+ id="tspan195">
+XML Mapping</tspan>
+ </text>
+ </g>
+</svg>
Copied: core/trunk/documentation/manual/ja-JP/src/main/docbook/legal_notice.xml (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/legal_notice.xml)
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/legal_notice.xml (rev 0)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/legal_notice.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -0,0 +1,52 @@
+<?xml version='1.0'?>
+<!DOCTYPE legalnotice PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<legalnotice id="Legal_Notice">
+ <title>Legal Notice</title>
+ <para>
+ <address>
+ <street>1801 Varsity Drive</street>
+ <city>Raleigh</city>, <state>NC</state><postcode>27606-2072</postcode><country>USA</country>
+ <phone>Phone: +1 919 754 3700</phone>
+ <phone>Phone: 888 733 4281</phone>
+ <fax>Fax: +1 919 754 3701</fax>
+ <pob>PO Box 13588</pob><city>Research Triangle Park</city>, <state>NC</state><postcode>27709</postcode><country>USA</country>
+ </address>
+ </para>
+ <para>
+ Copyright <trademark class="copyright"></trademark> 2007 by Red Hat, Inc. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, V1.0 or later (the latest version is presently available at <ulink url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).
+ </para>
+ <para>
+ Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder.
+ </para>
+ <para>
+ Distribution of the work or derivative of the work in any standard (paper) book form for commercial purposes is prohibited unless prior permission is obtained from the copyright holder.
+ </para>
+ <para>
+ Red Hat and the Red Hat "Shadow Man" logo are registered trademarks of Red Hat, Inc. in the United States and other countries.
+ </para>
+ <para>
+ All other trademarks referenced herein are the property of their respective owners.
+ </para>
+ <para>
+ The GPG fingerprint of the security(a)redhat.com key is:
+ </para>
+ <para>
+ CA 20 86 86 2B D6 9D FC 65 F6 EC C4 21 91 80 CD DB 42 A6 0E
+ </para>
+</legalnotice>
\ No newline at end of file
Deleted: core/trunk/documentation/manual/ja-JP/src/main/docbook/master.xml
===================================================================
--- core/trunk/documentation/manual/ja-JP/src/main/docbook/master.xml 2007-10-09 18:45:36 UTC (rev 14075)
+++ core/trunk/documentation/manual/ja-JP/src/main/docbook/master.xml 2007-10-09 19:02:00 UTC (rev 14076)
@@ -1,231 +0,0 @@
-<?xml version="1.0" encoding="Shift_JIS"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3CR3//EN"
- "../support/docbook-dtd/docbookx.dtd"
-[
-<!ENTITY tutorial SYSTEM "modules/tutorial.xml">
-<!ENTITY architecture SYSTEM "modules/architecture.xml">
-<!ENTITY configuration SYSTEM "modules/configuration.xml">
-<!ENTITY persistent-classes SYSTEM "modules/persistent_classes.xml">
-<!ENTITY basic-mapping SYSTEM "modules/basic_mapping.xml">
-<!ENTITY collection-mapping SYSTEM "modules/collection_mapping.xml">
-<!ENTITY association-mapping SYSTEM "modules/association_mapping.xml">
-<!ENTITY component-mapping SYSTEM "modules/component_mapping.xml">
-<!ENTITY inheritance-mapping SYSTEM "modules/inheritance_mapping.xml">
-<!ENTITY session-api SYSTEM "modules/session_api.xml">
-<!ENTITY transactions SYSTEM "modules/transactions.xml">
-<!ENTITY events SYSTEM "modules/events.xml">
-<!ENTITY batch SYSTEM "modules/batch.xml">
-<!ENTITY query-hql SYSTEM "modules/query_hql.xml">
-<!ENTITY query-criteria SYSTEM "modules/query_criteria.xml">
-<!ENTITY query-sql SYSTEM "modules/query_sql.xml">
-<!ENTITY filters SYSTEM "modules/filters.xml">
-<!ENTITY xml SYSTEM "modules/xml.xml">
-<!ENTITY performance SYSTEM "modules/performance.xml">
-<!ENTITY toolset-guide SYSTEM "modules/toolset_guide.xml">
-<!ENTITY example-parentchild SYSTEM "modules/example_parentchild.xml">
-<!ENTITY example-weblog SYSTEM "modules/example_weblog.xml">
-<!ENTITY example-mappings SYSTEM "modules/example_mappings.xml">
-<!ENTITY best-practices SYSTEM "modules/best_practices.xml">
-]>
-
-<book lang="ja">
-
- <bookinfo>
- <title>HIBERNATE - Relational Persistence for Idiomatic Java</title>
- <subtitle>Hibernate Reference Documentation</subtitle>
- <releaseinfo>3.2 cr3</releaseinfo>
- </bookinfo>
-
- <toc/>
-
- <preface id="preface" revision="2">
- <title>�O����</title>
-
- <para>
- �����̊�Ɗ��ɂ����āA�I�u�W�F�N�g�w���\�t�g�E�F�A�ƃ����[�V���i���f�[�^�x�[�X�Ɋւ���Ƃ�
- �ώG�Ŗc��Ȏ��Ԃ�K�v�Ƃ��܂��B
- Hibernate��Java���̃I�u�W�F�N�g/�����[�V���i���}�b�s���O�c�[���ł��B
- �I�u�W�F�N�g/�����[�V���i���}�b�s���O�iORM�j�Ƃ́A
- �I�u�W�F�N�g���f������SQL�x�[�X�X�L�[�}�̃����[�V���i���f�[�^���f���ւƁA
- �f�[�^�\����}�b�s���O����i�Ή��t����j�Z�p�̂��Ƃł��B
- </para>
-
- <para>
- Hibernate��Java�N���X����f�[�^�x�[�X�e�[�u���ցi������Java�f�[�^�^����SQL�f�[�^�^�ցj
- �̃}�b�s���O�������邾���ł͂Ȃ��A�f�[�^�̃N�G���ƕ����̎d�g�݂���܂��B
- ���̂�������SQL��JDBC��g�������Ƃł̃f�[�^�����ɔ�₳��Ă����J�����Ԃ�啝�ɍ팸�ł��܂��B
- </para>
-
- <para>
- Hibernate�̍ŏI�ڕW�́A�f�[�^�̉i�����Ɋւ���ʓI�ȃv���O���~���O��Ƃ�95������J���҂������邱�Ƃł��B
- Hibernate�̓r�W�l�X���W�b�N�̎����ɃX�g�A�h�v���V�[�W����g��
- �f�[�^���S�A�v���P�[�V�����ɑ��Ẵx�X�g�\�����[�V�����ł���ɗ��܂�܂���B
- �I�u�W�F�N�g�w���h���C�����f����Java�x�[�X�̒��ԑw�ł̃r�W�l�X���W�b�N�ɑ��čł��ɗ����܂��B
- ������Hibernate�̓x���_�ŗL��SQL�R�[�h��팸�܂��̓J�v�Z����������A
- �\�`������I�u�W�F�N�g�̃O���t�ւƃ��U���g�Z�b�g��ϊ�����Ȃǂ́A
- ��ʓI�ȃ^�X�N�ɂ�𗧂ł��傤�B
- </para>
-
- <para>
- Hibernate��I�u�W�F�N�g/�����[�V���i���}�b�s���O�A
- ����ɂ�Java�����߂Ă̕��́A�ȉ��̃X�e�b�v�ɏ]���Ă��������F
- </para>
-
- <orderedlist>
- <listitem>
- <para>
- <xref linkend="tutorial"/> ��ǂ�ł��������B
- �i�K�I�ɉ����Ă����܂��B
- �`���[�g���A���̃\�[�X�R�[�h�̓f�B�X�g���r���[�V������
- <literal>doc/reference/tutorial</literal> �f�B���N�g���Ɋ܂܂�Ă��܂��B
- </para>
- </listitem>
- <listitem>
- <para>
- <xref linkend="architecture"/> ��ǂ�ŁAHibernate�����p�\�Ȋ��𗝉��Ă��������B
- </para>
- </listitem>
- <listitem>
- <para>
- Hibernate�f�B�X�g���r���[�V������ <literal>eg/</literal> �f�B���N�g�������������B
- �ȒP�ȃX�^���h�A���[���̃A�v���P�[�V����������܂��B
- JDBC�h���C�o�� <literal>lib/</literal> �f�B���N�g���ɃR�s�[���āA
- �����̃f�[�^�x�[�X�ɍ����������l��w�肷��悤�� <literal>etc/hibernate.properties</literal>
- ��ҏW���Ă��������B
- �f�B�X�g���r���[�V�����f�B���N�g������A�R�}���h�v�����v�g��
- <literal>ant eg</literal> �ƃ^�C�v���Ă��������iAnt��g���܂��j�B
- �܂�Windows���ł� <literal>build eg</literal> �ƃ^�C�v���Ă��������B
- </para>
- </listitem>
- <listitem>
- <para>
- ���̃��t�@�����X�h�L�������g����̏�Ƃ��ė��p���Ă��������B
- �A�v���P�[�V�����v�ɂ��Ă̂���Ȃ����i�K�I�ȃ`���[�g���A����T���Ă���Ȃ�A
- <emphasis>Java Persistence with Hibernate</emphasis>�ihttp://www.manning.com/bauer2�j
- �������߂��܂��B
- �܂�http://caveatemptor.hibernate.org����
- Java Persistence with Hibernate�̗��̃A�v���P�[�V������_�E�����[�h�ł��܂��B
- </para>
- </listitem>
- <listitem>
- <para>
- FAQ��Hibernate�E�F�u�T�C�g�ɂ���܂��B
- </para>
- </listitem>
- <listitem>
- <para>
- �T�[�h�p�[�e�B�̃f���A��A�`���[�g���A����Hibernate�E�F�u�T�C�g�Ƀ����N������܂��B
- </para>
- </listitem>
- <listitem>
- <para>
- Hibernate�E�F�u�T�C�g�̃R�~���j�e�B�G���A�́A�f�U�C���p�^�[���₳�܂��܂ȓ����\�����[�V����
- �iTomcat, JBoss AS, Struts, EJB, ���j�ɂ��Ă̂悢��ł��B
- </para>
- </listitem>
- </orderedlist>
-
- <para>
- ���₪�����Hibernate�E�F�u�T�C�g�̃��[�U�t�H�[�������p���Ă��������B
- �܂��o�O���|�[�g�ƃt�B�[�`�����N�G�X�g�̂���JIRA�ۑ�ǐՃV�X�e����p�ӂ��Ă��܂��B
- Hibernate�̊J���ɋ���������A�J���҃��[�����O���X�g�ɎQ�����Ă��������B
- ���̃h�L�������g���Ȃ��̍��̌��t�ɖ|�����ꍇ�́A
- �J���҃��[�����O���X�g�Ŏ������ɃR���^�N�g�����Ă��������B
- </para>
-
- <para>
- ���p�J���̃T�|�[�g�A���i�̃T�|�[�g�AHibernate�̃g���[�j���O��JBoss Inc.�����Ă��܂�
- �ihttp://www.hibernate.org/SupportTraining/�����������j�B
- Hibernate��Professional Open Source�v���W�F�N�g�A
- ������JBoss Enterprise Middleware System�iJEMS�j�v���_�N�g�X�C�[�g�̃N���e�B�J���R���|�[�l���g�ł��B
- </para>
-
- <sect1 id="preface-s1" revision="-1">
-
- <title>���{���ɂ���</title>
-
- <para id="preface-s1-p1" revision="-1">
- ���̓��{���Hibernate Reference Document�i�ȉ��A���{��Łj�́A
- Hibernate�v���W�F�N�g�̖|��v���Z�X�Ɋ�Â��č쐬����Ă��܂��B
- ���{��łȂ�тɌ�����LGPL���C�Z���X�ɏ����܂��B
- </para>
-
- <para id="preface-s1-p2" revision="-1">
- ���{��ł̗��p�ɂ���đ�O�҂���邠����s���v�ɑ��āA
- �����ҁA�|��҂Ȃ�тɂ��̑g�D�͈�̕ۏ��������˂܂��B
- ���{��ł͌���܂މ\�������邱�Ƃ�F��������ł����p���������B
- ��e�̐��m�ȈӖ���c�����邽�߂ɂ́A������ǂނ��Ƃ������߂��܂��B
- �܂��A������{��łɌ�������ꂽ�ꍇ�́A�|��҂ɂ��A������������K���ł��B
- ��������e�Ɋւ��Ă̂��₢���킹�ɂ͉������˂܂��̂ŁA���������������B
- </para>
-
- <sect2 id="preface-s1-1" revision="-1">
-
- <title>���{��Ŗ|��҂ɂ���</title>
-
- <para id="preface-s1-1-p4" revision="-1">
- ���{��Ńo�[�W����3.2 cr3�̖|��͊�����ЃG�N�T
- �i<ulink url="http://www.exa-corp.co.jp">�z�[���y�[�W�͂�����</ulink>�j
- �̈ȉ��̃����o�[�ōs���܂����B
- �{�ԗ́i6,18,19,21,22,23�͒S���j�A
- �L�˗T��i�O����,2,5,13,14,24,25�͒S���j�A
- ���s���l�i7,8,9,10�͒S���j�A
- �ߐ{�G�j�i12,16,17�͒S���j�A
- ��֒m���i1,3,11�͒S���j�A
- �ѓc�_�i�i4,15�͒S���j�A
- ���Ԍ���i20�͒S���j�A
- �X����i���r���[�S���j�B
- �Ȃ���̂��w�E�͖{�ԁA�L�˂܂ł��肢�������܂��B
-
- <mediaobject>
- <imageobject role="fo">
- <imagedata fileref="images/mailaddr.gif" format="GIF" align="center"/>
- </imageobject>
- <imageobject role="html">
- <imagedata fileref="../shared/images/mailaddr.gif" format="GIF" align="center"/>
- </imageobject>
- </mediaobject>
-
- </para>
- </sect2>
- </sect1>
-
- </preface>
-
- &tutorial;
-
- &architecture;
-
- &configuration;
-
- &persistent-classes;
-
- &basic-mapping;
- &collection-mapping;
- &association-mapping;
- &component-mapping;
- &inheritance-mapping;
-
- &session-api;
- &transactions;
- &events;
- &batch;
-
- &query-hql;
- &query-criteria;
- &query-sql;
- &filters;
- &xml;
-
- &performance;
-
- &toolset-guide;
-
- &example-parentchild;
- &example-weblog;
- &example-mappings;
-
- &best-practices;
-
-</book>
-
18 years, 6 months