Hibernate SVN: r19292 - core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-25 22:06:03 -0400 (Sun, 25 Apr 2010)
New Revision: 19292
Modified:
core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java
Log:
HHH-4773 @CollectionId does not force the id column to not-null
Modified: core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java
===================================================================
--- core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java 2010-04-26 02:03:34 UTC (rev 19291)
+++ core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java 2010-04-26 02:06:03 UTC (rev 19292)
@@ -439,10 +439,11 @@
column.setPropertyName(
BinderHelper.getRelativePath( propertyHolder, inferredData.getPropertyName() )
);
- column.setNullable(
- col.nullable()
- ); //TODO force to not null if available? This is a (bad) user choice.
- column.setUnique( col.unique() );
+ //although in theory, null is an acceptable value in a Map key
+ //we need force this column to be not null, as it intended to be the primary key.
+ if ( nullability != Nullability.FORCED_NULL ) {
+ column.setNullable( false );
+ } column.setUnique( col.unique() );
column.setInsertable( col.insertable() );
column.setUpdatable( col.updatable() );
column.setSecondaryTableName( tableName );
14 years
Hibernate SVN: r19291 - core/trunk/annotations/src/main/java/org/hibernate/cfg.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-25 22:03:34 -0400 (Sun, 25 Apr 2010)
New Revision: 19291
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java
Log:
HHH-4773 @CollectionId does not force the id column to not-null
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java 2010-04-25 10:49:36 UTC (rev 19290)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java 2010-04-26 02:03:34 UTC (rev 19291)
@@ -439,9 +439,11 @@
column.setPropertyName(
BinderHelper.getRelativePath( propertyHolder, inferredData.getPropertyName() )
);
- column.setNullable(
- col.nullable()
- ); //TODO force to not null if available? This is a (bad) user choice.
+ //although in theory, null is an acceptable value in a Map key
+ //we need force this column to be not null, as it intended to be the primary key.
+ if ( nullability != Nullability.FORCED_NULL ) {
+ column.setNullable( false );
+ }
column.setUnique( col.unique() );
column.setInsertable( col.insertable() );
column.setUpdatable( col.updatable() );
14 years
Hibernate SVN: r19290 - search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2010-04-25 06:49:36 -0400 (Sun, 25 Apr 2010)
New Revision: 19290
Modified:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/PerDPResources.java
Log:
HSEARCH-516 Lucene Directories might be closed before the backend finished all tasks on shutdown
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/PerDPResources.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/PerDPResources.java 2010-04-24 10:08:27 UTC (rev 19289)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/PerDPResources.java 2010-04-25 10:49:36 UTC (rev 19290)
@@ -30,8 +30,11 @@
import org.hibernate.search.engine.SearchFactoryImplementor;
import org.hibernate.search.exception.ErrorHandler;
import org.hibernate.search.store.DirectoryProvider;
+import org.hibernate.search.util.LoggerFactory;
+import org.slf4j.Logger;
import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
/**
* Collects all resources needed to apply changes to one index,
@@ -41,6 +44,8 @@
*/
class PerDPResources {
+ private static final Logger log = LoggerFactory.make();
+
private final ExecutorService executor;
private final LuceneWorkVisitor visitor;
private final Workspace workspace;
@@ -77,6 +82,12 @@
executor.execute( new CloseIndexRunnable( workspace ) );
}
executor.shutdown();
+ try {
+ executor.awaitTermination( Long.MAX_VALUE, TimeUnit.SECONDS );
+ }
+ catch (InterruptedException e) {
+ log.warn( "Was interrupted while waiting for index activity to finish. Index might be inconsistent or have a stale lock" );
+ }
}
public ErrorHandler getErrorHandler() {
14 years
Hibernate SVN: r19289 - in validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap: util and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: gunnar.morling
Date: 2010-04-24 06:08:27 -0400 (Sat, 24 Apr 2010)
New Revision: 19289
Added:
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/MessagerAdapter.java
Modified:
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintAnnotationVisitor.java
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintValidationProcessor.java
Log:
HV-313: moving ConstraintAnnotationVisitor#reportError() to new class MessagerAdapter, moving ConstraintAnnotationVisitor#initDiagnosticKind() to ConstraintValidationProcessor
Modified: validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintAnnotationVisitor.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintAnnotationVisitor.java 2010-04-23 17:49:40 UTC (rev 19288)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintAnnotationVisitor.java 2010-04-24 10:08:27 UTC (rev 19289)
@@ -17,10 +17,7 @@
*/
package org.hibernate.validator.ap;
-import java.text.MessageFormat;
import java.util.List;
-import java.util.ResourceBundle;
-
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
@@ -32,11 +29,11 @@
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementKindVisitor6;
-import javax.tools.Diagnostic.Kind;
import org.hibernate.validator.ap.util.AnnotationApiHelper;
import org.hibernate.validator.ap.util.ConstraintHelper;
import org.hibernate.validator.ap.util.ConstraintHelper.ConstraintCheckResult;
+import org.hibernate.validator.ap.util.MessagerAdapter;
/**
* An {@link ElementVisitor} that visits elements (type declarations, methods
@@ -47,35 +44,13 @@
*/
final class ConstraintAnnotationVisitor extends ElementKindVisitor6<Void, List<AnnotationMirror>> {
- /**
- * The name of the processor option for setting the diagnostic kind to be
- * used when reporting errors during annotation processing. Can be set on
- * the command line using the -A option, e.g.
- * <code>-AdiagnosticKind=ERROR</code>.
- */
- public final static String DIAGNOSTIC_KIND_PROCESSOR_OPTION_NAME = "diagnosticKind";
-
- /**
- * The diagnostic kind to be used if no or an invalid kind is given as processor option.
- */
- public final static Kind DEFAULT_DIAGNOSTIC_KIND = Kind.ERROR;
-
- /**
- * The kind of diagnostic to be used when reporting any problems.
- */
- private Kind diagnosticKind;
-
- private final ProcessingEnvironment processingEnvironment;
-
- private final ResourceBundle errorMessages;
-
private final ConstraintHelper constraintHelper;
- public ConstraintAnnotationVisitor(ProcessingEnvironment processingEnvironment) {
+ private final MessagerAdapter messager;
- this.processingEnvironment = processingEnvironment;
+ public ConstraintAnnotationVisitor(ProcessingEnvironment processingEnvironment, MessagerAdapter messager) {
- errorMessages = ResourceBundle.getBundle( "org.hibernate.validator.ap.ValidationProcessorMessages" );
+ this.messager = messager;
AnnotationApiHelper annotationApiHelper = new AnnotationApiHelper(
processingEnvironment.getElementUtils(), processingEnvironment.getTypeUtils()
@@ -84,35 +59,8 @@
constraintHelper = new ConstraintHelper(
processingEnvironment.getElementUtils(), processingEnvironment.getTypeUtils(), annotationApiHelper
);
-
- initializeDiagnosticKind();
}
- private void initializeDiagnosticKind() {
-
- String diagnosticKindFromOptions = processingEnvironment.getOptions()
- .get( DIAGNOSTIC_KIND_PROCESSOR_OPTION_NAME );
-
- if ( diagnosticKindFromOptions != null ) {
- try {
- diagnosticKind = Kind.valueOf( diagnosticKindFromOptions );
- }
- catch ( IllegalArgumentException e ) {
-
- processingEnvironment.getMessager().printMessage(
- Kind.ERROR, MessageFormat.format(
- errorMessages.getString( "INVALID_DIAGNOSTIC_KIND_GIVEN" ), diagnosticKindFromOptions
- )
- );
-
- diagnosticKind = DEFAULT_DIAGNOSTIC_KIND;
- }
- }
- else {
- diagnosticKind = DEFAULT_DIAGNOSTIC_KIND;
- }
- }
-
/**
* <p>
* Checks whether the given mirrors representing one or more constraint annotations are correctly
@@ -136,6 +84,7 @@
for ( AnnotationMirror oneAnnotationMirror : mirrors ) {
+
switch ( constraintHelper.getAnnotationType( oneAnnotationMirror ) ) {
case CONSTRAINT_ANNOTATION:
@@ -208,13 +157,6 @@
* declarations.
* </p>
*/
- // TODO GM: do a more complete check of constraint annotation type
- // declarations:
- //
- // - check existence of groups(), message(), payload()
- // - check retention policy
- // - check, that the set of supported types is not empty
- // - optionally check, that validated types resolve to non-parametrized types
@Override
public Void visitTypeAsAnnotationType(TypeElement annotationType,
List<AnnotationMirror> mirrors) {
@@ -289,7 +231,7 @@
mirror.getAnnotationType(), annotatedType.asType()
) != ConstraintCheckResult.ALLOWED ) {
- reportError(
+ messager.reportError(
annotatedType, mirror, "NOT_SUPPORTED_TYPE",
mirror.getAnnotationType().asElement().getSimpleName()
);
@@ -300,7 +242,7 @@
if ( isStaticElement( annotatedField ) ) {
- reportError( annotatedField, annotationMirror, "STATIC_FIELDS_MAY_NOT_BE_ANNOTATED" );
+ messager.reportError( annotatedField, annotationMirror, "STATIC_FIELDS_MAY_NOT_BE_ANNOTATED" );
return;
}
@@ -309,7 +251,7 @@
annotationMirror.getAnnotationType(), annotatedField.asType()
) != ConstraintCheckResult.ALLOWED ) {
- reportError(
+ messager.reportError(
annotatedField, annotationMirror, "NOT_SUPPORTED_TYPE",
annotationMirror.getAnnotationType().asElement().getSimpleName()
);
@@ -320,14 +262,14 @@
if ( !isGetterMethod( method ) ) {
- reportError( method, mirror, "ONLY_GETTERS_MAY_BE_ANNOTATED" );
+ messager.reportError( method, mirror, "ONLY_GETTERS_MAY_BE_ANNOTATED" );
return;
}
if ( isStaticElement( method ) ) {
- reportError( method, mirror, "STATIC_METHODS_MAY_NOT_BE_ANNOTATED" );
+ messager.reportError( method, mirror, "STATIC_METHODS_MAY_NOT_BE_ANNOTATED" );
return;
}
@@ -336,7 +278,7 @@
mirror.getAnnotationType(), method.getReturnType()
) != ConstraintCheckResult.ALLOWED ) {
- reportError(
+ messager.reportError(
method, mirror, "NOT_SUPPORTED_RETURN_TYPE",
mirror.getAnnotationType().asElement().getSimpleName()
);
@@ -346,7 +288,7 @@
private void checkConstraintAtAnnotationType(TypeElement annotationType, AnnotationMirror annotationMirror) {
if ( !constraintHelper.isConstraintAnnotation( annotationType ) ) {
- reportError( annotationType, annotationMirror, "ONLY_CONSTRAINT_ANNOTATIONS_MAY_BE_ANNOTATED" );
+ messager.reportError( annotationType, annotationMirror, "ONLY_CONSTRAINT_ANNOTATIONS_MAY_BE_ANNOTATED" );
}
}
@@ -356,7 +298,7 @@
if ( isStaticElement( annotatedField ) ) {
- reportError(
+ messager.reportError(
annotatedField, annotationMirror,
"STATIC_FIELDS_MAY_NOT_BE_ANNOTATED"
);
@@ -366,7 +308,7 @@
if ( isPrimitiveType( annotatedField.asType() ) ) {
- reportError(
+ messager.reportError(
annotatedField, annotationMirror,
"ATVALID_NOT_ALLOWED_AT_PRIMITIVE_FIELD"
);
@@ -378,7 +320,7 @@
if ( !isGetterMethod( method ) ) {
- reportError(
+ messager.reportError(
method, annotationMirror,
"ONLY_GETTERS_MAY_BE_ANNOTATED"
);
@@ -388,7 +330,7 @@
if ( isStaticElement( method ) ) {
- reportError(
+ messager.reportError(
method, annotationMirror,
"STATIC_METHODS_MAY_NOT_BE_ANNOTATED"
);
@@ -398,7 +340,7 @@
if ( isPrimitiveType( method.getReturnType() ) ) {
- reportError(
+ messager.reportError(
method, annotationMirror,
"ATVALID_NOT_ALLOWED_AT_METHOD_RETURNING_PRIMITIVE_TYPE"
);
@@ -430,30 +372,4 @@
return typeMirror.getKind().isPrimitive();
}
- /**
- * Reports an error at the given location using the given message key and
- * optionally the given message parameters.
- *
- * @param element The element at which the error shall be reported.
- * @param annotationMirror The annotation mirror at which the error shall be reported.
- * @param messageKey The message key to be used to retrieve the text.
- * @param messageParameters An optional array of message parameters to be put into the
- * message using a {@link MessageFormat}.
- */
- private void reportError(Element element, AnnotationMirror annotationMirror, String messageKey, Object... messageParameters) {
-
- String message;
-
- if ( messageParameters == null ) {
- message = errorMessages.getString( messageKey );
- }
- else {
- message = MessageFormat.format( errorMessages.getString( messageKey ), messageParameters );
- }
-
- processingEnvironment.getMessager().printMessage(
- diagnosticKind, message, element, annotationMirror
- );
- }
-
}
Modified: validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintValidationProcessor.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintValidationProcessor.java 2010-04-23 17:49:40 UTC (rev 19288)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintValidationProcessor.java 2010-04-24 10:08:27 UTC (rev 19289)
@@ -17,9 +17,11 @@
*/
package org.hibernate.validator.ap;
+import java.text.MessageFormat;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
@@ -29,15 +31,17 @@
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementVisitor;
import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic.Kind;
import org.hibernate.validator.ap.util.AnnotationApiHelper;
+import org.hibernate.validator.ap.util.MessagerAdapter;
/**
* An annotation processor for checking <a
* href="http://jcp.org/en/jsr/detail?id=303">Bean Validation</a> constraints.
* The processor supports the following options:
* <ul>
- * <li><code>diagnosticKind</code>: the severity with which any occured problems
+ * <li><code>diagnosticKind</code>: the severity with which any occurred problems
* shall be reported. Must be given in form of the string representation of a
* value from {@link javax.tools.Diagnostic.Kind}, e.g.
* "diagnosticKind=WARNING". Default is Kind.ERROR.</li>
@@ -48,19 +52,42 @@
* @author Hardy Ferentschik
* @author Gunnar Morling
*/
-// TODO GM: check @Valid annotation
-// TODO GM: add documentation for AP to HV reference guide
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
-(a)SupportedOptions(ConstraintAnnotationVisitor.DIAGNOSTIC_KIND_PROCESSOR_OPTION_NAME)
+(a)SupportedOptions(ConstraintValidationProcessor.DIAGNOSTIC_KIND_PROCESSOR_OPTION_NAME)
public class ConstraintValidationProcessor extends AbstractProcessor {
/**
+ * The name of the processor option for setting the diagnostic kind to be
+ * used when reporting errors during annotation processing. Can be set on
+ * the command line using the -A option, e.g.
+ * <code>-AdiagnosticKind=ERROR</code>.
+ */
+ public final static String DIAGNOSTIC_KIND_PROCESSOR_OPTION_NAME = "diagnosticKind";
+
+ /**
+ * The diagnostic kind to be used if no or an invalid kind is given as processor option.
+ */
+ public final static Kind DEFAULT_DIAGNOSTIC_KIND = Kind.ERROR;
+ /**
* Whether this processor claims all processed annotations exclusively or not.
*/
private static final boolean ANNOTATIONS_CLAIMED_EXCLUSIVELY = false;
+ /**
+ * The messager to be used for error reports.
+ */
+ private MessagerAdapter messager;
+
@Override
+ public synchronized void init(ProcessingEnvironment processingEnv) {
+
+ super.init( processingEnv );
+
+ messager = new MessagerAdapter( processingEnv.getMessager(), getDiagnosticKind() );
+ }
+
+ @Override
public boolean process(
final Set<? extends TypeElement> annotations,
final RoundEnvironment roundEnvironment) {
@@ -69,7 +96,9 @@
processingEnv.getElementUtils(), processingEnv.getTypeUtils()
);
- ElementVisitor<Void, List<AnnotationMirror>> visitor = new ConstraintAnnotationVisitor( processingEnv );
+ ElementVisitor<Void, List<AnnotationMirror>> visitor = new ConstraintAnnotationVisitor(
+ processingEnv, messager
+ );
for ( TypeElement oneAnnotation : annotations ) {
@@ -88,4 +117,33 @@
return ANNOTATIONS_CLAIMED_EXCLUSIVELY;
}
+ /**
+ * Retrieves the diagnostic kind to be used for error messages. If given in processor options, it
+ * will be taken from there, otherwise the default value Kind.ERROR will be returned.
+ *
+ * @return The diagnostic kind to be used for error messages.
+ */
+ private Kind getDiagnosticKind() {
+
+ String diagnosticKindFromOptions = processingEnv.getOptions()
+ .get( DIAGNOSTIC_KIND_PROCESSOR_OPTION_NAME );
+
+ if ( diagnosticKindFromOptions != null ) {
+ try {
+ return Kind.valueOf( diagnosticKindFromOptions );
+ }
+ catch ( IllegalArgumentException e ) {
+ super.processingEnv.getMessager().printMessage(
+ Kind.WARNING, MessageFormat.format(
+ "The given value {0} is no valid diagnostic kind. {1} will be used.",
+ diagnosticKindFromOptions,
+ DEFAULT_DIAGNOSTIC_KIND
+ )
+ );
+ }
+ }
+
+ return DEFAULT_DIAGNOSTIC_KIND;
+ }
+
}
Added: validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/MessagerAdapter.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/MessagerAdapter.java (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/MessagerAdapter.java 2010-04-24 10:08:27 UTC (rev 19289)
@@ -0,0 +1,88 @@
+// $Id: MessagerAdapter.java 19033 2010-03-19 21:27:15Z gunnar.morling $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validator.ap.util;
+
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+import javax.annotation.processing.Messager;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.tools.Diagnostic.Kind;
+
+/**
+ * Wrapper around {@link Messager}, which adds the ability to format error messages using {@link MessageFormat}.
+ *
+ * @author Gunnar Morling
+ */
+public class MessagerAdapter {
+
+ /**
+ * Contains the texts to be displayed.
+ */
+ private final ResourceBundle errorMessages;
+
+ private final Messager messager;
+
+ /**
+ * The kind of diagnostic to be used when reporting any problems.
+ */
+ private Kind diagnosticKind;
+
+ /**
+ * Creates a new MessagerAdapter.
+ *
+ * @param messager The underlying messager.
+ * @param diagnosticKind The kind with which messages shall be reported.
+ */
+ public MessagerAdapter(Messager messager, Kind diagnosticKind) {
+
+ this.messager = messager;
+ this.diagnosticKind = diagnosticKind;
+
+ errorMessages = ResourceBundle.getBundle( "org.hibernate.validator.ap.ValidationProcessorMessages" );
+ }
+
+ /**
+ * Reports an error at the given location using the given message key and
+ * optionally the given message parameters.
+ *
+ * @param element The element at which the error shall be reported.
+ * @param annotation The annotation mirror at which the error shall be reported.
+ * @param messageKey The message key to be used to retrieve the text.
+ * @param messageParameters An optional array of message parameters to be put into the
+ * message using a {@link MessageFormat}.
+ */
+ public void reportError(Element element, AnnotationMirror annotation, String messageKey, Object... messageParameters) {
+
+ String message = errorMessages.getString( messageKey );
+
+ if ( message != null &&
+ messageParameters != null ) {
+
+ message = MessageFormat.format( errorMessages.getString( messageKey ), messageParameters );
+ }
+ else {
+ message = messageKey;
+ }
+
+ messager.printMessage(
+ diagnosticKind, message, element, annotation
+ );
+ }
+
+}
14 years
Hibernate SVN: r19288 - in search/trunk/hibernate-search/src/main/java/org/hibernate/search: query and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2010-04-23 13:49:40 -0400 (Fri, 23 Apr 2010)
New Revision: 19288
Modified:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/TwoWayStringBridge.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java
Log:
two javadoc typos
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/TwoWayStringBridge.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/TwoWayStringBridge.java 2010-04-23 17:31:04 UTC (rev 19287)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/TwoWayStringBridge.java 2010-04-23 17:49:40 UTC (rev 19288)
@@ -33,7 +33,7 @@
* <li><code>stringToObject( objectToString( object ) ).equals(object)</code>, for non <code>null</code> object. </li>
* </ul>
*
- * As for all Bridges implementations must be threasafe.
+ * As for all Bridges implementations must be threadsafe.
*
* @author Emmanuel Bernard
*/
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java 2010-04-23 17:31:04 UTC (rev 19287)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java 2010-04-23 17:49:40 UTC (rev 19288)
@@ -391,7 +391,7 @@
* Execute the lucene search and return the matching hits.
*
* @param searcher The index searcher.
- * @param n Numer of documents to retrieve
+ * @param n Number of documents to retrieve
*
* @return An instance of <code>QueryHits</code> wrapping the Lucene query and the matching documents.
*
14 years
Hibernate SVN: r19287 - search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2010-04-23 13:31:04 -0400 (Fri, 23 Apr 2010)
New Revision: 19287
Modified:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessor.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsMasterMessageListener.java
Log:
HSEARCH-514 logging and typo improvements in JGroups backend
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessor.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessor.java 2010-04-23 17:09:47 UTC (rev 19286)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessor.java 2010-04-23 17:31:04 UTC (rev 19287)
@@ -45,7 +45,7 @@
*/
public class JGroupsBackendQueueProcessor implements Runnable {
- protected static final Logger log = LoggerFactory.make();
+ private static final Logger log = LoggerFactory.make();
private final JGroupsBackendQueueProcessorFactory factory;
private final List<LuceneWork> queue;
@@ -57,8 +57,11 @@
@SuppressWarnings("unchecked")
public void run() {
+ boolean trace = log.isTraceEnabled();
List<LuceneWork> filteredQueue = new ArrayList<LuceneWork>( queue );
- log.trace( "Preparing {} Lucene works to be sent to master node.", filteredQueue.size() );
+ if ( trace ) {
+ log.trace( "Preparing {} Lucene works to be sent to master node.", filteredQueue.size() );
+ }
for ( LuceneWork work : queue ) {
if ( work instanceof OptimizeLuceneWork ) {
@@ -66,14 +69,16 @@
filteredQueue.remove( work );
}
}
- log.trace(
+ if ( trace ) {
+ log.trace(
"Filtering: optimized Lucene works are not going to be sent to master node. There is {} Lucene works after filtering.",
filteredQueue.size()
- );
- if ( filteredQueue.size() == 0 ) {
- log.trace(
- "Nothing to send. Propagating works to a cluster has been skipped."
);
+ }
+ if ( filteredQueue.isEmpty() ) {
+ if ( trace ) {
+ log.trace( "Nothing to send. Propagating works to a cluster has been skipped." );
+ }
return;
}
@@ -83,9 +88,9 @@
try {
Message message = new Message( null, factory.getAddress(), ( Serializable ) filteredQueue );
factory.getChannel().send( message );
- log.trace(
- "Lucene works have been sent from slave {} to master node.", factory.getAddress()
- );
+ if ( trace ) {
+ log.trace( "Lucene works have been sent from slave {} to master node.", factory.getAddress() );
+ }
}
catch ( ChannelNotConnectedException e ) {
throw new SearchException(
@@ -96,6 +101,6 @@
catch ( ChannelClosedException e ) {
throw new SearchException( "Unable to send Lucene work. Attempt to send message on closed JGroups channel" );
}
-
}
+
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java 2010-04-23 17:09:47 UTC (rev 19286)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java 2010-04-23 17:31:04 UTC (rev 19287)
@@ -51,7 +51,7 @@
*/
public abstract class JGroupsBackendQueueProcessorFactory implements BackendQueueProcessorFactory {
- protected static final Logger log = LoggerFactory.make();
+ private static final Logger log = LoggerFactory.make();
public static final String JGROUPS_PREFIX = Environment.WORKER_BACKEND + ".jgroups.";
@@ -97,7 +97,7 @@
}
/**
- * Reads configuration and builds channnel with its base.
+ * Reads configuration and builds channel with its base.
* In order of preference - we first look for an external JGroups file, then a set of XML properties, and
* finally the legacy JGroups String properties.
*
@@ -142,7 +142,7 @@
if ( channel == null ) {
log.info(
- "Unable to use any JGroups configuration mechanisms provided in properties {}. Using default JGroups configuration file!",
+ "Unable to use any JGroups configuration mechanisms provided in properties {}. Using default JGroups configuration file!",
props
);
try {
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsMasterMessageListener.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsMasterMessageListener.java 2010-04-23 17:09:47 UTC (rev 19286)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsMasterMessageListener.java 2010-04-23 17:31:04 UTC (rev 19287)
@@ -66,11 +66,13 @@
}
if ( queue != null && !queue.isEmpty() ) {
- log.debug(
+ if ( log.isDebugEnabled() ) {
+ log.debug(
"There are {} Lucene docs received from slave node {} to be processed by master",
queue.size(),
message.getSrc()
- );
+ );
+ }
Runnable worker = getWorker( queue );
worker.run();
}
14 years
Hibernate SVN: r19286 - core/trunk/documentation/manual/src/main/docbook/en-US/content.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-04-23 13:09:47 -0400 (Fri, 23 Apr 2010)
New Revision: 19286
Modified:
core/trunk/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml
Log:
HHH-5152 @Entity description
Modified: core/trunk/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml
===================================================================
--- core/trunk/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml 2010-04-23 17:04:00 UTC (rev 19285)
+++ core/trunk/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml 2010-04-23 17:09:47 UTC (rev 19286)
@@ -374,11 +374,219 @@
</section>
<section id="mapping-declaration-class" revision="3">
- <title>Class</title>
+ <title>Entity</title>
- <para>You can declare a persistent class using the
- <literal>class</literal> element. For example:</para>
+ <para>An entity is a regular Java object (aka POJO) which will be
+ persisted by Hibernate.</para>
+ <para>To mark an object as an entity in annotations, use the
+ <classname>@Entity</classname> annotation.</para>
+
+ <programlisting language="JAVA" role="JAVA">@Entity
+public class Flight implements Serializable {
+ Long id;
+
+ @Id
+ public Long getId() { return id; }
+
+ public void setId(Long id) { this.id = id; }
+} </programlisting>
+
+ <para>That's pretty much it, the rest is optional. There are however any
+ options to tweak your entity mapping, let's explore them.</para>
+
+ <para><classname>@Table</classname> lets you define the table the entity
+ will be persisted into. If undefined, the table name is the unqualified
+ class name of the entity. You can also optionally define the catalog,
+ the schema as well as unique constraints on the table.</para>
+
+ <programlisting role="JAVA">@Entity
+@Table(name="TBL_FLIGHT",
+ schema="AIR_COMMAND",
+ uniqueConstraints=
+ @UniqueConstraint(
+ name="flight_number",
+ columnNames={"comp_prefix", "flight_number"} ) )
+public class Flight implements Serializable {
+ @Column(name="comp_prefix")
+ public String getCompagnyPrefix() { return companyPrefix; }
+
+ @Column(name="flight_number")
+ public String getNumber() { return number; }
+}</programlisting>
+
+ <para>The constraint name is optional (generated if left undefined). The
+ column names composing the constraint correspond to the column names as
+ defined before the Hibernate <classname>NamingStrategy</classname> is
+ applied.</para>
+
+ <para><literal>@Entity.name</literal> lets you define the shortcut name
+ of the entity you can used in JP-QL and HQL queries. It defaults to the
+ unqualified class name of the class.</para>
+
+ <para>Hibernate goes beyond the JPA specification and provide additional
+ configurations. Some of them are hosted on
+ <classname>@org.hibernate.annotations.Entity</classname>:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>mutable</literal> (defaults to true): Immutable
+ classes, <literal>mutable=false</literal>, cannot be updated or
+ deleted by the application. This allows Hibernate to make some minor
+ performance optimizations.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>dynamicInsert</literal> /
+ <literal>dynamicUpdate</literal> (defaults to false): specifies that
+ <literal>INSERT</literal> / <literal>UPDATE</literal> SQL should be
+ generated at runtime and contain only the columns whose values are
+ not null. The <literal>dynamic-update</literal> and
+ <literal>dynamic-insert</literal> settings are not inherited by
+ subclasses. Although these settings can increase performance in some
+ cases, they can actually decrease performance in others.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>selectBeforeUpdate</literal> (defaults to false):
+ specifies that Hibernate should <emphasis>never</emphasis> perform
+ an SQL <literal>UPDATE</literal> unless it is certain that an object
+ is actually modified. Only when a transient object has been
+ associated with a new session using <literal>update()</literal>,
+ will Hibernate perform an extra SQL <literal>SELECT</literal> to
+ determine if an <literal>UPDATE</literal> is actually required. Use
+ of <literal>select-before-update</literal> will usually decrease
+ performance. It is useful to prevent a database update trigger being
+ called unnecessarily if you reattach a graph of detached instances
+ to a <literal>Session</literal>.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>polymorphism</literal> (defaults to
+ <literal>IMPLICIT</literal>): determines whether implicit or
+ explicit query polymorphism is used. <emphasis>Implicit</emphasis>
+ polymorphism means that instances of the class will be returned by a
+ query that names any superclass or implemented interface or class,
+ and that instances of any subclass of the class will be returned by
+ a query that names the class itself. <emphasis>Explicit</emphasis>
+ polymorphism means that class instances will be returned only by
+ queries that explicitly name that class. Queries that name the class
+ will return only instances of subclasses mapped. For most purposes,
+ the default <literal>polymorphism=IMPLICIT</literal> is appropriate.
+ Explicit polymorphism is useful when two different classes are
+ mapped to the same table This allows a "lightweight" class that
+ contains a subset of the table columns.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>persister</literal>: specifies a custom
+ <literal>ClassPersister</literal>. The <literal>persister</literal>
+ attribute lets you customize the persistence strategy used for the
+ class. You can, for example, specify your own subclass of
+ <literal>org.hibernate.persister.EntityPersister</literal>, or you
+ can even provide a completely new implementation of the interface
+ <literal>org.hibernate.persister.ClassPersister</literal> that
+ implements, for example, persistence via stored procedure calls,
+ serialization to flat files or LDAP. See
+ <literal>org.hibernate.test.CustomPersister</literal> for a simple
+ example of "persistence" to a <literal>Hashtable</literal>.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>optimisticLock</literal> (defaults to
+ <literal>VERSION</literal>): determines the optimistic locking
+ strategy. If you enable <literal>dynamicUpdate</literal>, you will
+ have a choice of optimistic locking strategies:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>version</literal>: check the version/timestamp
+ columns</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>all</literal>: check all columns</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>dirty</literal>: check the changed columns,
+ allowing some concurrent updates</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>none</literal>: do not use optimistic
+ locking</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>It is <emphasis>strongly</emphasis> recommended that you use
+ version/timestamp columns for optimistic locking with Hibernate.
+ This strategy optimizes performance and correctly handles
+ modifications made to detached instances (i.e. when
+ <literal>Session.merge()</literal> is used).</para>
+ </listitem>
+ </itemizedlist>
+
+ <tip>
+ <para>Be sure to import
+ <classname>@javax.persistence.Entity</classname> to mark a class as an
+ entity. It's a common mistake to import
+ <classname>@org.hibernate.annotations.Entity</classname> by
+ accident.</para>
+ </tip>
+
+ <para>You can also alter how Hibernate deals with lazy initialization
+ for this class. On <classname>@Proxy</classname>, use
+ <literal>lazy</literal>=false to disable lazy fetching (not
+ recommended). You can also specify an interface to use for lazy
+ initializing proxies (defaults to the class itself): use
+ <literal>proxyClass</literal> on <classname>@Proxy</classname>.
+ Hibernate will initially return proxies (Javassist or CGLIB) that
+ implement the named interface. The persistent object will load when a
+ method of the proxy is invoked. See "Initializing collections and
+ proxies" below.</para>
+
+ <para><classname>@BatchSize</classname> specifies a "batch size" for
+ fetching instances of this class by identifier. Not yet loaded instances
+ are loaded batch-size at a time (default 1). </para>
+
+ <para>You can specific an arbitrary SQL WHERE condition to be used when
+ retrieving objects of this class. Use <classname>@Where</classname> for
+ that.</para>
+
+ <para>In the same vein, <classname>@Check</classname> lets you define an
+ SQL expression used to generate a multi-row <emphasis>check</emphasis>
+ constraint for automatic schema generation.</para>
+
+ <para>There is no difference between a view and a base table for a
+ Hibernate mapping. This is transparent at the database level, although
+ some DBMS do not support views properly, especially with updates.
+ Sometimes you want to use a view, but you cannot create one in the
+ database (i.e. with a legacy schema). In this case, you can map an
+ immutable and read-only entity to a given SQL subselect expression using
+ <classname>@org.hibernate.annotations.Subselect</classname>:</para>
+
+ <programlisting role="JAVA">@Entity
+@Subselect("select item.name, max(bid.amount), count(*) "
+ + "from item "
+ + "join bid on bid.item_id = item.id "
+ + "group by item.name")
+@Synchronize( {"item", "bid"} ) //tables impacted
+public class Summary {
+ @Id
+ public String getId() { return id; }
+ ...
+}</programlisting>
+
+ <para>Declare the tables to synchronize this entity with, ensuring that
+ auto-flush happens correctly and that queries against the derived entity
+ do not return stale data. The <literal><subselect></literal> is
+ available both as an attribute and a nested mapping element.</para>
+
+ <para>We will now explore the same options using the hbm.xml structure.
+ You can declare a persistent class using the <literal>class</literal>
+ element. For example:</para>
+
<programlistingco role="XML">
<areaspec>
<area coords="2" id="class1" />
@@ -600,92 +808,8 @@
<emphasis>static</emphasis> inner class. Specify the class name using
the standard form i.e. <literal>e.g.Foo$Bar</literal>.</para>
- <para>Immutable classes, <literal>mutable="false"</literal>, cannot be
- updated or deleted by the application. This allows Hibernate to make
- some minor performance optimizations.</para>
+ <para>Here is how to do a virtual view (subselect) in XML:</para>
- <para>The optional <literal>proxy</literal> attribute enables lazy
- initialization of persistent instances of the class. Hibernate will
- initially return CGLIB proxies that implement the named interface. The
- persistent object will load when a method of the proxy is invoked. See
- "Initializing collections and proxies" below.</para>
-
- <para><emphasis>Implicit</emphasis> polymorphism means that instances of
- the class will be returned by a query that names any superclass or
- implemented interface or class, and that instances of any subclass of
- the class will be returned by a query that names the class itself.
- <emphasis>Explicit</emphasis> polymorphism means that class instances
- will be returned only by queries that explicitly name that class.
- Queries that name the class will return only instances of subclasses
- mapped inside this <literal><class></literal> declaration as a
- <literal><subclass></literal> or
- <literal><joined-subclass></literal>. For most purposes, the
- default <literal>polymorphism="implicit"</literal> is appropriate.
- Explicit polymorphism is useful when two different classes are mapped to
- the same table This allows a "lightweight" class that contains a subset
- of the table columns.</para>
-
- <para>The <literal>persister</literal> attribute lets you customize the
- persistence strategy used for the class. You can, for example, specify
- your own subclass of
- <literal>org.hibernate.persister.EntityPersister</literal>, or you can
- even provide a completely new implementation of the interface
- <literal>org.hibernate.persister.ClassPersister</literal> that
- implements, for example, persistence via stored procedure calls,
- serialization to flat files or LDAP. See
- <literal>org.hibernate.test.CustomPersister</literal> for a simple
- example of "persistence" to a <literal>Hashtable</literal>.</para>
-
- <para>The <literal>dynamic-update</literal> and
- <literal>dynamic-insert</literal> settings are not inherited by
- subclasses, so they can also be specified on the
- <literal><subclass></literal> or
- <literal><joined-subclass></literal> elements. Although these
- settings can increase performance in some cases, they can actually
- decrease performance in others.</para>
-
- <para>Use of <literal>select-before-update</literal> will usually
- decrease performance. It is useful to prevent a database update trigger
- being called unnecessarily if you reattach a graph of detached instances
- to a <literal>Session</literal>.</para>
-
- <para>If you enable <literal>dynamic-update</literal>, you will have a
- choice of optimistic locking strategies:</para>
-
- <itemizedlist>
- <listitem>
- <para><literal>version</literal>: check the version/timestamp
- columns</para>
- </listitem>
-
- <listitem>
- <para><literal>all</literal>: check all columns</para>
- </listitem>
-
- <listitem>
- <para><literal>dirty</literal>: check the changed columns, allowing
- some concurrent updates</para>
- </listitem>
-
- <listitem>
- <para><literal>none</literal>: do not use optimistic locking</para>
- </listitem>
- </itemizedlist>
-
- <para>It is <emphasis>strongly</emphasis> recommended that you use
- version/timestamp columns for optimistic locking with Hibernate. This
- strategy optimizes performance and correctly handles modifications made
- to detached instances (i.e. when <literal>Session.merge()</literal> is
- used).</para>
-
- <para>There is no difference between a view and a base table for a
- Hibernate mapping. This is transparent at the database level, although
- some DBMS do not support views properly, especially with updates.
- Sometimes you want to use a view, but you cannot create one in the
- database (i.e. with a legacy schema). In this case, you can map an
- immutable and read-only entity to a given SQL subselect
- expression:</para>
-
<programlisting role="XML"><class name="Summary">
<subselect>
select item.name, max(bid.amount), count(*)
@@ -699,10 +823,8 @@
...
</class></programlisting>
- <para>Declare the tables to synchronize this entity with, ensuring that
- auto-flush happens correctly and that queries against the derived entity
- do not return stale data. The <literal><subselect></literal> is
- available both as an attribute and a nested mapping element.</para>
+ <para>The <literal><subselect></literal> is available both as an
+ attribute and a nested mapping element.</para>
</section>
<section id="mapping-declaration-id" revision="4">
14 years
Hibernate SVN: r19285 - core/trunk/annotations/src/main/java/org/hibernate/annotations.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-04-23 13:04:00 -0400 (Fri, 23 Apr 2010)
New Revision: 19285
Modified:
core/trunk/annotations/src/main/java/org/hibernate/annotations/Synchronize.java
Log:
Better JavaDoc
Modified: core/trunk/annotations/src/main/java/org/hibernate/annotations/Synchronize.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/annotations/Synchronize.java 2010-04-23 11:03:02 UTC (rev 19284)
+++ core/trunk/annotations/src/main/java/org/hibernate/annotations/Synchronize.java 2010-04-23 17:04:00 UTC (rev 19285)
@@ -17,5 +17,8 @@
@Target(TYPE)
@Retention(RUNTIME)
public @interface Synchronize {
+ /**
+ * Table names
+ */
String [] value();
}
14 years
Hibernate SVN: r19284 - in validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator: xml and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2010-04-23 07:03:02 -0400 (Fri, 23 Apr 2010)
New Revision: 19284
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/ValidationXmlParser.java
Log:
HV-312 Made sure that streams opened by the framework gets closed as well
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java 2010-04-22 17:20:04 UTC (rev 19283)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java 2010-04-23 11:03:02 UTC (rev 19284)
@@ -17,7 +17,9 @@
*/
package org.hibernate.validator.engine;
+import java.io.IOException;
import java.io.InputStream;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -68,6 +70,8 @@
private ValidationBootstrapParameters validationBootstrapParameters;
private boolean ignoreXmlConfiguration = false;
+ private Set<InputStream> configurationStreams = new HashSet<InputStream>();
+
public ConfigurationImpl(BootstrapState state) {
if ( state.getValidationProviderResolver() == null ) {
this.providerResolver = state.getDefaultValidationProviderResolver();
@@ -122,26 +126,39 @@
public ValidatorFactory buildValidatorFactory() {
parseValidationXml();
ValidatorFactory factory = null;
- if ( isSpecificProvider() ) {
- factory = validationBootstrapParameters.provider.buildValidatorFactory( this );
- }
- else {
- final Class<? extends ValidationProvider<?>> providerClass = validationBootstrapParameters.providerClass;
- if ( providerClass != null ) {
- for ( ValidationProvider provider : providerResolver.getValidationProviders() ) {
- if ( providerClass.isAssignableFrom( provider.getClass() ) ) {
- factory = provider.buildValidatorFactory( this );
- break;
+ try {
+ if ( isSpecificProvider() ) {
+ factory = validationBootstrapParameters.provider.buildValidatorFactory( this );
+ }
+ else {
+ final Class<? extends ValidationProvider<?>> providerClass = validationBootstrapParameters.providerClass;
+ if ( providerClass != null ) {
+ for ( ValidationProvider provider : providerResolver.getValidationProviders() ) {
+ if ( providerClass.isAssignableFrom( provider.getClass() ) ) {
+ factory = provider.buildValidatorFactory( this );
+ break;
+ }
}
+ if ( factory == null ) {
+ throw new ValidationException( "Unable to find provider: " + providerClass );
+ }
}
- if ( factory == null ) {
- throw new ValidationException( "Unable to find provider: " + providerClass );
+ else {
+ List<ValidationProvider<?>> providers = providerResolver.getValidationProviders();
+ assert providers.size() != 0; // I run therefore I am
+ factory = providers.get( 0 ).buildValidatorFactory( this );
}
}
- else {
- List<ValidationProvider<?>> providers = providerResolver.getValidationProviders();
- assert providers.size() != 0; // I run therefore I am
- factory = providers.get( 0 ).buildValidatorFactory( this );
+ }
+ finally {
+ // close all input streams opened by this configuration
+ for ( InputStream in : configurationStreams ) {
+ try {
+ in.close();
+ }
+ catch ( IOException io ) {
+ log.warn( "Unable to close input stream." );
+ }
}
}
@@ -248,6 +265,7 @@
}
validationBootstrapParameters.mappings.addAll( xmlParameters.mappings );
+ configurationStreams.addAll( xmlParameters.mappings );
for ( Map.Entry<String, String> entry : xmlParameters.configProperties.entrySet() ) {
if ( validationBootstrapParameters.configProperties.get( entry.getKey() ) == null ) {
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/ValidationXmlParser.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/ValidationXmlParser.java 2010-04-22 17:20:04 UTC (rev 19283)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/ValidationXmlParser.java 2010-04-23 11:03:02 UTC (rev 19284)
@@ -17,6 +17,7 @@
*/
package org.hibernate.validator.xml;
+import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.AccessController;
@@ -235,6 +236,13 @@
log.error( "Error parsing validation.xml: {}", e.getMessage() );
throw new ValidationException( "Unable to parse " + VALIDATION_XML_FILE );
}
+ finally {
+ try {
+ inputStream.close();
+ } catch ( IOException io) {
+ log.warn( "Unable to close input stream for " + VALIDATION_XML_FILE);
+ }
+ }
return validationConfig;
}
14 years
Hibernate SVN: r19283 - core/trunk/documentation/manual/src/main/docbook/en-US/content.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-04-22 13:20:04 -0400 (Thu, 22 Apr 2010)
New Revision: 19283
Modified:
core/trunk/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml
Log:
HHH-5149 start injecting annotations in mapping section
Modified: core/trunk/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml
===================================================================
--- core/trunk/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml 2010-04-22 09:56:24 UTC (rev 19282)
+++ core/trunk/documentation/manual/src/main/docbook/en-US/content/basic_mapping.xml 2010-04-22 17:20:04 UTC (rev 19283)
@@ -1,4 +1,4 @@
-<?xml version='1.0' encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
@@ -22,190 +22,287 @@
~ 51 Franklin Street, Fifth Floor
~ Boston, MA 02110-1301 USA
-->
-
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "../HIBERNATE_-_Relational_Persistence_for_Idiomatic_Java.ent">
%BOOK_ENTITIES;
-
]>
-
<chapter id="mapping">
- <title>Basic O/R Mapping</title>
+ <title>Basic O/R Mapping</title>
- <section id="mapping-declaration" revision="2">
- <title>Mapping declaration</title>
+ <section id="mapping-declaration" revision="2">
+ <title>Mapping declaration</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 and not table declarations.
- </para>
+ <para>Object/relational mappings can be defined in three
+ approaches:</para>
- <para>
- Please note that even though many Hibernate users choose to write the XML by hand,
- a number of tools exist to generate the mapping document. These include XDoclet,
- Middlegen and AndroMDA.
- </para>
+ <itemizedlist>
+ <listitem>
+ <para>using Java 5 annotations (via the Java Persistence 2
+ annotations)</para>
+ </listitem>
- <para>
- Here is an example mapping:
- </para>
+ <listitem>
+ <para>using JPA 2 XML deployment descriptors (described in chapter
+ XXX)</para>
+ </listitem>
+ <listitem>
+ <para>using the Hibernate legacy XML files approach known as
+ hbm.xml</para>
+ </listitem>
+ </itemizedlist>
- <programlisting role="XML"><![CDATA[<?xml version="1.0"?>
-<!DOCTYPE hibernate-mapping PUBLIC
+ <para>Annotations are split in two categories, the logical mapping
+ annotations (describing the object model, the association between two
+ entities etc.) and the physical mapping annotations (describing the
+ physical schema, tables, columns, indexes, etc). We will mix annotations
+ from both categories in the following code examples.</para>
+
+ <para>JPA annotations are in the <literal>javax.persistence.*</literal>
+ package. Hibernate specific extensions are in
+ <literal>org.hibernate.annotations.*</literal>. You favorite IDE can
+ auto-complete annotations and their attributes for you (even without a
+ specific "JPA" plugin, since JPA annotations are plain Java 5
+ annotations).</para>
+
+ <para>Here is an example of mapping</para>
+
+ <programlisting role="JAVA">package eg;
+
+@Entity
+@Table(name="cats") @Inheritance(strategy=SINGLE_TABLE)
+@DiscriminatorValue("C") @DiscriminatorColumn(name="subclass", discriminatorType=CHAR)
+public class Cat {
+
+ @Id @GeneratedValue
+ public Integer getId() { return id; }
+ public void setId(Integer id) { this.id = id; }
+ private Integer id;
+
+ public BigDecimal getWeight() { return weight; }
+ public void setWeight(BigDecimal weight) { this.weight = weight; }
+ private BigDecimal weight;
+
+ @Temporal(DATE) @NotNull @Column(updatable=false)
+ public Date getBirthdate() { return birthdate; }
+ public void setBirthdate(Date birthdate) { this.birthdate = birthdate; }
+ private Date birthdate;
+
+ @org.hibernate.annotations.Type(type="eg.types.ColorUserType")
+ @NotNull @Column(updatable=false)
+ public ColorType getColor() { return color; }
+ public void setColor(ColorType color) { this.color = color; }
+ private ColorType color;
+
+ @NotNull @Column(updatable=false)
+ public String getSex() { return sex; }
+ public void setSex(String sex) { this.sex = sex; }
+ private String sex;
+
+ @NotNull @Column(updatable=false)
+ public Integer getLitterId() { return litterId; }
+ public void setLitterId(Integer litterId) { this.litterId = litterId; }
+ private Integer litterId;
+
+ @ManyToOne @JoinColumn(name="mother_id", updatable=false)
+ public Cat getMother() { return mother; }
+ public void setMother(Cat mother) { this.mother = mother; }
+ private Cat mother;
+
+ @OneToMany(mappedBy="mother") @OrderBy("litterId")
+ public Set<Cat> getKittens() { return kittens; }
+ public void setKittens(Set<Cat> kittens) { this.kittens = kittens; }
+ private Set<Cat> kittens = new HashSet<Cat>();
+}
+
+@Entity @DiscriminatorValue("D")
+public class DomesticCat extends Cat {
+
+ public String getName() { return name; }
+ public void setName(String name) { this.name = name }
+ private String name;
+}
+
+@Entity
+public class Dog { ... }</programlisting>
+
+ <para>The legacy hbm.xml approach uses an XML schema designed to be
+ readable and hand-editable. The mapping language is Java-centric, meaning
+ that mappings are constructed around persistent class declarations and not
+ table declarations.</para>
+
+ <para>Please note that even though many Hibernate users choose to write
+ the XML by hand, a number of tools exist to generate the mapping document.
+ These include XDoclet, Middlegen and AndroMDA.</para>
+
+ <para>Here is an example mapping:</para>
+
+ <programlisting role="XML"><?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
-<hibernate-mapping package="eg">
+<hibernate-mapping package="eg">
- <class name="Cat"
+ <class name="Cat"
table="cats"
- discriminator-value="C">
+ discriminator-value="C">
- <id name="id">
- <generator class="native"/>
- </id>
+ <id name="id">
+ <generator class="native"/>
+ </id>
- <discriminator column="subclass"
- type="character"/>
+ <discriminator column="subclass"
+ type="character"/>
- <property name="weight"/>
+ <property name="weight"/>
- <property name="birthdate"
+ <property name="birthdate"
type="date"
not-null="true"
- update="false"/>
+ update="false"/>
- <property name="color"
+ <property name="color"
type="eg.types.ColorUserType"
not-null="true"
- update="false"/>
+ update="false"/>
- <property name="sex"
+ <property name="sex"
not-null="true"
- update="false"/>
+ update="false"/>
- <property name="litterId"
+ <property name="litterId"
column="litterId"
- update="false"/>
+ update="false"/>
- <many-to-one name="mother"
+ <many-to-one name="mother"
column="mother_id"
- update="false"/>
+ update="false"/>
- <set name="kittens"
+ <set name="kittens"
inverse="true"
- order-by="litter_id">
- <key column="mother_id"/>
- <one-to-many class="Cat"/>
- </set>
+ order-by="litter_id">
+ <key column="mother_id"/>
+ <one-to-many class="Cat"/>
+ </set>
- <subclass name="DomesticCat"
- discriminator-value="D">
+ <subclass name="DomesticCat"
+ discriminator-value="D">
- <property name="name"
- type="string"/>
+ <property name="name"
+ type="string"/>
- </subclass>
+ </subclass>
- </class>
+ </class>
- <class name="Dog">
- <!-- mapping for Dog could go here -->
- </class>
+ <class name="Dog">
+ <!-- mapping for Dog could go here -->
+ </class>
-</hibernate-mapping>]]></programlisting>
+</hibernate-mapping></programlisting>
- <para>
- We will now discuss the content of the mapping document. We will only describe, however, the
- document elements and attributes that are used by Hibernate at runtime. The mapping
- document also contains some extra optional attributes and elements that affect the
- database schemas exported by the schema export tool (for example, the <literal>
- not-null</literal> attribute).
- </para>
+ <para>We will now discuss the concepts of the mapping documents (both
+ annotations and XML). We will only describe, however, the document
+ elements and attributes that are used by Hibernate at runtime. The mapping
+ document also contains some extra optional attributes and elements that
+ affect the database schemas exported by the schema export tool (for
+ example, the <literal> not-null</literal> attribute).</para>
+ <section>
+ <title>Some hbm.xml specificities</title>
+ <para>The hbm.xml structure has some specificities naturally not present
+ when using annotations, let's describe them briefly.</para>
- <section id="mapping-declaration-doctype" revision="3">
- <title>Doctype</title>
+ <section id="mapping-declaration-doctype" revision="3">
+ <title>Doctype</title>
- <para>
- All XML mappings should declare the doctype shown. The actual DTD can be found
- at the URL above, in the directory <literal>hibernate-x.x.x/src/org/hibernate
- </literal>, or in <literal>hibernate3.jar</literal>. Hibernate will always look for
- the DTD in its classpath first. If you experience lookups of the DTD using an
- Internet connection, check the DTD declaration against the contents of your
- classpath.
- </para>
+ <para>All XML mappings should declare the doctype shown. The actual
+ DTD can be found at the URL above, in the directory
+ <literal>hibernate-x.x.x/src/org/hibernate </literal>, or in
+ <literal>hibernate3.jar</literal>. Hibernate will always look for the
+ DTD in its classpath first. If you experience lookups of the DTD using
+ an Internet connection, check the DTD declaration against the contents
+ of your classpath.</para>
- <section id="mapping-declaration-entity-resolution">
- <title>EntityResolver</title>
- <para>
- Hibernate will first attempt to resolve DTDs in its classpath.
- 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 encounters a systemId starting with
- <literal>http://hibernate.sourceforge.net/</literal>. The resolver
- attempts to resolve these entities via the classloader which loaded
- the Hibernate classes.
- </para>
- </listitem>
- <listitem>
- <para>
- a <literal>user namespace</literal> is recognized whenever the
- resolver encounters 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>
- The following is an example of utilizing user namespacing:
- </para>
- <programlisting language="XML" role="XML">
-<xi:include parse="text" href="../extras/namespacing.xml_sample" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <section id="mapping-declaration-entity-resolution">
+ <title>EntityResolver</title>
+
+ <para>Hibernate will first attempt to resolve DTDs in its classpath.
+ 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 encounters a systemId starting with
+ <literal>http://hibernate.sourceforge.net/</literal>. The
+ resolver attempts to resolve these entities via the classloader
+ which loaded the Hibernate classes.</para>
+ </listitem>
+
+ <listitem>
+ <para>a <literal>user namespace</literal> is recognized whenever
+ the resolver encounters 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>The following is an example of utilizing user
+ namespacing:</para>
+
+ <programlisting language="XML" role="XML">
+<xi:include href="../extras/namespacing.xml_sample" parse="text"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
</programlisting>
- <para>
- Where <literal>types.xml</literal> is a resource in the <literal>your.domain</literal>
- package and contains a custom <link linkend="mapping-types-custom">typedef</link>.
- </para>
- </section>
+
+ <para>Where <literal>types.xml</literal> is a resource in the
+ <literal>your.domain</literal> package and contains a custom <link
+ linkend="mapping-types-custom">typedef</link>.</para>
</section>
+ </section>
- <section id="mapping-declaration-mapping" revision="3">
- <title>Hibernate-mapping</title>
+ <section id="mapping-declaration-mapping" revision="3">
+ <title>Hibernate-mapping</title>
- <para>
- This element has several optional attributes. The <literal>schema</literal> and
- <literal>catalog</literal> attributes specify that tables referred to in this mapping
- belong to the named schema and/or catalog. If they are specified, tablenames will be qualified
- by the given schema and catalog names. If they are missing, tablenames will be unqualified.
- The <literal>default-cascade</literal> attribute specifies what cascade style
- should be assumed for properties and collections that do not specify a
- <literal>cascade</literal> attribute. By default, the <literal>auto-import</literal> attribute allows you
- to use unqualified class names in the query language.
- </para>
+ <para>This element has several optional attributes. The
+ <literal>schema</literal> and <literal>catalog</literal> attributes
+ specify that tables referred to in this mapping belong to the named
+ schema and/or catalog. If they are specified, tablenames will be
+ qualified by the given schema and catalog names. If they are missing,
+ tablenames will be unqualified. The <literal>default-cascade</literal>
+ attribute specifies what cascade style should be assumed for
+ properties and collections that do not specify a
+ <literal>cascade</literal> attribute. By default, the
+ <literal>auto-import</literal> attribute allows you to use unqualified
+ class names in the query language.</para>
- <programlistingco role="XML">
- <areaspec>
- <area id="hm1" coords="2"/>
- <area id="hm2" coords="3"/>
- <area id="hm3" coords="4"/>
- <area id="hm4" coords="5"/>
- <area id="hm5" coords="6"/>
- <area id="hm6" coords="7"/>
- <area id="hm7" coords="8"/>
- </areaspec>
- <programlisting><![CDATA[<hibernate-mapping
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="hm1" />
+
+ <area coords="3" id="hm2" />
+
+ <area coords="4" id="hm3" />
+
+ <area coords="5" id="hm4" />
+
+ <area coords="6" id="hm5" />
+
+ <area coords="7" id="hm6" />
+
+ <area coords="8" id="hm7" />
+ </areaspec>
+
+ <programlisting><hibernate-mapping
schema="schemaName"
catalog="catalogName"
default-cascade="cascade_style"
@@ -213,104 +310,121 @@
default-lazy="true|false"
auto-import="true|false"
package="package.name"
- />]]></programlisting>
- <calloutlist>
- <callout arearefs="hm1">
- <para>
- <literal>schema</literal> (optional): the name of a database schema.
- </para>
- </callout>
- <callout arearefs="hm2">
- <para>
- <literal>catalog</literal> (optional): the name of a database catalog.
- </para>
- </callout>
- <callout arearefs="hm3">
- <para>
- <literal>default-cascade</literal> (optional - defaults to <literal>none</literal>):
- a default cascade style.
- </para>
- </callout>
- <callout arearefs="hm4">
- <para>
- <literal>default-access</literal> (optional - defaults to <literal>property</literal>):
- the strategy Hibernate should use for accessing all properties. It can be a custom
- implementation of <literal>PropertyAccessor</literal>.
- </para>
- </callout>
- <callout arearefs="hm5">
- <para>
- <literal>default-lazy</literal> (optional - defaults to <literal>true</literal>):
- the default value for unspecified <literal>lazy</literal> attributes of class and
- collection mappings.
- </para>
- </callout>
- <callout arearefs="hm6">
- <para>
- <literal>auto-import</literal> (optional - defaults to <literal>true</literal>):
- specifies whether we can use unqualified class names of classes in this mapping
- in the query language.
- </para>
- </callout>
- <callout arearefs="hm7">
- <para>
- <literal>package</literal> (optional): specifies a package prefix to use for
- unqualified class names in the mapping document.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+ /></programlisting>
- <para>
- If you have two persistent classes with the same unqualified name, you should set
- <literal>auto-import="false"</literal>. An exception will result if you attempt
- to assign two classes to the same "imported" name.
- </para>
+ <calloutlist>
+ <callout arearefs="hm1">
+ <para><literal>schema</literal> (optional): the name of a
+ database schema.</para>
+ </callout>
- <para>
- The <literal>hibernate-mapping</literal> element allows you to nest
- several persistent <literal><class></literal> mappings, as shown above.
- It is, however, good practice (and expected by some tools) to map only a single
- persistent class, or a single class hierarchy, in one mapping file and name
- it after the persistent superclass. For example, <literal>Cat.hbm.xml</literal>,
- <literal>Dog.hbm.xml</literal>, or if using inheritance,
- <literal>Animal.hbm.xml</literal>.
- </para>
+ <callout arearefs="hm2">
+ <para><literal>catalog</literal> (optional): the name of a
+ database catalog.</para>
+ </callout>
- </section>
+ <callout arearefs="hm3">
+ <para><literal>default-cascade</literal> (optional - defaults to
+ <literal>none</literal>): a default cascade style.</para>
+ </callout>
- <section id="mapping-declaration-class" revision="3">
- <title>Class</title>
+ <callout arearefs="hm4">
+ <para><literal>default-access</literal> (optional - defaults to
+ <literal>property</literal>): the strategy Hibernate should use
+ for accessing all properties. It can be a custom implementation
+ of <literal>PropertyAccessor</literal>.</para>
+ </callout>
- <para>
- You can declare a persistent class using the <literal>class</literal> element. For example:
- </para>
+ <callout arearefs="hm5">
+ <para><literal>default-lazy</literal> (optional - defaults to
+ <literal>true</literal>): the default value for unspecified
+ <literal>lazy</literal> attributes of class and collection
+ mappings.</para>
+ </callout>
- <programlistingco role="XML">
- <areaspec>
- <area id="class1" coords="2"/>
- <area id="class2" coords="3" />
- <area id="class3" coords="4"/>
- <area id="class4" coords="5" />
- <area id="class5" coords="6"/>
- <area id="class6" coords="7" />
- <area id="class7" coords="8"/>
- <area id="class8" coords="9" />
- <area id="class9" coords="10" />
- <area id="class10" coords="11"/>
- <area id="class11" coords="12"/>
- <area id="class12" coords="13"/>
- <area id="class13" coords="14"/>
- <area id="class14" coords="15"/>
- <area id="class15" coords="16"/>
- <area id="class16" coords="17"/>
- <area id="class17" coords="18"/>
- <area id="class18" coords="19"/>
- <area id="class19" coords="20"/>
- <area id="class20" coords="21"/>
- <area id="class21" coords="22"/>
- </areaspec>
- <programlisting><![CDATA[<class
+ <callout arearefs="hm6">
+ <para><literal>auto-import</literal> (optional - defaults to
+ <literal>true</literal>): specifies whether we can use
+ unqualified class names of classes in this mapping in the query
+ language.</para>
+ </callout>
+
+ <callout arearefs="hm7">
+ <para><literal>package</literal> (optional): specifies a package
+ prefix to use for unqualified class names in the mapping
+ document.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>If you have two persistent classes with the same unqualified
+ name, you should set <literal>auto-import="false"</literal>. An
+ exception will result if you attempt to assign two classes to the same
+ "imported" name.</para>
+
+ <para>The <literal>hibernate-mapping</literal> element allows you to
+ nest several persistent <literal><class></literal> mappings, as
+ shown above. It is, however, good practice (and expected by some
+ tools) to map only a single persistent class, or a single class
+ hierarchy, in one mapping file and name it after the persistent
+ superclass. For example, <literal>Cat.hbm.xml</literal>,
+ <literal>Dog.hbm.xml</literal>, or if using inheritance,
+ <literal>Animal.hbm.xml</literal>.</para>
+ </section>
+ </section>
+
+ <section id="mapping-declaration-class" revision="3">
+ <title>Class</title>
+
+ <para>You can declare a persistent class using the
+ <literal>class</literal> element. For example:</para>
+
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="class1" />
+
+ <area coords="3" id="class2" />
+
+ <area coords="4" id="class3" />
+
+ <area coords="5" id="class4" />
+
+ <area coords="6" id="class5" />
+
+ <area coords="7" id="class6" />
+
+ <area coords="8" id="class7" />
+
+ <area coords="9" id="class8" />
+
+ <area coords="10" id="class9" />
+
+ <area coords="11" id="class10" />
+
+ <area coords="12" id="class11" />
+
+ <area coords="13" id="class12" />
+
+ <area coords="14" id="class13" />
+
+ <area coords="15" id="class14" />
+
+ <area coords="16" id="class15" />
+
+ <area coords="17" id="class16" />
+
+ <area coords="18" id="class17" />
+
+ <area coords="19" id="class18" />
+
+ <area coords="20" id="class19" />
+
+ <area coords="21" id="class20" />
+
+ <area coords="22" id="class21" />
+ </areaspec>
+
+ <programlisting><class
name="ClassName"
table="tableName"
discriminator-value="discriminator_value"
@@ -333,1000 +447,1003 @@
subselect="SQL expression"
abstract="true|false"
node="element-name"
-/>]]></programlisting>
- <calloutlist>
- <callout arearefs="class1">
- <para>
- <literal>name</literal> (optional): the fully qualified Java class name of the
- persistent class or interface. If this attribute is missing, it is assumed
- that the mapping is for a non-POJO entity.
- </para>
- </callout>
- <callout arearefs="class2">
- <para>
- <literal>table</literal> (optional - defaults to the unqualified class name): the
- name of its database table.
- </para>
- </callout>
- <callout arearefs="class3">
- <para>
- <literal>discriminator-value</literal> (optional - defaults to the class name): a value
- that distinguishes individual subclasses that is used for polymorphic behavior. Acceptable
- values include <literal>null</literal> and <literal>not null</literal>.
- </para>
- </callout>
- <callout arearefs="class4">
- <para>
- <literal>mutable</literal> (optional - defaults to <literal>true</literal>): specifies
- that instances of the class are (not) mutable.
- </para>
- </callout>
- <callout arearefs="class5">
- <para>
- <literal>schema</literal> (optional): overrides the schema name specified by
- the root <literal><hibernate-mapping></literal> element.
- </para>
- </callout>
- <callout arearefs="class6">
- <para>
- <literal>catalog</literal> (optional): overrides the catalog name specified by
- the root <literal><hibernate-mapping></literal> element.
- </para>
- </callout>
- <callout arearefs="class7">
- <para>
- <literal>proxy</literal> (optional): specifies an interface to use for lazy
- initializing proxies. You can specify the name of the class itself.
- </para>
- </callout>
- <callout arearefs="class8">
- <para>
- <literal>dynamic-update</literal> (optional - defaults to <literal>false</literal>):
- specifies that <literal>UPDATE</literal> SQL should be generated at runtime and
- can contain only those columns whose values have changed.
- </para>
- </callout>
- <callout arearefs="class9">
- <para>
- <literal>dynamic-insert</literal> (optional - defaults to <literal>false</literal>):
- specifies that <literal>INSERT</literal> SQL should be generated at runtime and
- contain only the columns whose values are not null.
- </para>
- </callout>
- <callout arearefs="class10">
- <para>
- <literal>select-before-update</literal> (optional - defaults to <literal>false</literal>):
- specifies that Hibernate should <emphasis>never</emphasis> perform an SQL <literal>UPDATE</literal>
- unless it is certain that an object is actually modified. Only
- when a transient object has been associated with a new session using <literal>update()</literal>,
- will Hibernate perform an extra SQL <literal>SELECT</literal> to determine
- if an <literal>UPDATE</literal> is actually required.
- </para>
- </callout>
- <callout arearefs="class11">
- <para>
- <literal>polymorphism</literal> (optional - defaults to <literal>implicit</literal>):
- determines whether implicit or explicit query polymorphism is used.
- </para>
- </callout>
- <callout arearefs="class12">
- <para>
- <literal>where</literal> (optional): specifies an arbitrary SQL <literal>WHERE</literal>
- condition to be used when retrieving objects of this class.
- </para>
- </callout>
- <callout arearefs="class13">
- <para>
- <literal>persister</literal> (optional): specifies a custom <literal>ClassPersister</literal>.
- </para>
- </callout>
- <callout arearefs="class14">
- <para>
- <literal>batch-size</literal> (optional - defaults to <literal>1</literal>): specifies a "batch size"
- for fetching instances of this class by identifier.
- </para>
- </callout>
- <callout arearefs="class15">
- <para>
- <literal>optimistic-lock</literal> (optional - defaults to <literal>version</literal>):
- determines the optimistic locking strategy.
- </para>
- </callout>
- <callout arearefs="class16">
- <para>
- <literal>lazy</literal> (optional): lazy fetching can be disabled by setting
- <literal>lazy="false"</literal>.
- </para>
- </callout>
- <callout arearefs="class17">
- <para>
- <literal>entity-name</literal> (optional - defaults to the class name): Hibernate3
- allows a class to be mapped multiple times, potentially to different tables.
- It also allows entity mappings that are represented by Maps or XML at the Java level.
- In these cases, you should provide an explicit arbitrary name for the entity. See
- <xref linkend="persistent-classes-dynamicmodels"/> and <xref linkend="xml"/>
- for more information.
- </para>
- </callout>
- <callout arearefs="class18">
- <para>
- <literal>check</literal> (optional): an SQL expression used to generate a multi-row
- <emphasis>check</emphasis> constraint for automatic schema generation.
- </para>
- </callout>
- <callout arearefs="class19">
- <para>
- <literal>rowid</literal> (optional): Hibernate can use ROWIDs on databases. On Oracle, for example, Hibernate can use the <literal>rowid</literal> extra
- column for fast updates once this option has been set to <literal>rowid</literal>. A ROWID
- is an implementation detail and represents the physical location of a stored tuple.
- </para>
- </callout>
- <callout arearefs="class20">
- <para>
- <literal>subselect</literal> (optional): maps an immutable and read-only entity
- to a database subselect. This is useful if you want to have a view instead of a base table.
- See below for more information.
- </para>
- </callout>
- <callout arearefs="class21">
- <para>
- <literal>abstract</literal> (optional): is used to mark abstract superclasses in
- <literal><union-subclass></literal> hierarchies.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+/></programlisting>
- <para>
- It is acceptable for the named persistent class to be an interface. You can
- declare implementing classes of that interface using the <literal><subclass></literal>
- element. You can persist any <emphasis>static</emphasis> inner class. Specify the
- class name using the standard form i.e. <literal>e.g.Foo$Bar</literal>.
- </para>
+ <calloutlist>
+ <callout arearefs="class1">
+ <para><literal>name</literal> (optional): the fully qualified Java
+ class name of the persistent class or interface. If this attribute
+ is missing, it is assumed that the mapping is for a non-POJO
+ entity.</para>
+ </callout>
- <para>
- Immutable classes, <literal>mutable="false"</literal>, cannot be updated or deleted by the
- application. This allows Hibernate to make some minor performance optimizations.
- </para>
+ <callout arearefs="class2">
+ <para><literal>table</literal> (optional - defaults to the
+ unqualified class name): the name of its database table.</para>
+ </callout>
- <para>
- The optional <literal>proxy</literal> attribute enables lazy initialization of persistent
- instances of the class. Hibernate will initially return CGLIB proxies that implement
- the named interface. The persistent object will load when a method of the
- proxy is invoked. See "Initializing collections and proxies" below.
- </para>
+ <callout arearefs="class3">
+ <para><literal>discriminator-value</literal> (optional - defaults
+ to the class name): a value that distinguishes individual
+ subclasses that is used for polymorphic behavior. Acceptable
+ values include <literal>null</literal> and <literal>not
+ null</literal>.</para>
+ </callout>
- <para><emphasis>Implicit</emphasis> polymorphism means that instances of the class will be returned
- by a query that names any superclass or implemented interface or class, and that instances
- of any subclass of the class will be returned by a query that names the class itself.
- <emphasis>Explicit</emphasis> polymorphism means that class instances will be returned only
- by queries that explicitly name that class. Queries that name the class will return
- only instances of subclasses mapped inside this <literal><class></literal> declaration
- as a <literal><subclass></literal> or <literal><joined-subclass></literal>. For
- most purposes, the default <literal>polymorphism="implicit"</literal> is appropriate.
- Explicit polymorphism is useful when two different classes are mapped to the same table
- This allows a "lightweight" class that contains a subset of the table columns.
- </para>
+ <callout arearefs="class4">
+ <para><literal>mutable</literal> (optional - defaults to
+ <literal>true</literal>): specifies that instances of the class
+ are (not) mutable.</para>
+ </callout>
- <para>
- The <literal>persister</literal> attribute lets you customize the persistence strategy used for
- the class. You can, for example, specify your own subclass of
- <literal>org.hibernate.persister.EntityPersister</literal>, or you can even provide a
- completely new implementation of the interface
- <literal>org.hibernate.persister.ClassPersister</literal> that implements, for example, persistence via
- stored procedure calls, serialization to flat files or LDAP. See
- <literal>org.hibernate.test.CustomPersister</literal> for a simple example of "persistence"
- to a <literal>Hashtable</literal>.
- </para>
+ <callout arearefs="class5">
+ <para><literal>schema</literal> (optional): overrides the schema
+ name specified by the root
+ <literal><hibernate-mapping></literal> element.</para>
+ </callout>
- <para>
- The <literal>dynamic-update</literal> and <literal>dynamic-insert</literal>
- settings are not inherited by subclasses, so they can also be specified on the
- <literal><subclass></literal> or <literal><joined-subclass></literal> elements.
- Although these settings can increase performance in some cases, they can actually decrease
- performance in others.
- </para>
+ <callout arearefs="class6">
+ <para><literal>catalog</literal> (optional): overrides the catalog
+ name specified by the root
+ <literal><hibernate-mapping></literal> element.</para>
+ </callout>
- <para>
- Use of <literal>select-before-update</literal> will usually decrease performance. It is
- useful to prevent a database update trigger being called unnecessarily if you reattach a
- graph of detached instances to a <literal>Session</literal>.
- </para>
+ <callout arearefs="class7">
+ <para><literal>proxy</literal> (optional): specifies an interface
+ to use for lazy initializing proxies. You can specify the name of
+ the class itself.</para>
+ </callout>
- <para>
- If you enable <literal>dynamic-update</literal>, you will have a choice of optimistic
- locking strategies:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <literal>version</literal>: check the version/timestamp columns
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>all</literal>: check all columns
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>dirty</literal>: check the changed columns, allowing some concurrent updates
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>none</literal>: do not use optimistic locking
- </para>
- </listitem>
- </itemizedlist>
- <para>
- It is <emphasis>strongly</emphasis> recommended that you use version/timestamp
- columns for optimistic locking with Hibernate.
- This strategy optimizes performance and correctly handles modifications
- made to detached instances (i.e. when <literal>Session.merge()</literal> is used).
- </para>
+ <callout arearefs="class8">
+ <para><literal>dynamic-update</literal> (optional - defaults to
+ <literal>false</literal>): specifies that
+ <literal>UPDATE</literal> SQL should be generated at runtime and
+ can contain only those columns whose values have changed.</para>
+ </callout>
- <para>
- There is no difference between a view and a base table for a Hibernate mapping.
- This is transparent at the database level, although some DBMS do not support
- views properly, especially with updates. Sometimes you want to use a view, but you cannot
- create one in the database (i.e. with a legacy schema). In this case, you can map an
- immutable and read-only entity to a given SQL subselect expression:
- </para>
+ <callout arearefs="class9">
+ <para><literal>dynamic-insert</literal> (optional - defaults to
+ <literal>false</literal>): specifies that
+ <literal>INSERT</literal> SQL should be generated at runtime and
+ contain only the columns whose values are not null.</para>
+ </callout>
- <programlisting role="XML"><![CDATA[<class name="Summary">
- <subselect>
+ <callout arearefs="class10">
+ <para><literal>select-before-update</literal> (optional - defaults
+ to <literal>false</literal>): specifies that Hibernate should
+ <emphasis>never</emphasis> perform an SQL
+ <literal>UPDATE</literal> unless it is certain that an object is
+ actually modified. Only when a transient object has been
+ associated with a new session using <literal>update()</literal>,
+ will Hibernate perform an extra SQL <literal>SELECT</literal> to
+ determine if an <literal>UPDATE</literal> is actually
+ required.</para>
+ </callout>
+
+ <callout arearefs="class11">
+ <para><literal>polymorphism</literal> (optional - defaults to
+ <literal>implicit</literal>): determines whether implicit or
+ explicit query polymorphism is used.</para>
+ </callout>
+
+ <callout arearefs="class12">
+ <para><literal>where</literal> (optional): specifies an arbitrary
+ SQL <literal>WHERE</literal> condition to be used when retrieving
+ objects of this class.</para>
+ </callout>
+
+ <callout arearefs="class13">
+ <para><literal>persister</literal> (optional): specifies a custom
+ <literal>ClassPersister</literal>.</para>
+ </callout>
+
+ <callout arearefs="class14">
+ <para><literal>batch-size</literal> (optional - defaults to
+ <literal>1</literal>): specifies a "batch size" for fetching
+ instances of this class by identifier.</para>
+ </callout>
+
+ <callout arearefs="class15">
+ <para><literal>optimistic-lock</literal> (optional - defaults to
+ <literal>version</literal>): determines the optimistic locking
+ strategy.</para>
+ </callout>
+
+ <callout arearefs="class16">
+ <para><literal>lazy</literal> (optional): lazy fetching can be
+ disabled by setting <literal>lazy="false"</literal>.</para>
+ </callout>
+
+ <callout arearefs="class17">
+ <para><literal>entity-name</literal> (optional - defaults to the
+ class name): Hibernate3 allows a class to be mapped multiple
+ times, potentially to different tables. It also allows entity
+ mappings that are represented by Maps or XML at the Java level. In
+ these cases, you should provide an explicit arbitrary name for the
+ entity. See <xref linkend="persistent-classes-dynamicmodels" />
+ and <xref linkend="xml" /> for more information.</para>
+ </callout>
+
+ <callout arearefs="class18">
+ <para><literal>check</literal> (optional): an SQL expression used
+ to generate a multi-row <emphasis>check</emphasis> constraint for
+ automatic schema generation.</para>
+ </callout>
+
+ <callout arearefs="class19">
+ <para><literal>rowid</literal> (optional): Hibernate can use
+ ROWIDs on databases. On Oracle, for example, Hibernate can use the
+ <literal>rowid</literal> extra column for fast updates once this
+ option has been set to <literal>rowid</literal>. A ROWID is an
+ implementation detail and represents the physical location of a
+ stored tuple.</para>
+ </callout>
+
+ <callout arearefs="class20">
+ <para><literal>subselect</literal> (optional): maps an immutable
+ and read-only entity to a database subselect. This is useful if
+ you want to have a view instead of a base table. See below for
+ more information.</para>
+ </callout>
+
+ <callout arearefs="class21">
+ <para><literal>abstract</literal> (optional): is used to mark
+ abstract superclasses in <literal><union-subclass></literal>
+ hierarchies.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>It is acceptable for the named persistent class to be an
+ interface. You can declare implementing classes of that interface using
+ the <literal><subclass></literal> element. You can persist any
+ <emphasis>static</emphasis> inner class. Specify the class name using
+ the standard form i.e. <literal>e.g.Foo$Bar</literal>.</para>
+
+ <para>Immutable classes, <literal>mutable="false"</literal>, cannot be
+ updated or deleted by the application. This allows Hibernate to make
+ some minor performance optimizations.</para>
+
+ <para>The optional <literal>proxy</literal> attribute enables lazy
+ initialization of persistent instances of the class. Hibernate will
+ initially return CGLIB proxies that implement the named interface. The
+ persistent object will load when a method of the proxy is invoked. See
+ "Initializing collections and proxies" below.</para>
+
+ <para><emphasis>Implicit</emphasis> polymorphism means that instances of
+ the class will be returned by a query that names any superclass or
+ implemented interface or class, and that instances of any subclass of
+ the class will be returned by a query that names the class itself.
+ <emphasis>Explicit</emphasis> polymorphism means that class instances
+ will be returned only by queries that explicitly name that class.
+ Queries that name the class will return only instances of subclasses
+ mapped inside this <literal><class></literal> declaration as a
+ <literal><subclass></literal> or
+ <literal><joined-subclass></literal>. For most purposes, the
+ default <literal>polymorphism="implicit"</literal> is appropriate.
+ Explicit polymorphism is useful when two different classes are mapped to
+ the same table This allows a "lightweight" class that contains a subset
+ of the table columns.</para>
+
+ <para>The <literal>persister</literal> attribute lets you customize the
+ persistence strategy used for the class. You can, for example, specify
+ your own subclass of
+ <literal>org.hibernate.persister.EntityPersister</literal>, or you can
+ even provide a completely new implementation of the interface
+ <literal>org.hibernate.persister.ClassPersister</literal> that
+ implements, for example, persistence via stored procedure calls,
+ serialization to flat files or LDAP. See
+ <literal>org.hibernate.test.CustomPersister</literal> for a simple
+ example of "persistence" to a <literal>Hashtable</literal>.</para>
+
+ <para>The <literal>dynamic-update</literal> and
+ <literal>dynamic-insert</literal> settings are not inherited by
+ subclasses, so they can also be specified on the
+ <literal><subclass></literal> or
+ <literal><joined-subclass></literal> elements. Although these
+ settings can increase performance in some cases, they can actually
+ decrease performance in others.</para>
+
+ <para>Use of <literal>select-before-update</literal> will usually
+ decrease performance. It is useful to prevent a database update trigger
+ being called unnecessarily if you reattach a graph of detached instances
+ to a <literal>Session</literal>.</para>
+
+ <para>If you enable <literal>dynamic-update</literal>, you will have a
+ choice of optimistic locking strategies:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>version</literal>: check the version/timestamp
+ columns</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>all</literal>: check all columns</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>dirty</literal>: check the changed columns, allowing
+ some concurrent updates</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>none</literal>: do not use optimistic locking</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>It is <emphasis>strongly</emphasis> recommended that you use
+ version/timestamp columns for optimistic locking with Hibernate. This
+ strategy optimizes performance and correctly handles modifications made
+ to detached instances (i.e. when <literal>Session.merge()</literal> is
+ used).</para>
+
+ <para>There is no difference between a view and a base table for a
+ Hibernate mapping. This is transparent at the database level, although
+ some DBMS do not support views properly, especially with updates.
+ Sometimes you want to use a view, but you cannot create one in the
+ database (i.e. with a legacy schema). In this case, you can map an
+ immutable and read-only entity to a given SQL subselect
+ expression:</para>
+
+ <programlisting role="XML"><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"/>
+ </subselect>
+ <synchronize table="item"/>
+ <synchronize table="bid"/>
+ <id name="name"/>
...
-</class>]]></programlisting>
+</class></programlisting>
- <para>
- Declare the tables to synchronize this entity with, ensuring that auto-flush happens
- correctly and that queries against the derived entity do not return stale data.
- The <literal><subselect></literal> is available both as an attribute and
- a nested mapping element.
- </para>
+ <para>Declare the tables to synchronize this entity with, ensuring that
+ auto-flush happens correctly and that queries against the derived entity
+ do not return stale data. The <literal><subselect></literal> is
+ available both as an attribute and a nested mapping element.</para>
+ </section>
- </section>
+ <section id="mapping-declaration-id" revision="4">
+ <title>id</title>
- <section id="mapping-declaration-id" revision="4">
- <title>id</title>
+ <para>Mapped classes <emphasis>must</emphasis> declare the primary key
+ column of the database table. Most classes will also have a
+ JavaBeans-style property holding the unique identifier of an instance.
+ The <literal><id></literal> element defines the mapping from that
+ property to the primary key column.</para>
- <para>
- Mapped classes <emphasis>must</emphasis> declare the primary key column of the database
- table. Most classes will also have a JavaBeans-style property holding the unique identifier
- of an instance. The <literal><id></literal> element defines the mapping from that
- property to the primary key column.
- </para>
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="id1" />
- <programlistingco role="XML">
- <areaspec>
- <area id="id1" coords="2"/>
- <area id="id2" coords="3" />
- <area id="id3" coords="4"/>
- <area id="id4" coords="5" />
- <area id="id5" coords="6" />
- </areaspec>
- <programlisting><![CDATA[<id
+ <area coords="3" id="id2" />
+
+ <area coords="4" id="id3" />
+
+ <area coords="5" id="id4" />
+
+ <area coords="6" id="id5" />
+ </areaspec>
+
+ <programlisting><id
name="propertyName"
type="typename"
column="column_name"
unsaved-value="null|any|none|undefined|id_value"
- access="field|property|ClassName">
+ access="field|property|ClassName">
node="element-name|@attribute-name|element/@attribute|."
- <generator class="generatorClass"/>
-</id>]]></programlisting>
- <calloutlist>
- <callout arearefs="id1">
- <para>
- <literal>name</literal> (optional): the name of the identifier property.
- </para>
- </callout>
- <callout arearefs="id2">
- <para>
- <literal>type</literal> (optional): a name that indicates the Hibernate type.
- </para>
- </callout>
- <callout arearefs="id3">
- <para>
- <literal>column</literal> (optional - defaults to the property name): the
- name of the primary key column.
- </para>
- </callout>
- <callout arearefs="id4">
- <para>
- <literal>unsaved-value</literal> (optional - defaults to a "sensible" value):
- an identifier property value that indicates an instance is newly instantiated
- (unsaved), distinguishing it from detached instances that were saved or loaded
- in a previous session.
- </para>
- </callout>
- <callout arearefs="id5">
- <para>
- <literal>access</literal> (optional - defaults to <literal>property</literal>): the
- strategy Hibernate should use for accessing the property value.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+ <generator class="generatorClass"/>
+</id></programlisting>
- <para>
- If the <literal>name</literal> attribute is missing, it is assumed that the class has no
- identifier property.
- </para>
+ <calloutlist>
+ <callout arearefs="id1">
+ <para><literal>name</literal> (optional): the name of the
+ identifier property.</para>
+ </callout>
- <para>
- The <literal>unsaved-value</literal> attribute is almost never needed in Hibernate3.
- </para>
+ <callout arearefs="id2">
+ <para><literal>type</literal> (optional): a name that indicates
+ the Hibernate type.</para>
+ </callout>
- <para>
- There is an alternative <literal><composite-id></literal> declaration that allows access to
- legacy data with composite keys. Its use is strongly discouraged for anything else.
- </para>
+ <callout arearefs="id3">
+ <para><literal>column</literal> (optional - defaults to the
+ property name): the name of the primary key column.</para>
+ </callout>
- <section id="mapping-declaration-id-generator" revision="2">
- <title>Generator</title>
+ <callout arearefs="id4">
+ <para><literal>unsaved-value</literal> (optional - defaults to a
+ "sensible" value): an identifier property value that indicates an
+ instance is newly instantiated (unsaved), distinguishing it from
+ detached instances that were saved or loaded in a previous
+ session.</para>
+ </callout>
- <para>
- The optional <literal><generator></literal> child element names a Java class used
- to generate unique identifiers for instances of the persistent class. If any parameters
- are required to configure or initialize the generator instance, they are passed using the
- <literal><param></literal> element.
- </para>
+ <callout arearefs="id5">
+ <para><literal>access</literal> (optional - defaults to
+ <literal>property</literal>): the strategy Hibernate should use
+ for accessing the property value.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
- <programlisting role="XML"><![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>If the <literal>name</literal> attribute is missing, it is assumed
+ that the class has no identifier property.</para>
- <para>
- All generators implement the interface <literal>org.hibernate.id.IdentifierGenerator</literal>.
- This is a very simple interface. Some applications can choose to provide their own specialized
- implementations, however, Hibernate provides a range of built-in implementations. The shortcut
- names for the built-in generators are as follows:
+ <para>The <literal>unsaved-value</literal> attribute is almost never
+ needed in Hibernate3.</para>
- <variablelist>
- <varlistentry>
- <term><literal>increment</literal></term>
- <listitem>
- <para>
- generates identifiers of type <literal>long</literal>, <literal>short</literal> or
- <literal>int</literal> that are unique only when no other process is inserting data
- into the same table.
- <emphasis>Do not use in a cluster.</emphasis>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>identity</literal></term>
- <listitem>
- <para>
- supports identity columns in DB2, MySQL, MS SQL Server, Sybase and
- HypersonicSQL. The returned identifier is of type <literal>long</literal>,
- <literal>short</literal> or <literal>int</literal>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>sequence</literal></term>
- <listitem>
- <para>
- uses a sequence in DB2, PostgreSQL, Oracle, SAP DB, McKoi or a generator
- in Interbase. The returned identifier is of type <literal>long</literal>,
- <literal>short</literal> or <literal>int</literal>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>hilo</literal></term>
- <listitem>
- <para id="mapping-declaration-id-hilodescription" revision="1">
- uses a hi/lo algorithm to efficiently generate identifiers of
- type <literal>long</literal>, <literal>short</literal> or <literal>int</literal>,
- given a table and column (by default <literal>hibernate_unique_key</literal> and
- <literal>next_hi</literal> respectively) as a source of hi values. The hi/lo
- algorithm generates identifiers that are unique only for a particular database.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>seqhilo</literal></term>
- <listitem>
- <para>
- uses a hi/lo algorithm to efficiently generate identifiers of type
- <literal>long</literal>, <literal>short</literal> or <literal>int</literal>,
- given a named database sequence.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>uuid</literal></term>
- <listitem>
- <para>
- uses a 128-bit UUID algorithm to generate identifiers of type string that are
- unique within a network (the IP address is used). The UUID is encoded
- as a string of 32 hexadecimal digits in length.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>guid</literal></term>
- <listitem>
- <para>
- uses a database-generated GUID string on MS SQL Server and MySQL.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>native</literal></term>
- <listitem>
- <para>
- selects <literal>identity</literal>, <literal>sequence</literal> or
- <literal>hilo</literal> depending upon the capabilities of the
- underlying database.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>assigned</literal></term>
- <listitem>
- <para>
- lets the application assign an identifier to the object before
- <literal>save()</literal> is called. This is the default strategy
- if no <literal><generator></literal> element is specified.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>select</literal></term>
- <listitem>
- <para>
- retrieves a primary key, assigned by a database trigger, by selecting
- the row by some unique key and retrieving the primary key value.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>foreign</literal></term>
- <listitem>
- <para>
- uses the identifier of another associated object. It is usually used in conjunction
- with a <literal><one-to-one></literal> primary key association.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>sequence-identity</literal></term>
- <listitem>
- <para>
- a specialized sequence generation strategy that utilizes a
- database sequence for the actual value generation, but combines
- this with JDBC3 getGeneratedKeys to return the generated
- identifier value as part of the insert statement execution. This
- strategy is only supported on Oracle 10g drivers
- targeted for JDK 1.4. Comments on these insert statements
- are disabled due to a bug in the Oracle drivers.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
+ <para>There is an alternative <literal><composite-id></literal>
+ declaration that allows access to legacy data with composite keys. Its
+ use is strongly discouraged for anything else.</para>
- </para>
- </section>
+ <section id="mapping-declaration-id-generator" revision="2">
+ <title>Generator</title>
- <section id="mapping-declaration-id-hilo" revision="1">
- <title>Hi/lo algorithm</title>
- <para>
- The <literal>hilo</literal> and <literal>seqhilo</literal> generators provide two alternate
- implementations of the hi/lo algorithm. The
- first implementation requires a "special" database table to hold the next available "hi" value.
- Where supported, the second uses an Oracle-style sequence.
- </para>
+ <para>The optional <literal><generator></literal> child element
+ names a Java class used to generate unique identifiers for instances
+ of the persistent class. If any parameters are required to configure
+ or initialize the generator instance, they are passed using the
+ <literal><param></literal> element.</para>
- <programlisting role="XML"><![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 role="XML"><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>
- <programlisting role="XML"><![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>All generators implement the interface
+ <literal>org.hibernate.id.IdentifierGenerator</literal>. This is a
+ very simple interface. Some applications can choose to provide their
+ own specialized implementations, however, Hibernate provides a range
+ of built-in implementations. The shortcut names for the built-in
+ generators are as follows: <variablelist>
+ <varlistentry>
+ <term><literal>increment</literal></term>
- <para>
- Unfortunately, you cannot use <literal>hilo</literal> when supplying your own
- <literal>Connection</literal> to Hibernate. When Hibernate uses an application
- server datasource to obtain connections enlisted with JTA, you must configure
- the <literal>hibernate.transaction.manager_lookup_class</literal>.
- </para>
- </section>
+ <listitem>
+ <para>generates identifiers of type <literal>long</literal>,
+ <literal>short</literal> or <literal>int</literal> that are
+ unique only when no other process is inserting data into the
+ same table. <emphasis>Do not use in a
+ cluster.</emphasis></para>
+ </listitem>
+ </varlistentry>
- <section id="mapping-declaration-id-uuid">
- <title>UUID algorithm</title>
- <para>
- The UUID contains: IP address, startup time of the JVM that is accurate to a quarter
- second, system time and a counter value that is unique within the JVM. It is not
- possible to obtain a MAC address or memory address from Java code, so this is
- the best option without using JNI.
- </para>
- </section>
+ <varlistentry>
+ <term><literal>identity</literal></term>
- <section id="mapping-declaration-id-sequences">
- <title>Identity columns and sequences</title>
- <para>
- For databases that support identity columns (DB2, MySQL, Sybase, MS SQL), you
- can use <literal>identity</literal> key generation. For databases that support
- sequences (DB2, Oracle, PostgreSQL, Interbase, McKoi, SAP DB) you can use
- <literal>sequence</literal> style key generation. Both of these strategies require
- two SQL queries to insert a new object. For example:
- </para>
+ <listitem>
+ <para>supports identity columns in DB2, MySQL, MS SQL Server,
+ Sybase and HypersonicSQL. The returned identifier is of type
+ <literal>long</literal>, <literal>short</literal> or
+ <literal>int</literal>.</para>
+ </listitem>
+ </varlistentry>
- <programlisting role="XML"><![CDATA[<id name="id" type="long" column="person_id">
- <generator class="sequence">
- <param name="sequence">person_id_sequence</param>
- </generator>
-</id>]]></programlisting>
+ <varlistentry>
+ <term><literal>sequence</literal></term>
- <programlisting role="XML"><![CDATA[<id name="id" type="long" column="person_id" unsaved-value="0">
- <generator class="identity"/>
-</id>]]></programlisting>
+ <listitem>
+ <para>uses a sequence in DB2, PostgreSQL, Oracle, SAP DB,
+ McKoi or a generator in Interbase. The returned identifier is
+ of type <literal>long</literal>, <literal>short</literal> or
+ <literal>int</literal></para>
+ </listitem>
+ </varlistentry>
- <para>
- For cross-platform development, the <literal>native</literal> strategy will, depending on the capabilities of the underlying database,
- choose from the <literal>identity</literal>, <literal>sequence</literal> and
- <literal>hilo</literal> strategies.
- </para>
- </section>
+ <varlistentry>
+ <term><literal>hilo</literal></term>
- <section id="mapping-declaration-id-assigned">
- <title>Assigned identifiers</title>
- <para>
- If you want the application to assign identifiers, as opposed to having
- Hibernate generate them, you can use the <literal>assigned</literal> generator.
- This special generator uses the identifier value already assigned to the
- object's identifier property. The generator is used when the primary key
- is a natural key instead of a surrogate key. This is the default behavior
- if you do not specify a <literal><generator></literal> element.
- </para>
+ <listitem>
+ <para id="mapping-declaration-id-hilodescription"
+ revision="1">uses a hi/lo algorithm to efficiently generate
+ identifiers of type <literal>long</literal>,
+ <literal>short</literal> or <literal>int</literal>, given a
+ table and column (by default
+ <literal>hibernate_unique_key</literal> and
+ <literal>next_hi</literal> respectively) as a source of hi
+ values. The hi/lo algorithm generates identifiers that are
+ unique only for a particular database.</para>
+ </listitem>
+ </varlistentry>
- <para>
- The <literal>assigned</literal> generator makes Hibernate use
- <literal>unsaved-value="undefined"</literal>. This forces Hibernate to go to
- the database to determine if an instance is transient or detached, unless
- there is a version or timestamp property, or you define
- <literal>Interceptor.isUnsaved()</literal>.
- </para>
- </section>
+ <varlistentry>
+ <term><literal>seqhilo</literal></term>
- <section id="mapping-declaration-id-select">
- <title>Primary keys assigned by triggers</title>
- <para>
- Hibernate does not generate DDL with triggers. It is for legacy schemas only.
- </para>
+ <listitem>
+ <para>uses a hi/lo algorithm to efficiently generate
+ identifiers of type <literal>long</literal>,
+ <literal>short</literal> or <literal>int</literal>, given a
+ named database sequence.</para>
+ </listitem>
+ </varlistentry>
- <programlisting role="XML"><![CDATA[<id name="id" type="long" column="person_id">
- <generator class="select">
- <param name="key">socialSecurityNumber</param>
- </generator>
-</id>]]></programlisting>
+ <varlistentry>
+ <term><literal>uuid</literal></term>
- <para>
- In the above example, there is a unique valued property named
- <literal>socialSecurityNumber</literal>. It is defined by the class, as a
- natural key and a surrogate key named <literal>person_id</literal>,
- whose value is generated by a trigger.
- </para>
+ <listitem>
+ <para>uses a 128-bit UUID algorithm to generate identifiers of
+ type string that are unique within a network (the IP address
+ is used). The UUID is encoded as a string of 32 hexadecimal
+ digits in length.</para>
+ </listitem>
+ </varlistentry>
- </section>
+ <varlistentry>
+ <term><literal>guid</literal></term>
- </section>
+ <listitem>
+ <para>uses a database-generated GUID string on MS SQL Server
+ and MySQL.</para>
+ </listitem>
+ </varlistentry>
- <section id="mapping-declaration-id-enhanced">
- <title>Enhanced identifier generators</title>
+ <varlistentry>
+ <term><literal>native</literal></term>
- <para>
- Starting with release 3.2.3, there are 2 new generators which represent a re-thinking of 2 different
- aspects of identifier generation. The first aspect is database portability; the second is optimization
- Optimization means that you do not have to query the database for every request for a new identifier value. These two new
- generators are intended to take the place of some of the named generators described above, starting
- in 3.3.x. However, they are included in the current releases and can be referenced by FQN.
- </para>
+ <listitem>
+ <para>selects <literal>identity</literal>,
+ <literal>sequence</literal> or <literal>hilo</literal>
+ depending upon the capabilities of the underlying
+ database.</para>
+ </listitem>
+ </varlistentry>
- <para>
- The first of these new generators is <literal>org.hibernate.id.enhanced.SequenceStyleGenerator</literal>
- which is intended, firstly, as a replacement for the <literal>sequence</literal> generator and, secondly, as
- a better portability generator than <literal>native</literal>. This is because <literal>native</literal>
- generally chooses between <literal>identity</literal> and <literal>sequence</literal> which have
- largely different semantics that can cause subtle issues in applications eyeing portability.
- <literal>org.hibernate.id.enhanced.SequenceStyleGenerator</literal>, however, achieves portability in
- a different manner. It chooses between a table or a sequence in the database to store its
- incrementing values, depending on the capabilities of the dialect being used. The difference between this
- and <literal>native</literal> is that table-based and sequence-based storage have the same exact
- semantic. In fact, sequences are exactly what Hibernate tries to emulate with its table-based
- generators. This generator has a number of configuration parameters:
- <itemizedlist spacing="compact">
- <listitem>
- <para>
- <literal>sequence_name</literal> (optional, defaults to <literal>hibernate_sequence</literal>):
- the name of the sequence or table to be used.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>initial_value</literal> (optional, defaults to <literal>1</literal>): the initial
- value to be retrieved from the sequence/table. In sequence creation terms, this is analogous
- to the clause typically named "STARTS WITH".
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>increment_size</literal> (optional - defaults to <literal>1</literal>): the value by
- which subsequent calls to the sequence/table should differ. In sequence creation terms, this
- is analogous to the clause typically named "INCREMENT BY".
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>force_table_use</literal> (optional - defaults to <literal>false</literal>): should
- we force the use of a table as the backing structure even though the dialect might support
- sequence?
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>value_column</literal> (optional - defaults to <literal>next_val</literal>): only
- relevant for table structures, it is the name of the column on the table which is used to
- hold the value.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>optimizer</literal> (optional - defaults to <literal>none</literal>):
- See <xref linkend="mapping-declaration-id-enhanced-optimizers"/>
- </para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- The second of these new generators is <literal>org.hibernate.id.enhanced.TableGenerator</literal>, which
- is intended, firstly, as a replacement for the <literal>table</literal> generator, even though it actually
- functions much more like <literal>org.hibernate.id.MultipleHiLoPerTableGenerator</literal>, and secondly,
- as a re-implementation of <literal>org.hibernate.id.MultipleHiLoPerTableGenerator</literal> that utilizes the
- notion of pluggable optimizers. Essentially this generator defines a table capable of holding
- a number of different increment values simultaneously by using multiple distinctly keyed rows. This
- generator has a number of configuration parameters:
- <itemizedlist spacing="compact">
- <listitem>
- <para>
- <literal>table_name</literal> (optional - defaults to <literal>hibernate_sequences</literal>):
- the name of the table to be used.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>value_column_name</literal> (optional - defaults to <literal>next_val</literal>):
- the name of the column on the table that is used to hold the value.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>segment_column_name</literal> (optional - defaults to <literal>sequence_name</literal>):
- the name of the column on the table that is used to hold the "segment key". This is the
- value which identifies which increment value to use.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>segment_value</literal> (optional - defaults to <literal>default</literal>):
- The "segment key" value for the segment from which we want to pull increment values for
- this generator.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>segment_value_length</literal> (optional - defaults to <literal>255</literal>):
- Used for schema generation; the column size to create this segment key column.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>initial_value</literal> (optional - defaults to <literal>1</literal>):
- The initial value to be retrieved from the table.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>increment_size</literal> (optional - defaults to <literal>1</literal>):
- The value by which subsequent calls to the table should differ.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>optimizer</literal> (optional - defaults to <literal></literal>):
- See <xref linkend="mapping-declaration-id-enhanced-optimizers"/>
- </para>
- </listitem>
- </itemizedlist>
- </para>
- </section>
+ <varlistentry>
+ <term><literal>assigned</literal></term>
- <section id="mapping-declaration-id-enhanced-optimizers">
- <title>Identifier generator optimization</title>
- <para>
- For identifier generators that store values in the database, it is inefficient for them to hit the
- database on each and every call to generate a new identifier value. Instead, you can
- group a bunch of them in memory and only hit the database when you have exhausted your in-memory
- value group. This is the role of the pluggable optimizers. Currently only the two enhanced generators
- (<xref linkend="mapping-declaration-id-enhanced"/> support this operation.
- <itemizedlist spacing="compact">
- <listitem>
- <para>
- <literal>none</literal> (generally this is the default if no optimizer was specified): this
- will not perform any optimizations and hit the database for each and every request.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>hilo</literal>: applies a hi/lo algorithm around the database retrieved values. The
- values from the database for this optimizer are expected to be sequential. The values
- retrieved from the database structure for this optimizer indicates the "group number". The
- <literal>increment_size</literal> is multiplied by that value in memory to define a group
- "hi value".
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>pooled</literal>: as with the case of <literal>hilo</literal>, this optimizer
- attempts to minimize the number of hits to the database. Here, however, we simply store
- the starting value for the "next group" into the database structure rather than a sequential
- value in combination with an in-memory grouping algorithm. Here, <literal>increment_size</literal>
- refers to the values coming from the database.
- </para>
- </listitem>
- </itemizedlist>
- </para>
- </section>
+ <listitem>
+ <para>lets the application assign an identifier to the object
+ before <literal>save()</literal> is called. This is the
+ default strategy if no <literal><generator></literal>
+ element is specified.</para>
+ </listitem>
+ </varlistentry>
- <section id="mapping-declaration-compositeid" revision="3">
- <title>composite-id</title>
+ <varlistentry>
+ <term><literal>select</literal></term>
- <programlisting role="XML"><![CDATA[<composite-id
+ <listitem>
+ <para>retrieves a primary key, assigned by a database trigger,
+ by selecting the row by some unique key and retrieving the
+ primary key value.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>foreign</literal></term>
+
+ <listitem>
+ <para>uses the identifier of another associated object. It is
+ usually used in conjunction with a
+ <literal><one-to-one></literal> primary key
+ association.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sequence-identity</literal></term>
+
+ <listitem>
+ <para>a specialized sequence generation strategy that utilizes
+ a database sequence for the actual value generation, but
+ combines this with JDBC3 getGeneratedKeys to return the
+ generated identifier value as part of the insert statement
+ execution. This strategy is only supported on Oracle 10g
+ drivers targeted for JDK 1.4. Comments on these insert
+ statements are disabled due to a bug in the Oracle
+ drivers.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </section>
+
+ <section id="mapping-declaration-id-hilo" revision="1">
+ <title>Hi/lo algorithm</title>
+
+ <para>The <literal>hilo</literal> and <literal>seqhilo</literal>
+ generators provide two alternate implementations of the hi/lo
+ algorithm. The first implementation requires a "special" database
+ table to hold the next available "hi" value. Where supported, the
+ second uses an Oracle-style sequence.</para>
+
+ <programlisting role="XML"><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 role="XML"><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>Unfortunately, you cannot use <literal>hilo</literal> when
+ supplying your own <literal>Connection</literal> to Hibernate. When
+ Hibernate uses an application server datasource to obtain connections
+ enlisted with JTA, you must configure the
+ <literal>hibernate.transaction.manager_lookup_class</literal>.</para>
+ </section>
+
+ <section id="mapping-declaration-id-uuid">
+ <title>UUID algorithm</title>
+
+ <para>The UUID contains: IP address, startup time of the JVM that is
+ accurate to a quarter second, system time and a counter value that is
+ unique within the JVM. It is not possible to obtain a MAC address or
+ memory address from Java code, so this is the best option without
+ using JNI.</para>
+ </section>
+
+ <section id="mapping-declaration-id-sequences">
+ <title>Identity columns and sequences</title>
+
+ <para>For databases that support identity columns (DB2, MySQL, Sybase,
+ MS SQL), you can use <literal>identity</literal> key generation. For
+ databases that support sequences (DB2, Oracle, PostgreSQL, Interbase,
+ McKoi, SAP DB) you can use <literal>sequence</literal> style key
+ generation. Both of these strategies require two SQL queries to insert
+ a new object. For example:</para>
+
+ <programlisting role="XML"><id name="id" type="long" column="person_id">
+ <generator class="sequence">
+ <param name="sequence">person_id_sequence</param>
+ </generator>
+</id></programlisting>
+
+ <programlisting role="XML"><id name="id" type="long" column="person_id" unsaved-value="0">
+ <generator class="identity"/>
+</id></programlisting>
+
+ <para>For cross-platform development, the <literal>native</literal>
+ strategy will, depending on the capabilities of the underlying
+ database, choose from the <literal>identity</literal>,
+ <literal>sequence</literal> and <literal>hilo</literal>
+ strategies.</para>
+ </section>
+
+ <section id="mapping-declaration-id-assigned">
+ <title>Assigned identifiers</title>
+
+ <para>If you want the application to assign identifiers, as opposed to
+ having Hibernate generate them, you can use the
+ <literal>assigned</literal> generator. This special generator uses the
+ identifier value already assigned to the object's identifier property.
+ The generator is used when the primary key is a natural key instead of
+ a surrogate key. This is the default behavior if you do not specify a
+ <literal><generator></literal> element.</para>
+
+ <para>The <literal>assigned</literal> generator makes Hibernate use
+ <literal>unsaved-value="undefined"</literal>. This forces Hibernate to
+ go to the database to determine if an instance is transient or
+ detached, unless there is a version or timestamp property, or you
+ define <literal>Interceptor.isUnsaved()</literal>.</para>
+ </section>
+
+ <section id="mapping-declaration-id-select">
+ <title>Primary keys assigned by triggers</title>
+
+ <para>Hibernate does not generate DDL with triggers. It is for legacy
+ schemas only.</para>
+
+ <programlisting role="XML"><id name="id" type="long" column="person_id">
+ <generator class="select">
+ <param name="key">socialSecurityNumber</param>
+ </generator>
+</id></programlisting>
+
+ <para>In the above example, there is a unique valued property named
+ <literal>socialSecurityNumber</literal>. It is defined by the class,
+ as a natural key and a surrogate key named
+ <literal>person_id</literal>, whose value is generated by a
+ trigger.</para>
+ </section>
+ </section>
+
+ <section id="mapping-declaration-id-enhanced">
+ <title>Enhanced identifier generators</title>
+
+ <para>Starting with release 3.2.3, there are 2 new generators which
+ represent a re-thinking of 2 different aspects of identifier generation.
+ The first aspect is database portability; the second is optimization
+ Optimization means that you do not have to query the database for every
+ request for a new identifier value. These two new generators are
+ intended to take the place of some of the named generators described
+ above, starting in 3.3.x. However, they are included in the current
+ releases and can be referenced by FQN.</para>
+
+ <para>The first of these new generators is
+ <literal>org.hibernate.id.enhanced.SequenceStyleGenerator</literal>
+ which is intended, firstly, as a replacement for the
+ <literal>sequence</literal> generator and, secondly, as a better
+ portability generator than <literal>native</literal>. This is because
+ <literal>native</literal> generally chooses between
+ <literal>identity</literal> and <literal>sequence</literal> which have
+ largely different semantics that can cause subtle issues in applications
+ eyeing portability.
+ <literal>org.hibernate.id.enhanced.SequenceStyleGenerator</literal>,
+ however, achieves portability in a different manner. It chooses between
+ a table or a sequence in the database to store its incrementing values,
+ depending on the capabilities of the dialect being used. The difference
+ between this and <literal>native</literal> is that table-based and
+ sequence-based storage have the same exact semantic. In fact, sequences
+ are exactly what Hibernate tries to emulate with its table-based
+ generators. This generator has a number of configuration parameters:
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>sequence_name</literal> (optional, defaults to
+ <literal>hibernate_sequence</literal>): the name of the sequence
+ or table to be used.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>initial_value</literal> (optional, defaults to
+ <literal>1</literal>): the initial value to be retrieved from the
+ sequence/table. In sequence creation terms, this is analogous to
+ the clause typically named "STARTS WITH".</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>increment_size</literal> (optional - defaults to
+ <literal>1</literal>): the value by which subsequent calls to the
+ sequence/table should differ. In sequence creation terms, this is
+ analogous to the clause typically named "INCREMENT BY".</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>force_table_use</literal> (optional - defaults to
+ <literal>false</literal>): should we force the use of a table as
+ the backing structure even though the dialect might support
+ sequence?</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>value_column</literal> (optional - defaults to
+ <literal>next_val</literal>): only relevant for table structures,
+ it is the name of the column on the table which is used to hold
+ the value.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>optimizer</literal> (optional - defaults to
+ <literal>none</literal>): See <xref
+ linkend="mapping-declaration-id-enhanced-optimizers" /></para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>The second of these new generators is
+ <literal>org.hibernate.id.enhanced.TableGenerator</literal>, which is
+ intended, firstly, as a replacement for the <literal>table</literal>
+ generator, even though it actually functions much more like
+ <literal>org.hibernate.id.MultipleHiLoPerTableGenerator</literal>, and
+ secondly, as a re-implementation of
+ <literal>org.hibernate.id.MultipleHiLoPerTableGenerator</literal> that
+ utilizes the notion of pluggable optimizers. Essentially this generator
+ defines a table capable of holding a number of different increment
+ values simultaneously by using multiple distinctly keyed rows. This
+ generator has a number of configuration parameters: <itemizedlist
+ spacing="compact">
+ <listitem>
+ <para><literal>table_name</literal> (optional - defaults to
+ <literal>hibernate_sequences</literal>): the name of the table to
+ be used.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>value_column_name</literal> (optional - defaults to
+ <literal>next_val</literal>): the name of the column on the table
+ that is used to hold the value.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>segment_column_name</literal> (optional - defaults
+ to <literal>sequence_name</literal>): the name of the column on
+ the table that is used to hold the "segment key". This is the
+ value which identifies which increment value to use.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>segment_value</literal> (optional - defaults to
+ <literal>default</literal>): The "segment key" value for the
+ segment from which we want to pull increment values for this
+ generator.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>segment_value_length</literal> (optional - defaults
+ to <literal>255</literal>): Used for schema generation; the column
+ size to create this segment key column.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>initial_value</literal> (optional - defaults to
+ <literal>1</literal>): The initial value to be retrieved from the
+ table.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>increment_size</literal> (optional - defaults to
+ <literal>1</literal>): The value by which subsequent calls to the
+ table should differ.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>optimizer</literal> (optional - defaults to
+ <literal></literal>): See <xref
+ linkend="mapping-declaration-id-enhanced-optimizers" /></para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section id="mapping-declaration-id-enhanced-optimizers">
+ <title>Identifier generator optimization</title>
+
+ <para>For identifier generators that store values in the database, it is
+ inefficient for them to hit the database on each and every call to
+ generate a new identifier value. Instead, you can group a bunch of them
+ in memory and only hit the database when you have exhausted your
+ in-memory value group. This is the role of the pluggable optimizers.
+ Currently only the two enhanced generators (<xref
+ linkend="mapping-declaration-id-enhanced" /> support this operation.
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>none</literal> (generally this is the default if no
+ optimizer was specified): this will not perform any optimizations
+ and hit the database for each and every request.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>hilo</literal>: applies a hi/lo algorithm around
+ the database retrieved values. The values from the database for
+ this optimizer are expected to be sequential. The values retrieved
+ from the database structure for this optimizer indicates the
+ "group number". The <literal>increment_size</literal> is
+ multiplied by that value in memory to define a group "hi
+ value".</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>pooled</literal>: as with the case of
+ <literal>hilo</literal>, this optimizer attempts to minimize the
+ number of hits to the database. Here, however, we simply store the
+ starting value for the "next group" into the database structure
+ rather than a sequential value in combination with an in-memory
+ grouping algorithm. Here, <literal>increment_size</literal> refers
+ to the values coming from the database.</para>
+ </listitem>
+ </itemizedlist></para>
+ </section>
+
+ <section id="mapping-declaration-compositeid" revision="3">
+ <title>composite-id</title>
+
+ <programlisting role="XML"><composite-id
name="propertyName"
class="ClassName"
mapped="true|false"
- access="field|property|ClassName">
+ 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"/>
+ <key-property name="propertyName" type="typename" column="column_name"/>
+ <key-many-to-one name="propertyName class="ClassName" column="column_name"/>
......
-</composite-id>]]></programlisting>
+</composite-id></programlisting>
- <para>
- A table with a composite key can be mapped with multiple properties of the class
- as identifier properties. The <literal><composite-id></literal> element
- accepts <literal><key-property></literal> property mappings and
- <literal><key-many-to-one></literal> mappings as child elements.
- </para>
+ <para>A table with a composite key can be mapped with multiple
+ properties of the class as identifier properties. The
+ <literal><composite-id></literal> element accepts
+ <literal><key-property></literal> property mappings and
+ <literal><key-many-to-one></literal> mappings as child
+ elements.</para>
- <programlisting role="XML"><![CDATA[<composite-id>
- <key-property name="medicareNumber"/>
- <key-property name="dependent"/>
-</composite-id>]]></programlisting>
+ <programlisting role="XML"><composite-id>
+ <key-property name="medicareNumber"/>
+ <key-property name="dependent"/>
+</composite-id></programlisting>
- <para>
- The persistent class <emphasis>must</emphasis> override <literal>equals()</literal>
- and <literal>hashCode()</literal> to implement composite identifier equality. It must
- also implement <literal>Serializable</literal>.
- </para>
+ <para>The persistent class <emphasis>must</emphasis> override
+ <literal>equals()</literal> and <literal>hashCode()</literal> to
+ implement composite identifier equality. It must also implement
+ <literal>Serializable</literal>.</para>
- <para>
- Unfortunately, this approach means that a persistent object
- is its own identifier. There is no convenient "handle" other than the object itself.
- You must instantiate an instance of the persistent class itself and populate its
- identifier properties before you can <literal>load()</literal> the persistent state
- associated with a composite key. We call this approach an <emphasis>embedded</emphasis>
- composite identifier, and discourage it for serious applications.
- </para>
+ <para>Unfortunately, this approach means that a persistent object is its
+ own identifier. There is no convenient "handle" other than the object
+ itself. You must instantiate an instance of the persistent class itself
+ and populate its identifier properties before you can
+ <literal>load()</literal> the persistent state associated with a
+ composite key. We call this approach an <emphasis>embedded</emphasis>
+ composite identifier, and discourage it for serious applications.</para>
- <para>
- A second approach is what we call a <emphasis>mapped</emphasis> composite identifier,
- where the identifier properties named inside the <literal><composite-id></literal>
- element are duplicated on both the persistent class and a separate identifier class.
- </para>
+ <para>A second approach is what we call a <emphasis>mapped</emphasis>
+ composite identifier, where the identifier properties named inside the
+ <literal><composite-id></literal> element are duplicated on both
+ the persistent class and a separate identifier class.</para>
- <programlisting role="XML"><![CDATA[<composite-id class="MedicareId" mapped="true">
- <key-property name="medicareNumber"/>
- <key-property name="dependent"/>
-</composite-id>]]></programlisting>
+ <programlisting role="XML"><composite-id class="MedicareId" mapped="true">
+ <key-property name="medicareNumber"/>
+ <key-property name="dependent"/>
+</composite-id></programlisting>
- <para>
- In this example, both the composite identifier class, <literal>MedicareId</literal>,
- and the entity class itself have properties named <literal>medicareNumber</literal>
- and <literal>dependent</literal>. The identifier class must override
- <literal>equals()</literal> and <literal>hashCode()</literal> and implement
- <literal>Serializable</literal>. The main disadvantage of this approach is
- code duplication.
- </para>
+ <para>In this example, both the composite identifier class,
+ <literal>MedicareId</literal>, and the entity class itself have
+ properties named <literal>medicareNumber</literal> and
+ <literal>dependent</literal>. The identifier class must override
+ <literal>equals()</literal> and <literal>hashCode()</literal> and
+ implement <literal>Serializable</literal>. The main disadvantage of this
+ approach is code duplication.</para>
- <para>
- The following attributes are used to specify a mapped composite identifier:
- </para>
+ <para>The following attributes are used to specify a mapped composite
+ identifier:</para>
- <itemizedlist spacing="compact">
- <listitem>
- <para>
- <literal>mapped</literal> (optional - defaults to <literal>false</literal>):
- indicates that a mapped composite identifier is used, and that the contained
- property mappings refer to both the entity class and the composite identifier
- class.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>class</literal> (optional - but required for a mapped composite identifier):
- the class used as a composite identifier.
- </para>
- </listitem>
- </itemizedlist>
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>mapped</literal> (optional - defaults to
+ <literal>false</literal>): indicates that a mapped composite
+ identifier is used, and that the contained property mappings refer
+ to both the entity class and the composite identifier class.</para>
+ </listitem>
- <para>
- We will describe a third, even more convenient approach, where the composite identifier
- is implemented as a component class in <xref linkend="components-compositeid"/>. The
- attributes described below apply only to this alternative approach:
- </para>
+ <listitem>
+ <para><literal>class</literal> (optional - but required for a mapped
+ composite identifier): the class used as a composite
+ identifier.</para>
+ </listitem>
+ </itemizedlist>
- <itemizedlist spacing="compact">
- <listitem>
- <para>
- <literal>name</literal> (optional - required for this approach): a property of
- component type that holds the composite identifier. Please see chapter 9 for more information.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>access</literal> (optional - defaults to <literal>property</literal>):
- the strategy Hibernate uses for accessing the property value.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>class</literal> (optional - defaults to the property type determined by
- reflection): the component class used as a composite identifier. Please see the next section for more information.
- </para>
- </listitem>
- </itemizedlist>
+ <para>We will describe a third, even more convenient approach, where the
+ composite identifier is implemented as a component class in <xref
+ linkend="components-compositeid" />. The attributes described below
+ apply only to this alternative approach:</para>
- <para>
- The third approach, an <emphasis>identifier component</emphasis>, is recommended
- for almost all applications.
- </para>
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>name</literal> (optional - required for this
+ approach): a property of component type that holds the composite
+ identifier. Please see chapter 9 for more information.</para>
+ </listitem>
- </section>
+ <listitem>
+ <para><literal>access</literal> (optional - defaults to
+ <literal>property</literal>): the strategy Hibernate uses for
+ accessing the property value.</para>
+ </listitem>
- <section id="mapping-declaration-discriminator" revision="3">
- <title>Discriminator</title>
+ <listitem>
+ <para><literal>class</literal> (optional - defaults to the property
+ type determined by reflection): the component class used as a
+ composite identifier. Please see the next section for more
+ information.</para>
+ </listitem>
+ </itemizedlist>
- <para>
- The <literal><discriminator></literal> element is required for polymorphic persistence
- using the table-per-class-hierarchy mapping strategy. It declares a discriminator column of the
- table. The discriminator column contains marker values that tell the persistence layer what
- subclass to instantiate for a particular row. A restricted set of types can be used:
- <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>
+ <para>The third approach, an <emphasis>identifier component</emphasis>,
+ is recommended for almost all applications.</para>
+ </section>
- <programlistingco role="XML">
- <areaspec>
- <area id="discriminator1" coords="2"/>
- <area id="discriminator2" coords="3" />
- <area id="discriminator3" coords="4" />
- <area id="discriminator4" coords="5" />
- <area id="discriminator5" coords="6" />
- </areaspec>
- <programlisting><![CDATA[<discriminator
+ <section id="mapping-declaration-discriminator" revision="3">
+ <title>Discriminator</title>
+
+ <para>The <literal><discriminator></literal> element is required
+ for polymorphic persistence using the table-per-class-hierarchy mapping
+ strategy. It declares a discriminator column of the table. The
+ discriminator column contains marker values that tell the persistence
+ layer what subclass to instantiate for a particular row. A restricted
+ set of types can be used: <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 role="XML">
+ <areaspec>
+ <area coords="2" id="discriminator1" />
+
+ <area coords="3" id="discriminator2" />
+
+ <area coords="4" id="discriminator3" />
+
+ <area coords="5" id="discriminator4" />
+
+ <area coords="6" id="discriminator5" />
+ </areaspec>
+
+ <programlisting><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> (optional - defaults to <literal>class</literal>): the
- name of the discriminator column.
- </para>
- </callout>
- <callout arearefs="discriminator2">
- <para>
- <literal>type</literal> (optional - defaults to <literal>string</literal>): a
- name that indicates the Hibernate type
- </para>
- </callout>
- <callout arearefs="discriminator3">
- <para>
- <literal>force</literal> (optional - defaults to <literal>false</literal>):
- "forces" Hibernate to specify the allowed discriminator values, even when retrieving
- all instances of the root class.
- </para>
- </callout>
- <callout arearefs="discriminator4">
- <para>
- <literal>insert</literal> (optional - defaults to <literal>true</literal>):
- set this to <literal>false</literal> if your discriminator column is also part
- of a mapped composite identifier. It tells Hibernate not to include the column
- in SQL <literal>INSERTs</literal>.
- </para>
- </callout>
- <callout arearefs="discriminator5">
- <para>
- <literal>formula</literal> (optional): an arbitrary SQL expression that is
- executed when a type has to be evaluated. It allows content-based discrimination.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+/></programlisting>
- <para>
- Actual values of the discriminator column are specified by the
- <literal>discriminator-value</literal> attribute of the <literal><class></literal> and
- <literal><subclass></literal> elements.
- </para>
+ <calloutlist>
+ <callout arearefs="discriminator1">
+ <para><literal>column</literal> (optional - defaults to
+ <literal>class</literal>): the name of the discriminator
+ column.</para>
+ </callout>
- <para>
- The <literal>force</literal> attribute is only useful if the table contains rows with
- "extra" discriminator values that are not mapped to a persistent class. This will not
- usually be the case.
- </para>
+ <callout arearefs="discriminator2">
+ <para><literal>type</literal> (optional - defaults to
+ <literal>string</literal>): a name that indicates the Hibernate
+ type</para>
+ </callout>
- <para>
- The <literal>formula</literal> attribute allows you to declare an arbitrary SQL expression
- that will be used to evaluate the type of a row. For example:
- </para>
+ <callout arearefs="discriminator3">
+ <para><literal>force</literal> (optional - defaults to
+ <literal>false</literal>): "forces" Hibernate to specify the
+ allowed discriminator values, even when retrieving all instances
+ of the root class.</para>
+ </callout>
- <programlisting role="XML"><![CDATA[<discriminator
+ <callout arearefs="discriminator4">
+ <para><literal>insert</literal> (optional - defaults to
+ <literal>true</literal>): set this to <literal>false</literal> if
+ your discriminator column is also part of a mapped composite
+ identifier. It tells Hibernate not to include the column in SQL
+ <literal>INSERTs</literal>.</para>
+ </callout>
+
+ <callout arearefs="discriminator5">
+ <para><literal>formula</literal> (optional): an arbitrary SQL
+ expression that is executed when a type has to be evaluated. It
+ allows content-based discrimination.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>Actual values of the discriminator column are specified by the
+ <literal>discriminator-value</literal> attribute of the
+ <literal><class></literal> and <literal><subclass></literal>
+ elements.</para>
+
+ <para>The <literal>force</literal> attribute is only useful if the table
+ contains rows with "extra" discriminator values that are not mapped to a
+ persistent class. This will not usually be the case.</para>
+
+ <para>The <literal>formula</literal> attribute allows you to declare an
+ arbitrary SQL expression that will be used to evaluate the type of a
+ row. For example:</para>
+
+ <programlisting role="XML"><discriminator
formula="case when CLASS_TYPE in ('a', 'b', 'c') then 0 else 1 end"
- type="integer"/>]]></programlisting>
+ type="integer"/></programlisting>
+ </section>
- </section>
+ <section id="mapping-declaration-version" revision="4">
+ <title>Version (optional)</title>
- <section id="mapping-declaration-version" revision="4">
- <title>Version (optional)</title>
+ <para>The <literal><version></literal> element is optional and
+ indicates that the table contains versioned data. This is particularly
+ useful if you plan to use <emphasis>long transactions</emphasis>. See
+ below for more information:</para>
- <para>
- The <literal><version></literal> element is optional and indicates that
- the table contains versioned data. This is particularly useful if you plan to
- use <emphasis>long transactions</emphasis>. See below for more information:
- </para>
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="version1" />
- <programlistingco role="XML">
- <areaspec>
- <area id="version1" coords="2"/>
- <area id="version2" coords="3"/>
- <area id="version3" coords="4"/>
- <area id="version4" coords="5"/>
- <area id="version5" coords="6"/>
- <area id="version6" coords="7"/>
- <area id="version7" coords="8"/>
- </areaspec>
- <programlisting><![CDATA[<version
+ <area coords="3" id="version2" />
+
+ <area coords="4" id="version3" />
+
+ <area coords="5" id="version4" />
+
+ <area coords="6" id="version5" />
+
+ <area coords="7" id="version6" />
+
+ <area coords="8" id="version7" />
+ </areaspec>
+
+ <programlisting><version
column="version_column"
name="propertyName"
type="typename"
@@ -1335,93 +1452,99 @@
generated="never|always"
insert="true|false"
node="element-name|@attribute-name|element/@attribute|."
-/>]]></programlisting>
- <calloutlist>
- <callout arearefs="version1">
- <para>
- <literal>column</literal> (optional - defaults to the property name): the name
- of the column holding the version number.
- </para>
- </callout>
- <callout arearefs="version2">
- <para>
- <literal>name</literal>: the name of a property of the persistent class.
- </para>
- </callout>
- <callout arearefs="version3">
- <para>
- <literal>type</literal> (optional - defaults to <literal>integer</literal>):
- the type of the version number.
- </para>
- </callout>
- <callout arearefs="version4">
- <para>
- <literal>access</literal> (optional - defaults to <literal>property</literal>): the
- strategy Hibernate uses to access the property value.
- </para>
- </callout>
- <callout arearefs="version5">
- <para>
- <literal>unsaved-value</literal> (optional - defaults to <literal>undefined</literal>):
- a version property value that indicates that an instance is newly instantiated
- (unsaved), distinguishing it from detached instances that were saved or loaded
- in a previous session. <literal>Undefined</literal> specifies that the identifier
- property value should be used.
- </para>
- </callout>
- <callout arearefs="version6">
- <para>
- <literal>generated</literal> (optional - defaults to <literal>never</literal>):
- specifies that this version property value is generated by the database.
- See the discussion of <link linkend="mapping-generated">generated properties</link> for more information.
- </para>
- </callout>
- <callout arearefs="version7">
- <para>
- <literal>insert</literal> (optional - defaults to <literal>true</literal>):
- specifies whether the version column should be included in SQL insert statements.
- It can be set to <literal>false</literal> if the database column
- is defined with a default value of <literal>0</literal>.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+/></programlisting>
- <para>
- Version numbers can be of Hibernate type <literal>long</literal>, <literal>integer</literal>,
- <literal>short</literal>, <literal>timestamp</literal> or <literal>calendar</literal>.
- </para>
+ <calloutlist>
+ <callout arearefs="version1">
+ <para><literal>column</literal> (optional - defaults to the
+ property name): the name of the column holding the version
+ number.</para>
+ </callout>
- <para>
- A version or timestamp property should never be null for a detached instance.
- Hibernate will detect any instance with a null version or timestamp as transient,
- irrespective of what other <literal>unsaved-value</literal> strategies are specified.
- <emphasis>Declaring a nullable version or timestamp property is an easy way to avoid
- problems with transitive reattachment in Hibernate. It is especially useful for people
- using assigned identifiers or composite keys</emphasis>.
- </para>
- </section>
+ <callout arearefs="version2">
+ <para><literal>name</literal>: the name of a property of the
+ persistent class.</para>
+ </callout>
- <section id="mapping-declaration-timestamp" revision="4" >
- <title>Timestamp (optional)</title>
+ <callout arearefs="version3">
+ <para><literal>type</literal> (optional - defaults to
+ <literal>integer</literal>): the type of the version
+ number.</para>
+ </callout>
- <para>
- The optional <literal><timestamp></literal> element indicates that the table contains
- timestamped data. This provides an alternative to versioning. Timestamps are
- a less safe implementation of optimistic locking. However, sometimes the application might
- use the timestamps in other ways.
- </para>
+ <callout arearefs="version4">
+ <para><literal>access</literal> (optional - defaults to
+ <literal>property</literal>): the strategy Hibernate uses to
+ access the property value.</para>
+ </callout>
- <programlistingco role="XML">
- <areaspec>
- <area id="timestamp1" coords="2"/>
- <area id="timestamp2" coords="3" />
- <area id="timestamp3" coords="4" />
- <area id="timestamp4" coords="5" />
- <area id="timestamp5" coords="6" />
- <area id="timestamp6" coords="7" />
- </areaspec>
- <programlisting><![CDATA[<timestamp
+ <callout arearefs="version5">
+ <para><literal>unsaved-value</literal> (optional - defaults to
+ <literal>undefined</literal>): a version property value that
+ indicates that an instance is newly instantiated (unsaved),
+ distinguishing it from detached instances that were saved or
+ loaded in a previous session. <literal>Undefined</literal>
+ specifies that the identifier property value should be
+ used.</para>
+ </callout>
+
+ <callout arearefs="version6">
+ <para><literal>generated</literal> (optional - defaults to
+ <literal>never</literal>): specifies that this version property
+ value is generated by the database. See the discussion of <link
+ linkend="mapping-generated">generated properties</link> for more
+ information.</para>
+ </callout>
+
+ <callout arearefs="version7">
+ <para><literal>insert</literal> (optional - defaults to
+ <literal>true</literal>): specifies whether the version column
+ should be included in SQL insert statements. It can be set to
+ <literal>false</literal> if the database column is defined with a
+ default value of <literal>0</literal>.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>Version numbers can be of Hibernate type <literal>long</literal>,
+ <literal>integer</literal>, <literal>short</literal>,
+ <literal>timestamp</literal> or <literal>calendar</literal>.</para>
+
+ <para>A version or timestamp property should never be null for a
+ detached instance. Hibernate will detect any instance with a null
+ version or timestamp as transient, irrespective of what other
+ <literal>unsaved-value</literal> strategies are specified.
+ <emphasis>Declaring a nullable version or timestamp property is an easy
+ way to avoid problems with transitive reattachment in Hibernate. It is
+ especially useful for people using assigned identifiers or composite
+ keys</emphasis>.</para>
+ </section>
+
+ <section id="mapping-declaration-timestamp" revision="4">
+ <title>Timestamp (optional)</title>
+
+ <para>The optional <literal><timestamp></literal> element
+ indicates that the table contains timestamped data. This provides an
+ alternative to versioning. Timestamps are a less safe implementation of
+ optimistic locking. However, sometimes the application might use the
+ timestamps in other ways.</para>
+
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="timestamp1" />
+
+ <area coords="3" id="timestamp2" />
+
+ <area coords="4" id="timestamp3" />
+
+ <area coords="5" id="timestamp4" />
+
+ <area coords="6" id="timestamp5" />
+
+ <area coords="7" id="timestamp6" />
+ </areaspec>
+
+ <programlisting><timestamp
column="timestamp_column"
name="propertyName"
access="field|property|ClassName"
@@ -1429,98 +1552,104 @@
source="vm|db"
generated="never|always"
node="element-name|@attribute-name|element/@attribute|."
-/>]]></programlisting>
- <calloutlist>
- <callout arearefs="timestamp1">
- <para>
- <literal>column</literal> (optional - defaults to the property name): the name
- of a column holding the timestamp.
- </para>
- </callout>
- <callout arearefs="timestamp2">
- <para>
- <literal>name</literal>: the name of a JavaBeans style property of
- Java type <literal>Date</literal> or <literal>Timestamp</literal> of the
- persistent class.
- </para>
- </callout>
- <callout arearefs="timestamp3">
- <para>
- <literal>access</literal> (optional - defaults to <literal>property</literal>): the
- strategy Hibernate uses for accessing the property value.
- </para>
- </callout>
- <callout arearefs="timestamp4">
- <para>
- <literal>unsaved-value</literal> (optional - defaults to <literal>null</literal>):
- a version property value that indicates that an instance is newly instantiated
- (unsaved), distinguishing it from detached instances that were saved or loaded
- in a previous session. <literal>Undefined</literal> specifies that the identifier
- property value should be used.
- </para>
- </callout>
- <callout arearefs="timestamp5">
- <para>
- <literal>source</literal> (optional - defaults to <literal>vm</literal>):
- Where should Hibernate retrieve the timestamp value from? From the database,
- or from the current JVM? Database-based timestamps incur an overhead because
- Hibernate must hit the database in order to determine the "next value".
- It is safer to use in clustered environments. Not
- all <literal>Dialects</literal> are known to support the retrieval of the
- database's current timestamp. Others may also be unsafe for usage
- in locking due to lack of precision (Oracle 8, for example).
- </para>
- </callout>
- <callout arearefs="timestamp6">
- <para>
- <literal>generated</literal> (optional - defaults to <literal>never</literal>):
- specifies that this timestamp property value is actually generated by the database.
- See the discussion of <link linkend="mapping-generated">generated properties</link> for more information.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+/></programlisting>
-
- <note>
- <title>Note</title>
- <para>
- <literal><Timestamp></literal> is equivalent to
- <literal><version type="timestamp"></literal>. And
- <literal><timestamp source="db"></literal> is equivalent to
- <literal><version type="dbtimestamp"></literal>
- </para>
- </note>
-
- </section>
+ <calloutlist>
+ <callout arearefs="timestamp1">
+ <para><literal>column</literal> (optional - defaults to the
+ property name): the name of a column holding the timestamp.</para>
+ </callout>
+ <callout arearefs="timestamp2">
+ <para><literal>name</literal>: the name of a JavaBeans style
+ property of Java type <literal>Date</literal> or
+ <literal>Timestamp</literal> of the persistent class.</para>
+ </callout>
- <section id="mapping-declaration-property" revision="4">
- <title>Property</title>
+ <callout arearefs="timestamp3">
+ <para><literal>access</literal> (optional - defaults to
+ <literal>property</literal>): the strategy Hibernate uses for
+ accessing the property value.</para>
+ </callout>
- <para>
- The <literal><property></literal> element declares a persistent JavaBean style
- property of the class.
- </para>
+ <callout arearefs="timestamp4">
+ <para><literal>unsaved-value</literal> (optional - defaults to
+ <literal>null</literal>): a version property value that indicates
+ that an instance is newly instantiated (unsaved), distinguishing
+ it from detached instances that were saved or loaded in a previous
+ session. <literal>Undefined</literal> specifies that the
+ identifier property value should be used.</para>
+ </callout>
- <programlistingco role="XML">
- <areaspec>
- <area id="property1" coords="2"/>
- <area id="property2" coords="3"/>
- <area id="property3" coords="4"/>
- <areaset id="property4-5" coords="">
- <area id="property4" coords='5'/>
- <area id="property5" coords='6'/>
- </areaset>
- <area id="property6" coords="7"/>
- <area id="property7" coords="8"/>
- <area id="property8" coords="9"/>
- <area id="property9" coords="10"/>
- <area id="property10" coords="11"/>
- <area id="property11" coords="12"/>
- <area id="property12" coords="13"/>
- </areaspec>
- <programlisting><![CDATA[<property
+ <callout arearefs="timestamp5">
+ <para><literal>source</literal> (optional - defaults to
+ <literal>vm</literal>): Where should Hibernate retrieve the
+ timestamp value from? From the database, or from the current JVM?
+ Database-based timestamps incur an overhead because Hibernate must
+ hit the database in order to determine the "next value". It is
+ safer to use in clustered environments. Not all
+ <literal>Dialects</literal> are known to support the retrieval of
+ the database's current timestamp. Others may also be unsafe for
+ usage in locking due to lack of precision (Oracle 8, for
+ example).</para>
+ </callout>
+
+ <callout arearefs="timestamp6">
+ <para><literal>generated</literal> (optional - defaults to
+ <literal>never</literal>): specifies that this timestamp property
+ value is actually generated by the database. See the discussion of
+ <link linkend="mapping-generated">generated properties</link> for
+ more information.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <note>
+ <title>Note</title>
+
+ <para><literal><Timestamp></literal> is equivalent to
+ <literal><version type="timestamp"></literal>. And
+ <literal><timestamp source="db"></literal> is equivalent to
+ <literal><version type="dbtimestamp"></literal></para>
+ </note>
+ </section>
+
+ <section id="mapping-declaration-property" revision="4">
+ <title>Property</title>
+
+ <para>The <literal><property></literal> element declares a
+ persistent JavaBean style property of the class.</para>
+
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="property1" />
+
+ <area coords="3" id="property2" />
+
+ <area coords="4" id="property3" />
+
+ <areaset coords="" id="property4-5">
+ <area coords="5" id="property4" />
+
+ <area coords="6" id="property5" />
+ </areaset>
+
+ <area coords="7" id="property6" />
+
+ <area coords="8" id="property7" />
+
+ <area coords="9" id="property8" />
+
+ <area coords="10" id="property9" />
+
+ <area coords="11" id="property10" />
+
+ <area coords="12" id="property11" />
+
+ <area coords="13" id="property12" />
+ </areaspec>
+
+ <programlisting><property
name="propertyName"
column="column_name"
type="typename"
@@ -1539,189 +1668,194 @@
length="L"
precision="P"
scale="S"
-/>]]></programlisting>
- <calloutlist>
- <callout arearefs="property1">
- <para>
- <literal>name</literal>: the name of the property, with an initial lowercase
- letter.
- </para>
- </callout>
- <callout arearefs="property2">
- <para>
- <literal>column</literal> (optional - defaults to the property name): the name
- of the mapped database table column. This can also be specified by nested
- <literal><column></literal> element(s).
- </para>
- </callout>
- <callout arearefs="property3">
- <para>
- <literal>type</literal> (optional): a name that indicates the Hibernate type.
- </para>
- </callout>
- <callout arearefs="property4-5">
- <para>
- <literal>update, insert</literal> (optional - defaults to <literal>true</literal>):
- specifies that the mapped columns should be included in SQL <literal>UPDATE</literal>
- and/or <literal>INSERT</literal> statements. Setting both to <literal>false</literal>
- allows a pure "derived" property whose value is initialized from some other
- property that maps to the same column(s), or by a trigger or other application.
- </para>
- </callout>
- <callout arearefs="property6">
- <para>
- <literal>formula</literal> (optional): an SQL expression that defines the value for a
- <emphasis>computed</emphasis> property. Computed properties do not have a column
- mapping of their own.
- </para>
- </callout>
- <callout arearefs="property7">
- <para>
- <literal>access</literal> (optional - defaults to <literal>property</literal>): the
- strategy Hibernate uses for accessing the property value.
- </para>
- </callout>
- <callout arearefs="property8">
- <para>
- <literal>lazy</literal> (optional - defaults to <literal>false</literal>): specifies
- that this property should be fetched lazily when the instance variable is first
- accessed. It requires build-time bytecode instrumentation.
- </para>
- </callout>
- <callout arearefs="property9">
- <para>
- <literal>unique</literal> (optional): enables the DDL generation of a unique
- constraint for the columns. Also, allow this to be the target of
- a <literal>property-ref</literal>.
- </para>
- </callout>
- <callout arearefs="property10">
- <para>
- <literal>not-null</literal> (optional): enables the DDL generation of a nullability
- constraint for the columns.
- </para>
- </callout>
- <callout arearefs="property11">
- <para>
- <literal>optimistic-lock</literal> (optional - defaults to <literal>true</literal>):
- specifies that updates to this property do or do not require acquisition of the
- optimistic lock. In other words, it determines if a version increment should occur when
- this property is dirty.
- </para>
- </callout>
- <callout arearefs="property12">
- <para>
- <literal>generated</literal> (optional - defaults to <literal>never</literal>):
- specifies that this property value is actually generated by the database.
- See the discussion of <link linkend="mapping-generated">generated properties</link> for more information.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+/></programlisting>
- <para>
- <emphasis>typename</emphasis> could be:
- </para>
+ <calloutlist>
+ <callout arearefs="property1">
+ <para><literal>name</literal>: the name of the property, with an
+ initial lowercase letter.</para>
+ </callout>
- <orderedlist spacing="compact">
- <listitem>
- <para>
- The name of a Hibernate basic type: <literal>integer, string, character,
- date, timestamp, float, binary, serializable, object, blob</literal> etc.
- </para>
- </listitem>
- <listitem>
- <para>
- The name of a Java class with a default basic type: <literal>int, float,
- char, java.lang.String, java.util.Date, java.lang.Integer, java.sql.Clob</literal> etc.
- </para>
- </listitem>
- <listitem>
- <para>
- The name of a serializable Java class.
- </para>
- </listitem>
- <listitem>
- <para>
- The class name of a custom type: <literal>com.illflow.type.MyCustomType</literal> etc.
- </para>
- </listitem>
- </orderedlist>
+ <callout arearefs="property2">
+ <para><literal>column</literal> (optional - defaults to the
+ property name): the name of the mapped database table column. This
+ can also be specified by nested <literal><column></literal>
+ element(s).</para>
+ </callout>
- <para>
- If you do not specify a type, Hibernate will use reflection upon the named
- property and guess the correct Hibernate type. Hibernate will attempt to
- interpret the name of the return class of the property getter using, in order, rules 2, 3,
- and 4.
- In certain cases you will need the <literal>type</literal>
- attribute. For example, to distinguish between <literal>Hibernate.DATE</literal> and
- <literal>Hibernate.TIMESTAMP</literal>, or to specify a custom type.
- </para>
+ <callout arearefs="property3">
+ <para><literal>type</literal> (optional): a name that indicates
+ the Hibernate type.</para>
+ </callout>
- <para>
- The <literal>access</literal> attribute allows you to control how Hibernate accesses
- the property at runtime. By default, Hibernate will call the property get/set pair.
- If you specify <literal>access="field"</literal>, Hibernate will bypass the get/set
- pair and access the field directly using reflection. You can specify your own
- strategy for property access by naming a class that implements the interface
- <literal>org.hibernate.property.PropertyAccessor</literal>.
- </para>
+ <callout arearefs="property4-5">
+ <para><literal>update, insert</literal> (optional - defaults to
+ <literal>true</literal>): specifies that the mapped columns should
+ be included in SQL <literal>UPDATE</literal> and/or
+ <literal>INSERT</literal> statements. Setting both to
+ <literal>false</literal> allows a pure "derived" property whose
+ value is initialized from some other property that maps to the
+ same column(s), or by a trigger or other application.</para>
+ </callout>
- <para>
- A powerful feature is derived properties. These properties are by
- definition read-only. The property value is computed at load time. You declare
- the computation as an SQL expression. This then translates to a <literal>SELECT</literal>
- clause subquery in the SQL query that loads an instance:
- </para>
+ <callout arearefs="property6">
+ <para><literal>formula</literal> (optional): an SQL expression
+ that defines the value for a <emphasis>computed</emphasis>
+ property. Computed properties do not have a column mapping of
+ their own.</para>
+ </callout>
- <programlisting role="XML"><![CDATA[
-<property name="totalPrice"
+ <callout arearefs="property7">
+ <para><literal>access</literal> (optional - defaults to
+ <literal>property</literal>): the strategy Hibernate uses for
+ accessing the property value.</para>
+ </callout>
+
+ <callout arearefs="property8">
+ <para><literal>lazy</literal> (optional - defaults to
+ <literal>false</literal>): specifies that this property should be
+ fetched lazily when the instance variable is first accessed. It
+ requires build-time bytecode instrumentation.</para>
+ </callout>
+
+ <callout arearefs="property9">
+ <para><literal>unique</literal> (optional): enables the DDL
+ generation of a unique constraint for the columns. Also, allow
+ this to be the target of a <literal>property-ref</literal>.</para>
+ </callout>
+
+ <callout arearefs="property10">
+ <para><literal>not-null</literal> (optional): enables the DDL
+ generation of a nullability constraint for the columns.</para>
+ </callout>
+
+ <callout arearefs="property11">
+ <para><literal>optimistic-lock</literal> (optional - defaults to
+ <literal>true</literal>): specifies that updates to this property
+ do or do not require acquisition of the optimistic lock. In other
+ words, it determines if a version increment should occur when this
+ property is dirty.</para>
+ </callout>
+
+ <callout arearefs="property12">
+ <para><literal>generated</literal> (optional - defaults to
+ <literal>never</literal>): specifies that this property value is
+ actually generated by the database. See the discussion of <link
+ linkend="mapping-generated">generated properties</link> for more
+ information.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para><emphasis>typename</emphasis> could be:</para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>The name of a Hibernate basic type: <literal>integer, string,
+ character, date, timestamp, float, binary, serializable, object,
+ blob</literal> etc.</para>
+ </listitem>
+
+ <listitem>
+ <para>The name of a Java class with a default basic type:
+ <literal>int, float, char, java.lang.String, java.util.Date,
+ java.lang.Integer, java.sql.Clob</literal> etc.</para>
+ </listitem>
+
+ <listitem>
+ <para>The name of a serializable Java class.</para>
+ </listitem>
+
+ <listitem>
+ <para>The class name of a custom type:
+ <literal>com.illflow.type.MyCustomType</literal> etc.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>If you do not specify a type, Hibernate will use reflection upon
+ the named property and guess the correct Hibernate type. Hibernate will
+ attempt to interpret the name of the return class of the property getter
+ using, in order, rules 2, 3, and 4. In certain cases you will need the
+ <literal>type</literal> attribute. For example, to distinguish between
+ <literal>Hibernate.DATE</literal> and
+ <literal>Hibernate.TIMESTAMP</literal>, or to specify a custom
+ type.</para>
+
+ <para>The <literal>access</literal> attribute allows you to control how
+ Hibernate accesses the property at runtime. By default, Hibernate will
+ call the property get/set pair. If you specify
+ <literal>access="field"</literal>, Hibernate will bypass the get/set
+ pair and access the field directly using reflection. You can specify
+ your own strategy for property access by naming a class that implements
+ the interface
+ <literal>org.hibernate.property.PropertyAccessor</literal>.</para>
+
+ <para>A powerful feature is derived properties. These properties are by
+ definition read-only. The property value is computed at load time. You
+ declare the computation as an SQL expression. This then translates to a
+ <literal>SELECT</literal> clause subquery in the SQL query that loads an
+ instance:</para>
+
+ <programlisting role="XML">
+<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>
+ AND li.orderNumber = orderNumber )"/></programlisting>
- <para>
- You can reference the entity table by not declaring an alias on
- a particular column. This would be <literal>customerId</literal> in the given example. You can also use
- the nested <literal><formula></literal> mapping element
- if you do not want to use the attribute.
- </para>
+ <para>You can reference the entity table by not declaring an alias on a
+ particular column. This would be <literal>customerId</literal> in the
+ given example. You can also use the nested
+ <literal><formula></literal> mapping element if you do not want to
+ use the attribute.</para>
+ </section>
- </section>
+ <section id="mapping-declaration-manytoone" revision="5">
+ <title>Many-to-one</title>
- <section id="mapping-declaration-manytoone" revision="5">
- <title>Many-to-one</title>
+ <para>An ordinary association to another persistent class is declared
+ using a <literal>many-to-one</literal> element. The relational model is
+ a many-to-one association; a foreign key in one table is referencing the
+ primary key column(s) of the target table.</para>
- <para>
- An ordinary association to another persistent class is declared using a
- <literal>many-to-one</literal> element. The relational model is a
- many-to-one association; a foreign key in one table is referencing
- the primary key column(s) of the target table.
- </para>
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="manytoone1" />
- <programlistingco role="XML">
- <areaspec>
- <area id="manytoone1" coords="2"/>
- <area id="manytoone2" coords="3"/>
- <area id="manytoone3" coords="4"/>
- <area id="manytoone4" coords="5"/>
- <area id="manytoone5" coords="6"/>
- <areaset id="manytoone6-7" coords="">
- <area id="manytoone6" coords='7'/>
- <area id="manytoone7" coords='8'/>
- </areaset>
- <area id="manytoone8" coords="9"/>
- <area id="manytoone9" coords="10"/>
- <area id="manytoone10" coords="11"/>
- <area id="manytoone11" coords="12"/>
- <area id="manytoone12" coords="13"/>
- <area id="manytoone13" coords="14"/>
- <area id="manytoone14" coords="15"/>
- <area id="manytoone15" coords="16"/>
- <area id="manytoone16" coords="17"/>
- </areaspec>
- <programlisting><![CDATA[<many-to-one
+ <area coords="3" id="manytoone2" />
+
+ <area coords="4" id="manytoone3" />
+
+ <area coords="5" id="manytoone4" />
+
+ <area coords="6" id="manytoone5" />
+
+ <areaset coords="" id="manytoone6-7">
+ <area coords="7" id="manytoone6" />
+
+ <area coords="8" id="manytoone7" />
+ </areaset>
+
+ <area coords="9" id="manytoone8" />
+
+ <area coords="10" id="manytoone9" />
+
+ <area coords="11" id="manytoone10" />
+
+ <area coords="12" id="manytoone11" />
+
+ <area coords="13" id="manytoone12" />
+
+ <area coords="14" id="manytoone13" />
+
+ <area coords="15" id="manytoone14" />
+
+ <area coords="16" id="manytoone15" />
+
+ <area coords="17" id="manytoone16" />
+ </areaspec>
+
+ <programlisting><many-to-one
name="propertyName"
column="column_name"
class="ClassName"
@@ -1743,188 +1877,188 @@
index="index_name"
unique_key="unique_key_id"
foreign-key="foreign_key_name"
-/>]]></programlisting>
- <calloutlist>
- <callout arearefs="manytoone1">
- <para>
- <literal>name</literal>: the name of the property.
- </para>
- </callout>
- <callout arearefs="manytoone2">
- <para>
- <literal>column</literal> (optional): the name of the foreign key column.
- This can also be specified by nested <literal><column></literal>
- element(s).
- </para>
- </callout>
- <callout arearefs="manytoone3">
- <para>
- <literal>class</literal> (optional - defaults to the property type
- determined by reflection): the name of the associated class.
- </para>
- </callout>
- <callout arearefs="manytoone4">
- <para>
- <literal>cascade</literal> (optional): specifies which operations should
- be cascaded from the parent object to the associated object.
- </para>
- </callout>
- <callout arearefs="manytoone5">
- <para>
- <literal>fetch</literal> (optional - defaults to <literal>select</literal>):
- chooses between outer-join fetching or sequential select fetching.
- </para>
- </callout>
- <callout arearefs="manytoone6-7">
- <para>
- <literal>update, insert</literal> (optional - defaults to <literal>true</literal>):
- specifies that the mapped columns should be included in SQL <literal>UPDATE</literal>
- and/or <literal>INSERT</literal> statements. Setting both to <literal>false</literal>
- allows a pure "derived" association whose value is initialized from another
- property that maps to the same column(s), or by a trigger or other application.
- </para>
- </callout>
- <callout arearefs="manytoone8">
- <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>
- <callout arearefs="manytoone9">
- <para>
- <literal>access</literal> (optional - defaults to <literal>property</literal>): the
- strategy Hibernate uses for accessing the property value.
- </para>
- </callout>
- <callout arearefs="manytoone10">
- <para>
- <literal>unique</literal> (optional): enables the DDL generation of a unique
- constraint for the foreign-key column. By allowing this to be the target of
- a <literal>property-ref</literal>, you can make the association multiplicity
- one-to-one.
- </para>
- </callout>
- <callout arearefs="manytoone11">
- <para>
- <literal>not-null</literal> (optional): enables the DDL generation of a nullability
- constraint for the foreign key columns.
- </para>
- </callout>
- <callout arearefs="manytoone12">
- <para>
- <literal>optimistic-lock</literal> (optional - defaults to <literal>true</literal>):
- specifies that updates to this property do or do not require acquisition of the
- optimistic lock. In other words, it determines if a version increment should occur when
- this property is dirty.
- </para>
- </callout>
- <callout arearefs="manytoone13">
- <para>
- <literal>lazy</literal> (optional - defaults to <literal>proxy</literal>):
- by default, single point associations are proxied. <literal>lazy="no-proxy"</literal>
- specifies that the property should be fetched lazily when the instance variable
- is first accessed. This requires build-time bytecode instrumentation.
- <literal>lazy="false"</literal> specifies that the association will always
- be eagerly fetched.
- </para>
- </callout>
- <callout arearefs="manytoone14">
- <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="manytoone15">
- <para>
- <literal>entity-name</literal> (optional): the entity name of the associated class.
- </para>
- </callout>
- <callout arearefs="manytoone16">
- <para>
- <literal>formula</literal> (optional): an SQL expression that defines the value for a
- <emphasis>computed</emphasis> foreign key.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+/></programlisting>
- <para>
- Setting a value of the <literal>cascade</literal> attribute to any meaningful
- value other than <literal>none</literal> will propagate certain operations to the
- associated object. The meaningful values are divided into three categories. First, basic
- operations, which include: <literal>persist, merge, delete, save-update, evict, replicate, lock and
- refresh</literal>; second, special values: <literal>delete-orphan</literal>;
- and third,<literal>all</literal> comma-separated combinations of operation
- names: <literal>cascade="persist,merge,evict"</literal> or
- <literal>cascade="all,delete-orphan"</literal>. See <xref linkend="objectstate-transitive"/>
- for a full explanation. Note that single valued, many-to-one and
- one-to-one, associations do not support orphan delete.
- </para>
+ <calloutlist>
+ <callout arearefs="manytoone1">
+ <para><literal>name</literal>: the name of the property.</para>
+ </callout>
- <para>
- Here is an example of a typical <literal>many-to-one</literal> declaration:
- </para>
+ <callout arearefs="manytoone2">
+ <para><literal>column</literal> (optional): the name of the
+ foreign key column. This can also be specified by nested
+ <literal><column></literal> element(s).</para>
+ </callout>
- <programlisting role="XML"><![CDATA[<many-to-one name="product" class="Product" column="PRODUCT_ID"/>]]></programlisting>
+ <callout arearefs="manytoone3">
+ <para><literal>class</literal> (optional - defaults to the
+ property type determined by reflection): the name of the
+ associated class.</para>
+ </callout>
- <para>
- The <literal>property-ref</literal> attribute should only be used for mapping legacy
- data where a foreign key refers to a unique key of the associated table other than
- the primary key. This is a complicated and confusing relational model. For example, if the
- <literal>Product</literal> class had a unique serial number that is not the primary
- key. The <literal>unique</literal> attribute controls Hibernate's DDL generation with
- the SchemaExport tool.
- </para>
+ <callout arearefs="manytoone4">
+ <para><literal>cascade</literal> (optional): specifies which
+ operations should be cascaded from the parent object to the
+ associated object.</para>
+ </callout>
- <programlisting role="XML"><![CDATA[<property name="serialNumber" unique="true" type="string" column="SERIAL_NUMBER"/>]]></programlisting>
+ <callout arearefs="manytoone5">
+ <para><literal>fetch</literal> (optional - defaults to
+ <literal>select</literal>): chooses between outer-join fetching or
+ sequential select fetching.</para>
+ </callout>
- <para>
- Then the mapping for <literal>OrderItem</literal> might use:
- </para>
+ <callout arearefs="manytoone6-7">
+ <para><literal>update, insert</literal> (optional - defaults to
+ <literal>true</literal>): specifies that the mapped columns should
+ be included in SQL <literal>UPDATE</literal> and/or
+ <literal>INSERT</literal> statements. Setting both to
+ <literal>false</literal> allows a pure "derived" association whose
+ value is initialized from another property that maps to the same
+ column(s), or by a trigger or other application.</para>
+ </callout>
- <programlisting role="XML"><![CDATA[<many-to-one name="product" property-ref="serialNumber" column="PRODUCT_SERIAL_NUMBER"/>]]></programlisting>
+ <callout arearefs="manytoone8">
+ <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>
- <para>
- This is not encouraged, however.
- </para>
+ <callout arearefs="manytoone9">
+ <para><literal>access</literal> (optional - defaults to
+ <literal>property</literal>): the strategy Hibernate uses for
+ accessing the property value.</para>
+ </callout>
- <para>
- If the referenced unique key comprises multiple properties of the associated entity, you should
- map the referenced properties inside a named <literal><properties></literal> element.
- </para>
+ <callout arearefs="manytoone10">
+ <para><literal>unique</literal> (optional): enables the DDL
+ generation of a unique constraint for the foreign-key column. By
+ allowing this to be the target of a
+ <literal>property-ref</literal>, you can make the association
+ multiplicity one-to-one.</para>
+ </callout>
- <para>
- If the referenced unique key is the property of a component, you can specify a property path:
- </para>
+ <callout arearefs="manytoone11">
+ <para><literal>not-null</literal> (optional): enables the DDL
+ generation of a nullability constraint for the foreign key
+ columns.</para>
+ </callout>
- <programlisting role="XML"><![CDATA[<many-to-one name="owner" property-ref="identity.ssn" column="OWNER_SSN"/>]]></programlisting>
+ <callout arearefs="manytoone12">
+ <para><literal>optimistic-lock</literal> (optional - defaults to
+ <literal>true</literal>): specifies that updates to this property
+ do or do not require acquisition of the optimistic lock. In other
+ words, it determines if a version increment should occur when this
+ property is dirty.</para>
+ </callout>
- </section>
+ <callout arearefs="manytoone13">
+ <para><literal>lazy</literal> (optional - defaults to
+ <literal>proxy</literal>): by default, single point associations
+ are proxied. <literal>lazy="no-proxy"</literal> specifies that the
+ property should be fetched lazily when the instance variable is
+ first accessed. This requires build-time bytecode instrumentation.
+ <literal>lazy="false"</literal> specifies that the association
+ will always be eagerly fetched.</para>
+ </callout>
- <section id="mapping-declaration-onetoone" revision="3">
- <title>One-to-one</title>
+ <callout arearefs="manytoone14">
+ <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>
- <para>
- A one-to-one association to another persistent class is declared using a
- <literal>one-to-one</literal> element.
- </para>
+ <callout arearefs="manytoone15">
+ <para><literal>entity-name</literal> (optional): the entity name
+ of the associated class.</para>
+ </callout>
- <programlistingco role="XML">
- <areaspec>
- <area id="onetoone1" coords="2"/>
- <area id="onetoone2" coords="3"/>
- <area id="onetoone3" coords="4"/>
- <area id="onetoone4" coords="5"/>
- <area id="onetoone5" coords="6"/>
- <area id="onetoone6" coords="7"/>
- <area id="onetoone7" coords="8"/>
- <area id="onetoone8" coords="9"/>
- <area id="onetoone9" coords="10"/>
- <area id="onetoone10" coords="11"/>
- </areaspec>
- <programlisting><![CDATA[<one-to-one
+ <callout arearefs="manytoone16">
+ <para><literal>formula</literal> (optional): an SQL expression
+ that defines the value for a <emphasis>computed</emphasis> foreign
+ key.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>Setting a value of the <literal>cascade</literal> attribute to any
+ meaningful value other than <literal>none</literal> will propagate
+ certain operations to the associated object. The meaningful values are
+ divided into three categories. First, basic operations, which include:
+ <literal>persist, merge, delete, save-update, evict, replicate, lock and
+ refresh</literal>; second, special values:
+ <literal>delete-orphan</literal>; and third,<literal>all</literal>
+ comma-separated combinations of operation names:
+ <literal>cascade="persist,merge,evict"</literal> or
+ <literal>cascade="all,delete-orphan"</literal>. See <xref
+ linkend="objectstate-transitive" /> for a full explanation. Note that
+ single valued, many-to-one and one-to-one, associations do not support
+ orphan delete.</para>
+
+ <para>Here is an example of a typical <literal>many-to-one</literal>
+ declaration:</para>
+
+ <programlisting role="XML"><many-to-one name="product" class="Product" column="PRODUCT_ID"/></programlisting>
+
+ <para>The <literal>property-ref</literal> attribute should only be used
+ for mapping legacy data where a foreign key refers to a unique key of
+ the associated table other than the primary key. This is a complicated
+ and confusing relational model. For example, if the
+ <literal>Product</literal> class had a unique serial number that is not
+ the primary key. The <literal>unique</literal> attribute controls
+ Hibernate's DDL generation with the SchemaExport tool.</para>
+
+ <programlisting role="XML"><property name="serialNumber" unique="true" type="string" column="SERIAL_NUMBER"/></programlisting>
+
+ <para>Then the mapping for <literal>OrderItem</literal> might
+ use:</para>
+
+ <programlisting role="XML"><many-to-one name="product" property-ref="serialNumber" column="PRODUCT_SERIAL_NUMBER"/></programlisting>
+
+ <para>This is not encouraged, however.</para>
+
+ <para>If the referenced unique key comprises multiple properties of the
+ associated entity, you should map the referenced properties inside a
+ named <literal><properties></literal> element.</para>
+
+ <para>If the referenced unique key is the property of a component, you
+ can specify a property path:</para>
+
+ <programlisting role="XML"><many-to-one name="owner" property-ref="identity.ssn" column="OWNER_SSN"/></programlisting>
+ </section>
+
+ <section id="mapping-declaration-onetoone" revision="3">
+ <title>One-to-one</title>
+
+ <para>A one-to-one association to another persistent class is declared
+ using a <literal>one-to-one</literal> element.</para>
+
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="onetoone1" />
+
+ <area coords="3" id="onetoone2" />
+
+ <area coords="4" id="onetoone3" />
+
+ <area coords="5" id="onetoone4" />
+
+ <area coords="6" id="onetoone5" />
+
+ <area coords="7" id="onetoone6" />
+
+ <area coords="8" id="onetoone7" />
+
+ <area coords="9" id="onetoone8" />
+
+ <area coords="10" id="onetoone9" />
+
+ <area coords="11" id="onetoone10" />
+ </areaspec>
+
+ <programlisting><one-to-one
name="propertyName"
class="ClassName"
cascade="cascade_style"
@@ -1938,207 +2072,202 @@
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>: the name of the property.
- </para>
- </callout>
- <callout arearefs="onetoone2">
- <para>
- <literal>class</literal> (optional - defaults to the property type
- determined by reflection): the name of the associated class.
- </para>
- </callout>
- <callout arearefs="onetoone3">
- <para>
- <literal>cascade</literal> (optional): specifies which operations should
- be cascaded from the parent object to the associated object.
- </para>
- </callout>
- <callout arearefs="onetoone4">
- <para>
- <literal>constrained</literal> (optional): specifies that a foreign key constraint
- on the primary key of the mapped table and references the table of the associated
- class. This option affects the order in which <literal>save()</literal> and
- <literal>delete()</literal> are cascaded, and determines whether the association
- can be proxied. It is also used by the schema export tool.
- </para>
- </callout>
- <callout arearefs="onetoone5">
- <para>
- <literal>fetch</literal> (optional - defaults to <literal>select</literal>):
- chooses between outer-join fetching or sequential select fetching.
- </para>
- </callout>
- <callout arearefs="onetoone6">
- <para>
- <literal>property-ref</literal> (optional): the name of a property of the associated class
- that is joined to the primary key of this class. If not specified, the primary key of
- the associated class is used.
- </para>
- </callout>
- <callout arearefs="onetoone7">
- <para>
- <literal>access</literal> (optional - defaults to <literal>property</literal>): the
- strategy Hibernate uses for accessing the property value.
- </para>
- </callout>
- <callout arearefs="onetoone8">
- <para>
- <literal>formula</literal> (optional): almost all one-to-one associations map to the
- primary key of the owning entity. If this is not the case, you can
- specify another column, columns or expression to join on using an SQL formula. See
- <literal>org.hibernate.test.onetooneformula</literal> for an example.
- </para>
- </callout>
- <callout arearefs="onetoone9">
- <para>
- <literal>lazy</literal> (optional - defaults to <literal>proxy</literal>):
- by default, single point associations are proxied. <literal>lazy="no-proxy"</literal>
- specifies that the property should be fetched lazily when the instance variable
- is first accessed. It requires build-time bytecode instrumentation.
- <literal>lazy="false"</literal> specifies that the association will always
- be eagerly fetched. <emphasis>Note that if <literal>constrained="false"</literal>,
- proxying is impossible and Hibernate will eagerly fetch the association</emphasis>.
- </para>
- </callout>
- <callout arearefs="onetoone10">
- <para>
- <literal>entity-name</literal> (optional): the entity name of the associated class.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+/></programlisting>
- <para>
- There are two varieties of one-to-one associations:
- </para>
- <itemizedlist>
- <listitem><para>
- primary key associations
- </para></listitem>
- <listitem><para>
- unique foreign key associations
- </para></listitem>
- </itemizedlist>
+ <calloutlist>
+ <callout arearefs="onetoone1">
+ <para><literal>name</literal>: the name of the property.</para>
+ </callout>
- <para>
- Primary key associations do not need an extra table column. If two rows are related by
- the association, then the two table rows share the same primary key value.
- To relate two objects by a primary key association, ensure that they
- are assigned the same identifier value.
- </para>
+ <callout arearefs="onetoone2">
+ <para><literal>class</literal> (optional - defaults to the
+ property type determined by reflection): the name of the
+ associated class.</para>
+ </callout>
- <para>
- For a primary key association, add the following mappings to <literal>Employee</literal> and
- <literal>Person</literal> respectively:
- </para>
+ <callout arearefs="onetoone3">
+ <para><literal>cascade</literal> (optional): specifies which
+ operations should be cascaded from the parent object to the
+ associated object.</para>
+ </callout>
- <programlisting role="XML"><![CDATA[<one-to-one name="person" class="Person"/>]]></programlisting>
- <programlisting role="XML"><![CDATA[<one-to-one name="employee" class="Employee" constrained="true"/>]]></programlisting>
+ <callout arearefs="onetoone4">
+ <para><literal>constrained</literal> (optional): specifies that a
+ foreign key constraint on the primary key of the mapped table and
+ references the table of the associated class. This option affects
+ the order in which <literal>save()</literal> and
+ <literal>delete()</literal> are cascaded, and determines whether
+ the association can be proxied. It is also used by the schema
+ export tool.</para>
+ </callout>
- <para>
- Ensure that the primary keys of the related rows in the PERSON and
- EMPLOYEE tables are equal. You use a special Hibernate identifier generation strategy
- called <literal>foreign</literal>:
- </para>
+ <callout arearefs="onetoone5">
+ <para><literal>fetch</literal> (optional - defaults to
+ <literal>select</literal>): chooses between outer-join fetching or
+ sequential select fetching.</para>
+ </callout>
- <programlisting role="XML"><![CDATA[<class name="person" table="PERSON">
- <id name="id" column="PERSON_ID">
- <generator class="foreign">
- <param name="property">employee</param>
- </generator>
- </id>
+ <callout arearefs="onetoone6">
+ <para><literal>property-ref</literal> (optional): the name of a
+ property of the associated class that is joined to the primary key
+ of this class. If not specified, the primary key of the associated
+ class is used.</para>
+ </callout>
+
+ <callout arearefs="onetoone7">
+ <para><literal>access</literal> (optional - defaults to
+ <literal>property</literal>): the strategy Hibernate uses for
+ accessing the property value.</para>
+ </callout>
+
+ <callout arearefs="onetoone8">
+ <para><literal>formula</literal> (optional): almost all one-to-one
+ associations map to the primary key of the owning entity. If this
+ is not the case, you can specify another column, columns or
+ expression to join on using an SQL formula. See
+ <literal>org.hibernate.test.onetooneformula</literal> for an
+ example.</para>
+ </callout>
+
+ <callout arearefs="onetoone9">
+ <para><literal>lazy</literal> (optional - defaults to
+ <literal>proxy</literal>): by default, single point associations
+ are proxied. <literal>lazy="no-proxy"</literal> specifies that the
+ property should be fetched lazily when the instance variable is
+ first accessed. It requires build-time bytecode instrumentation.
+ <literal>lazy="false"</literal> specifies that the association
+ will always be eagerly fetched. <emphasis>Note that if
+ <literal>constrained="false"</literal>, proxying is impossible and
+ Hibernate will eagerly fetch the association</emphasis>.</para>
+ </callout>
+
+ <callout arearefs="onetoone10">
+ <para><literal>entity-name</literal> (optional): the entity name
+ of the associated class.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>There are two varieties of one-to-one associations:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>primary key associations</para>
+ </listitem>
+
+ <listitem>
+ <para>unique foreign key associations</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Primary key associations do not need an extra table column. If two
+ rows are related by the association, then the two table rows share the
+ same primary key value. To relate two objects by a primary key
+ association, ensure that they are assigned the same identifier
+ value.</para>
+
+ <para>For a primary key association, add the following mappings to
+ <literal>Employee</literal> and <literal>Person</literal>
+ respectively:</para>
+
+ <programlisting role="XML"><one-to-one name="person" class="Person"/></programlisting>
+
+ <programlisting role="XML"><one-to-one name="employee" class="Employee" constrained="true"/></programlisting>
+
+ <para>Ensure that the primary keys of the related rows in the PERSON and
+ EMPLOYEE tables are equal. You use a special Hibernate identifier
+ generation strategy called <literal>foreign</literal>:</para>
+
+ <programlisting role="XML"><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"
+ <one-to-one name="employee"
class="Employee"
- constrained="true"/>
-</class>]]></programlisting>
+ constrained="true"/>
+</class></programlisting>
- <para>
- A newly saved instance of <literal>Person</literal> is assigned the same primary
- key value as the <literal>Employee</literal> instance referred with the <literal>employee</literal>
- property of that <literal>Person</literal>.
- </para>
+ <para>A newly saved instance of <literal>Person</literal> is assigned
+ the same primary key value as the <literal>Employee</literal> instance
+ referred with the <literal>employee</literal> property of that
+ <literal>Person</literal>.</para>
- <para>
- Alternatively, a foreign key with a unique constraint, from <literal>Employee</literal> to
- <literal>Person</literal>, can be expressed as:
- </para>
+ <para>Alternatively, a foreign key with a unique constraint, from
+ <literal>Employee</literal> to <literal>Person</literal>, can be
+ expressed as:</para>
- <programlisting role="XML"><![CDATA[<many-to-one name="person" class="Person" column="PERSON_ID" unique="true"/>]]></programlisting>
+ <programlisting role="XML"><many-to-one name="person" class="Person" column="PERSON_ID" unique="true"/></programlisting>
- <para>
- This association can be made bidirectional by adding the following to the
- <literal>Person</literal> mapping:
- </para>
+ <para>This association can be made bidirectional by adding the following
+ to the <literal>Person</literal> mapping:</para>
- <programlisting role="XML"><![CDATA[<one-to-one name="employee" class="Employee" property-ref="person"/>]]></programlisting>
+ <programlisting role="XML"><one-to-one name="employee" class="Employee" property-ref="person"/></programlisting>
+ </section>
- </section>
+ <section id="mapping-declaration-naturalid">
+ <title>Natural-id</title>
- <section id="mapping-declaration-naturalid">
- <title>Natural-id</title>
-
- <programlisting role="XML"><![CDATA[<natural-id mutable="true|false"/>
- <property ... />
- <many-to-one ... />
+ <programlisting role="XML"><natural-id mutable="true|false"/>
+ <property ... />
+ <many-to-one ... />
......
-</natural-id>]]></programlisting>
+</natural-id></programlisting>
- <para>
- Although we recommend the use of surrogate keys as primary keys, you should try
- to identify natural keys for all entities. A natural key is a property or combination of
- properties that is unique and non-null. It is also immutable. Map the
- properties of the natural key inside the <literal><natural-id></literal> element.
- Hibernate will generate the necessary unique key and nullability constraints and, as a result, your
- mapping will be more self-documenting.
- </para>
+ <para>Although we recommend the use of surrogate keys as primary keys,
+ you should try to identify natural keys for all entities. A natural key
+ is a property or combination of properties that is unique and non-null.
+ It is also immutable. Map the properties of the natural key inside the
+ <literal><natural-id></literal> element. Hibernate will generate
+ the necessary unique key and nullability constraints and, as a result,
+ your mapping will be more self-documenting.</para>
- <para>
- It is recommended that you implement <literal>equals()</literal> and
- <literal>hashCode()</literal> to compare the natural key properties of the entity.
- </para>
+ <para>It is recommended that you implement <literal>equals()</literal>
+ and <literal>hashCode()</literal> to compare the natural key properties
+ of the entity.</para>
- <para>
- This mapping is not intended for use with entities that have natural primary keys.
- </para>
+ <para>This mapping is not intended for use with entities that have
+ natural primary keys.</para>
- <itemizedlist spacing="compact">
- <listitem>
- <para>
- <literal>mutable</literal> (optional - defaults to <literal>false</literal>):
- by default, natural identifier properties are assumed to be immutable (constant).
- </para>
- </listitem>
- </itemizedlist>
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>mutable</literal> (optional - defaults to
+ <literal>false</literal>): by default, natural identifier properties
+ are assumed to be immutable (constant).</para>
+ </listitem>
+ </itemizedlist>
+ </section>
- </section>
+ <section id="mapping-declaration-component" revision="2">
+ <title>Component and dynamic-component</title>
- <section id="mapping-declaration-component" revision="2">
- <title>Component and dynamic-component</title>
+ <para>The <literal><component></literal> element maps properties
+ of a child object to columns of the table of a parent class. Components
+ can, in turn, declare their own properties, components or collections.
+ See the "Component" examples below:</para>
- <para>
- The <literal><component></literal> element maps properties of a
- child object to columns of the table of a parent class. Components can, in
- turn, declare their own properties, components or collections. See
- the "Component" examples below:
- </para>
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="component1" />
- <programlistingco role="XML">
- <areaspec>
- <area id="component1" coords="2"/>
- <area id="component2" coords="3"/>
- <area id="component3" coords="4"/>
- <area id="component4" coords="5"/>
- <area id="component5" coords="6"/>
- <area id="component6" coords="7"/>
- <area id="component7" coords="8"/>
- <area id="component8" coords="9"/>
- </areaspec>
- <programlisting><![CDATA[<component
+ <area coords="3" id="component2" />
+
+ <area coords="4" id="component3" />
+
+ <area coords="5" id="component4" />
+
+ <area coords="6" id="component5" />
+
+ <area coords="7" id="component6" />
+
+ <area coords="8" id="component7" />
+
+ <area coords="9" id="component8" />
+ </areaspec>
+
+ <programlisting><component
name="propertyName"
class="className"
insert="true|false"
@@ -2148,206 +2277,194 @@
optimistic-lock="true|false"
unique="true|false"
node="element-name|."
->
+>
- <property ...../>
- <many-to-one .... />
+ <property ...../>
+ <many-to-one .... />
........
-</component>]]></programlisting>
- <calloutlist>
- <callout arearefs="component1">
- <para>
- <literal>name</literal>: the name of the property.
- </para>
- </callout>
- <callout arearefs="component2">
- <para>
- <literal>class</literal> (optional - defaults to the property type
- determined by reflection): the name of the component (child) class.
- </para>
- </callout>
- <callout arearefs="component3">
- <para>
- <literal>insert</literal>: do the mapped columns appear in SQL
- <literal>INSERTs</literal>?
- </para>
- </callout>
- <callout arearefs="component4">
- <para>
- <literal>update</literal>: do the mapped columns appear in SQL
- <literal>UPDATEs</literal>?
- </para>
- </callout>
- <callout arearefs="component5">
- <para>
- <literal>access</literal> (optional - defaults to <literal>property</literal>): the
- strategy Hibernate uses for accessing the property value.
- </para>
- </callout>
- <callout arearefs="component6">
- <para>
- <literal>lazy</literal> (optional - defaults to <literal>false</literal>): specifies
- that this component should be fetched lazily when the instance variable is first
- accessed. It requires build-time bytecode instrumentation.
- </para>
- </callout>
- <callout arearefs="component7">
- <para>
- <literal>optimistic-lock</literal> (optional - defaults to <literal>true</literal>):
- specifies that updates to this component either do or do not require acquisition of the
- optimistic lock. It determines if a version increment should occur when
- this property is dirty.
- </para>
- </callout>
- <callout arearefs="component8">
- <para>
- <literal>unique</literal> (optional - defaults to <literal>false</literal>):
- specifies that a unique constraint exists upon all mapped columns of the
- component.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+</component></programlisting>
- <para>
- The child <literal><property></literal> tags map properties of the
- child class to table columns.
- </para>
+ <calloutlist>
+ <callout arearefs="component1">
+ <para><literal>name</literal>: the name of the property.</para>
+ </callout>
- <para>
- The <literal><component></literal> element allows a <literal><parent></literal>
- subelement that maps a property of the component class as a reference back to the
- containing entity.
- </para>
+ <callout arearefs="component2">
+ <para><literal>class</literal> (optional - defaults to the
+ property type determined by reflection): the name of the component
+ (child) class.</para>
+ </callout>
- <para>
- The <literal><dynamic-component></literal> element allows a <literal>Map</literal>
- to be mapped as a component, where the property names refer to keys of the map. See
- <xref linkend="components-dynamic"/> for more information.
- </para>
+ <callout arearefs="component3">
+ <para><literal>insert</literal>: do the mapped columns appear in
+ SQL <literal>INSERTs</literal>?</para>
+ </callout>
- </section>
+ <callout arearefs="component4">
+ <para><literal>update</literal>: do the mapped columns appear in
+ SQL <literal>UPDATEs</literal>?</para>
+ </callout>
- <section id="mapping-declaration-properties" revision="2">
- <title>Properties</title>
+ <callout arearefs="component5">
+ <para><literal>access</literal> (optional - defaults to
+ <literal>property</literal>): the strategy Hibernate uses for
+ accessing the property value.</para>
+ </callout>
- <para>
- The <literal><properties></literal> element allows the definition of a named,
- logical grouping of the properties of a class. The most important use of the construct
- is that it allows a combination of properties to be the target of a
- <literal>property-ref</literal>. It is also a convenient way to define a multi-column
- unique constraint. For example:
- </para>
+ <callout arearefs="component6">
+ <para><literal>lazy</literal> (optional - defaults to
+ <literal>false</literal>): specifies that this component should be
+ fetched lazily when the instance variable is first accessed. It
+ requires build-time bytecode instrumentation.</para>
+ </callout>
- <programlistingco role="XML">
- <areaspec>
- <area id="properties1" coords="2"/>
- <area id="properties2" coords="3"/>
- <area id="properties3" coords="4"/>
- <area id="properties4" coords="5"/>
- <area id="properties5" coords="6"/>
- </areaspec>
- <programlisting><![CDATA[<properties
+ <callout arearefs="component7">
+ <para><literal>optimistic-lock</literal> (optional - defaults to
+ <literal>true</literal>): specifies that updates to this component
+ either do or do not require acquisition of the optimistic lock. It
+ determines if a version increment should occur when this property
+ is dirty.</para>
+ </callout>
+
+ <callout arearefs="component8">
+ <para><literal>unique</literal> (optional - defaults to
+ <literal>false</literal>): specifies that a unique constraint
+ exists upon all mapped columns of the component.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>The child <literal><property></literal> tags map properties
+ of the child class to table columns.</para>
+
+ <para>The <literal><component></literal> element allows a
+ <literal><parent></literal> subelement that maps a property of the
+ component class as a reference back to the containing entity.</para>
+
+ <para>The <literal><dynamic-component></literal> element allows a
+ <literal>Map</literal> to be mapped as a component, where the property
+ names refer to keys of the map. See <xref
+ linkend="components-dynamic" /> for more information.</para>
+ </section>
+
+ <section id="mapping-declaration-properties" revision="2">
+ <title>Properties</title>
+
+ <para>The <literal><properties></literal> element allows the
+ definition of a named, logical grouping of the properties of a class.
+ The most important use of the construct is that it allows a combination
+ of properties to be the target of a <literal>property-ref</literal>. It
+ is also a convenient way to define a multi-column unique constraint. For
+ example:</para>
+
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="properties1" />
+
+ <area coords="3" id="properties2" />
+
+ <area coords="4" id="properties3" />
+
+ <area coords="5" id="properties4" />
+
+ <area coords="6" id="properties5" />
+ </areaspec>
+
+ <programlisting><properties
name="logicalName"
insert="true|false"
update="true|false"
optimistic-lock="true|false"
unique="true|false"
->
+>
- <property ...../>
- <many-to-one .... />
+ <property ...../>
+ <many-to-one .... />
........
-</properties>]]></programlisting>
- <calloutlist>
- <callout arearefs="properties1">
- <para>
- <literal>name</literal>: the logical name of the grouping. It is
- <emphasis>not</emphasis> an actual property name.
- </para>
- </callout>
- <callout arearefs="properties2">
- <para>
- <literal>insert</literal>: do the mapped columns appear in SQL
- <literal>INSERTs</literal>?
- </para>
- </callout>
- <callout arearefs="properties3">
- <para>
- <literal>update</literal>: do the mapped columns appear in SQL
- <literal>UPDATEs</literal>?
- </para>
- </callout>
- <callout arearefs="properties4">
- <para>
- <literal>optimistic-lock</literal> (optional - defaults to <literal>true</literal>):
- specifies that updates to these properties either do or do not require acquisition of the
- optimistic lock. It determines if a version increment should occur when
- these properties are dirty.
- </para>
- </callout>
- <callout arearefs="properties5">
- <para>
- <literal>unique</literal> (optional - defaults to <literal>false</literal>):
- specifies that a unique constraint exists upon all mapped columns of the
- component.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+</properties></programlisting>
- <para>
- For example, if we have the following <literal><properties></literal> mapping:
- </para>
+ <calloutlist>
+ <callout arearefs="properties1">
+ <para><literal>name</literal>: the logical name of the grouping.
+ It is <emphasis>not</emphasis> an actual property name.</para>
+ </callout>
- <programlisting role="XML"><![CDATA[<class name="Person">
- <id name="personNumber"/>
+ <callout arearefs="properties2">
+ <para><literal>insert</literal>: do the mapped columns appear in
+ SQL <literal>INSERTs</literal>?</para>
+ </callout>
+ <callout arearefs="properties3">
+ <para><literal>update</literal>: do the mapped columns appear in
+ SQL <literal>UPDATEs</literal>?</para>
+ </callout>
+
+ <callout arearefs="properties4">
+ <para><literal>optimistic-lock</literal> (optional - defaults to
+ <literal>true</literal>): specifies that updates to these
+ properties either do or do not require acquisition of the
+ optimistic lock. It determines if a version increment should occur
+ when these properties are dirty.</para>
+ </callout>
+
+ <callout arearefs="properties5">
+ <para><literal>unique</literal> (optional - defaults to
+ <literal>false</literal>): specifies that a unique constraint
+ exists upon all mapped columns of the component.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>For example, if we have the following
+ <literal><properties></literal> mapping:</para>
+
+ <programlisting role="XML"><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>
+ <properties name="name"
+ unique="true" update="false">
+ <property name="firstName"/>
+ <property name="initial"/>
+ <property name="lastName"/>
+ </properties>
+</class></programlisting>
- <para>
- You might have some legacy data association that refers to this unique key of
- the <literal>Person</literal> table, instead of to the primary key:
- </para>
+ <para>You might have some legacy data association that refers to this
+ unique key of the <literal>Person</literal> table, instead of to the
+ primary key:</para>
- <programlisting role="XML"><![CDATA[<many-to-one name="person"
- class="Person" property-ref="name">
- <column name="firstName"/>
- <column name="initial"/>
- <column name="lastName"/>
-</many-to-one>]]></programlisting>
+ <programlisting role="XML"><many-to-one name="person"
+ class="Person" property-ref="name">
+ <column name="firstName"/>
+ <column name="initial"/>
+ <column name="lastName"/>
+</many-to-one></programlisting>
- <para>
- The use of this outside the context of mapping
- legacy data is not recommended.
- </para>
+ <para>The use of this outside the context of mapping legacy data is not
+ recommended.</para>
+ </section>
- </section>
+ <section id="mapping-declaration-subclass" revision="4">
+ <title>Subclass</title>
- <section id="mapping-declaration-subclass" revision="4">
- <title>Subclass</title>
+ <para>Polymorphic persistence requires the declaration of each subclass
+ of the root persistent class. For the table-per-class-hierarchy mapping
+ strategy, the <literal><subclass></literal> declaration is used.
+ For example:</para>
- <para>
- Polymorphic persistence requires the declaration of each subclass of
- the root persistent class. For the table-per-class-hierarchy
- mapping strategy, the <literal><subclass></literal> declaration is used. For example:
- </para>
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="subclass1" />
- <programlistingco role="XML">
- <areaspec>
- <area id="subclass1" coords="2"/>
- <area id="subclass2" coords="3"/>
- <area id="subclass3" coords="4"/>
- <area id="subclass4" coords="5"/>
- </areaspec>
- <programlisting><![CDATA[<subclass
+ <area coords="3" id="subclass2" />
+
+ <area coords="4" id="subclass3" />
+
+ <area coords="5" id="subclass4" />
+ </areaspec>
+
+ <programlisting><subclass
name="ClassName"
discriminator-value="discriminator_value"
proxy="ProxyInterface"
@@ -2356,69 +2473,68 @@
dynamic-insert="true|false"
entity-name="EntityName"
node="element-name"
- extends="SuperclassName">
+ extends="SuperclassName">
- <property .... />
+ <property .... />
.....
-</subclass>]]></programlisting>
- <calloutlist>
- <callout arearefs="subclass1">
- <para>
- <literal>name</literal>: the fully qualified class name of the subclass.
- </para>
- </callout>
- <callout arearefs="subclass2">
- <para>
- <literal>discriminator-value</literal> (optional - defaults to the class name): a
- value that distinguishes individual subclasses.
- </para>
- </callout>
- <callout arearefs="subclass3">
- <para>
- <literal>proxy</literal> (optional): specifies a class or interface used for
- lazy initializing proxies.
- </para>
- </callout>
- <callout arearefs="subclass4">
- <para>
- <literal>lazy</literal> (optional - defaults to <literal>true</literal>): setting
- <literal>lazy="false"</literal> disables the use of lazy fetching.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+</subclass></programlisting>
- <para>
- Each subclass declares its own persistent properties and subclasses.
- <literal><version></literal> and <literal><id></literal> properties
- are assumed to be inherited from the root class. Each subclass in a hierarchy must
- define a unique <literal>discriminator-value</literal>. If this is not specified, the
- fully qualified Java class name is used.
- </para>
+ <calloutlist>
+ <callout arearefs="subclass1">
+ <para><literal>name</literal>: the fully qualified class name of
+ the subclass.</para>
+ </callout>
- <para>
- For information about inheritance mappings see <xref linkend="inheritance"/>.
- </para>
+ <callout arearefs="subclass2">
+ <para><literal>discriminator-value</literal> (optional - defaults
+ to the class name): a value that distinguishes individual
+ subclasses.</para>
+ </callout>
- </section>
+ <callout arearefs="subclass3">
+ <para><literal>proxy</literal> (optional): specifies a class or
+ interface used for lazy initializing proxies.</para>
+ </callout>
- <section id="mapping-declaration-joinedsubclass" revision="3">
- <title>Joined-subclass</title>
+ <callout arearefs="subclass4">
+ <para><literal>lazy</literal> (optional - defaults to
+ <literal>true</literal>): setting <literal>lazy="false"</literal>
+ disables the use of lazy fetching.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
- <para>
- Each subclass can also be mapped to its own table. This is called the table-per-subclass
- mapping strategy. An inherited state is retrieved by joining with the table of the
- superclass. To do this you use the <literal><joined-subclass></literal> element. For example:
- </para>
+ <para>Each subclass declares its own persistent properties and
+ subclasses. <literal><version></literal> and
+ <literal><id></literal> properties are assumed to be inherited
+ from the root class. Each subclass in a hierarchy must define a unique
+ <literal>discriminator-value</literal>. If this is not specified, the
+ fully qualified Java class name is used.</para>
- <programlistingco role="XML">
- <areaspec>
- <area id="joinedsubclass1" coords="2"/>
- <area id="joinedsubclass2" coords="3"/>
- <area id="joinedsubclass3" coords="4"/>
- <area id="joinedsubclass4" coords="5"/>
- </areaspec>
- <programlisting><![CDATA[<joined-subclass
+ <para>For information about inheritance mappings see <xref
+ linkend="inheritance" />.</para>
+ </section>
+
+ <section id="mapping-declaration-joinedsubclass" revision="3">
+ <title>Joined-subclass</title>
+
+ <para>Each subclass can also be mapped to its own table. This is called
+ the table-per-subclass mapping strategy. An inherited state is retrieved
+ by joining with the table of the superclass. To do this you use the
+ <literal><joined-subclass></literal> element. For example:</para>
+
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="joinedsubclass1" />
+
+ <area coords="3" id="joinedsubclass2" />
+
+ <area coords="4" id="joinedsubclass3" />
+
+ <area coords="5" id="joinedsubclass4" />
+ </areaspec>
+
+ <programlisting><joined-subclass
name="ClassName"
table="tablename"
proxy="ProxyInterface"
@@ -2431,106 +2547,104 @@
persister="ClassName"
subselect="SQL expression"
entity-name="EntityName"
- node="element-name">
+ node="element-name">
- <key .... >
+ <key .... >
- <property .... />
+ <property .... />
.....
-</joined-subclass>]]></programlisting>
- <calloutlist>
- <callout arearefs="joinedsubclass1">
- <para>
- <literal>name</literal>: the fully qualified class name of the subclass.
- </para>
- </callout>
- <callout arearefs="joinedsubclass2">
- <para>
- <literal>table</literal>: the name of the subclass table.
- </para>
- </callout>
- <callout arearefs="joinedsubclass3">
- <para>
- <literal>proxy</literal> (optional): specifies a class or interface to use
- for lazy initializing proxies.
- </para>
- </callout>
- <callout arearefs="joinedsubclass4">
- <para>
- <literal>lazy</literal> (optional, defaults to <literal>true</literal>): setting
- <literal>lazy="false"</literal> disables the use of lazy fetching.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+</joined-subclass></programlisting>
- <para>
- A discriminator column is not required for this mapping strategy. Each subclass must,
- however, declare a table column holding the object identifier using the
- <literal><key></literal> element. The mapping at the start of the chapter
- would then be re-written as:
- </para>
+ <calloutlist>
+ <callout arearefs="joinedsubclass1">
+ <para><literal>name</literal>: the fully qualified class name of
+ the subclass.</para>
+ </callout>
- <programlisting role="XML"><![CDATA[<?xml version="1.0"?>
-<!DOCTYPE hibernate-mapping PUBLIC
+ <callout arearefs="joinedsubclass2">
+ <para><literal>table</literal>: the name of the subclass
+ table.</para>
+ </callout>
+
+ <callout arearefs="joinedsubclass3">
+ <para><literal>proxy</literal> (optional): specifies a class or
+ interface to use for lazy initializing proxies.</para>
+ </callout>
+
+ <callout arearefs="joinedsubclass4">
+ <para><literal>lazy</literal> (optional, defaults to
+ <literal>true</literal>): setting <literal>lazy="false"</literal>
+ disables the use of lazy fetching.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>A discriminator column is not required for this mapping strategy.
+ Each subclass must, however, declare a table column holding the object
+ identifier using the <literal><key></literal> element. The mapping
+ at the start of the chapter would then be re-written as:</para>
+
+ <programlisting role="XML"><?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
-<hibernate-mapping package="eg">
+<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="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>
+ <class name="eg.Dog">
+ <!-- mapping for Dog could go here -->
+ </class>
-</hibernate-mapping>]]></programlisting>
+</hibernate-mapping></programlisting>
- <para>
- For information about inheritance mappings see <xref linkend="inheritance"/>.
- </para>
+ <para>For information about inheritance mappings see <xref
+ linkend="inheritance" />.</para>
+ </section>
- </section>
+ <section id="mapping-declaration-unionsubclass" revision="2">
+ <title>Union-subclass</title>
- <section id="mapping-declaration-unionsubclass" revision="2">
- <title>Union-subclass</title>
+ <para>A third option is to map only the concrete classes of an
+ inheritance hierarchy to tables. This is called the
+ table-per-concrete-class strategy. Each table defines all persistent
+ states of the class, including the inherited state. In Hibernate, it is
+ not necessary to explicitly map such inheritance hierarchies. You can
+ map each class with a separate <literal><class></literal>
+ declaration. However, if you wish use polymorphic associations (e.g. an
+ association to the superclass of your hierarchy), you need to use the
+ <literal><union-subclass></literal> mapping. For example:</para>
- <para>
- A third option is to map only the concrete classes of an inheritance hierarchy
- to tables. This is called the table-per-concrete-class strategy. Each table defines all
- persistent states of the class, including the inherited state. In Hibernate, it is
- not necessary to explicitly map such inheritance hierarchies. You
- can map each class with a separate <literal><class></literal>
- declaration. However, if you wish use polymorphic associations (e.g. an association
- to the superclass of your hierarchy), you need to
- use the <literal><union-subclass></literal> mapping. For example:
- </para>
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="unionsubclass1" />
- <programlistingco role="XML">
- <areaspec>
- <area id="unionsubclass1" coords="2"/>
- <area id="unionsubclass2" coords="3"/>
- <area id="unionsubclass3" coords="4"/>
- <area id="unionsubclass4" coords="5"/>
- </areaspec>
- <programlisting><![CDATA[<union-subclass
+ <area coords="3" id="unionsubclass2" />
+
+ <area coords="4" id="unionsubclass3" />
+
+ <area coords="5" id="unionsubclass4" />
+ </areaspec>
+
+ <programlisting><union-subclass
name="ClassName"
table="tablename"
proxy="ProxyInterface"
@@ -2544,252 +2658,246 @@
persister="ClassName"
subselect="SQL expression"
entity-name="EntityName"
- node="element-name">
+ node="element-name">
- <property .... />
+ <property .... />
.....
-</union-subclass>]]></programlisting>
- <calloutlist>
- <callout arearefs="unionsubclass1">
- <para>
- <literal>name</literal>: the fully qualified class name of the subclass.
- </para>
- </callout>
- <callout arearefs="unionsubclass2">
- <para>
- <literal>table</literal>: the name of the subclass table.
- </para>
- </callout>
- <callout arearefs="unionsubclass3">
- <para>
- <literal>proxy</literal> (optional): specifies a class or interface to use
- for lazy initializing proxies.
- </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.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+</union-subclass></programlisting>
- <para>
- No discriminator column or key column is required for this mapping strategy.
- </para>
+ <calloutlist>
+ <callout arearefs="unionsubclass1">
+ <para><literal>name</literal>: the fully qualified class name of
+ the subclass.</para>
+ </callout>
- <para>
- For information about inheritance mappings see <xref linkend="inheritance"/>.
- </para>
+ <callout arearefs="unionsubclass2">
+ <para><literal>table</literal>: the name of the subclass
+ table.</para>
+ </callout>
- </section>
+ <callout arearefs="unionsubclass3">
+ <para><literal>proxy</literal> (optional): specifies a class or
+ interface to use for lazy initializing proxies.</para>
+ </callout>
- <section id="mapping-declaration-join" revision="3">
- <title>Join</title>
+ <callout arearefs="unionsubclass4">
+ <para><literal>lazy</literal> (optional, defaults to
+ <literal>true</literal>): setting <literal>lazy="false"</literal>
+ disables the use of lazy fetching.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
- <para>
- Using the <literal><join></literal> element, it is possible to map
- properties of one class to several tables that have a one-to-one relationship. For example:
- </para>
+ <para>No discriminator column or key column is required for this mapping
+ strategy.</para>
- <programlistingco role="XML">
- <areaspec>
- <area id="join1" coords="2"/>
- <area id="join2" coords="3"/>
- <area id="join3" coords="4"/>
- <area id="join4" coords="5"/>
- <area id="join5" coords="6"/>
- <area id="join6" coords="7"/>
- </areaspec>
- <programlisting><![CDATA[<join
+ <para>For information about inheritance mappings see <xref
+ linkend="inheritance" />.</para>
+ </section>
+
+ <section id="mapping-declaration-join" revision="3">
+ <title>Join</title>
+
+ <para>Using the <literal><join></literal> element, it is possible
+ to map properties of one class to several tables that have a one-to-one
+ relationship. For example:</para>
+
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="join1" />
+
+ <area coords="3" id="join2" />
+
+ <area coords="4" id="join3" />
+
+ <area coords="5" id="join4" />
+
+ <area coords="6" id="join5" />
+
+ <area coords="7" id="join6" />
+ </areaspec>
+
+ <programlisting><join
table="tablename"
schema="owner"
catalog="catalog"
fetch="join|select"
inverse="true|false"
- optional="true|false">
+ optional="true|false">
- <key ... />
+ <key ... />
- <property ... />
+ <property ... />
...
-</join>]]></programlisting>
+</join></programlisting>
- <calloutlist>
- <callout arearefs="join1">
- <para>
- <literal>table</literal>: the name of the joined table.
- </para>
- </callout>
- <callout arearefs="join2">
- <para>
- <literal>schema</literal> (optional): overrides the schema name specified by
- the root <literal><hibernate-mapping></literal> element.
- </para>
- </callout>
- <callout arearefs="join3">
- <para>
- <literal>catalog</literal> (optional): overrides the catalog name specified by
- the root <literal><hibernate-mapping></literal> element.
- </para>
- </callout>
- <callout arearefs="join4">
- <para>
- <literal>fetch</literal> (optional - defaults to <literal>join</literal>):
- if set to <literal>join</literal>, the default, Hibernate will use an inner join
- to retrieve a <literal><join></literal> defined by a class or its superclasses. It will use
- an outer join for a <literal><join></literal> defined by a subclass.
- If set to <literal>select</literal> then Hibernate will use a sequential select for
- a <literal><join></literal> defined on a subclass. This will be issued only
- if a row represents an instance of the subclass. Inner joins will still
- be used to retrieve a <literal><join></literal> defined by the class and its
- superclasses.
- </para>
- </callout>
- <callout arearefs="join5">
- <para>
- <literal>inverse</literal> (optional - defaults to <literal>false</literal>):
- if enabled, Hibernate will not insert or update the properties defined
- by this join.
- </para>
- </callout>
- <callout arearefs="join6">
- <para>
- <literal>optional</literal> (optional - defaults to <literal>false</literal>):
- if enabled, Hibernate will insert a row only if the properties defined by this
- join are non-null. It will always use an outer join to retrieve the properties.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+ <calloutlist>
+ <callout arearefs="join1">
+ <para><literal>table</literal>: the name of the joined
+ table.</para>
+ </callout>
- <para>
- For example, address information for a person can be mapped to a separate
- table while preserving value type semantics for all properties:
- </para>
+ <callout arearefs="join2">
+ <para><literal>schema</literal> (optional): overrides the schema
+ name specified by the root
+ <literal><hibernate-mapping></literal> element.</para>
+ </callout>
- <programlisting role="XML"><![CDATA[<class name="Person"
- table="PERSON">
+ <callout arearefs="join3">
+ <para><literal>catalog</literal> (optional): overrides the catalog
+ name specified by the root
+ <literal><hibernate-mapping></literal> element.</para>
+ </callout>
- <id name="id" column="PERSON_ID">...</id>
+ <callout arearefs="join4">
+ <para><literal>fetch</literal> (optional - defaults to
+ <literal>join</literal>): if set to <literal>join</literal>, the
+ default, Hibernate will use an inner join to retrieve a
+ <literal><join></literal> defined by a class or its
+ superclasses. It will use an outer join for a
+ <literal><join></literal> defined by a subclass. If set to
+ <literal>select</literal> then Hibernate will use a sequential
+ select for a <literal><join></literal> defined on a
+ subclass. This will be issued only if a row represents an instance
+ of the subclass. Inner joins will still be used to retrieve a
+ <literal><join></literal> defined by the class and its
+ superclasses.</para>
+ </callout>
- <join table="ADDRESS">
- <key column="ADDRESS_ID"/>
- <property name="address"/>
- <property name="zip"/>
- <property name="country"/>
- </join>
- ...]]></programlisting>
+ <callout arearefs="join5">
+ <para><literal>inverse</literal> (optional - defaults to
+ <literal>false</literal>): if enabled, Hibernate will not insert
+ or update the properties defined by this join.</para>
+ </callout>
- <para>
- This feature is often only useful for legacy data models. We recommend fewer
- tables than classes and a fine-grained domain model. However, it is useful
- for switching between inheritance mapping strategies in a single hierarchy, as
- explained later.
- </para>
+ <callout arearefs="join6">
+ <para><literal>optional</literal> (optional - defaults to
+ <literal>false</literal>): if enabled, Hibernate will insert a row
+ only if the properties defined by this join are non-null. It will
+ always use an outer join to retrieve the properties.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
- </section>
+ <para>For example, address information for a person can be mapped to a
+ separate table while preserving value type semantics for all
+ properties:</para>
- <section id="mapping-declaration-key">
- <title>Key</title>
+ <programlisting role="XML"><class name="Person"
+ table="PERSON">
- <para>
- The <literal><key></literal> element has featured a few times within this guide.
- It appears anywhere the parent mapping element defines a join to
- a new table that references
- the primary key of the original table. It also defines the foreign key in the joined table:
- </para>
+ <id name="id" column="PERSON_ID">...</id>
- <programlistingco role="XML">
- <areaspec>
- <area id="key1" coords="2"/>
- <area id="key2" coords="3"/>
- <area id="key3" coords="4"/>
- <area id="key4" coords="5"/>
- <area id="key5" coords="6"/>
- <area id="key6" coords="7"/>
- </areaspec>
- <programlisting><![CDATA[<key
+ <join table="ADDRESS">
+ <key column="ADDRESS_ID"/>
+ <property name="address"/>
+ <property name="zip"/>
+ <property name="country"/>
+ </join>
+ ...</programlisting>
+
+ <para>This feature is often only useful for legacy data models. We
+ recommend fewer tables than classes and a fine-grained domain model.
+ However, it is useful for switching between inheritance mapping
+ strategies in a single hierarchy, as explained later.</para>
+ </section>
+
+ <section id="mapping-declaration-key">
+ <title>Key</title>
+
+ <para>The <literal><key></literal> element has featured a few
+ times within this guide. It appears anywhere the parent mapping element
+ defines a join to a new table that references the primary key of the
+ original table. It also defines the foreign key in the joined
+ table:</para>
+
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="key1" />
+
+ <area coords="3" id="key2" />
+
+ <area coords="4" id="key3" />
+
+ <area coords="5" id="key4" />
+
+ <area coords="6" id="key5" />
+
+ <area coords="7" id="key6" />
+ </areaspec>
+
+ <programlisting><key
column="columnname"
on-delete="noaction|cascade"
property-ref="propertyName"
not-null="true|false"
update="true|false"
unique="true|false"
-/>]]></programlisting>
+/></programlisting>
- <calloutlist>
- <callout arearefs="key1">
- <para>
- <literal>column</literal> (optional): the name of the foreign key column.
- This can also be specified by nested <literal><column></literal>
- element(s).
- </para>
- </callout>
- <callout arearefs="key2">
- <para>
- <literal>on-delete</literal> (optional - defaults to <literal>noaction</literal>):
- specifies whether the foreign key constraint has database-level cascade delete
- enabled.
- </para>
- </callout>
- <callout arearefs="key3">
- <para>
- <literal>property-ref</literal> (optional): specifies that the foreign key refers
- to columns that are not the primary key of the original table. It is provided for
- legacy data.
- </para>
- </callout>
- <callout arearefs="key4">
- <para>
- <literal>not-null</literal> (optional): specifies that the foreign key columns
- are not nullable. This is implied whenever the foreign key is also part of the
- primary key.
- </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.
- </para>
- </callout>
- <callout arearefs="key6">
- <para>
- <literal>unique</literal> (optional): specifies that the foreign key should have
- a unique constraint. This is implied whenever the foreign key is also the primary key.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+ <calloutlist>
+ <callout arearefs="key1">
+ <para><literal>column</literal> (optional): the name of the
+ foreign key column. This can also be specified by nested
+ <literal><column></literal> element(s).</para>
+ </callout>
- <para>
- For systems where delete performance is important, we recommend that all keys should be
- defined <literal>on-delete="cascade"</literal>. Hibernate uses a database-level
- <literal>ON CASCADE DELETE</literal> constraint, instead of many individual
- <literal>DELETE</literal> statements. Be aware that this feature bypasses Hibernate's
- usual optimistic locking strategy for versioned data.
- </para>
+ <callout arearefs="key2">
+ <para><literal>on-delete</literal> (optional - defaults to
+ <literal>noaction</literal>): specifies whether the foreign key
+ constraint has database-level cascade delete enabled.</para>
+ </callout>
- <para>
- The <literal>not-null</literal> and <literal>update</literal> attributes are useful when
- mapping a unidirectional one-to-many association. If you map a unidirectional one-to-many association
- to a non-nullable foreign key, you <emphasis>must</emphasis> declare the key column using
- <literal><key not-null="true"></literal>.
- </para>
+ <callout arearefs="key3">
+ <para><literal>property-ref</literal> (optional): specifies that
+ the foreign key refers to columns that are not the primary key of
+ the original table. It is provided for legacy data.</para>
+ </callout>
- </section>
+ <callout arearefs="key4">
+ <para><literal>not-null</literal> (optional): specifies that the
+ foreign key columns are not nullable. This is implied whenever the
+ foreign key is also part of the primary key.</para>
+ </callout>
- <section id="mapping-column" revision="5">
- <title>Column and formula elements</title>
- <para>
- Mapping elements which accept a <literal>column</literal> attribute will alternatively
- accept a <literal><column></literal> subelement. Likewise, <literal><formula></literal>
- is an alternative to the <literal>formula</literal> attribute. For example:
- </para>
+ <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.</para>
+ </callout>
- <programlisting role="XML"><![CDATA[<column
+ <callout arearefs="key6">
+ <para><literal>unique</literal> (optional): specifies that the
+ foreign key should have a unique constraint. This is implied
+ whenever the foreign key is also the primary key.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>For systems where delete performance is important, we recommend
+ that all keys should be defined <literal>on-delete="cascade"</literal>.
+ Hibernate uses a database-level <literal>ON CASCADE DELETE</literal>
+ constraint, instead of many individual <literal>DELETE</literal>
+ statements. Be aware that this feature bypasses Hibernate's usual
+ optimistic locking strategy for versioned data.</para>
+
+ <para>The <literal>not-null</literal> and <literal>update</literal>
+ attributes are useful when mapping a unidirectional one-to-many
+ association. If you map a unidirectional one-to-many association to a
+ non-nullable foreign key, you <emphasis>must</emphasis> declare the key
+ column using <literal><key not-null="true"></literal>.</para>
+ </section>
+
+ <section id="mapping-column" revision="5">
+ <title>Column and formula elements</title>
+
+ <para>Mapping elements which accept a <literal>column</literal>
+ attribute will alternatively accept a <literal><column></literal>
+ subelement. Likewise, <literal><formula></literal> is an
+ alternative to the <literal>formula</literal> attribute. For
+ example:</para>
+
+ <programlisting role="XML"><column
name="column_name"
length="N"
precision="N"
@@ -2802,553 +2910,528 @@
check="SQL expression"
default="SQL expression"
read="SQL expression"
- write="SQL expression"/>]]></programlisting>
+ write="SQL expression"/></programlisting>
- <programlisting role="XML"><![CDATA[<formula>SQL expression</formula>]]></programlisting>
+ <programlisting role="XML"><formula>SQL expression</formula></programlisting>
- <para>
- Most of the attributes on <literal>column</literal> provide a means of tailoring the
- DDL during automatic schema generation. The <literal>read</literal> and <literal>write</literal>
- attributes allow you to specify custom SQL that Hibernate will use to access the column's value.
- For more on this, see the discussion of
- <link linkend="mapping-column-read-and-write">column read and write expressions</link>.
- </para>
+ <para>Most of the attributes on <literal>column</literal> provide a
+ means of tailoring the DDL during automatic schema generation. The
+ <literal>read</literal> and <literal>write</literal> attributes allow
+ you to specify custom SQL that Hibernate will use to access the column's
+ value. For more on this, see the discussion of <link
+ linkend="mapping-column-read-and-write">column read and write
+ expressions</link>.</para>
- <para>
- The <literal>column</literal> and <literal>formula</literal> elements can even be combined
- within the same property or association mapping to express, for example, exotic join
- conditions.
- </para>
+ <para>The <literal>column</literal> and <literal>formula</literal>
+ elements can even be combined within the same property or association
+ mapping to express, for example, exotic join conditions.</para>
- <programlisting role="XML"><![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>
-
+ <programlisting role="XML"><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>
</section>
- <section id="mapping-declaration-import">
- <title>Import</title>
+ <section id="mapping-declaration-import">
+ <title>Import</title>
- <para>
- If your application has two persistent classes with the same name, and you do not want to
- specify the fully qualified package name in Hibernate queries, classes can be "imported"
- explicitly, rather than relying upon <literal>auto-import="true"</literal>. You can also import
- classes and interfaces that are not explicitly mapped:
- </para>
+ <para>If your application has two persistent classes with the same name,
+ and you do not want to specify the fully qualified package name in
+ Hibernate queries, classes can be "imported" explicitly, rather than
+ relying upon <literal>auto-import="true"</literal>. You can also import
+ classes and interfaces that are not explicitly mapped:</para>
- <programlisting role="XML"><![CDATA[<import class="java.lang.Object" rename="Universe"/>]]></programlisting>
+ <programlisting role="XML"><import class="java.lang.Object" rename="Universe"/></programlisting>
- <programlistingco role="XML">
- <areaspec>
- <area id="import1" coords="2"/>
- <area id="import2" coords="3"/>
- </areaspec>
- <programlisting><![CDATA[<import
+ <programlistingco role="XML">
+ <areaspec>
+ <area coords="2" id="import1" />
+
+ <area coords="3" id="import2" />
+ </areaspec>
+
+ <programlisting><import
class="ClassName"
rename="ShortName"
-/>]]></programlisting>
- <calloutlist>
- <callout arearefs="import1">
- <para>
- <literal>class</literal>: the fully qualified class name of any Java class.
- </para>
- </callout>
- <callout arearefs="import2">
- <para>
- <literal>rename</literal> (optional - defaults to the unqualified class name):
- a name that can be used in the query language.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+/></programlisting>
- </section>
+ <calloutlist>
+ <callout arearefs="import1">
+ <para><literal>class</literal>: the fully qualified class name of
+ any Java class.</para>
+ </callout>
- <section id="mapping-types-anymapping" revision="2">
- <title>Any</title>
+ <callout arearefs="import2">
+ <para><literal>rename</literal> (optional - defaults to the
+ unqualified class name): a name that can be used in the query
+ language.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ </section>
- <para>
- There is one more type of property mapping. The <literal><any></literal> mapping element
- defines a polymorphic association to classes from multiple tables. This type of mapping
- requires more than one column. The first column contains the type of the associated entity.
- The remaining columns contain the identifier. It is impossible to specify a foreign key constraint
- for this kind of association. This is not the usual way of mapping
- polymorphic associations and you should use this only in special cases. For example, for audit logs,
- user session data, etc.
- </para>
+ <section id="mapping-types-anymapping" revision="2">
+ <title>Any</title>
- <para>
- The <literal>meta-type</literal> attribute allows the application to specify a custom type that
- maps database column values to persistent classes that have identifier properties of the
- type specified by <literal>id-type</literal>. You must specify the mapping from values of
- the meta-type to class names.
- </para>
+ <para>There is one more type of property mapping. The
+ <literal><any></literal> mapping element defines a polymorphic
+ association to classes from multiple tables. This type of mapping
+ requires more than one column. The first column contains the type of the
+ associated entity. The remaining columns contain the identifier. It is
+ impossible to specify a foreign key constraint for this kind of
+ association. This is not the usual way of mapping polymorphic
+ associations and you should use this only in special cases. For example,
+ for audit logs, user session data, etc.</para>
- <programlisting role="XML"><![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>
+ <para>The <literal>meta-type</literal> attribute allows the application
+ to specify a custom type that maps database column values to persistent
+ classes that have identifier properties of the type specified by
+ <literal>id-type</literal>. You must specify the mapping from values of
+ the meta-type to class names.</para>
- <programlistingco role="XML">
- <areaspec>
- <area id="any1" coords="2"/>
- <area id="any2" coords="3"/>
- <area id="any3" coords="4"/>
- <area id="any4" coords="5"/>
- <area id="any5" coords="6"/>
- <area id="any6" coords="7"/>
- </areaspec>
- <programlisting><![CDATA[<any
+ <programlisting role="XML"><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 role="XML">
+ <areaspec>
+ <area coords="2" id="any1" />
+
+ <area coords="3" id="any2" />
+
+ <area coords="4" id="any3" />
+
+ <area coords="5" id="any4" />
+
+ <area coords="6" id="any5" />
+
+ <area coords="7" id="any6" />
+ </areaspec>
+
+ <programlisting><any
name="propertyName"
id-type="idtypename"
meta-type="metatypename"
cascade="cascade_style"
access="field|property|ClassName"
optimistic-lock="true|false"
->
- <meta-value ... />
- <meta-value ... />
+>
+ <meta-value ... />
+ <meta-value ... />
.....
- <column .... />
- <column .... />
+ <column .... />
+ <column .... />
.....
-</any>]]></programlisting>
- <calloutlist>
- <callout arearefs="any1">
- <para>
- <literal>name</literal>: the property name.
- </para>
- </callout>
- <callout arearefs="any2">
- <para>
- <literal>id-type</literal>: the identifier type.
- </para>
- </callout>
- <callout arearefs="any3">
- <para>
- <literal>meta-type</literal> (optional - defaults to <literal>string</literal>):
- any type that is allowed for a discriminator mapping.
- </para>
- </callout>
- <callout arearefs="any4">
- <para>
- <literal>cascade</literal> (optional- defaults to <literal>none</literal>):
- the cascade style.
- </para>
- </callout>
- <callout arearefs="any5">
- <para>
- <literal>access</literal> (optional - defaults to <literal>property</literal>): the
- strategy Hibernate uses for accessing the property value.
- </para>
- </callout>
- <callout arearefs="any6">
- <para>
- <literal>optimistic-lock</literal> (optional - defaults to <literal>true</literal>):
- specifies that updates to this property either do or do not require acquisition of the
- optimistic lock. It defines whether a version increment should occur if this
- property is dirty.
- </para>
- </callout>
- </calloutlist>
- </programlistingco>
+</any></programlisting>
- </section>
+ <calloutlist>
+ <callout arearefs="any1">
+ <para><literal>name</literal>: the property name.</para>
+ </callout>
+ <callout arearefs="any2">
+ <para><literal>id-type</literal>: the identifier type.</para>
+ </callout>
+
+ <callout arearefs="any3">
+ <para><literal>meta-type</literal> (optional - defaults to
+ <literal>string</literal>): any type that is allowed for a
+ discriminator mapping.</para>
+ </callout>
+
+ <callout arearefs="any4">
+ <para><literal>cascade</literal> (optional- defaults to
+ <literal>none</literal>): the cascade style.</para>
+ </callout>
+
+ <callout arearefs="any5">
+ <para><literal>access</literal> (optional - defaults to
+ <literal>property</literal>): the strategy Hibernate uses for
+ accessing the property value.</para>
+ </callout>
+
+ <callout arearefs="any6">
+ <para><literal>optimistic-lock</literal> (optional - defaults to
+ <literal>true</literal>): specifies that updates to this property
+ either do or do not require acquisition of the optimistic lock. It
+ defines whether a version increment should occur if this property
+ is dirty.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
</section>
+ </section>
- <section id="mapping-types">
- <title>Hibernate types</title>
+ <section id="mapping-types">
+ <title>Hibernate types</title>
- <section id="mapping-types-entitiesvalues" revision="1">
- <title>Entities and values</title>
+ <section id="mapping-types-entitiesvalues" revision="1">
+ <title>Entities and values</title>
- <para>
- In relation to the persistence service, Java language-level objects are classified
- into two groups:
- </para>
+ <para>In relation to the persistence service, Java language-level
+ objects are classified into two groups:</para>
- <para>
- An <emphasis>entity</emphasis> exists independently of any other objects holding
- references to the entity. Contrast this with the usual Java model, where an
- unreferenced object is garbage collected. Entities must be explicitly saved and
- deleted. Saves and deletions, however, can be <emphasis>cascaded</emphasis>
- from a parent entity to its children. This is different from the ODMG model of
- object persistence by reachability and corresponds more closely to how
- application objects are usually used in large systems. Entities support
- circular and shared references. They can also be versioned.
- </para>
+ <para>An <emphasis>entity</emphasis> exists independently of any other
+ objects holding references to the entity. Contrast this with the usual
+ Java model, where an unreferenced object is garbage collected. Entities
+ must be explicitly saved and deleted. Saves and deletions, however, can
+ be <emphasis>cascaded</emphasis> from a parent entity to its children.
+ This is different from the ODMG model of object persistence by
+ reachability and corresponds more closely to how application objects are
+ usually used in large systems. Entities support circular and shared
+ references. They can also be versioned.</para>
- <para>
- An entity's persistent state consists of references to other entities and
- instances of <emphasis>value</emphasis> types. Values are primitives:
- collections (not what is inside a collection), components and certain immutable
- objects. Unlike entities, values in particular collections and components,
- <emphasis>are</emphasis> persisted and deleted by reachability. Since value
- objects and primitives are persisted and deleted along with their containing
- entity, they cannot be independently versioned. Values have no independent
- identity, so they cannot be shared by two entities or collections.
- </para>
+ <para>An entity's persistent state consists of references to other
+ entities and instances of <emphasis>value</emphasis> types. Values are
+ primitives: collections (not what is inside a collection), components
+ and certain immutable objects. Unlike entities, values in particular
+ collections and components, <emphasis>are</emphasis> persisted and
+ deleted by reachability. Since value objects and primitives are
+ persisted and deleted along with their containing entity, they cannot be
+ independently versioned. Values have no independent identity, so they
+ cannot be shared by two entities or collections.</para>
- <para>
- Until now, we have been using the term "persistent class" to refer to
- entities. We will continue to do that. Not all
- user-defined classes with a persistent state, however, are entities. A
- <emphasis>component</emphasis> is a user-defined class with value semantics.
- A Java property of type <literal>java.lang.String</literal> also has value
- semantics. Given this definition, all types (classes) provided
- by the JDK have value type semantics in Java, while user-defined types can
- be mapped with entity or value type semantics. This decision is up to the
- application developer. An entity class in a domain model will normally have
- shared references to a single instance of that class, while composition or
- aggregation usually translates to a value type.
- </para>
+ <para>Until now, we have been using the term "persistent class" to refer
+ to entities. We will continue to do that. Not all user-defined classes
+ with a persistent state, however, are entities. A
+ <emphasis>component</emphasis> is a user-defined class with value
+ semantics. A Java property of type <literal>java.lang.String</literal>
+ also has value semantics. Given this definition, all types (classes)
+ provided by the JDK have value type semantics in Java, while
+ user-defined types can be mapped with entity or value type semantics.
+ This decision is up to the application developer. An entity class in a
+ domain model will normally have shared references to a single instance
+ of that class, while composition or aggregation usually translates to a
+ value type.</para>
- <para>
- We will revisit both concepts throughout this reference guide.
- </para>
+ <para>We will revisit both concepts throughout this reference
+ guide.</para>
- <para>
- The challenge is to map the Java type system, and the developers' definition of
- entities and value types, to the SQL/database type system. The bridge between
- both systems is provided by Hibernate. For entities,
- <literal><class></literal>, <literal><subclass></literal> and so on are used.
- For value types we use <literal><property></literal>,
- <literal><component></literal>etc., that usually have a <literal>type</literal>
- attribute. The value of this attribute is the name of a Hibernate
- <emphasis>mapping type</emphasis>. Hibernate provides a range of mappings for standard
- JDK value types out of the box. You can write your own mapping types and implement your own
- custom conversion strategies.
- </para>
+ <para>The challenge is to map the Java type system, and the developers'
+ definition of entities and value types, to the SQL/database type system.
+ The bridge between both systems is provided by Hibernate. For entities,
+ <literal><class></literal>, <literal><subclass></literal>
+ and so on are used. For value types we use
+ <literal><property></literal>,
+ <literal><component></literal>etc., that usually have a
+ <literal>type</literal> attribute. The value of this attribute is the
+ name of a Hibernate <emphasis>mapping type</emphasis>. Hibernate
+ provides a range of mappings for standard JDK value types out of the
+ box. You can write your own mapping types and implement your own custom
+ conversion strategies.</para>
- <para>
- With the exception of collections, all built-in Hibernate types support null semantics.
- </para>
+ <para>With the exception of collections, all built-in Hibernate types
+ support null semantics.</para>
+ </section>
- </section>
+ <section id="mapping-types-basictypes" revision="3">
+ <title>Basic value types</title>
- <section id="mapping-types-basictypes" revision="3">
- <title>Basic value types</title>
+ <para>The built-in <emphasis>basic mapping types</emphasis> can be
+ roughly categorized into the following: <variablelist>
+ <varlistentry>
+ <term><literal>integer, long, short, float, double, character,
+ byte, boolean, yes_no, true_false</literal></term>
- <para>
- The built-in <emphasis>basic mapping types</emphasis> can be roughly categorized into the following:
+ <listitem>
+ <para>Type mappings from Java primitives or wrapper classes to
+ appropriate (vendor-specific) SQL column types.
+ <literal>boolean, yes_no</literal> and
+ <literal>true_false</literal> are all alternative encodings for
+ a Java <literal>boolean</literal> or
+ <literal>java.lang.Boolean</literal>.</para>
+ </listitem>
+ </varlistentry>
- <variablelist>
- <varlistentry>
- <term><literal>integer, long, short, float, double, character, byte,
- boolean, yes_no, true_false</literal></term>
- <listitem>
- <para>
- Type mappings from Java primitives or wrapper classes to appropriate
- (vendor-specific) SQL column types. <literal>boolean, yes_no</literal>
- and <literal>true_false</literal> are all alternative encodings for
- a Java <literal>boolean</literal> or <literal>java.lang.Boolean</literal>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>string</literal></term>
- <listitem>
- <para>
- A type mapping from <literal>java.lang.String</literal> to
- <literal>VARCHAR</literal> (or Oracle <literal>VARCHAR2</literal>).
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>date, time, timestamp</literal></term>
- <listitem>
- <para>
- Type mappings from <literal>java.util.Date</literal> and its subclasses
- to SQL types <literal>DATE</literal>, <literal>TIME</literal> and
- <literal>TIMESTAMP</literal> (or equivalent).
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>calendar, calendar_date</literal></term>
- <listitem>
- <para>
- Type mappings from <literal>java.util.Calendar</literal> to
- SQL types <literal>TIMESTAMP</literal> and <literal>DATE</literal>
- (or equivalent).
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>big_decimal, big_integer</literal></term>
- <listitem>
- <para>
- Type mappings from <literal>java.math.BigDecimal</literal> and
- <literal>java.math.BigInteger</literal> to <literal>NUMERIC</literal>
- (or Oracle <literal>NUMBER</literal>).
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>locale, timezone, currency</literal></term>
- <listitem>
- <para>
- Type mappings from <literal>java.util.Locale</literal>,
- <literal>java.util.TimeZone</literal> and
- <literal>java.util.Currency</literal>
- to <literal>VARCHAR</literal> (or Oracle <literal>VARCHAR2</literal>).
- Instances of <literal>Locale</literal> and <literal>Currency</literal> are
- mapped to their ISO codes. Instances of <literal>TimeZone</literal> are
- mapped to their <literal>ID</literal>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>class</literal></term>
- <listitem>
- <para>
- A type mapping from <literal>java.lang.Class</literal> to
- <literal>VARCHAR</literal> (or Oracle <literal>VARCHAR2</literal>).
- A <literal>Class</literal> is mapped to its fully qualified name.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>binary</literal></term>
- <listitem>
- <para>
- Maps byte arrays to an appropriate SQL binary type.
- </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.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>serializable</literal></term>
- <listitem>
- <para>
- Maps serializable Java types to an appropriate SQL binary type. You
- can also indicate the Hibernate type <literal>serializable</literal> with
- the name of a serializable Java class or interface that does not default
- to a basic type.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><literal>clob, blob</literal></term>
- <listitem>
- <para>
- Type mappings for the JDBC classes <literal>java.sql.Clob</literal> and
- <literal>java.sql.Blob</literal>. These types can be inconvenient for some
- applications, since the blob or clob object cannot be reused outside of
- a transaction. Driver support is patchy and inconsistent.
- </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>
- Type mappings for what are considered mutable Java types. This is where
- Hibernate makes certain optimizations appropriate only for immutable
- Java types, and the application treats the object as immutable. For
- example, you should not call <literal>Date.setTime()</literal> for an
- instance mapped as <literal>imm_timestamp</literal>. To change the
- value of the property, and have that change made persistent, the
- application must assign a new, nonidentical, object to the property.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
+ <varlistentry>
+ <term><literal>string</literal></term>
- </para>
+ <listitem>
+ <para>A type mapping from <literal>java.lang.String</literal> to
+ <literal>VARCHAR</literal> (or Oracle
+ <literal>VARCHAR2</literal>).</para>
+ </listitem>
+ </varlistentry>
- <para>
- Unique identifiers of entities and collections can be of any basic type except
- <literal>binary</literal>, <literal>blob</literal> and <literal>clob</literal>.
- Composite identifiers are also allowed. See below for more information.
- </para>
+ <varlistentry>
+ <term><literal>date, time, timestamp</literal></term>
- <para>
- The basic value types have corresponding <literal>Type</literal> constants defined on
- <literal>org.hibernate.Hibernate</literal>. For example, <literal>Hibernate.STRING</literal>
- represents the <literal>string</literal> type.
- </para>
+ <listitem>
+ <para>Type mappings from <literal>java.util.Date</literal> and
+ its subclasses to SQL types <literal>DATE</literal>,
+ <literal>TIME</literal> and <literal>TIMESTAMP</literal> (or
+ equivalent).</para>
+ </listitem>
+ </varlistentry>
- </section>
+ <varlistentry>
+ <term><literal>calendar, calendar_date</literal></term>
- <section id="mapping-types-custom" revision="2">
- <title>Custom value types</title>
+ <listitem>
+ <para>Type mappings from <literal>java.util.Calendar</literal>
+ to SQL types <literal>TIMESTAMP</literal> and
+ <literal>DATE</literal> (or equivalent).</para>
+ </listitem>
+ </varlistentry>
- <para>
- It is relatively easy for developers to create their own value types. For example,
- you might want to persist properties of type <literal>java.lang.BigInteger</literal>
- to <literal>VARCHAR</literal> columns. Hibernate does not provide a built-in type
- for this. Custom types are not limited to mapping a property, or collection element,
- to a single table column. So, for example, you might have a Java property
- <literal>getName()</literal>/<literal>setName()</literal> of type
- <literal>java.lang.String</literal> that is persisted to the columns
- <literal>FIRST_NAME</literal>, <literal>INITIAL</literal>, <literal>SURNAME</literal>.
- </para>
+ <varlistentry>
+ <term><literal>big_decimal, big_integer</literal></term>
- <para>
- To implement a custom type, implement either <literal>org.hibernate.UserType</literal>
- or <literal>org.hibernate.CompositeUserType</literal> and declare properties using the
- fully qualified classname of the type. View
- <literal>org.hibernate.test.DoubleStringType</literal> to see the kind of things that
- are possible.
- </para>
+ <listitem>
+ <para>Type mappings from <literal>java.math.BigDecimal</literal>
+ and <literal>java.math.BigInteger</literal> to
+ <literal>NUMERIC</literal> (or Oracle
+ <literal>NUMBER</literal>).</para>
+ </listitem>
+ </varlistentry>
- <programlisting role="XML"><![CDATA[<property name="twoStrings" type="org.hibernate.test.DoubleStringType">
- <column name="first_string"/>
- <column name="second_string"/>
-</property>]]></programlisting>
+ <varlistentry>
+ <term><literal>locale, timezone, currency</literal></term>
- <para>
- Notice the use of <literal><column></literal> tags to map a property to multiple
- columns.
- </para>
+ <listitem>
+ <para>Type mappings from <literal>java.util.Locale</literal>,
+ <literal>java.util.TimeZone</literal> and
+ <literal>java.util.Currency</literal> to
+ <literal>VARCHAR</literal> (or Oracle
+ <literal>VARCHAR2</literal>). Instances of
+ <literal>Locale</literal> and <literal>Currency</literal> are
+ mapped to their ISO codes. Instances of
+ <literal>TimeZone</literal> are mapped to their
+ <literal>ID</literal>.</para>
+ </listitem>
+ </varlistentry>
- <para>
- The <literal>CompositeUserType</literal>, <literal>EnhancedUserType</literal>,
- <literal>UserCollectionType</literal>, and <literal>UserVersionType</literal>
- interfaces provide support for more specialized uses.
- </para>
+ <varlistentry>
+ <term><literal>class</literal></term>
- <para>
- You can even supply parameters to a <literal>UserType</literal> in the mapping file. To
- do this, your <literal>UserType</literal> must implement the
- <literal>org.hibernate.usertype.ParameterizedType</literal> interface. To supply parameters
- to your custom type, you can use the <literal><type></literal> element in your mapping
- files.
- </para>
+ <listitem>
+ <para>A type mapping from <literal>java.lang.Class</literal> to
+ <literal>VARCHAR</literal> (or Oracle
+ <literal>VARCHAR2</literal>). A <literal>Class</literal> is
+ mapped to its fully qualified name.</para>
+ </listitem>
+ </varlistentry>
- <programlisting role="XML"><![CDATA[<property name="priority">
- <type name="com.mycompany.usertypes.DefaultValueIntegerType">
- <param name="default">0</param>
- </type>
-</property>]]></programlisting>
+ <varlistentry>
+ <term><literal>binary</literal></term>
- <para>
- The <literal>UserType</literal> can now retrieve the value for the parameter named
- <literal>default</literal> from the <literal>Properties</literal> object passed to it.
- </para>
+ <listitem>
+ <para>Maps byte arrays to an appropriate SQL binary type.</para>
+ </listitem>
+ </varlistentry>
- <para>
- If you regularly use a certain <literal>UserType</literal>, it is useful to define a
- shorter name for it. You can do this using the <literal><typedef></literal> element.
- Typedefs assign a name to a custom type, and can also contain a list of default
- parameter values if the type is parameterized.
- </para>
+ <varlistentry>
+ <term><literal>text</literal></term>
- <programlisting role="XML"><![CDATA[<typedef class="com.mycompany.usertypes.DefaultValueIntegerType" name="default_zero">
- <param name="default">0</param>
-</typedef>]]></programlisting>
+ <listitem>
+ <para>Maps long Java strings to a SQL <literal>CLOB</literal> or
+ <literal>TEXT</literal> type.</para>
+ </listitem>
+ </varlistentry>
- <programlisting role="XML"><![CDATA[<property name="priority" type="default_zero"/>]]></programlisting>
+ <varlistentry>
+ <term><literal>serializable</literal></term>
- <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>
+ <listitem>
+ <para>Maps serializable Java types to an appropriate SQL binary
+ type. You can also indicate the Hibernate type
+ <literal>serializable</literal> with the name of a serializable
+ Java class or interface that does not default to a basic
+ type.</para>
+ </listitem>
+ </varlistentry>
- <para>
- Even though Hibernate's rich range of built-in types and support for components means you
- will rarely need to use a custom type, it is
- considered good practice 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 be mapped
- as a component. One reason for this is abstraction. With a custom type, your mapping
- documents would be protected against changes to the way
- monetary values are represented.
- </para>
+ <varlistentry>
+ <term><literal>clob, blob</literal></term>
- </section>
+ <listitem>
+ <para>Type mappings for the JDBC classes
+ <literal>java.sql.Clob</literal> and
+ <literal>java.sql.Blob</literal>. These types can be
+ inconvenient for some applications, since the blob or clob
+ object cannot be reused outside of a transaction. Driver support
+ is patchy and inconsistent.</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>Type mappings for what are considered mutable Java types.
+ This is where Hibernate makes certain optimizations appropriate
+ only for immutable Java types, and the application treats the
+ object as immutable. For example, you should not call
+ <literal>Date.setTime()</literal> for an instance mapped as
+ <literal>imm_timestamp</literal>. To change the value of the
+ property, and have that change made persistent, the application
+ must assign a new, nonidentical, object to the property.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+
+ <para>Unique identifiers of entities and collections can be of any basic
+ type except <literal>binary</literal>, <literal>blob</literal> and
+ <literal>clob</literal>. Composite identifiers are also allowed. See
+ below for more information.</para>
+
+ <para>The basic value types have corresponding <literal>Type</literal>
+ constants defined on <literal>org.hibernate.Hibernate</literal>. For
+ example, <literal>Hibernate.STRING</literal> represents the
+ <literal>string</literal> type.</para>
</section>
- <section 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> to 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>
+ <section id="mapping-types-custom" revision="2">
+ <title>Custom value types</title>
- <programlisting><![CDATA[<class name="Contract" table="Contracts"
- entity-name="CurrentContract">
+ <para>It is relatively easy for developers to create their own value
+ types. For example, you might want to persist properties of type
+ <literal>java.lang.BigInteger</literal> to <literal>VARCHAR</literal>
+ columns. Hibernate does not provide a built-in type for this. Custom
+ types are not limited to mapping a property, or collection element, to a
+ single table column. So, for example, you might have a Java property
+ <literal>getName()</literal>/<literal>setName()</literal> of type
+ <literal>java.lang.String</literal> that is persisted to the columns
+ <literal>FIRST_NAME</literal>, <literal>INITIAL</literal>,
+ <literal>SURNAME</literal>.</para>
+
+ <para>To implement a custom type, implement either
+ <literal>org.hibernate.UserType</literal> or
+ <literal>org.hibernate.CompositeUserType</literal> and declare
+ properties using the fully qualified classname of the type. View
+ <literal>org.hibernate.test.DoubleStringType</literal> to see the kind
+ of things that are possible.</para>
+
+ <programlisting role="XML"><property name="twoStrings" type="org.hibernate.test.DoubleStringType">
+ <column name="first_string"/>
+ <column name="second_string"/>
+</property></programlisting>
+
+ <para>Notice the use of <literal><column></literal> tags to map a
+ property to multiple columns.</para>
+
+ <para>The <literal>CompositeUserType</literal>,
+ <literal>EnhancedUserType</literal>,
+ <literal>UserCollectionType</literal>, and
+ <literal>UserVersionType</literal> interfaces provide support for more
+ specialized uses.</para>
+
+ <para>You can even supply parameters to a <literal>UserType</literal> in
+ the mapping file. To do this, your <literal>UserType</literal> must
+ implement the
+ <literal>org.hibernate.usertype.ParameterizedType</literal> interface.
+ To supply parameters to your custom type, you can use the
+ <literal><type></literal> element in your mapping files.</para>
+
+ <programlisting role="XML"><property name="priority">
+ <type name="com.mycompany.usertypes.DefaultValueIntegerType">
+ <param name="default">0</param>
+ </type>
+</property></programlisting>
+
+ <para>The <literal>UserType</literal> can now retrieve the value for the
+ parameter named <literal>default</literal> from the
+ <literal>Properties</literal> object passed to it.</para>
+
+ <para>If you regularly use a certain <literal>UserType</literal>, it is
+ useful to define a shorter name for it. You can do this using the
+ <literal><typedef></literal> element. Typedefs assign a name to a
+ custom type, and can also contain a list of default parameter values if
+ the type is parameterized.</para>
+
+ <programlisting role="XML"><typedef class="com.mycompany.usertypes.DefaultValueIntegerType" name="default_zero">
+ <param name="default">0</param>
+</typedef></programlisting>
+
+ <programlisting role="XML"><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 rarely need to use a custom type, it is
+ considered good practice 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 be mapped as
+ a component. One reason for this is abstraction. With a custom type,
+ your mapping documents would be protected against changes to the way
+ monetary values are represented.</para>
+ </section>
+ </section>
+
+ <section 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> to 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><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>
+ <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">
+<class name="Contract" table="ContractHistory"
+ entity-name="HistoricalContract">
...
- <many-to-one name="currentContract"
+ <many-to-one name="currentContract"
column="currentContractId"
- entity-name="CurrentContract"/>
-</class>]]></programlisting>
+ entity-name="CurrentContract"/>
+</class></programlisting>
- <para>
- Associations are now specified using <literal>entity-name</literal> instead of
- <literal>class</literal>.
- </para>
+ <para>Associations are now specified using <literal>entity-name</literal>
+ instead of <literal>class</literal>.</para>
+ </section>
- </section>
+ <section id="mapping-quotedidentifiers">
+ <title>SQL quoted identifiers</title>
- <section id="mapping-quotedidentifiers">
- <title>SQL quoted identifiers</title>
- <para>
- You can 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>. This is usually double quotes, but the SQL
- Server uses brackets and MySQL uses backticks.
- </para>
+ <para>You can 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>. This is usually double quotes, but the SQL
+ Server uses brackets and MySQL uses backticks.</para>
- <programlisting role="XML"><![CDATA[<class name="LineItem" table="`Line Item`">
- <id name="id" column="`Item Id`"/><generator class="assigned"/></id>
- <property name="itemNumber" column="`Item #`"/>
+ <programlisting role="XML"><class name="LineItem" table="`Line Item`">
+ <id name="id" column="`Item Id`"/><generator class="assigned"/></id>
+ <property name="itemNumber" column="`Item #`"/>
...
-</class>]]></programlisting>
+</class></programlisting>
+ </section>
- </section>
+ <section id="mapping-alternatives">
+ <title>Metadata alternatives</title>
+ <para>XML does not suit all users so there are some alternative ways to
+ define O/R mapping metadata in Hibernate.</para>
- <section id="mapping-alternatives">
- <title>Metadata alternatives</title>
-
- <para>
- XML does not suit all users so there are some alternative ways to define O/R mapping metadata in Hibernate.
- </para>
-
<section id="mapping-xdoclet">
- <title>Using XDoclet markup</title>
+ <title>Using XDoclet markup</title>
- <para>
- Many Hibernate users prefer to embed mapping information directly in sourcecode using
- XDoclet <literal>@hibernate.tags</literal>. We do not cover this approach in this
- reference guide since it is considered part of XDoclet. However, we include the
- following example of the <literal>Cat</literal> class with XDoclet mappings:
- </para>
+ <para>Many Hibernate users prefer to embed mapping information directly
+ in sourcecode using XDoclet <literal>@hibernate.tags</literal>. We do
+ not cover this approach in this reference guide since it is considered
+ part of XDoclet. However, we include the following example of the
+ <literal>Cat</literal> class with XDoclet mappings:</para>
- <programlisting role="JAVA"><![CDATA[package eg;
+ <programlisting role="JAVA">package eg;
import java.util.Set;
import java.util.Date;
@@ -3451,33 +3534,31 @@
void setSex(char sex) {
this.sex=sex;
}
-}]]></programlisting>
+}</programlisting>
- <para>
- See the Hibernate website for more examples of XDoclet and Hibernate.
- </para>
-
+ <para>See the Hibernate website for more examples of XDoclet and
+ Hibernate.</para>
</section>
<section id="mapping-annotations" revision="2">
- <title>Using JDK 5.0 Annotations</title>
+ <title>Using JDK 5.0 Annotations</title>
- <para>
- JDK 5.0 introduced XDoclet-style annotations at the language level that are type-safe and
- checked at compile time. This mechanism 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>JDK 5.0 introduced XDoclet-style annotations at the language level
+ that are type-safe and checked at compile time. This mechanism 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>
+ <para>This is an example of a POJO class annotated as an EJB entity
+ bean:</para>
- <programlisting role="JAVA"><![CDATA[@Entity(access = AccessType.FIELD)
+ <programlisting role="JAVA">@Entity(access = AccessType.FIELD)
public class Customer implements Serializable {
@Id;
@@ -3495,141 +3576,133 @@
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="CUSTOMER_ID")
- Set<Order> orders;
+ Set<Order> orders;
// Getter/setter and business methods
-}]]></programlisting>
+}</programlisting>
- <note>
- <title>Note</title>
- <para>
- Support for JDK 5.0 Annotations (and JSR-220) is currently under development.
- Please refer to the Hibernate Annotations module for more details.
- </para>
- </note>
+ <note>
+ <title>Note</title>
+ <para>Support for JDK 5.0 Annotations (and JSR-220) is currently under
+ development. Please refer to the Hibernate Annotations module for more
+ details.</para>
+ </note>
</section>
- </section>
+ </section>
- <section id="mapping-generated" revision="1">
- <title>Generated properties</title>
- <para>
- Generated properties are properties that have their values generated by the
- database. Typically, Hibernate applications needed to <literal>refresh</literal>
- objects that contain any properties for which the database was generating values.
- Marking properties as generated, however, lets the application delegate this
- responsibility to Hibernate. When Hibernate issues an SQL INSERT
- or UPDATE for an entity that 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 <link linkend="mapping-declaration-version">versions</link>,
- <link linkend="mapping-declaration-timestamp">timestamps</link>, and
- <link linkend="mapping-declaration-property">simple properties</link>, can be marked as
- generated.
- </para>
- <para>
- <literal>never</literal> (the default): the given property value
- is not generated within the database.
- </para>
- <para>
- <literal>insert</literal>: the given property value is generated on
- insert, but is not regenerated on subsequent updates. Properties like created-date
- fall into this category. Even though
- <link linkend="mapping-declaration-version">version</link> and
- <link linkend="mapping-declaration-timestamp">timestamp</link> properties can
- be marked as generated, this option is not available.
- </para>
- <para>
- <literal>always</literal>: the property value is generated both
- on insert and on update.
- </para>
- </section>
+ <section id="mapping-generated" revision="1">
+ <title>Generated properties</title>
- <section id="mapping-column-read-and-write" revision="1">
- <title>Column read and write expressions</title>
- <para>
- Hibernate allows you to customize the SQL it uses to read and write the values
- of columns mapped to <link linkend="mapping-declaration-property">simple properties</link>.
- For example, if your database provides a set of data encryption functions, you can
- invoke them for individual columns like this:
- <programlisting role="XML"><![CDATA[<property name="creditCardNumber">
- <column
+ <para>Generated properties are properties that have their values generated
+ by the database. Typically, Hibernate applications needed to
+ <literal>refresh</literal> objects that contain any properties for which
+ the database was generating values. Marking properties as generated,
+ however, lets the application delegate this responsibility to Hibernate.
+ When Hibernate issues an SQL INSERT or UPDATE for an entity that 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 <link
+ linkend="mapping-declaration-version">versions</link>, <link
+ linkend="mapping-declaration-timestamp">timestamps</link>, and <link
+ linkend="mapping-declaration-property">simple properties</link>, can be
+ marked as generated.</para>
+
+ <para><literal>never</literal> (the default): the given property value is
+ not generated within the database.</para>
+
+ <para><literal>insert</literal>: the given property value is generated on
+ insert, but is not regenerated on subsequent updates. Properties like
+ created-date fall into this category. Even though <link
+ linkend="mapping-declaration-version">version</link> and <link
+ linkend="mapping-declaration-timestamp">timestamp</link> properties can be
+ marked as generated, this option is not available.</para>
+
+ <para><literal>always</literal>: the property value is generated both on
+ insert and on update.</para>
+ </section>
+
+ <section id="mapping-column-read-and-write" revision="1">
+ <title>Column read and write expressions</title>
+
+ <para>Hibernate allows you to customize the SQL it uses to read and write
+ the values of columns mapped to <link
+ linkend="mapping-declaration-property">simple properties</link>. For
+ example, if your database provides a set of data encryption functions, you
+ can invoke them for individual columns like this: <programlisting
+ role="XML"><property name="creditCardNumber">
+ <column
name="credit_card_num"
read="decrypt(credit_card_num)"
- write="encrypt(?)"/>
-</property>]]></programlisting>
- </para>
- <para>
- Hibernate applies the custom expressions automatically whenever the property is
- referenced in a query. This functionality is similar to a derived-property
- <literal>formula</literal> with two differences:
- <itemizedlist spacing="compact">
- <listitem>
- <para>
- The property is backed by one or more columns that are exported as part of automatic
- schema generation.
- </para>
- </listitem>
- <listitem>
- <para>
- The property is read-write, not read-only.
- </para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- The <literal>write</literal> expression, if specified, must contain exactly one '?' placeholder
- for the value.
- </para>
- </section>
+ write="encrypt(?)"/>
+</property></programlisting></para>
- <section id="mapping-database-object">
- <title>Auxiliary database objects</title>
- <para>
- Auxiliary database objects allow for the CREATE and DROP of arbitrary database objects. In conjunction with
- Hibernate's schema evolution tools, they have 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, any
- SQL command that can be run via a <literal>java.sql.Statement.execute()</literal>
- method is valid (for example, 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 in the mapping
- file:
- </para>
- <programlisting role="XML"><![CDATA[<hibernate-mapping>
+ <para>Hibernate applies the custom expressions automatically whenever the
+ property is referenced in a query. This functionality is similar to a
+ derived-property <literal>formula</literal> with two differences:
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>The property is backed by one or more columns that are
+ exported as part of automatic schema generation.</para>
+ </listitem>
+
+ <listitem>
+ <para>The property is read-write, not read-only.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>The <literal>write</literal> expression, if specified, must contain
+ exactly one '?' placeholder for the value.</para>
+ </section>
+
+ <section id="mapping-database-object">
+ <title>Auxiliary database objects</title>
+
+ <para>Auxiliary database objects allow for the CREATE and DROP of
+ arbitrary database objects. In conjunction with Hibernate's schema
+ evolution tools, they have 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, any SQL
+ command that can be run via a
+ <literal>java.sql.Statement.execute()</literal> method is valid (for
+ example, 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 in
+ the mapping file:</para>
+
+ <programlisting role="XML"><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 that constructs the
- CREATE and DROP commands. This custom class must implement the
- <literal>org.hibernate.mapping.AuxiliaryDatabaseObject</literal> interface.
- </para>
- <programlisting role="XML"><![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 that constructs the
+ CREATE and DROP commands. This custom class must implement the
+ <literal>org.hibernate.mapping.AuxiliaryDatabaseObject</literal>
+ interface.</para>
+
+ <programlisting role="XML"><hibernate-mapping>
...
- <database-object>
- <definition class="MyTriggerDefinition"/>
- </database-object>
-</hibernate-mapping>]]></programlisting>
- <para>
- Additionally, these database objects can be optionally scoped so that they only
- apply when certain dialects are used.
- </para>
- <programlisting role="XML"><![CDATA[<hibernate-mapping>
+ <database-object>
+ <definition class="MyTriggerDefinition"/>
+ </database-object>
+</hibernate-mapping></programlisting>
+
+ <para>Additionally, these database objects can be optionally scoped so
+ that they only apply when certain dialects are used.</para>
+
+ <programlisting role="XML"><hibernate-mapping>
...
- <database-object>
- <definition class="MyTriggerDefinition"/>
- <dialect-scope name="org.hibernate.dialect.Oracle9iDialect"/>
- <dialect-scope name="org.hibernate.dialect.Oracle10gDialect"/>
- </database-object>
-</hibernate-mapping>]]></programlisting>
- </section>
+ <database-object>
+ <definition class="MyTriggerDefinition"/>
+ <dialect-scope name="org.hibernate.dialect.Oracle9iDialect"/>
+ <dialect-scope name="org.hibernate.dialect.Oracle10gDialect"/>
+ </database-object>
+</hibernate-mapping></programlisting>
+ </section>
</chapter>
-
14 years