Hibernate SVN: r10660 - in branches/Branch_3_2/Hibernate3/src/org/hibernate: cfg mapping
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2006-10-30 21:18:40 -0500 (Mon, 30 Oct 2006)
New Revision: 10660
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/cfg/Configuration.java
branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/Constraint.java
branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/Index.java
branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/Table.java
branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/UniqueKey.java
Log:
HHH-2199 apply supportsNoNullUnique to UniqueKey
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/cfg/Configuration.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/cfg/Configuration.java 2006-10-30 16:19:10 UTC (rev 10659)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/cfg/Configuration.java 2006-10-31 02:18:40 UTC (rev 10660)
@@ -800,7 +800,8 @@
Iterator subIter = table.getUniqueKeyIterator();
while ( subIter.hasNext() ) {
UniqueKey uk = (UniqueKey) subIter.next();
- script.add( uk.sqlCreateString( dialect, mapping, defaultCatalog, defaultSchema ) );
+ String constraintString = uk.sqlCreateString( dialect, mapping, defaultCatalog, defaultSchema );
+ if (constraintString != null) script.add( constraintString );
}
}
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/Constraint.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/Constraint.java 2006-10-30 16:19:10 UTC (rev 10659)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/Constraint.java 2006-10-31 02:18:40 UTC (rev 10660)
@@ -11,6 +11,7 @@
/**
* A relational constraint.
+ *
* @author Gavin King
*/
public abstract class Constraint implements RelationalModel, Serializable {
@@ -22,63 +23,88 @@
public String getName() {
return name;
}
+
public void setName(String name) {
this.name = name;
}
+
public Iterator getColumnIterator() {
return columns.iterator();
}
+
public void addColumn(Column column) {
- if ( !columns.contains(column) ) columns.add(column);
+ if ( !columns.contains( column ) ) columns.add( column );
}
+
public void addColumns(Iterator columnIterator) {
while ( columnIterator.hasNext() ) {
Selectable col = (Selectable) columnIterator.next();
if ( !col.isFormula() ) addColumn( (Column) col );
}
}
+
/**
* @param column
* @return true if this constraint already contains a column with same name.
*/
public boolean containsColumn(Column column) {
- return columns.contains(column);
- }
+ return columns.contains( column );
+ }
+
public int getColumnSpan() {
return columns.size();
}
-
+
public Column getColumn(int i) {
- return (Column) columns.get(i);
+ return (Column) columns.get( i );
}
-
+
public Iterator columnIterator() {
return columns.iterator();
}
+
public Table getTable() {
return table;
}
+
public void setTable(Table table) {
this.table = table;
}
+ public boolean isGenerated(Dialect dialect) {
+ return true;
+ }
+
public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
- return "alter table " + getTable().getQualifiedName(dialect, defaultCatalog, defaultSchema) + " drop constraint " + getName();
+ if ( isGenerated( dialect ) ) {
+ return "alter table " + getTable()
+ .getQualifiedName( dialect, defaultCatalog, defaultSchema ) + " drop constraint " + getName();
+ }
+ else {
+ return null;
+ }
}
public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) {
- StringBuffer buf = new StringBuffer("alter table ")
- .append( getTable().getQualifiedName(dialect, defaultCatalog, defaultSchema) )
- .append( sqlConstraintString( dialect, getName(), defaultCatalog, defaultSchema ) );
- return buf.toString();
+ if ( isGenerated( dialect ) ) {
+ String constraintString = sqlConstraintString( dialect, getName(), defaultCatalog, defaultSchema );
+ StringBuffer buf = new StringBuffer( "alter table " )
+ .append( getTable().getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
+ .append( constraintString );
+ return buf.toString();
+ }
+ else {
+ return null;
+ }
}
-
+
public List getColumns() {
return columns;
}
- public abstract String sqlConstraintString(Dialect d, String constraintName, String defaultCatalog, String defaultSchema);
-
+ public abstract String sqlConstraintString(Dialect d, String constraintName, String defaultCatalog,
+ String defaultSchema);
+
public String toString() {
return getClass().getName() + '(' + getTable().getName() + getColumns() + ") as " + name;
}
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/Index.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/Index.java 2006-10-30 16:19:10 UTC (rev 10659)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/Index.java 2006-10-31 02:18:40 UTC (rev 10660)
@@ -13,6 +13,7 @@
/**
* A relational table index
+ *
* @author Gavin King
*/
public class Index implements RelationalModel, Serializable {
@@ -20,107 +21,120 @@
private Table table;
private List columns = new ArrayList();
private String name;
-
- public String sqlCreateString(Dialect dialect, Mapping mapping, String defaultCatalog, String defaultSchema)
+
+ public String sqlCreateString(Dialect dialect, Mapping mapping, String defaultCatalog, String defaultSchema)
throws HibernateException {
return buildSqlCreateIndexString(
- dialect,
- getName(),
- getTable(),
- getColumnIterator(),
- false,
- defaultCatalog,
+ dialect,
+ getName(),
+ getTable(),
+ getColumnIterator(),
+ false,
+ defaultCatalog,
defaultSchema
- );
+ );
}
-
- public static String buildSqlDropIndexString(
- Dialect dialect,
- Table table,
- String name,
- String defaultCatalog,
- String defaultSchema
- ) {
- return "drop index " +
- StringHelper.qualify(
- table.getQualifiedName(dialect, defaultCatalog, defaultSchema),
- name
- );
- }
- public static String buildSqlCreateIndexString(
- Dialect dialect,
- String name,
- Table table,
- Iterator columns,
- boolean unique,
- String defaultCatalog,
- String defaultSchema
- ) {
- StringBuffer buf = new StringBuffer("create")
- .append( unique ? " unique" : "")
- .append(" index ")
- .append( dialect.qualifyIndexName() ? name : StringHelper.unqualify(name) )
- .append(" on ")
- .append( table.getQualifiedName(dialect, defaultCatalog, defaultSchema) )
- .append(" (");
- Iterator iter = columns;
- while ( iter.hasNext() ) {
- buf.append( ( (Column) iter.next() ).getQuotedName(dialect) );
- if ( iter.hasNext() ) buf.append(", ");
- }
- buf.append(")");
- return buf.toString();
- }
-
+ public static String buildSqlDropIndexString(
+ Dialect dialect,
+ Table table,
+ String name,
+ String defaultCatalog,
+ String defaultSchema
+ ) {
+ return "drop index " +
+ StringHelper.qualify(
+ table.getQualifiedName( dialect, defaultCatalog, defaultSchema ),
+ name
+ );
+ }
+
+ public static String buildSqlCreateIndexString(
+ Dialect dialect,
+ String name,
+ Table table,
+ Iterator columns,
+ boolean unique,
+ String defaultCatalog,
+ String defaultSchema
+ ) {
+ //TODO handle supportsNotNullUnique=false, but such a case does not exist in the wild so far
+ StringBuffer buf = new StringBuffer( "create" )
+ .append( unique ?
+ " unique" :
+ "" )
+ .append( " index " )
+ .append( dialect.qualifyIndexName() ?
+ name :
+ StringHelper.unqualify( name ) )
+ .append( " on " )
+ .append( table.getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
+ .append( " (" );
+ Iterator iter = columns;
+ while ( iter.hasNext() ) {
+ buf.append( ( (Column) iter.next() ).getQuotedName( dialect ) );
+ if ( iter.hasNext() ) buf.append( ", " );
+ }
+ buf.append( ")" );
+ return buf.toString();
+ }
+
+
// Used only in Table for sqlCreateString (but commented out at the moment)
public String sqlConstraintString(Dialect dialect) {
- StringBuffer buf = new StringBuffer(" index (");
+ StringBuffer buf = new StringBuffer( " index (" );
Iterator iter = getColumnIterator();
while ( iter.hasNext() ) {
- buf.append( ( (Column) iter.next() ).getQuotedName(dialect) );
- if ( iter.hasNext() ) buf.append(", ");
+ buf.append( ( (Column) iter.next() ).getQuotedName( dialect ) );
+ if ( iter.hasNext() ) buf.append( ", " );
}
- return buf.append(')').toString();
+ return buf.append( ')' ).toString();
}
public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
- return "drop index " +
- StringHelper.qualify(
- table.getQualifiedName(dialect, defaultCatalog, defaultSchema),
+ return "drop index " +
+ StringHelper.qualify(
+ table.getQualifiedName( dialect, defaultCatalog, defaultSchema ),
name
- );
+ );
}
public Table getTable() {
return table;
}
+
public void setTable(Table table) {
this.table = table;
}
+
public int getColumnSpan() {
return columns.size();
}
+
public Iterator getColumnIterator() {
return columns.iterator();
}
+
public void addColumn(Column column) {
- if ( !columns.contains(column) ) columns.add(column);
+ if ( !columns.contains( column ) ) columns.add( column );
}
+
public void addColumns(Iterator extraColumns) {
while ( extraColumns.hasNext() ) addColumn( (Column) extraColumns.next() );
}
+
/**
* @param column
* @return true if this constraint already contains a column with same name.
*/
public boolean containsColumn(Column column) {
- return columns.contains(column);
- }
-
+ return columns.contains( column );
+ }
+
public String getName() {
return name;
}
+
public void setName(String name) {
this.name = name;
}
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/Table.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/Table.java 2006-10-30 16:19:10 UTC (rev 10659)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/Table.java 2006-10-31 02:18:40 UTC (rev 10660)
@@ -51,15 +51,15 @@
String referencedClassName;
List columns;
List referencedColumns;
-
+
ForeignKeyKey(List columns, String referencedClassName, List referencedColumns) {
this.referencedClassName = referencedClassName;
this.columns = new ArrayList();
this.columns.addAll( columns );
- if(referencedColumns!=null) {
+ if ( referencedColumns != null ) {
this.referencedColumns = new ArrayList();
- this.referencedColumns.addAll( referencedColumns );
- }
+ this.referencedColumns.addAll( referencedColumns );
+ }
else {
this.referencedColumns = CollectionHelper.EMPTY_LIST;
}
@@ -70,28 +70,33 @@
}
public boolean equals(Object other) {
- ForeignKeyKey fkk = ( ForeignKeyKey ) other;
+ ForeignKeyKey fkk = (ForeignKeyKey) other;
return fkk.columns.equals( columns ) &&
- fkk.referencedClassName.equals( referencedClassName ) && fkk.referencedColumns.equals( referencedColumns );
+ fkk.referencedClassName.equals( referencedClassName ) && fkk.referencedColumns
+ .equals( referencedColumns );
}
}
public Table() {
uniqueInteger = tableCounter++;
}
-
+
public Table(String name) {
this();
- setName(name);
+ setName( name );
}
public String getQualifiedName(Dialect dialect, String defaultCatalog, String defaultSchema) {
if ( subselect != null ) {
return "( " + subselect + " )";
}
- String quotedName = getQuotedName(dialect);
- String usedSchema = schema == null ? defaultSchema : getQuotedSchema(dialect);
- String usedCatalog = catalog == null ? defaultCatalog : catalog;
+ String quotedName = getQuotedName( dialect );
+ String usedSchema = schema == null ?
+ defaultSchema :
+ getQuotedSchema( dialect );
+ String usedCatalog = catalog == null ?
+ defaultCatalog :
+ catalog;
return qualify( usedCatalog, usedSchema, quotedName );
}
@@ -110,32 +115,36 @@
return name;
}
- /** returns quoted name as it would be in the mapping file. */
+ /**
+ * returns quoted name as it would be in the mapping file.
+ */
public String getQuotedName() {
return quoted ?
"`" + name + "`" :
name;
}
-
+
public String getQuotedName(Dialect dialect) {
return quoted ?
dialect.openQuote() + name + dialect.closeQuote() :
name;
}
- /** returns quoted name as it is in the mapping file. */
+ /**
+ * returns quoted name as it is in the mapping file.
+ */
public String getQuotedSchema() {
return schemaQuoted ?
"`" + schema + "`" :
schema;
}
-
+
public String getQuotedSchema(Dialect dialect) {
return schemaQuoted ?
dialect.openQuote() + schema + dialect.closeQuote() :
schema;
}
-
+
public void setName(String name) {
if ( name.charAt( 0 ) == '`' ) {
quoted = true;
@@ -157,7 +166,7 @@
return null;
}
- Column myColumn = ( Column ) columns.get( column.getCanonicalName() );
+ Column myColumn = (Column) columns.get( column.getCanonicalName() );
return column.equals( myColumn ) ?
myColumn :
@@ -169,11 +178,11 @@
for ( int i = 0; i < n - 1; i++ ) {
iter.next();
}
- return ( Column ) iter.next();
+ return (Column) iter.next();
}
public void addColumn(Column column) {
- Column old = ( Column ) getColumn( column );
+ Column old = (Column) getColumn( column );
if ( old == null ) {
columns.put( column.getCanonicalName(), column );
column.uniqueInteger = columns.size();
@@ -202,9 +211,9 @@
public Iterator getUniqueKeyIterator() {
return getUniqueKeys().values().iterator();
}
-
+
Map getUniqueKeys() {
- if ( uniqueKeys.size() > 1) {
+ if ( uniqueKeys.size() > 1 ) {
//deduplicate unique constraints sharing the same columns
//this is needed by Hibernate Annotations since it creates automagically
// unique constraints for the user
@@ -219,12 +228,13 @@
Iterator tempUks = finalUniqueKeys.entrySet().iterator();
while ( tempUks.hasNext() ) {
final UniqueKey currentUk = (UniqueKey) ( (Map.Entry) tempUks.next() ).getValue();
- if ( currentUk.getColumns().containsAll( columns ) && columns.containsAll( currentUk.getColumns() ) ) {
+ if ( currentUk.getColumns().containsAll( columns ) && columns
+ .containsAll( currentUk.getColumns() ) ) {
skip = true;
break;
}
}
- if (! skip) finalUniqueKeys.put(entry.getKey(), uk);
+ if ( !skip ) finalUniqueKeys.put( entry.getKey(), uk );
}
return finalUniqueKeys;
}
@@ -232,11 +242,11 @@
return uniqueKeys;
}
}
-
+
public void validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo) {
Iterator iter = getColumnIterator();
while ( iter.hasNext() ) {
- Column col = ( Column ) iter.next();
+ Column col = (Column) iter.next();
ColumnMetadata columnInfo = tableInfo.getColumnMetadata( col.getName() );
@@ -244,21 +254,22 @@
throw new HibernateException( "Missing column: " + col.getName() );
}
else {
- final boolean typesMatch = col.getSqlType(dialect, mapping)
+ final boolean typesMatch = col.getSqlType( dialect, mapping )
.startsWith( columnInfo.getTypeName().toLowerCase() )
- || columnInfo.getTypeCode() == col.getSqlTypeCode(mapping);
+ || columnInfo.getTypeCode() == col.getSqlTypeCode( mapping );
if ( !typesMatch ) {
throw new HibernateException(
- "Wrong column type: " + col.getName() +
- ", expected: " + col.getSqlType(dialect, mapping)
- );
+ "Wrong column type: " + col.getName() +
+ ", expected: " + col.getSqlType( dialect, mapping )
+ );
}
}
}
-
+
}
- public Iterator sqlAlterStrings(Dialect dialect, Mapping p, TableMetadata tableInfo, String defaultCatalog, String defaultSchema)
+ public Iterator sqlAlterStrings(Dialect dialect, Mapping p, TableMetadata tableInfo, String defaultCatalog,
+ String defaultSchema)
throws HibernateException {
StringBuffer root = new StringBuffer( "alter table " )
@@ -269,7 +280,7 @@
Iterator iter = getColumnIterator();
List results = new ArrayList();
while ( iter.hasNext() ) {
- Column column = ( Column ) iter.next();
+ Column column = (Column) iter.next();
ColumnMetadata columnInfo = tableInfo.getColumnMetadata( column.getName() );
@@ -280,27 +291,27 @@
.append( column.getQuotedName( dialect ) )
.append( ' ' )
.append( column.getSqlType( dialect, p ) );
-
+
String defaultValue = column.getDefaultValue();
- if (defaultValue!=null) {
- alter.append( " default ").append(defaultValue);
-
+ if ( defaultValue != null ) {
+ alter.append( " default " ).append( defaultValue );
+
if ( column.isNullable() ) {
alter.append( dialect.getNullColumnString() );
}
else {
alter.append( " not null" );
}
-
+
}
-
- boolean useUniqueConstraint = column.isUnique() &&
- dialect.supportsUnique() &&
+
+ boolean useUniqueConstraint = column.isUnique() &&
+ dialect.supportsUnique() &&
( !column.isNullable() || dialect.supportsNotNullUnique() );
if ( useUniqueConstraint ) {
alter.append( " unique" );
}
-
+
if ( column.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
alter.append( " check(" )
.append( column.getCheckConstraint() )
@@ -319,9 +330,9 @@
return results.iterator();
}
-
+
public boolean hasPrimaryKey() {
- return getPrimaryKey()!=null;
+ return getPrimaryKey() != null;
}
public String sqlTemporaryTableCreateString(Dialect dialect, Mapping mapping) throws HibernateException {
@@ -330,8 +341,8 @@
.append( name )
.append( " (" );
Iterator itr = getColumnIterator();
- while( itr.hasNext() ) {
- final Column column = ( Column ) itr.next();
+ while ( itr.hasNext() ) {
+ final Column column = (Column) itr.next();
buffer.append( column.getQuotedName( dialect ) ).append( ' ' );
buffer.append( column.getSqlType( dialect, mapping ) );
if ( column.isNullable() ) {
@@ -352,20 +363,20 @@
public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema)
throws HibernateException {
StringBuffer buf = new StringBuffer( "create table " )
- .append( getQualifiedName( dialect , defaultCatalog, defaultSchema ) )
+ .append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
.append( " (" );
- boolean identityColumn = idValue != null && idValue.isIdentityColumn(dialect);
+ boolean identityColumn = idValue != null && idValue.isIdentityColumn( dialect );
// Try to find out the name of the primary key to create it as identity if the IdentityGenerator is used
String pkname = null;
if ( hasPrimaryKey() && identityColumn ) {
- pkname = ( ( Column ) getPrimaryKey().getColumnIterator().next() ).getQuotedName( dialect );
+ pkname = ( (Column) getPrimaryKey().getColumnIterator().next() ).getQuotedName( dialect );
}
Iterator iter = getColumnIterator();
while ( iter.hasNext() ) {
- Column col = ( Column ) iter.next();
+ Column col = (Column) iter.next();
buf.append( col.getQuotedName( dialect ) )
.append( ' ' );
@@ -383,20 +394,20 @@
buf.append( col.getSqlType( dialect, p ) );
String defaultValue = col.getDefaultValue();
- if (defaultValue!=null) {
- buf.append( " default ").append(defaultValue);
+ if ( defaultValue != null ) {
+ buf.append( " default " ).append( defaultValue );
}
-
+
if ( col.isNullable() ) {
buf.append( dialect.getNullColumnString() );
}
else {
buf.append( " not null" );
}
-
+
}
- boolean useUniqueConstraint = col.isUnique() &&
+ boolean useUniqueConstraint = col.isUnique() &&
( !col.isNullable() || dialect.supportsNotNullUnique() );
if ( useUniqueConstraint ) {
if ( dialect.supportsUnique() ) {
@@ -407,16 +418,16 @@
uk.addColumn( col );
}
}
-
+
if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
buf.append( " check (" )
.append( col.getCheckConstraint() )
.append( ")" );
}
-
+
String columnComment = col.getComment();
- if (columnComment!=null) {
- buf.append( dialect.getColumnComment(columnComment) );
+ if ( columnComment != null ) {
+ buf.append( dialect.getColumnComment( columnComment ) );
}
if ( iter.hasNext() ) {
@@ -426,15 +437,17 @@
}
if ( hasPrimaryKey() ) {
buf.append( ", " )
- .append( getPrimaryKey().sqlConstraintString( dialect ) );
+ .append( getPrimaryKey().sqlConstraintString( dialect ) );
}
if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
Iterator ukiter = getUniqueKeyIterator();
while ( ukiter.hasNext() ) {
- UniqueKey uk = ( UniqueKey ) ukiter.next();
- buf.append( ", " )
- .append( uk.sqlConstraintString( dialect ) );
+ UniqueKey uk = (UniqueKey) ukiter.next();
+ String constraint = uk.sqlConstraintString( dialect );
+ if ( constraint != null ) {
+ buf.append( ", " ).append( constraint );
+ }
}
}
/*Iterator idxiter = getIndexIterator();
@@ -447,17 +460,17 @@
Iterator chiter = checkConstraints.iterator();
while ( chiter.hasNext() ) {
buf.append( ", check (" )
- .append( chiter.next() )
- .append( ')' );
+ .append( chiter.next() )
+ .append( ')' );
}
}
-
+
buf.append( ')' );
if ( comment != null ) {
buf.append( dialect.getTableComment( comment ) );
}
-
+
return buf.append( dialect.getTableTypeString() ).toString();
}
@@ -466,7 +479,7 @@
if ( dialect.supportsIfExistsBeforeTableName() ) {
buf.append( "if exists " );
}
- buf.append( getQualifiedName( dialect , defaultCatalog, defaultSchema ) )
+ buf.append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
.append( dialect.getCascadeConstraintsString() );
if ( dialect.supportsIfExistsAfterTableName() ) {
buf.append( " if exists" );
@@ -483,9 +496,9 @@
}
public Index getOrCreateIndex(String indexName) {
-
- Index index = ( Index ) indexes.get( indexName );
+ Index index = (Index) indexes.get( indexName );
+
if ( index == null ) {
index = new Index();
index.setName( indexName );
@@ -497,11 +510,11 @@
}
public Index getIndex(String indexName) {
- return ( Index ) indexes.get( indexName );
+ return (Index) indexes.get( indexName );
}
public Index addIndex(Index index) {
- Index current = ( Index ) indexes.get( index.getName() );
+ Index current = (Index) indexes.get( index.getName() );
if ( current != null ) {
throw new MappingException( "Index " + index.getName() + " already exists!" );
}
@@ -510,7 +523,7 @@
}
public UniqueKey addUniqueKey(UniqueKey uniqueKey) {
- UniqueKey current = ( UniqueKey ) uniqueKeys.get( uniqueKey.getName() );
+ UniqueKey current = (UniqueKey) uniqueKeys.get( uniqueKey.getName() );
if ( current != null ) {
throw new MappingException( "UniqueKey " + uniqueKey.getName() + " already exists!" );
}
@@ -528,9 +541,9 @@
public UniqueKey getUniqueKey(String keyName) {
return (UniqueKey) uniqueKeys.get( keyName );
}
-
+
public UniqueKey getOrCreateUniqueKey(String keyName) {
- UniqueKey uk = ( UniqueKey ) uniqueKeys.get( keyName );
+ UniqueKey uk = (UniqueKey) uniqueKeys.get( keyName );
if ( uk == null ) {
uk = new UniqueKey();
@@ -545,20 +558,21 @@
}
public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName) {
- return createForeignKey(keyName, keyColumns, referencedEntityName, null);
+ return createForeignKey( keyName, keyColumns, referencedEntityName, null );
}
-
- public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName, List referencedColumns) {
+
+ public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName,
+ List referencedColumns) {
Object key = new ForeignKeyKey( keyColumns, referencedEntityName, referencedColumns );
- ForeignKey fk = ( ForeignKey ) foreignKeys.get( key );
+ ForeignKey fk = (ForeignKey) foreignKeys.get( key );
if ( fk == null ) {
fk = new ForeignKey();
if ( keyName != null ) {
fk.setName( keyName );
}
else {
- fk.setName( "FK" + uniqueColumnString( keyColumns.iterator(), referencedEntityName ) );
+ fk.setName( "FK" + uniqueColumnString( keyColumns.iterator(), referencedEntityName ) );
//TODO: add referencedClass to disambiguate to FKs on the same
// columns, pointing to different tables
}
@@ -575,11 +589,12 @@
fk.setName( keyName );
}
- return fk; }
+ return fk;
+ }
-
+
public String uniqueColumnString(Iterator iterator) {
- return uniqueColumnString(iterator, null);
+ return uniqueColumnString( iterator, null );
}
public String uniqueColumnString(Iterator iterator, String referencedEntityName) {
@@ -599,7 +614,7 @@
}
public void setSchema(String schema) {
- if ( schema!=null && schema.charAt( 0 ) == '`' ) {
+ if ( schema != null && schema.charAt( 0 ) == '`' ) {
schemaQuoted = true;
this.schema = schema.substring( 1, schema.length() - 1 );
}
@@ -631,7 +646,7 @@
public boolean isSchemaQuoted() {
return schemaQuoted;
}
-
+
public boolean isQuoted() {
return quoted;
}
@@ -658,14 +673,14 @@
public String toString() {
StringBuffer buf = new StringBuffer().append( getClass().getName() )
- .append('(');
+ .append( '(' );
if ( getCatalog() != null ) {
buf.append( getCatalog() + "." );
}
if ( getSchema() != null ) {
buf.append( getSchema() + "." );
}
- buf.append( getName() ).append(')');
+ buf.append( getName() ).append( ')' );
return buf.toString();
}
@@ -684,11 +699,11 @@
public boolean isAbstractUnionTable() {
return hasDenormalizedTables() && isAbstract;
}
-
+
public boolean hasDenormalizedTables() {
return hasDenormalizedTables;
}
-
+
void setHasDenormalizedTables() {
hasDenormalizedTables = true;
}
@@ -720,29 +735,29 @@
public Iterator sqlCommentStrings(Dialect dialect, String defaultCatalog, String defaultSchema) {
List comments = new ArrayList();
if ( dialect.supportsCommentOn() ) {
- String tableName = getQualifiedName( dialect , defaultCatalog, defaultSchema );
- if ( comment!=null ) {
+ String tableName = getQualifiedName( dialect, defaultCatalog, defaultSchema );
+ if ( comment != null ) {
StringBuffer buf = new StringBuffer()
- .append("comment on table ")
- .append( tableName )
- .append(" is '")
- .append(comment)
- .append("'");
+ .append( "comment on table " )
+ .append( tableName )
+ .append( " is '" )
+ .append( comment )
+ .append( "'" );
comments.add( buf.toString() );
}
Iterator iter = getColumnIterator();
while ( iter.hasNext() ) {
Column column = (Column) iter.next();
String columnComment = column.getComment();
- if ( columnComment!=null ) {
+ if ( columnComment != null ) {
StringBuffer buf = new StringBuffer()
- .append("comment on column ")
- .append( tableName )
- .append('.')
- .append( column.getQuotedName(dialect) )
- .append(" is '")
- .append(columnComment)
- .append("'");
+ .append( "comment on column " )
+ .append( tableName )
+ .append( '.' )
+ .append( column.getQuotedName( dialect ) )
+ .append( " is '" )
+ .append( columnComment )
+ .append( "'" );
comments.add( buf.toString() );
}
}
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/UniqueKey.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/UniqueKey.java 2006-10-30 16:19:10 UTC (rev 10659)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/UniqueKey.java 2006-10-31 02:18:40 UTC (rev 10660)
@@ -9,48 +9,74 @@
/**
* A relational unique key constraint
+ *
* @author Gavin King
*/
public class UniqueKey extends Constraint {
public String sqlConstraintString(Dialect dialect) {
- StringBuffer buf = new StringBuffer("unique (");
+ StringBuffer buf = new StringBuffer( "unique (" );
Iterator iter = getColumnIterator();
+ boolean nullable = false;
while ( iter.hasNext() ) {
- buf.append( ( (Column) iter.next() ).getQuotedName(dialect) );
- if ( iter.hasNext() ) buf.append(", ");
+ Column column = (Column) iter.next();
+ if ( !nullable && column.isNullable() ) nullable = true;
+ buf.append( column.getQuotedName( dialect ) );
+ if ( iter.hasNext() ) buf.append( ", " );
}
- return buf.append(')').toString();
+ //do not add unique constraint on DB not supporting unique and nullable columns
+ return !nullable || dialect.supportsNotNullUnique() ?
+ buf.append( ')' ).toString() :
+ null;
}
- public String sqlConstraintString(Dialect dialect, String constraintName, String defaultCatalog, String defaultSchema) {
+ public String sqlConstraintString(Dialect dialect, String constraintName, String defaultCatalog,
+ String defaultSchema) {
StringBuffer buf = new StringBuffer(
- dialect.getAddPrimaryKeyConstraintString(constraintName)
- ).append('(');
+ dialect.getAddPrimaryKeyConstraintString( constraintName )
+ ).append( '(' );
Iterator iter = getColumnIterator();
+ boolean nullable = false;
while ( iter.hasNext() ) {
- buf.append( ( (Column) iter.next() ).getQuotedName(dialect) );
- if ( iter.hasNext() ) buf.append(", ");
+ Column column = (Column) iter.next();
+ if ( !nullable && column.isNullable() ) nullable = true;
+ buf.append( column.getQuotedName( dialect ) );
+ if ( iter.hasNext() ) buf.append( ", " );
}
- return StringHelper.replace( buf.append(')').toString(), "primary key", "unique" ); //TODO: improve this hack!
+ return !nullable || dialect.supportsNotNullUnique() ?
+ StringHelper.replace( buf.append( ')' ).toString(), "primary key", "unique" ) :
+ //TODO: improve this hack!
+ null;
}
-
+
public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) {
- if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
- return super.sqlCreateString(dialect, p, defaultCatalog, defaultSchema);
- }
- else {
- return Index.buildSqlCreateIndexString(dialect, getName(), getTable(), getColumnIterator(), true, defaultCatalog, defaultSchema);
- }
- }
-
- public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
- if( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
- return super.sqlDropString(dialect, defaultCatalog, defaultSchema);
- }
- else {
- return Index.buildSqlDropIndexString(dialect, getTable(), getName(), defaultCatalog, defaultSchema);
- }
- }
-
+ if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
+ return super.sqlCreateString( dialect, p, defaultCatalog, defaultSchema );
+ }
+ else {
+ return Index.buildSqlCreateIndexString( dialect, getName(), getTable(), getColumnIterator(), true,
+ defaultCatalog, defaultSchema );
+ }
+ }
+
+ public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
+ if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
+ return super.sqlDropString( dialect, defaultCatalog, defaultSchema );
+ }
+ else {
+ return Index.buildSqlDropIndexString( dialect, getTable(), getName(), defaultCatalog, defaultSchema );
+ }
+ }
+
+ public boolean isGenerated(Dialect dialect) {
+ if ( dialect.supportsNotNullUnique() ) return true;
+ Iterator iter = getColumnIterator();
+ while ( iter.hasNext() ) {
+ if ( ( (Column) iter.next() ).isNullable() ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
}
18 years, 1 month
Hibernate SVN: r10659 - in trunk/Hibernate3: src/org/hibernate/cfg src/org/hibernate/mapping test/org/hibernate/test/legacy
by hibernate-commits@lists.jboss.org
Author: max.andersen(a)jboss.com
Date: 2006-10-30 11:19:10 -0500 (Mon, 30 Oct 2006)
New Revision: 10659
Modified:
trunk/Hibernate3/src/org/hibernate/cfg/HbmBinder.java
trunk/Hibernate3/src/org/hibernate/mapping/MetaAttribute.java
trunk/Hibernate3/test/org/hibernate/test/legacy/NonReflectiveBinderTest.java
trunk/Hibernate3/test/org/hibernate/test/legacy/Wicked.hbm.xml
Log:
HBX-621 & HBX-793 meta attribute were doing a concat instead of an override.
(merge from branch_3_2)
Modified: trunk/Hibernate3/src/org/hibernate/cfg/HbmBinder.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/cfg/HbmBinder.java 2006-10-30 15:46:48 UTC (rev 10658)
+++ trunk/Hibernate3/src/org/hibernate/cfg/HbmBinder.java 2006-10-30 16:19:10 UTC (rev 10659)
@@ -2861,13 +2861,9 @@
if ( meta == null ) {
meta = new MetaAttribute( name );
map.put( name, meta );
- } else if (meta == inheritedAttribute) { // to prevent mutation of the inherited meta attribute.
+ } else if (meta == inheritedAttribute) { // overriding inherited meta attribute. HBX-621 & HBX-793
meta = new MetaAttribute( name );
- map.put( name, meta );
- java.util.List values = inheritedAttribute.getValues();
- for (Iterator iterator = values.iterator(); iterator.hasNext();) {
- meta.addValue( (String) iterator.next() );
- }
+ map.put( name, meta );
}
meta.addValue( metaNode.getText() );
}
Modified: trunk/Hibernate3/src/org/hibernate/mapping/MetaAttribute.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/mapping/MetaAttribute.java 2006-10-30 15:46:48 UTC (rev 10658)
+++ trunk/Hibernate3/src/org/hibernate/mapping/MetaAttribute.java 2006-10-30 16:19:10 UTC (rev 10659)
@@ -30,7 +30,9 @@
}
public String getValue() {
- if ( values.size()!=1 ) throw new IllegalStateException("no unique value");
+ if ( values.size()!=1 ) {
+ throw new IllegalStateException("no unique value");
+ }
return (String) values.get(0);
}
Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/NonReflectiveBinderTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/legacy/NonReflectiveBinderTest.java 2006-10-30 15:46:48 UTC (rev 10658)
+++ trunk/Hibernate3/test/org/hibernate/test/legacy/NonReflectiveBinderTest.java 2006-10-30 16:19:10 UTC (rev 10659)
@@ -104,9 +104,18 @@
assertNotNull(element.getMetaAttribute("global"));
assertNotNull(element.getMetaAttribute("componentonly"));
assertNotNull(element.getMetaAttribute("allcomponent"));
- assertNotNull(element.getMetaAttribute("implements"));
assertNull(element.getMetaAttribute("globalnoinherit"));
+ MetaAttribute compimplements = element.getMetaAttribute("implements");
+ assertNotNull(compimplements);
+ assertEquals(compimplements.getValue(), "AnotherInterface");
+
+ Property xp = ((Component)element.getValue()).getProperty( "x" );
+ MetaAttribute propximplements = xp.getMetaAttribute( "implements" );
+ assertNotNull(propximplements);
+ assertEquals(propximplements.getValue(), "AnotherInterface");
+
+
}
// HBX-718
@@ -118,46 +127,46 @@
MetaAttribute metaAttribute = cm.getMetaAttribute( "globalmutated" );
assertNotNull(metaAttribute);
- assertEquals( metaAttribute.getValues().size(), 2 );
- assertEquals( "top level", metaAttribute.getValues().get(0) );
- assertEquals( "wicked level", metaAttribute.getValues().get(1) );
+ /*assertEquals( metaAttribute.getValues().size(), 2 );
+ assertEquals( "top level", metaAttribute.getValues().get(0) );*/
+ assertEquals( "wicked level", metaAttribute.getValue() );
Property property = cm.getProperty( "component" );
MetaAttribute propertyAttribute = property.getMetaAttribute( "globalmutated" );
assertNotNull(propertyAttribute);
- assertEquals( propertyAttribute.getValues().size(), 3 );
+ /*assertEquals( propertyAttribute.getValues().size(), 3 );
assertEquals( "top level", propertyAttribute.getValues().get(0) );
- assertEquals( "wicked level", propertyAttribute.getValues().get(1) );
- assertEquals( "monetaryamount level", propertyAttribute.getValues().get(2) );
+ assertEquals( "wicked level", propertyAttribute.getValues().get(1) );*/
+ assertEquals( "monetaryamount level", propertyAttribute.getValue() );
org.hibernate.mapping.Component component = (Component)property.getValue();
property = component.getProperty( "x" );
propertyAttribute = property.getMetaAttribute( "globalmutated" );
assertNotNull(propertyAttribute);
- assertEquals( propertyAttribute.getValues().size(), 4 );
+ /*assertEquals( propertyAttribute.getValues().size(), 4 );
assertEquals( "top level", propertyAttribute.getValues().get(0) );
assertEquals( "wicked level", propertyAttribute.getValues().get(1) );
- assertEquals( "monetaryamount level", propertyAttribute.getValues().get(2) );
- assertEquals( "monetaryamount x level", propertyAttribute.getValues().get(3) );
+ assertEquals( "monetaryamount level", propertyAttribute.getValues().get(2) );*/
+ assertEquals( "monetaryamount x level", propertyAttribute.getValue() );
property = cm.getProperty( "sortedEmployee" );
propertyAttribute = property.getMetaAttribute( "globalmutated" );
assertNotNull(propertyAttribute);
- assertEquals( propertyAttribute.getValues().size(), 3 );
+ /*assertEquals( propertyAttribute.getValues().size(), 3 );
assertEquals( "top level", propertyAttribute.getValues().get(0) );
- assertEquals( "wicked level", propertyAttribute.getValues().get(1) );
- assertEquals( "sortedemployee level", propertyAttribute.getValues().get(2) );
+ assertEquals( "wicked level", propertyAttribute.getValues().get(1) );*/
+ assertEquals( "sortedemployee level", propertyAttribute.getValue() );
property = cm.getProperty( "anotherSet" );
propertyAttribute = property.getMetaAttribute( "globalmutated" );
assertNotNull(propertyAttribute);
- assertEquals( propertyAttribute.getValues().size(), 2 );
- assertEquals( "top level", propertyAttribute.getValues().get(0) );
- assertEquals( "wicked level", propertyAttribute.getValues().get(1) );
+ /*assertEquals( propertyAttribute.getValues().size(), 2 );
+ assertEquals( "top level", propertyAttribute.getValues().get(0) );*/
+ assertEquals( "wicked level", propertyAttribute.getValue() );
Bag bag = (Bag) property.getValue();
component = (Component)bag.getElement();
@@ -165,31 +174,31 @@
assertEquals(4,component.getMetaAttributes().size());
metaAttribute = component.getMetaAttribute( "globalmutated" );
- assertEquals( metaAttribute.getValues().size(), 3 );
+ /*assertEquals( metaAttribute.getValues().size(), 3 );
assertEquals( "top level", metaAttribute.getValues().get(0) );
- assertEquals( "wicked level", metaAttribute.getValues().get(1) );
- assertEquals( "monetaryamount anotherSet composite level", metaAttribute.getValues().get(2) );
+ assertEquals( "wicked level", metaAttribute.getValues().get(1) );*/
+ assertEquals( "monetaryamount anotherSet composite level", metaAttribute.getValue() );
property = component.getProperty( "emp" );
propertyAttribute = property.getMetaAttribute( "globalmutated" );
assertNotNull(propertyAttribute);
- assertEquals( propertyAttribute.getValues().size(), 4 );
+ /*assertEquals( propertyAttribute.getValues().size(), 4 );
assertEquals( "top level", propertyAttribute.getValues().get(0) );
assertEquals( "wicked level", propertyAttribute.getValues().get(1) );
- assertEquals( "monetaryamount anotherSet composite level", propertyAttribute.getValues().get(2) );
- assertEquals( "monetaryamount anotherSet composite property emp level", propertyAttribute.getValues().get(3) );
+ assertEquals( "monetaryamount anotherSet composite level", propertyAttribute.getValues().get(2) );*/
+ assertEquals( "monetaryamount anotherSet composite property emp level", propertyAttribute.getValue() );
property = component.getProperty( "empinone" );
propertyAttribute = property.getMetaAttribute( "globalmutated" );
assertNotNull(propertyAttribute);
- assertEquals( propertyAttribute.getValues().size(), 4 );
+ /*assertEquals( propertyAttribute.getValues().size(), 4 );
assertEquals( "top level", propertyAttribute.getValues().get(0) );
assertEquals( "wicked level", propertyAttribute.getValues().get(1) );
- assertEquals( "monetaryamount anotherSet composite level", propertyAttribute.getValues().get(2) );
- assertEquals( "monetaryamount anotherSet composite property empinone level", propertyAttribute.getValues().get(3) );
+ assertEquals( "monetaryamount anotherSet composite level", propertyAttribute.getValues().get(2) );*/
+ assertEquals( "monetaryamount anotherSet composite property empinone level", propertyAttribute.getValue() );
}
Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/Wicked.hbm.xml
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/legacy/Wicked.hbm.xml 2006-10-30 15:46:48 UTC (rev 10658)
+++ trunk/Hibernate3/test/org/hibernate/test/legacy/Wicked.hbm.xml 2006-10-30 16:19:10 UTC (rev 10659)
@@ -32,6 +32,7 @@
<many-to-one name="objectManyToOne" class="org.hibernate.test.legacy.Employee" column="MANAGER_ID"/>
<component name="component" class="net.sf.hibern8ide.test.MonetaryAmount">
<meta attribute="componentonly" inherit="true"/>
+ <meta attribute="implements">AnotherInterface</meta>
<meta attribute="allcomponent"/>
<meta attribute="globalmutated">monetaryamount level</meta>
<property name="x" type="string">
18 years, 1 month
Hibernate SVN: r10658 - in branches/Branch_3_2/Hibernate3: src/org/hibernate/cfg src/org/hibernate/mapping test/org/hibernate/test/legacy
by hibernate-commits@lists.jboss.org
Author: max.andersen(a)jboss.com
Date: 2006-10-30 10:46:48 -0500 (Mon, 30 Oct 2006)
New Revision: 10658
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/cfg/HbmBinder.java
branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/MetaAttribute.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/legacy/NonReflectiveBinderTest.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/legacy/Wicked.hbm.xml
Log:
HBX-621 & HBX-793 meta attribute were doing a concat instead of an override.
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/cfg/HbmBinder.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/cfg/HbmBinder.java 2006-10-27 21:35:48 UTC (rev 10657)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/cfg/HbmBinder.java 2006-10-30 15:46:48 UTC (rev 10658)
@@ -2861,13 +2861,9 @@
if ( meta == null ) {
meta = new MetaAttribute( name );
map.put( name, meta );
- } else if (meta == inheritedAttribute) { // to prevent mutation of the inherited meta attribute.
+ } else if (meta == inheritedAttribute) { // overriding inherited meta attribute. HBX-621 & HBX-793
meta = new MetaAttribute( name );
- map.put( name, meta );
- java.util.List values = inheritedAttribute.getValues();
- for (Iterator iterator = values.iterator(); iterator.hasNext();) {
- meta.addValue( (String) iterator.next() );
- }
+ map.put( name, meta );
}
meta.addValue( metaNode.getText() );
}
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/MetaAttribute.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/MetaAttribute.java 2006-10-27 21:35:48 UTC (rev 10657)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/mapping/MetaAttribute.java 2006-10-30 15:46:48 UTC (rev 10658)
@@ -30,7 +30,9 @@
}
public String getValue() {
- if ( values.size()!=1 ) throw new IllegalStateException("no unique value");
+ if ( values.size()!=1 ) {
+ throw new IllegalStateException("no unique value");
+ }
return (String) values.get(0);
}
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/legacy/NonReflectiveBinderTest.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/legacy/NonReflectiveBinderTest.java 2006-10-27 21:35:48 UTC (rev 10657)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/legacy/NonReflectiveBinderTest.java 2006-10-30 15:46:48 UTC (rev 10658)
@@ -104,9 +104,18 @@
assertNotNull(element.getMetaAttribute("global"));
assertNotNull(element.getMetaAttribute("componentonly"));
assertNotNull(element.getMetaAttribute("allcomponent"));
- assertNotNull(element.getMetaAttribute("implements"));
assertNull(element.getMetaAttribute("globalnoinherit"));
+ MetaAttribute compimplements = element.getMetaAttribute("implements");
+ assertNotNull(compimplements);
+ assertEquals(compimplements.getValue(), "AnotherInterface");
+
+ Property xp = ((Component)element.getValue()).getProperty( "x" );
+ MetaAttribute propximplements = xp.getMetaAttribute( "implements" );
+ assertNotNull(propximplements);
+ assertEquals(propximplements.getValue(), "AnotherInterface");
+
+
}
// HBX-718
@@ -118,46 +127,46 @@
MetaAttribute metaAttribute = cm.getMetaAttribute( "globalmutated" );
assertNotNull(metaAttribute);
- assertEquals( metaAttribute.getValues().size(), 2 );
- assertEquals( "top level", metaAttribute.getValues().get(0) );
- assertEquals( "wicked level", metaAttribute.getValues().get(1) );
+ /*assertEquals( metaAttribute.getValues().size(), 2 );
+ assertEquals( "top level", metaAttribute.getValues().get(0) );*/
+ assertEquals( "wicked level", metaAttribute.getValue() );
Property property = cm.getProperty( "component" );
MetaAttribute propertyAttribute = property.getMetaAttribute( "globalmutated" );
assertNotNull(propertyAttribute);
- assertEquals( propertyAttribute.getValues().size(), 3 );
+ /*assertEquals( propertyAttribute.getValues().size(), 3 );
assertEquals( "top level", propertyAttribute.getValues().get(0) );
- assertEquals( "wicked level", propertyAttribute.getValues().get(1) );
- assertEquals( "monetaryamount level", propertyAttribute.getValues().get(2) );
+ assertEquals( "wicked level", propertyAttribute.getValues().get(1) );*/
+ assertEquals( "monetaryamount level", propertyAttribute.getValue() );
org.hibernate.mapping.Component component = (Component)property.getValue();
property = component.getProperty( "x" );
propertyAttribute = property.getMetaAttribute( "globalmutated" );
assertNotNull(propertyAttribute);
- assertEquals( propertyAttribute.getValues().size(), 4 );
+ /*assertEquals( propertyAttribute.getValues().size(), 4 );
assertEquals( "top level", propertyAttribute.getValues().get(0) );
assertEquals( "wicked level", propertyAttribute.getValues().get(1) );
- assertEquals( "monetaryamount level", propertyAttribute.getValues().get(2) );
- assertEquals( "monetaryamount x level", propertyAttribute.getValues().get(3) );
+ assertEquals( "monetaryamount level", propertyAttribute.getValues().get(2) );*/
+ assertEquals( "monetaryamount x level", propertyAttribute.getValue() );
property = cm.getProperty( "sortedEmployee" );
propertyAttribute = property.getMetaAttribute( "globalmutated" );
assertNotNull(propertyAttribute);
- assertEquals( propertyAttribute.getValues().size(), 3 );
+ /*assertEquals( propertyAttribute.getValues().size(), 3 );
assertEquals( "top level", propertyAttribute.getValues().get(0) );
- assertEquals( "wicked level", propertyAttribute.getValues().get(1) );
- assertEquals( "sortedemployee level", propertyAttribute.getValues().get(2) );
+ assertEquals( "wicked level", propertyAttribute.getValues().get(1) );*/
+ assertEquals( "sortedemployee level", propertyAttribute.getValue() );
property = cm.getProperty( "anotherSet" );
propertyAttribute = property.getMetaAttribute( "globalmutated" );
assertNotNull(propertyAttribute);
- assertEquals( propertyAttribute.getValues().size(), 2 );
- assertEquals( "top level", propertyAttribute.getValues().get(0) );
- assertEquals( "wicked level", propertyAttribute.getValues().get(1) );
+ /*assertEquals( propertyAttribute.getValues().size(), 2 );
+ assertEquals( "top level", propertyAttribute.getValues().get(0) );*/
+ assertEquals( "wicked level", propertyAttribute.getValue() );
Bag bag = (Bag) property.getValue();
component = (Component)bag.getElement();
@@ -165,31 +174,31 @@
assertEquals(4,component.getMetaAttributes().size());
metaAttribute = component.getMetaAttribute( "globalmutated" );
- assertEquals( metaAttribute.getValues().size(), 3 );
+ /*assertEquals( metaAttribute.getValues().size(), 3 );
assertEquals( "top level", metaAttribute.getValues().get(0) );
- assertEquals( "wicked level", metaAttribute.getValues().get(1) );
- assertEquals( "monetaryamount anotherSet composite level", metaAttribute.getValues().get(2) );
+ assertEquals( "wicked level", metaAttribute.getValues().get(1) );*/
+ assertEquals( "monetaryamount anotherSet composite level", metaAttribute.getValue() );
property = component.getProperty( "emp" );
propertyAttribute = property.getMetaAttribute( "globalmutated" );
assertNotNull(propertyAttribute);
- assertEquals( propertyAttribute.getValues().size(), 4 );
+ /*assertEquals( propertyAttribute.getValues().size(), 4 );
assertEquals( "top level", propertyAttribute.getValues().get(0) );
assertEquals( "wicked level", propertyAttribute.getValues().get(1) );
- assertEquals( "monetaryamount anotherSet composite level", propertyAttribute.getValues().get(2) );
- assertEquals( "monetaryamount anotherSet composite property emp level", propertyAttribute.getValues().get(3) );
+ assertEquals( "monetaryamount anotherSet composite level", propertyAttribute.getValues().get(2) );*/
+ assertEquals( "monetaryamount anotherSet composite property emp level", propertyAttribute.getValue() );
property = component.getProperty( "empinone" );
propertyAttribute = property.getMetaAttribute( "globalmutated" );
assertNotNull(propertyAttribute);
- assertEquals( propertyAttribute.getValues().size(), 4 );
+ /*assertEquals( propertyAttribute.getValues().size(), 4 );
assertEquals( "top level", propertyAttribute.getValues().get(0) );
assertEquals( "wicked level", propertyAttribute.getValues().get(1) );
- assertEquals( "monetaryamount anotherSet composite level", propertyAttribute.getValues().get(2) );
- assertEquals( "monetaryamount anotherSet composite property empinone level", propertyAttribute.getValues().get(3) );
+ assertEquals( "monetaryamount anotherSet composite level", propertyAttribute.getValues().get(2) );*/
+ assertEquals( "monetaryamount anotherSet composite property empinone level", propertyAttribute.getValue() );
}
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/legacy/Wicked.hbm.xml
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/legacy/Wicked.hbm.xml 2006-10-27 21:35:48 UTC (rev 10657)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/legacy/Wicked.hbm.xml 2006-10-30 15:46:48 UTC (rev 10658)
@@ -32,6 +32,7 @@
<many-to-one name="objectManyToOne" class="org.hibernate.test.legacy.Employee" column="MANAGER_ID"/>
<component name="component" class="net.sf.hibern8ide.test.MonetaryAmount">
<meta attribute="componentonly" inherit="true"/>
+ <meta attribute="implements">AnotherInterface</meta>
<meta attribute="allcomponent"/>
<meta attribute="globalmutated">monetaryamount level</meta>
<property name="x" type="string">
18 years, 1 month
Hibernate SVN: r10657 - in branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate: cfg/annotations reflection/java validator/event
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2006-10-27 17:35:48 -0400 (Fri, 27 Oct 2006)
New Revision: 10657
Modified:
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/PropertyBinder.java
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/Version.java
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXProperty.java
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/event/ValidateEventListener.java
Log:
ANN-456 use the same reflectionManager in ValidateEventListener
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/PropertyBinder.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/PropertyBinder.java 2006-10-27 20:03:29 UTC (rev 10656)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/PropertyBinder.java 2006-10-27 21:35:48 UTC (rev 10657)
@@ -152,7 +152,7 @@
prop.setGeneration( PropertyGeneration.parse( generated.toString().toLowerCase() ) );
}
}
- log.debug( "Cascading " + name + " with " + cascade );
+ log.trace( "Cascading " + name + " with " + cascade );
return prop;
}
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/Version.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/Version.java 2006-10-27 20:03:29 UTC (rev 10656)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/Version.java 2006-10-27 21:35:48 UTC (rev 10657)
@@ -8,7 +8,7 @@
* @author Emmanuel Bernard
*/
public class Version {
- public static final String VERSION = "3.2.0.GA";
+ public static final String VERSION = "3.2.1-dev";
private static Log log = LogFactory.getLog( Version.class );
static {
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXProperty.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXProperty.java 2006-10-27 20:03:29 UTC (rev 10656)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXProperty.java 2006-10-27 21:35:48 UTC (rev 10657)
@@ -19,10 +19,10 @@
class JavaXProperty extends JavaXMember implements XProperty {
static boolean isProperty(Field f, Type boundType, Filter filter) {
- return isPropertyType( boundType )
- && !f.isSynthetic()
- && ( filter.returnStatic() || ! Modifier.isStatic( f.getModifiers() ) )
- && ( filter.returnTransient() || ! Modifier.isTransient( f.getModifiers() ) );
+ return ( filter.returnStatic() || ! Modifier.isStatic( f.getModifiers() ) )
+ && ( filter.returnTransient() || ! Modifier.isTransient( f.getModifiers() ) )
+ && !f.isSynthetic()
+ && isPropertyType( boundType );
}
private static boolean isPropertyType(Type type) {
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/event/ValidateEventListener.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/event/ValidateEventListener.java 2006-10-27 20:03:29 UTC (rev 10656)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/event/ValidateEventListener.java 2006-10-27 21:35:48 UTC (rev 10657)
@@ -12,9 +12,12 @@
import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
+import org.hibernate.reflection.ReflectionManager;
+import org.hibernate.reflection.java.JavaXFactory;
import org.hibernate.util.StringHelper;
import org.hibernate.util.ReflectHelper;
import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.event.Initializable;
import org.hibernate.event.PreInsertEvent;
import org.hibernate.event.PreInsertEventListener;
@@ -69,10 +72,18 @@
}
}
Iterator<PersistentClass> classes = (Iterator<PersistentClass>) cfg.getClassMappings();
- while ( classes.hasNext() ) {
+ ReflectionManager reflectionManager;
+ if ( cfg instanceof AnnotationConfiguration ) {
+ //reuse the existing reflectionManager one when possible
+ reflectionManager = ( (AnnotationConfiguration) cfg).getReflectionManager();
+ }
+ else {
+ reflectionManager = new JavaXFactory();
+ }
+ while ( classes.hasNext() ) {
PersistentClass clazz = classes.next();
final Class mappedClass = clazz.getMappedClass();
- ClassValidator validator = new ClassValidator( mappedClass, interpolator );
+ ClassValidator validator = new ClassValidator( mappedClass, null, interpolator, null, reflectionManager );
ValidatableElement element = new ValidatableElement( mappedClass, validator );
addSubElement( clazz.getIdentifierProperty(), element );
Iterator properties = clazz.getPropertyIterator();
18 years, 1 month
Hibernate SVN: r10656 - in branches/Branch_3_2/HibernateExt/metadata/doc/reference: . fr fr/images fr/modules fr/styles
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2006-10-27 16:03:29 -0400 (Fri, 27 Oct 2006)
New Revision: 10656
Added:
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/images/
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/images/hibernate_logo_a.png
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/master.xml
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/entity.xml
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/lucene.xml
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/setup.xml
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/validator.xml
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/xml-overriding.xml
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/fopdf.xsl
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/html.css
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/html.xsl
branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/html_chunk.xsl
Modified:
branches/Branch_3_2/HibernateExt/metadata/doc/reference/build.xml
Log:
ANN-478 French translation (Vincent Ricard)
Modified: branches/Branch_3_2/HibernateExt/metadata/doc/reference/build.xml
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/doc/reference/build.xml 2006-10-27 19:56:30 UTC (rev 10655)
+++ branches/Branch_3_2/HibernateExt/metadata/doc/reference/build.xml 2006-10-27 20:03:29 UTC (rev 10656)
@@ -12,10 +12,14 @@
<param name="docname" value="hibernate_annotations"/>
<param name="lang" value="en"/>
</antcall>
- <antcall target="lang.all">
+ <antcall target="lang.all">
<param name="docname" value="hibernate_annotations"/>
<param name="lang" value="zh_cn"/>
</antcall>
+ <antcall target="lang.all">
+ <param name="docname" value="hibernate_annotations"/>
+ <param name="lang" value="fr"/>
+ </antcall>
</target>
</project>
Added: branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/images/hibernate_logo_a.png
===================================================================
(Binary files differ)
Property changes on: branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/images/hibernate_logo_a.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/master.xml
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/master.xml 2006-10-27 19:56:30 UTC (rev 10655)
+++ branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/master.xml 2006-10-27 20:03:29 UTC (rev 10656)
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3CR3//EN"
+"../../../../../Hibernate3/doc/reference/support/docbook-dtd/docbookx.dtd" [
+<!ENTITY setup SYSTEM "modules/setup.xml">
+<!ENTITY entity SYSTEM "modules/entity.xml">
+<!ENTITY xml-overriding SYSTEM "modules/xml-overriding.xml">
+<!ENTITY validator SYSTEM "modules/validator.xml">
+<!ENTITY lucene SYSTEM "modules/lucene.xml">
+]>
+<book lang="fr">
+ <bookinfo>
+ <title>Hibernate Annotations</title>
+
+ <subtitle>Guide de r�f�rence</subtitle>
+
+ <releaseinfo>3.2.0.GA</releaseinfo>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/hibernate_logo_a.png" format="png" />
+ </imageobject>
+ </mediaobject>
+ </bookinfo>
+
+ <toc></toc>
+
+ <preface id="preface" revision="1">
+ <title>Pr�face</title>
+ <para>Traducteur(s): Vincent Ricard</para>
+
+ <para>Hibernate, comme tous les autres outils de mapping objet/relationnel,
+ n�cessite des m�ta-donn�es qui r�gissent la transformation des donn�es
+ d'une repr�sentation vers l'autre (et vice versa). Dans Hibernate 2.x, les
+ m�ta-donn�es de mapping sont la plupart du temps d�clar�es dans des fichiers
+ XML. Une autre option est XDoclet, qui utilise les annotations du code source
+ Javadoc et un pr�processeur au moment de la compilation. Le m�me genre
+ d'annotation est maintenant disponible avec le JDK standard, quoique plus
+ puissant et mieux pris en charge par les outils. IntelliJ IDEA et Eclipse,
+ par exemple, prennent en charge la compl�tion automatique et la coloration
+ syntaxique des annotations du JDK 5.0. Les annotations sont compil�es en
+ bytecode et lues au moment de l'ex�cution (dans le cas d'Hibernate, au
+ d�marrage) en utilisant la r�flexion, donc pas besoin de fichiers XML
+ externes.</para>
+
+ <para>La sp�cification EJB3 reconna�t l'int�r�t et le succ�s du paradigme
+ du mapping objet/relationnel transparent. La sp�cification EJB3 standardise
+ les APIs de base et les m�ta-donn�es requises par n'importe quel m�canisme
+ de persistance objet/relationnel. <emphasis>Hibernate EntityManager</emphasis>
+ impl�mente les interfaces de programmation et les r�gles de cycle de vie
+ telles que d�finies par la sp�cification de persistance EJB3. Avec
+ <emphasis>Hibernate Annotations</emphasis>, ce wrapper impl�mente une
+ solution de persistance EJB3 compl�te (et autonome) au-dessus du noyau
+ mature d'Hibernate. Vous pouvez utiliser soit les trois ensembles, soit les
+ annotations sans le cycle de vie et les interfaces de programmations EJB3,
+ ou m�me Hibernate tout seul, selon les besoins techniques et fonctionnels
+ de votre projet. Vous pouvez � tout moment recourir aux APIs natives
+ d'Hibernate ou m�me, si besoin est, � celles de JDBC et au SQL.</para>
+
+ <para>Cette version est bas�e sur la derni�re version de la sp�cification
+ EJB 3.0 / JPA (alias JSP-220) et prend en charge toutes les fonctionnalit�s
+ de la sp�cification (dont certaines optionnelles). La plupart des
+ fonctionnalit�s d'Hibernate et des extensions sont aussi disponibles �
+ travers des annotations sp�cifiques � Hibernate. Bien que la couverture
+ d'Hibernate en termes de fonctionnalit�s soit maintenant tr�s grande,
+ certaines sont encore manquantes. Le but ultime est de tout couvrir. Voir la
+ section JIRA "road map" pour plus d'informations.</para>
+
+ <para>Si vous utilisiez une version pr�c�dente d'Hibernate Annotations,
+ veuillez regarder <uri>http://www.hibernate.org/371.html</uri> pour un guide
+ de migration.</para>
+ </preface>
+
+ &setup;
+
+ &entity;
+
+ &xml-overriding;
+
+ &validator;
+
+ &lucene;
+</book>
\ No newline at end of file
Added: branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/entity.xml
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/entity.xml 2006-10-27 19:56:30 UTC (rev 10655)
+++ branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/entity.xml 2006-10-27 20:03:29 UTC (rev 10656)
@@ -0,0 +1,3458 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<chapter id="entity">
+ <title>Entity Beans</title>
+
+ <sect1 id="entity-overview" revision="1">
+ <title>Introduction</title>
+
+ <para>Cette section couvre les annotations entity bean EJB 3.0 (alias JPA)
+ et les extensions sp�cifiques � Hibernate.</para>
+ </sect1>
+
+ <sect1 id="entity-mapping" revision="2">
+ <title>Mapping avec les annotations EJB3/JPA</title>
+
+ <para>Les entit�s EJB3 sont des POJOs ordinaires. En fait, ils
+ repr�sentent exactement le m�me concept que les entit�s de persistance
+ Hibernate. Leur mapping est d�fini � travers les annotations du JDK 5.0
+ (une syntaxe de descripteur XML pour la surcharge est d�finie dans la
+ sp�cification EJB3). Les annotations peuvent �tre divis�es en deux
+ cat�gories, les annotations de mapping logique (vous permettant de d�crire
+ le mod�le objet, les associations de classe, etc) et les annotations de
+ mapping physique (d�crivant le sch�ma physique, les tables, les colonnes,
+ les index, etc). Nous m�langerons les annotations des deux cat�gories dans
+ les exemples de code.</para>
+
+ <para>Les annotations EJB3 sont dans le package
+ <literal>javax.persistence.*</literal>. La plupart des IDE compatibles JDK 5
+ (comme Eclipse, IntelliJ IDEA et Netbeans) peuvent auto-compl�ter les
+ interfaces et les attributes d'annotation pour vous (m�me sans module "EJB3"
+ sp�cifique, puisque les annotations EJB3 sont des annotations ordinaires de
+ JDK 5).</para>
+
+ <para>Pour plus d'exemples concrets, lisez le tutorial EJB 3.0 de JBoss ou
+ parcourez la suite de tests d'Hibernate Annotations. La plupart des tests
+ unitaires ont �t� con�us pour repr�senter un exemple concret et �tre une
+ source d'inspiration.</para>
+
+ <sect2>
+ <title>D�clarer un entity bean</title>
+
+ <para>Chaque classe POJO persistante li�e est un entity bean et est
+ d�clar�e en utilisant l'annotation <literal>@Entity</literal> (au niveau
+ de la classe) :</para>
+
+ <programlisting>
+@Entity
+public class Flight implements Serializable {
+ Long id;
+
+ @Id
+ public Long getId() { return id; }
+
+ public void setId(Long id) { this.id = id; }
+}
+</programlisting>
+
+ <para><literal>@Entity</literal> d�clare la classe comme un entity bean
+ (ie une classe POJO persistante), <literal>@Id</literal> d�clare la
+ propri�t� identifiante de cet entity bean. Les autres d�clarations de
+ mapping sont implicites. Ce concept de d�claration par exception est
+ un composant essentiel de la nouvelle sp�cification EJB3 et une
+ am�lioration majeure. La classe Flight est mapp�e sur la table Flight, en
+ utilisant la colonne id comme colonne de la clef primaire.</para>
+
+ <para>Selon que vous annotez des champs ou des m�thodes, le type d'acc�s
+ utilis� par Hibernate sera <literal>field</literal> ou
+ <literal>property</literal>. La sp�cification EJB3 exige que vous
+ d�clariez les annotations sur le type d'�l�ment qui sera acc�d�,
+ c'est-�-dire le getter si vous utilisez l'acc�s
+ <literal>property</literal>, le champ si vous utilisez l'acc�s
+ <literal>field</literal>. M�langer des EJB3 annotations dans les champs et
+ les m�thodes devrait �tre �vit�. Hibernate devinera le type d'acc�s de
+ l'identifiant � partir de la position d'<literal>@Id</literal> ou
+ d'<literal>@EmbeddedId</literal>.</para>
+
+ <sect3>
+ <title>D�finir la table</title>
+
+ <para><literal>@Table</literal> est positionn�e au niveau de la classe ;
+ cela vous permet de d�finir le nom de la table, du catalogue et du
+ sch�ma pour le mapping de votre entity bean. Si aucune
+ <literal>@Table</literal> n'est d�finie les valeurs par d�faut sont
+ utilis�es : le nom de la classe de l'entit� (sans le nom de
+ package).</para>
+
+ <programlisting>
+@Entity
+@Table(name="tbl_sky")
+public class Sky implements Serializable {
+...
+ </programlisting>
+
+ <para>L'�l�ment <literal>@Table</literal> contient aussi un attribut
+ <literal>schema</literal> et un attribut <literal>catalog</literal>,
+ si vous avez besoin de les d�finir. Vous pouvez aussi d�finir des
+ contraintes d'unicit� sur la table en utilisant l'annotation
+ <literal>@UniqueConstraint</literal> en conjonction avec
+ <literal>@Table</literal> (pour une contrainte d'unicit� n'impliquant
+ qu'une seule colonne, r�f�rez-vous � <literal>@Column</literal>).</para>
+
+ <programlisting>@Table(name="tbl_sky",
+ <emphasis role="bold">uniqueConstraints = {@UniqueConstraint(columnNames={"month", "day"})}</emphasis>
+)</programlisting>
+
+ <para>Une contrainte d'unicit� est appliqu�e au tuple {month, day}.
+ Notez que le tableau <literal>columnNames</literal> fait r�f�rence aux
+ noms logiques des colonnes.</para>
+
+ <remark>Le nom logique d'une colonne est d�fini par l'impl�mentation
+ de NamingStrategy d'Hibernate. La strat�gie de nommage EJB3 par d�faut
+ utilise le nom de colonne physique comme nom de colonne logique. Notez
+ qu'il peut �tre diff�rent du nom de la propri�t� (si le nom de colonne
+ est explicite). A moins que vous surchargiez la strat�gie de nommage,
+ vous ne devriez pas vous soucier de �a.</remark>
+ </sect3>
+
+ <sect3>
+ <title>Versionner pour un contr�le de concurrence optimiste</title>
+
+ <para>Vous pouvez ajouter un contr�le de concurrence optimiste � un
+ entity bean en utilisant l'annotation
+ <literal>@Version</literal> :</para>
+
+ <programlisting>
+@Entity
+public class Flight implements Serializable {
+...
+ @Version
+ @Column(name="OPTLOCK")
+ public Integer getVersion() { ... }
+} </programlisting>
+
+ <para>La propri�t� de version sera mapp�e sur la colonne
+ <literal>OPTLOCK</literal>, et le gestionnaire d'entit�s l'utilisera
+ pour d�tecter des conflits lors des mises � jour (pr�venant des pertes
+ de donn�es lors de mises � jours que vous pourriez voir avec la
+ strat�gie du last-commit-wins).</para>
+
+ <para>La colonne de version peut �tre un num�rique (solution
+ recommand�e) ou un timestamp comme pour la sp�cification EJB3. Hibernate
+ prend en charge n'importe quel type fourni que vous d�finissez et
+ impl�mentez avec la classe <classname>UserVersionType</classname>
+ appropri�e.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Mapping de simples propri�t�s</title>
+
+ <sect3>
+ <title>D�clarer des mappings de propri�t�s �l�mentaires</title>
+
+ <para>Chaque propri�t� (champ ou m�thode) non statique non transient
+ d'un entity bean est consid�r�e persistante, � moins que vous l'annotiez
+ comme <literal>@Transient</literal>. Ne pas avoir d'annotation pour
+ votre propri�t� est �quivalent � l'annotation <literal>@Basic</literal>.
+ L'annotation <literal>@Basic</literal> vous permet de d�clarer la
+ strat�gie de r�cup�ration pour une propri�t� :</para>
+
+ <programlisting>public transient int counter; // propri�t� transient
+
+private String firstname; // propri�t� persistante
+
+@Transient
+String getLengthInMeter() { ... } // propri�t� transient
+
+String getName() {... } // propri�t� persistante
+
+@Basic
+int getLength() { ... } // propri�t� persistante
+
+@Basic(fetch = FetchType.LAZY)
+String getDetailedComment() { ... } // propri�t� persistante
+
+(a)Temporal(TemporalType.TIME)
+java.util.Date getDepartureTime() { ... } // propri�t� persistante
+
+@Enumerated(STRING)
+Starred getNote() { ... } // enum persist�e en tant que String dans la base de donn�es</programlisting>
+
+ <para><literal>counter</literal>, un champ transient, et
+ <literal>lengthInMeter</literal>, une m�thode annot�e comme
+ <literal>@Transient</literal>, seront ignor�s par le gestionnaire
+ d'entit�s. Les propri�t�s <literal>name</literal>,
+ <literal>length</literal>, et <literal>firstname</literal> sont mapp�es
+ comme persistantes et � charger imm�diatement (ce sont les valeurs
+ par d�faut pour les propri�t�s simples). La valeur de la propri�t�
+ <literal>detailedComment</literal> sera charg�e � partir de la base de
+ donn�es d�s que la propri�t� de l'entit� sera acc�d�e pour la premi�re
+ fois. En g�n�ral vous n'avez pas besoin de marquer de simples propri�t�s
+ comme "� charger � la demande" (NdT: lazy) (� ne pas confondre avec la
+ r�cup�ration d'association "lazy").</para>
+
+ <note>
+ <para>Pour activer la r�cup�ration � la demande au niveau de la
+ propri�t�, vos classes doivent �tre instrument�es : du bytecode est
+ ajout� au code original pour activer cette fonctionnalit�, veuillez
+ vous r�f�rer � la documentation de r�f�rence d'Hibernate. Si vos
+ classes ne sont pas instrument�es, le chargement � la demande au
+ niveau de la propri�t� est silencieusement ignor�.</para>
+ </note>
+
+ <para>L'alternative recommand�e est d'utiliser la capacit� de projection
+ de JPA-QL ou des requ�tes Criteria.</para>
+
+ <para>EJB3 prend en charge le mapping de propri�t� de tous les types
+ �l�mentaires pris en charge par Hibernate (tous les types de base Java,
+ leur wrapper respectif et les classes s�rialisables). Hibernate
+ Annotations prend en charge le mapping des types Enum soit vers une
+ colonne ordinale (en stockant le num�ro ordinal de l'enum), soit vers
+ une colonne de type cha�ne de caract�res (en stockant la cha�ne de
+ caract�res repr�sentant l'enum) : la repr�sentation de la persistance,
+ par d�faut ordinale, peut �tre surcharg�e gr�ce � l'annotation
+ <literal>@Enumerated</literal> comme montr� avec la propri�t�
+ <literal>note</literal> de l'exemple.</para>
+
+ <para>Dans les APIs core de Java, la pr�cision temporelle n'est pas
+ d�finie. Lors du traitement de donn�es temporelles vous pourriez vouloir
+ d�crire la pr�cision attendue dans la base de donn�es. Les donn�es
+ temporelles peuvent avoir une pr�cision de type <literal>DATE</literal>,
+ <literal>TIME</literal>, ou <literal>TIMESTAMP</literal> (c'est-�-dire
+ seulement la date, seulement l'heure, ou les deux). Utilisez
+ l'annotation <literal>@Temporal</literal> pour ajuster cela.</para>
+
+ <para><literal>@Lob</literal> indique que la propri�t� devrait �tre
+ persist�e dans un Blob ou un Clob selon son type :
+ <classname>java.sql.Clob</classname>,
+ <classname>Character[]</classname>, <classname>char[]</classname> et
+ java.lang.<classname>String</classname> seront persist�s dans un Clob.
+ <classname>java.sql.Blob</classname>, <classname>Byte[]</classname>,
+ <classname>byte[] </classname> et les types s�rialisables seront
+ persist�s dans un Blob.</para>
+
+ <programlisting>
+@Lob
+public String getFullText() {
+ return fullText;
+}
+
+@Lob
+public byte[] getFullCode() {
+ return fullCode;
+}
+ </programlisting>
+
+ <para>Si le type de la propri�t� impl�mente
+ <classname>java.io.Serializable</classname> et n'est pas un type de
+ base, et si la propri�t� n'est pas annot�e avec <literal>@Lob</literal>,
+ alors le type Hibernate <literal>serializable</literal> est
+ utilis�.</para>
+ </sect3>
+
+ <sect3>
+ <title>D�clarer des attributs de colonne</title>
+
+ <para>La(les) colonne(s) utilis�e(s) pour mapper une propri�t� peuvent
+ �tre d�finies en utilisant l'annotation <literal>@Column</literal>.
+ Utilisez-la pour surcharger les valeurs par d�faut (voir la
+ sp�cification EJB3 pour plus d'informations sur les valeurs par d�faut).
+ Vous pouvez utilisez cette annotation au niveau de la propri�t� pour
+ celles qui sont :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>pas du tout annot�es</para>
+ </listitem>
+
+ <listitem>
+ <para>annot�es avec <literal>@Basic</literal></para>
+ </listitem>
+
+ <listitem>
+ <para>annot�es avec <literal>@Version</literal></para>
+ </listitem>
+
+ <listitem>
+ <para>annot�es avec <literal>@Lob</literal></para>
+ </listitem>
+
+ <listitem>
+ <para>annot�es avec <literal>@Temporal</literal></para>
+ </listitem>
+
+ <listitem>
+ <para>annot�es avec
+ <literal>@org.hibernate.annotations.CollectionOfElements</literal>
+ (pour Hibernate uniquement)</para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting>
+@Entity
+public class Flight implements Serializable {
+...
+@Column(updatable = false, name = "flight_name", nullable = false, length=50)
+public String getName() { ... }
+ </programlisting>
+
+ <para>La propri�t� <literal>name</literal> est mapp�e sur la colonne
+ <literal>flight_name</literal>, laquelle ne peut pas avoir de valeur
+ nulle, a une longueur de 50 et ne peut pas �tre mise � jour (rendant
+ la propri�t� immuable).</para>
+
+ <para>Cette annotation peut �tre appliqu�e aux propri�t�s habituelles
+ ainsi qu'aux propri�t�s <literal>@Id</literal> ou
+ <literal>@Version</literal>.</para>
+
+ <programlistingco>
+ <areaspec>
+ <area coords="2 55" id="hm1" />
+
+ <area coords="3 55" id="hm2" />
+
+ <area coords="4 55" id="hm3" />
+
+ <area coords="5 55" id="hm4" />
+
+ <area coords="6 55" id="hm5" />
+
+ <area coords="7 55" id="hm6" />
+
+ <area coords="8 55" id="hm7" />
+
+ <area coords="9 55" id="hm8" />
+
+ <area coords="10 55" id="hm9" />
+
+ <area coords="11 55" id="hm10" />
+ </areaspec>
+
+ <programlisting>@Column(
+ name="columnName";
+ boolean unique() default false;
+ boolean nullable() default true;
+ boolean insertable() default true;
+ boolean updatable() default true;
+ String columnDefinition() default "";
+ String table() default "";
+ int length() default 255;
+ int precision() default 0; // decimal precision
+ int scale() default 0; // decimal scale</programlisting>
+
+ <calloutlist>
+ <callout arearefs="hm1">
+ <para><literal>name</literal> (optionnel) : le nom de la colonne
+ (par d�faut le nom de la propri�t�)</para>
+ </callout>
+
+ <callout arearefs="hm2">
+ <para><literal>unique</literal> (optionnel) : indique si la colonne
+ fait partie d'une contrainte d'unicit� ou non (par d�faut
+ false)</para>
+ </callout>
+
+ <callout arearefs="hm3">
+ <para><literal>nullable</literal> (optionnel) : indique si la
+ colonne peut avoir une valeur nulle (par d�faut false).</para>
+ </callout>
+
+ <callout arearefs="hm4">
+ <para><literal>insertable</literal> (optionnel) : indique si la
+ colonne fera partie de la commande insert (par d�faut true)</para>
+ </callout>
+
+ <callout arearefs="hm5">
+ <para><literal>updatable</literal> (optionnel) : indique si la
+ colonne fera partie de la commande update (par d�faut true)</para>
+ </callout>
+
+ <callout arearefs="hm6">
+ <para><literal>columnDefinition</literal> (optionnel) : surcharge
+ le fragment DDL sql pour cette colonne en particulier (non
+ portable)</para>
+ </callout>
+
+ <callout arearefs="hm7">
+ <para><literal>table</literal> (optionnel) : d�finit la table
+ cible (par d�faut la table principale)</para>
+ </callout>
+
+ <callout arearefs="hm8">
+ <para><literal><literal>length</literal></literal> (optionnel) :
+ longueur de la colonne (par d�faut 255)</para>
+ </callout>
+
+ <callout arearefs="hm8">
+ <para><literal><literal>precision</literal></literal>
+ (optionnel) : pr�cision d�cimale de la colonne (par d�faut
+ 0)</para>
+ </callout>
+
+ <callout arearefs="hm10">
+ <para><literal><literal>scale</literal></literal> (optionnel) :
+ �chelle d�cimale de la colonne si n�cessaire (par d�faut 0)</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ </sect3>
+
+ <sect3>
+ <title>Objets embarqu�s (alias composants)</title>
+
+ <para>Il est possible de d�clarer un composant embarqu� � l'int�rieur
+ d'une entit� et m�me de surcharger le mapping de ses colonnes. Les
+ classes de composant doivent �tre annot�es au niveau de la classe avec
+ l'annotation <literal>@Embeddable</literal>. Il est possible de
+ surcharger le mapping de colonne d'un objet embarqu� pour une entit�
+ particuli�re en utilisant les annotations
+ <literal>@Embedded</literal> et <literal>@AttributeOverride</literal>
+ sur la propri�t� associ�e :</para>
+
+ <programlisting>
+@Entity
+public class Person implements Serializable {
+
+ // Composant persistant utilisant les valeurs par d�faut
+ Address homeAddress;
+
+ @Embedded
+ @AttributeOverrides( {
+ @AttributeOverride(name="iso2", column = @Column(name="bornIso2") ),
+ @AttributeOverride(name="name", column = @Column(name="bornCountryName") )
+ } )
+ Country bornIn;
+ ...
+}
+ </programlisting>
+
+ <programlisting>
+@Embeddable
+public class Address implements Serializable {
+ String city;
+ Country nationality; // par de surcharge ici
+}
+ </programlisting>
+
+ <programlisting>
+@Embeddable
+public class Country implements Serializable {
+ private String iso2;
+ @Column(name="countryName") private String name;
+
+ public String getIso2() { return iso2; }
+ public void setIso2(String iso2) { this.iso2 = iso2; }
+
+
+ public String getName() { return name; }
+ public void setName(String name) { this.name = name; }
+ ...
+}
+ </programlisting>
+
+ <para>Un objet embarquable h�rite du type d'acc�s de son entit�
+ d'appartenance (notez que vous pouvez surcharger cela en utilisant les
+ annotations sp�cifiques � Hibernate <literal>@AccessType</literal>,
+ voir <xref linkend="entity-hibspec" />).</para>
+
+ <para>L'entity bean <literal>Person</literal> a deux propri�t�s
+ composant, <literal>homeAddress</literal> et
+ <literal>bornIn</literal>. La propri�t� <literal>homeAddress</literal>
+ n'a pas �t� annot�e, mais Hibernate devinera que c'est un composant
+ persistant en cherchant l'annotation <literal>@Embeddable</literal>
+ dans la classe Address. Nous surchargeons aussi le mapping d'un nom de
+ colonne (pour <literal>bornCountryName</literal>) avec les annotations
+ <literal>@Embedded</literal> et <literal>@AttributeOverride</literal>
+ pour chaque attribut mapp� de <literal>Country</literal>. Comme vous
+ pouvez le voir, <literal>Country</literal> est aussi un composant
+ imbriqu� de <literal>Address</literal>, utilisant de nouveau la
+ d�tection automatique d'Hibernate et les valeurs par d�faut EJB3.
+ Surcharger des colonnes d'objets embarqu�s d'objets (eux-m�mes)
+ embarqu�s n'est actuellement pas pris en charge par la sp�cification
+ EJB3, cependant, Hibernate Annotations le prend en charge � travers des
+ expressions s�par�es par des points.</para>
+
+ <para><programlisting> @Embedded
+ @AttributeOverrides( {
+ @AttributeOverride(name="city", column = @Column(name="fld_city") )
+ @AttributeOverride(name="<emphasis role="bold">nationality.iso2</emphasis>", column = @Column(name="nat_Iso2") ),
+ @AttributeOverride(name="<emphasis role="bold">nationality.name</emphasis>", column = @Column(name="nat_CountryName") )
+ // les colonnes de nationality dans homeAddress sont surcharg�es
+ } )
+ Address homeAddress;</programlisting>Hibernate Annotations prend en charge
+ une fonctionnalit� de plus qui n'est pas explicitement prise en charge
+ par la sp�cification EJB3. Vous pouvez annoter un objet embarqu� avec
+ l'annotation
+ <literal>@MappedSuperclass</literal> pour rendre les propri�t�s de la
+ classe parente persistantes (voir <literal>@MappedSuperclass</literal>
+ pour plus d'informations).</para>
+
+ <para>Alors que ce n'est pas pris en charge par la sp�cification EJB3,
+ Hibernate Annotations vous permet d'utiliser les annotations
+ d'association dans un objet embarquable (ie <literal>@*ToOne</literal>
+ ou <literal>@*ToMany</literal>). Pour surcharger les colonnes de
+ l'association vous pouvez utiliser
+ <literal>@AssociationOverride</literal>.</para>
+
+ <para>Si vous voulez avoir le m�me type d'objet embarquable deux fois
+ dans la m�me entit�, le nom de colonne par d�faut ne fonctionnera pas :
+ au moins une des colonnes devra �tre explicit�e. Hibernate va au-del�
+ de la sp�cification EJB3 et vous permet d'am�liorer le m�canisme par
+ d�faut avec <classname>NamingStrategy</classname>.
+ <classname>DefaultComponentSafeNamingStrategy</classname> est une petite
+ am�lioration par rapport � la strat�gie par d�faut
+ <classname>EJB3NamingStrategy</classname> qui permet aux objets
+ embarqu�s de fonctionner avec leur valeur par d�faut m�me s'ils sont
+ utilis�s deux fois dans la m�me entit�.</para>
+ </sect3>
+
+ <sect3>
+ <title>Valeurs par d�faut des propri�t�s non annot�es</title>
+
+ <para>Si une propri�t� n'est pas annot�e, les r�gles suivantes
+ s'appliquent :</para>
+
+ <itemizedlist>
+ <listitem>
+ Si la propri�t� est de type simple, elle est mapp�e comme @Basic
+ </listitem>
+
+ <listitem>
+ Sinon, si le type de la propri�t� est annot� comme @Embeddable,
+ elle est mapp�e comme @Embedded
+ </listitem>
+
+ <listitem>
+ Sinon, si le type de la propri�t� est Serializable, elle est mapp�e
+ comme @Basic vers une colonne contenant l'objet sous sa forme
+ s�rialis�e
+ </listitem>
+
+ <listitem>
+ Sinon, si le type de la propri�t� est java.sql.Clob ou
+ java.sql.Blob, elle est mapp�e comme @Lob avec le LobType
+ appropri�
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+
+ <sect2 id="entity-mapping-identifier"
+ xreflabel="Mapper des propri�t�s identifiantes">
+ <title>Mapper des propri�t�s identifiantes</title>
+
+ <para>L'annotation <literal>@Id</literal> vous permet de d�finir quelle
+ propri�t� identifie votre entity bean. Cette propri�t� peut �tre
+ positionn�e par l'application elle-m�me ou g�n�r�e par Hibernate
+ (pr�f�r�). Vous pouvez d�finir la strat�gie de g�n�ration de l'identifiant
+ gr�ce � l'annotation <literal>@GeneratedValue</literal> :</para>
+
+ <itemizedlist>
+ <listitem>
+ AUTO - soit la colonne identity, soit la s�quence, soit la table
+ selon la base de donn�es sous-jacente
+ </listitem>
+
+ <listitem>
+ TABLE - table contenant l'id
+ </listitem>
+
+ <listitem>
+ IDENTITY - colonne identity
+ </listitem>
+
+ <listitem>
+ SEQUENCE - s�quence
+ </listitem>
+ </itemizedlist>
+
+ <para>Hibernate fournit plus de g�n�rateurs d'identifiant que les simples
+ g�n�rateurs EJB3. V�rifiez <xref linkend="entity-hibspec" /> pour plus
+ d'informations.</para>
+
+ <para>L'exemple suivant montre un g�n�rateur par s�quence utilisant la
+ configuration SEQ_STORE (voir plus bas) :</para>
+
+ <programlisting>
+@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")
+public Integer getId() { ... }
+ </programlisting>
+
+ <para>L'exemple suivant utilise le g�n�rateur identity :</para>
+
+ <programlisting>
+@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
+public Long getId() { ... }
+ </programlisting>
+
+ <para>Le g�n�rateur <literal>AUTO</literal> est le type pr�f�r� pour les
+ applications portables (vers diff�rentes base de donn�es). La
+ configuration de la g�n�ration d'identifiant peut �tre partag�e par
+ diff�rents mappings <literal>@Id</literal> avec l'attribut du g�n�rateur.
+ Il y a diff�rentes configurations disponibles avec
+ <literal>@SequenceGenerator</literal> et
+ <literal>@TableGenerator</literal>. La port�e d'un g�n�rateur peut �tre
+ l'application ou la classe. Les g�n�rateurs d�finis dans les classes ne
+ sont pas visibles � l'ext�rieur de la classe et peuvent surcharger les
+ g�n�rateurs de niveau applicatif. Les g�n�rateurs de niveau applicatif
+ sont d�finis au niveau XML (voir
+ <xref linkend="xml-overriding" />) :</para>
+
+ <programlisting><table-generator name="EMP_GEN"
+ table="GENERATOR_TABLE"
+ pk-column-name="key"
+ value-column-name="hi"
+ pk-column-value="EMP"
+ allocation-size="20"/>
+
+// et l'annotation �quivalente
+
+(a)javax.persistence.TableGenerator(
+ name="EMP_GEN",
+ table="GENERATOR_TABLE",
+ pkColumnName = "key",
+ valueColumnName = "hi"
+ pkColumnValue="EMP",
+ allocationSize=20
+)
+
+<sequence-generator name="SEQ_GEN"
+ sequence-name="my_sequence"
+ allocation-size="20"/>
+
+// et l'annotation �quivalente
+
+(a)javax.persistence.SequenceGenerator(
+ name="SEQ_GEN",
+ sequenceName="my_sequence",
+ allocationSize=20
+)
+ </programlisting>
+
+ <para>Si JPA XML (comme <filename>META-INF/orm.xml</filename>) est utilis�
+ pour d�finir les g�n�rateurs, <literal>EMP_GEN</literal> et
+ <literal>SEQ_GEN</literal> sont des g�n�rateurs de niveau applicatif.
+ <literal>EMP_GEN</literal> d�finit un g�n�rateur d'identifiant bas� sur
+ une table utilisant l'algorithme hilo avec un <literal>max_lo</literal> de
+ 20. La valeur haute est conserv�e dans une <literal>table</literal>
+ "<literal>GENERATOR_TABLE</literal>". L'information est gard�e dans une
+ ligne o� la colonne <literal>pkColumnName</literal> ("clef") est �gale �
+ <literal>pkColumnValue</literal> "<literal>EMP</literal>" et une colonne
+ <literal>valueColumnName</literal> "<literal>hi</literal>" contient la
+ prochaine valeur haute utilis�e.</para>
+
+ <para><literal>SEQ_GEN</literal> d�finit un g�n�rateur par s�quence
+ utilisant une s�quence nomm�e <literal>my_sequence</literal>. La taille
+ d'allocation utilis�e pour cet algorithme hilo bas� sur une s�quence est
+ 20. Notez que cette version d'Hibernate Annotations ne g�re pas
+ <literal>initialValue</literal> dans le g�n�rateur par s�quence.
+ La taille par d�faut de l'allocation est 50, donc si vous voulez utiliser
+ une s�quence et r�cup�rer la valeur chaque fois, vous devez positionner
+ la taille de l'allocation � 1.</para>
+
+ <note>
+ <para>La d�finition au niveau package n'est plus prise en charge par la
+ sp�cification EJB 3.0. Vous pouvez cependant utiliser
+ <literal>@GenericGenerator</literal> au niveau du package (voir <xref
+ linkend="entity-hibspec-identifier" />).</para>
+ </note>
+
+ <para>Le prochain exemple montre la d�finition d'un g�n�rateur par
+ s�quence dans la port�e d'une classe :</para>
+
+ <programlisting>
+@Entity
+(a)javax.persistence.SequenceGenerator(
+ name="SEQ_STORE",
+ sequenceName="my_sequence"
+)
+public class Store implements Serializable {
+ private Long id;
+
+ @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")
+ public Long getId() { return id; }
+}
+ </programlisting>
+
+ <para>Cette classe utilisera une s�quence nomm�e my_sequence et le
+ g�n�rateur SEQ_STORE n'est pas visible dans les autres classes. Notez que
+ vous pouvez regarder les tests unitaires d'Hibernate Annotations dans le
+ package org.hibernate.test.metadata.id pour plus d'exemples.</para>
+
+ <para>Vous pouvez d�finir une clef primaire compos�e � travers diff�rentes
+ syntaxes :</para>
+
+ <itemizedlist>
+ <listitem>
+ annote la propri�t� du composant comme @Id et rend la classe du
+ composant @Embeddable
+ </listitem>
+
+ <listitem>
+ annote la propri�t� du composant comme @EmbeddedId
+ </listitem>
+
+ <listitem>
+ annote la classe comme @IdClass et annote chaque propri�t� de
+ l'entit� impliqu�e dans la clef primaire avec @Id
+ </listitem>
+ </itemizedlist>
+
+ <para>Bien qu'assez commun pour le d�veloppeur EJB2,
+ <literal>@IdClass</literal> est probablement nouveau pour les utilisateurs
+ d'Hibernate. La classe de la clef primaire compos�e correspond aux
+ multiples champs ou propri�t�s de l'entit� ; de plus, les noms des champs
+ ou propri�t�s de la clef primaire et ceux de l'entit� doivent
+ correspondre ; et enfin, leur type doit �tre le m�me. Regardons un
+ exemple :</para>
+
+ <programlisting>@Entity
+<emphasis role="bold">@IdClass(FootballerPk.class)</emphasis>
+public class Footballer {
+ // partie de la clef
+ <emphasis role="bold">@Id</emphasis> public String getFirstname() {
+ return firstname;
+ }
+
+ public void setFirstname(String firstname) {
+ this.firstname = firstname;
+ }
+
+ // partie de la clef
+ <emphasis role="bold">@Id</emphasis> public String getLastname() {
+ return lastname;
+ }
+
+ public void setLastname(String lastname) {
+ this.lastname = lastname;
+ }
+
+ public String getClub() {
+ return club;
+ }
+
+ public void setClub(String club) {
+ this.club = club;
+ }
+
+ // impl�mentation appropri�e de equals() et hashCode()
+}
+
+@Embeddable
+public class FootballerPk implements Serializable {
+ // m�me nom et m�me type que dans Footballer
+ public String getFirstname() {
+ return firstname;
+ }
+
+ public void setFirstname(String firstname) {
+ this.firstname = firstname;
+ }
+
+ // m�me nom et m�me type que dans Footballer
+ public String getLastname() {
+ return lastname;
+ }
+
+ public void setLastname(String lastname) {
+ this.lastname = lastname;
+ }
+
+ // impl�mentation appropri�e de equals() et hashCode()
+}
+</programlisting>
+
+ <para>Comme vous pouvez le voir, <literal>@IdClass</literal> pointe vers
+ la classe de la clef primaire correspondante.</para>
+
+ <para>Bien que ce ne soit pas pris en charge par la sp�cification EJB3,
+ Hibernate vous permet de d�finir des associations � l'int�rieur d'un
+ identifiant compos�. Pour cela, utilisez simplement les annotations
+ habituelles.</para>
+
+ <programlisting>@Entity
+@AssociationOverride( name="id.channel", joinColumns = @JoinColumn(name="chan_id") )
+public class TvMagazin {
+ @EmbeddedId public TvMagazinPk id;
+ @Temporal(TemporalType.TIME) Date time;
+}
+
+@Embeddable
+public class TvMagazinPk implements Serializable {
+ @ManyToOne
+ public Channel channel;
+ public String name;
+ @ManyToOne
+ public Presenter presenter;
+}
+</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Mapper l'h�ritage</title>
+
+ <para>EJB3 prend en charge les trois types d'h�ritage :</para>
+
+ <itemizedlist>
+ <listitem>
+ Strat�gie d'une table par classe concr�te : l'�l�ment
+ <union-class> dans Hibernate
+ </listitem>
+
+ <listitem>
+ Strat�gie d'une seule table par hi�rarchie de classe : l'�l�ment
+ <subclass> dans Hibernate
+ </listitem>
+
+ <listitem>
+ Strat�gie d'une table par classe fille : l'�l�ment
+ <joined-subclass> dans Hibernate
+ </listitem>
+ </itemizedlist>
+
+ <para>La strat�gie choisie est d�clar�e au niveau de la classe de l'entit�
+ la plus haute dans la hi�rarhie en utilisant l'annotation
+ <literal>@Inheritance</literal>.</para>
+
+ <note>
+ <para>Annoter des interfaces n'est pour le moment pas pris en
+ charge.</para>
+ </note>
+
+ <sect3>
+ <title>Une table par classe concr�te</title>
+
+ <para>Cette strat�gie a beaucoup d'inconv�nients (surtout avec les
+ requ�tes polymorphiques et les associations) expliqu�s dans la
+ sp�cification EJB3, la documentation de r�f�rence d'Hibernate, Hibernate
+ in Action, et plusieurs autres endroits. Hibernate en contourne la
+ plupart en impl�mentant cette strat�gie en utilisant des requ�tes
+ <literal>SQL UNION</literal>. Elle est habituellement utilis�e pour le
+ niveau le plus haut d'une hi�rarchie d'h�ritage :</para>
+
+ <programlisting>
+@Entity
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class Flight implements Serializable {
+ </programlisting>
+
+ <para>Cette strat�gie prend en charge les associations de un vers
+ plusieurs bidirectionnelles. Cette strat�gie ne prend pas en charge
+ la strat�gie de g�n�rateur <literal>IDENTITY</literal> : l'identifiant
+ doit �tre partag� par plusieurs tables. Par cons�quent, lors de
+ l'utilisation de cette strat�gie, vous ne devriez pas utilisez
+ <literal>AUTO</literal> ni <literal>IDENTITY</literal>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Une seule table par hi�rarchie de classe</title>
+
+ <para>Toutes les propri�t�s de toutes les classes parentes et classes
+ filles sont mapp�es dans la m�me table, les instances sont diff�renci�es
+ par une colonne sp�ciale discriminante :</para>
+
+ <programlisting>
+@Entity
+(a)Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(
+ name="planetype",
+ discriminatorType=DiscriminatorType.STRING
+)
+@DiscriminatorValue("Plane")
+public class Plane { ... }
+
+@Entity
+@DiscriminatorValue("A320")
+public class A320 extends Plane { ... }
+ </programlisting>
+
+ <para><classname>Plane</classname> est la classe parente, elle d�finit
+ la strat�gie d'h�ritage <literal>InheritanceType.SINGLE_TABLE</literal>.
+ Elle d�finit aussi la colonne discriminante avec l'annotation
+ <literal>@DiscriminatorColumn</literal>, une colonne discriminante peut
+ aussi d�finir le type du discriminant. Finalement, l'annotation
+ <literal>@DiscriminatorValue</literal> d�finit la valeur utilis�e pour
+ diff�rencier une classe dans la hi�rarchie. Tous ces attributs ont des
+ valeurs par d�faut sens�es. Le nom par d�faut de la colonne
+ discriminante est <literal>DTYPE</literal>. La valeur discriminante par
+ d�faut est le nom de l'entit� (comme d�fini dans
+ <literal>@Entity.name</literal>) avec le type
+ <literal>DiscriminatorType.STRING</literal>. <classname>A320</classname>
+ est une classe fille ; vous devez seulement d�finir la valeur
+ discriminante si vous ne voulez pas utiliser la valeur par d�faut. La
+ strat�gie et le type du discriminant sont implicites.</para>
+
+ <para><literal>@Inheritance</literal> et
+ <literal>@DiscriminatorColumn</literal> devraient seulement �tre
+ d�finies sur l'entit� la plus haute de la hi�rarchie.</para>
+ </sect3>
+
+ <sect3>
+ <title>Une table par classe fille</title>
+
+ <para>Les annotations <literal> @PrimaryKeyJoinColumn</literal> et
+ <literal>@PrimaryKeyJoinColumns</literal> d�finissent la (les) clef(s)
+ primaire(s) de la table de la classe fille jointe :</para>
+
+ <programlisting>
+@Entity
+(a)Inheritance(strategy=InheritanceType.JOINED)
+public class Boat implements Serializable { ... }
+
+@Entity
+public class Ferry extends Boat { ... }
+
+@Entity
+@PrimaryKeyJoinColumn(name="BOAT_ID")
+public class AmericaCupClass extends Boat { ... }
+ </programlisting>
+
+ <para>Toutes les entit�s ci-dessus utilisent la strat�gie
+ <literal>JOINED</literal>, la table <literal>Ferry</literal> est jointe
+ avec la table <literal>Boat</literal> en utilisant les m�mes noms de
+ clef primaire. La table <literal>AmericaCupClass</literal> est jointe
+ avec <literal>Boat</literal> en utilisant la condition de jointure
+ <code>Boat.id = AmericaCupClass.BOAT_ID</code>.</para>
+ </sect3>
+
+ <sect3>
+ <title>H�ritage de propri�t�s des classes parentes</title>
+
+ <para>Il est parfois utile de partager des propri�t�s communes � travers
+ une classe technique ou m�tier sans l'inclure comme une entit�
+ habituelle (c'est-�-dire aucune table sp�cifique pour cette entit�).
+ Pour cela, vous pouvez les mapper comme
+ <literal>@MappedSuperclass</literal>.</para>
+
+ <programlisting>@MappedSuperclass
+public class BaseEntity {
+ @Basic
+ @Temporal(TemporalType.TIMESTAMP)
+ public Date getLastUpdate() { ... }
+ public String getLastUpdater() { ... }
+ ...
+}
+
+@Entity class Order extends BaseEntity {
+ @Id public Integer getId() { ... }
+ ...
+}</programlisting>
+
+ <para>En base de donn�es, cette hi�rarchie sera repr�sent�e comme une
+ table <literal>Order</literal> ayant les colonnes <literal>id</literal>,
+ <literal>lastUpdate</literal> et <literal>lastUpdater</literal>.
+ Les mappings de propri�t� de la classe parente embarqu�e sont copi�s
+ dans les classes filles de l'entit�. Souvenez-vous que la classe parente
+ embarquable n'est cependant pas la racine de la hi�rarchie.</para>
+
+ <note>
+ <para>Les propri�t�s des classes parentes non mapp�es comme
+ <literal>@MappedSuperclass</literal> sont ignor�es.</para>
+ </note>
+
+ <note>
+ <para>Le type d'acc�s (champ ou m�thode) est h�rit� de l'entit�
+ racine, � moins que vous utilisiez l'annotation Hibernate
+ <literal>@AccessType</literal>.</para>
+ </note>
+
+ <note>
+ <para>La m�me notion peut �tre appliqu�e aux objets
+ <literal>@Embeddable</literal> pour persister des propri�t�s de leurs
+ classes parentes. Vous avez aussi besoin d'utiliser
+ <literal>@MappedSuperclass</literal> pour faire �a (cependant cela ne
+ devrait pas �tre consid�r� comme une fonctionnalit� EJB3
+ standard).</para>
+ </note>
+
+ <note>
+ <para>Il est permis de marquer une classe comme
+ <literal>@MappedSuperclass</literal> dans le milieu d'une hi�rarchie
+ d'h�ritage mapp�e.</para>
+ </note>
+
+ <note>
+ <para>Toute classe de la hi�rarchie non annot�e avec
+ <literal>@MappedSuperclass</literal> ou <literal>@Entity</literal>
+ sera ignor�e.</para>
+ </note>
+
+ <para>Vous pouvez surcharger des colonnes d�finies dans des entit�s
+ parentes au niveau de l'entit� racine en utilisant l'annotation
+ <literal>@AttributeOverride</literal>.</para>
+
+ <programlisting>@MappedSuperclass
+public class FlyingObject implements Serializable {
+
+ public int getAltitude() {
+ return altitude;
+ }
+
+ @Transient
+ public int getMetricAltitude() {
+ return metricAltitude;
+ }
+
+ @ManyToOne
+ public PropulsionType getPropulsion() {
+ return metricAltitude;
+ }
+ ...
+}
+
+@Entity
+@AttributeOverride( name="altitude", column = @Column(name="fld_altitude") )
+@AssociationOverride( name="propulsion", joinColumns = @JoinColumn(name="fld_propulsion_fk") )
+public class Plane extends FlyingObject {
+ ...
+}</programlisting>
+
+ <para>La propri�t� <literal>altitude</literal> sera persist�e dans la
+ colonne <literal>fld_altitude</literal> de la table
+ <literal>Plane</literal> et l'association <literal>propulsion</literal>
+ sera mat�rialis�e dans la colonne de clef �trang�re
+ <literal>fld_propulsion_fk</literal>.</para>
+
+ <para>Vous pouvez d�finir <literal>@AttributeOverride</literal>(s) et
+ <literal>@AssociationOverride</literal>(s) sur des classes
+ <literal>@Entity</literal>, des classes
+ <literal>@MappedSuperclass</literal> et des propri�t�s pointant vers un
+ objet <literal>@Embeddable</literal>.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="entity-mapping-association">
+ <title>Mapper des associations/relations d'entity beans</title>
+
+ <sect3>
+ <title>One-to-one</title>
+
+ <para>Vous pouvez associer des entity beans avec une relation one-to-one
+ en utilisant <literal>@OneToOne</literal>. Il y a trois cas pour les
+ associations one-to-one : soit les entit�s associ�es partagent les m�mes
+ valeurs de clef primaire, soit une clef �trang�re est d�tenue par une
+ des entit�s (notez que cette colonne de clef �trang�re dans la base de
+ donn�es devrait �tre avoir une contrainte d'unicit� pour simuler la
+ cardinalit� one-to-one), soit une table d'association est utilis�e pour
+ stocker le lien entre les 2 entit�s (une contrainte d'unicit� doit �tre
+ d�finie sur chaque clef �trang�re pour assurer la cardinalit� un �
+ un).</para>
+
+ <para>Tout d'abord, nous mappons une v�ritable association one-to-one en
+ utilisant des clefs primaires partag�es :</para>
+
+ <programlisting>
+@Entity
+public class Body {
+ @Id
+ public Long getId() { return id; }
+
+ @OneToOne(cascade = CascadeType.ALL)
+ @PrimaryKeyJoinColumn
+ public Heart getHeart() {
+ return heart;
+ }
+ ...
+}
+ </programlisting>
+
+ <programlisting>
+@Entity
+public class Heart {
+ @Id
+ public Long getId() { ...}
+}
+ </programlisting>
+
+ <para>L'association un � un est activ�e en utilisant l'annotation
+ <literal>@PrimaryKeyJoinColumn</literal>.</para>
+
+ <para>Dans l'exemple suivant, les entit�s associ�es sont li�es � travers
+ une clef �trang�re :</para>
+
+ <programlisting>
+@Entity
+public class Customer implements Serializable {
+ @OneToOne(cascade = CascadeType.ALL)
+ <emphasis role="bold">@JoinColumn(name="passport_fk")</emphasis>
+ public Passport getPassport() {
+ ...
+ }
+
+@Entity
+public class Passport implements Serializable {
+ @OneToOne(<emphasis role="bold">mappedBy = "passport"</emphasis>)
+ public Customer getOwner() {
+ ...
+}
+ </programlisting>
+
+ <para>Un <classname>Customer</classname> est li� � un
+ <classname>Passport</classname>, avec une colonne de clef �trang�re
+ nomm�e <literal>passport_fk</literal> dans la table
+ <literal>Customer</literal>. La colonne de jointure est d�clar�e avec
+ l'annotation <literal>@JoinColumn</literal> qui ressemble � l'annotation
+ <literal>@Column</literal>. Elle a un param�tre de plus nomm�
+ <literal>referencedColumnName</literal>. Ce param�tre d�clare la colonne
+ dans l'entit� cible qui sera utilis�e pour la jointure. Notez que lors
+ de l'utilisation de <literal>referencedColumnName</literal> vers une
+ colonne qui ne fait pas partie de la clef primaire, la classe associ�e
+ doit �tre <classname>Serializable</classname>. Notez aussi que
+ <literal>referencedColumnName</literal> doit �tre mapp� sur une
+ propri�t� ayant une seule colonne lorsqu'elle pointe vers une colonne
+ qui ne fait pas partie de la clef primaire (d'autres cas pourraient ne
+ pas fonctionnner).</para>
+
+ <para>L'association peut �tre bidirectionnelle. Dans une relation
+ bidirectionnelle, une des extr�mit�s (et seulement une) doit �tre la
+ propri�taire : la propri�taire est responsable de la mise � jour des
+ colonnes de l'association. Pour d�clarer une extr�mit� comme
+ <emphasis>non</emphasis> responsable de la relation, l'attribut
+ <literal>mappedBy</literal> est utilis�.
+ <literal>mappedBy</literal> r�f�rence le nom de la propri�t� de
+ l'association du c�t� du propri�taire. Dans notre cas, c'est
+ <literal>passport</literal>. Comme vous pouvez le voir, vous ne devez
+ (absolument) pas d�clarer la colonne de jointure puisqu'elle a d�j� �t�
+ d�clar�e du c�t� du propri�taire.</para>
+
+ <para>Si aucune <literal>@JoinColumn</literal> n'est d�clar�e du c�t� du
+ propri�taire, les valeurs par d�faut s'appliquent. Une(des) colonne(s)
+ de jointure sera(ont) cr��e(s) dans la table propri�taire, et son(leur)
+ nom sera la concat�nation du nom de la relation du c�t� propri�taire,
+ <keycap>_</keycap> (underscore), et le nom de la (des) colonne(s) de la
+ clef primaire du propri�taire. Dans cet exemple
+ <literal>passport_id</literal> parce que le nom de la propri�t� est
+ <literal>passport</literal> et la colonne identifiante de
+ <literal>Passport</literal> est <literal>id</literal>.</para>
+
+ <para>La troisi�me possibilit� (utilisant une table d'association) est
+ tr�s exotique.</para>
+
+ <programlisting>
+@Entity
+public class Customer implements Serializable {
+ @OneToOne(cascade = CascadeType.ALL)
+ <emphasis role="bold">@JoinTable(name = "CustomerPassports"
+ joinColumns = @JoinColumn(name="customer_fk"),
+ inverseJoinColumns = @JoinColumns(name="passport_fk")</emphasis>
+ )
+ public Passport getPassport() {
+ ...
+ }
+
+@Entity
+public class Passport implements Serializable {
+ @OneToOne(<emphasis role="bold">mappedBy = "passport"</emphasis>)
+ public Customer getOwner() {
+ ...
+}
+ </programlisting>
+
+ <para>Un <classname>Customer</classname> est li� � un
+ <classname>Passport</classname> � travers une table d'association
+ nomm�e <literal>CustomerPassports</literal> ; cette table d'association
+ a une colonne de clef �trang�re nomm�e <literal>passport_fk</literal>
+ pointant vers la table <literal>Passport</literal> (mat�rialis�e par
+ l'attribut <literal>inverseJoinColumn</literal>), et une colonne de clef
+ �trang�re nomm�e <literal>customer_fk</literal> pointant vers la table
+ <literal>Customer</literal> (mat�rialis�e par l'attribut
+ <literal>joinColumns</literal>).</para>
+
+ <para>Vous devez d�clarer le nom de la table de jointure et les colonnes
+ de jointure explicitement dans un tel mapping.</para>
+ </sect3>
+
+ <sect3>
+ <title>Many-to-one</title>
+
+ <para>Les associations Many-to-one sont d�clar�es au niveau de la
+ propri�t� avec l'annotation <literal>@ManyToOne</literal> :</para>
+
+ <programlisting>
+@Entity()
+public class Flight implements Serializable {
+ <emphasis role="bold">@ManyToOne</emphasis>( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
+ @JoinColumn(name="COMP_ID")
+ public Company getCompany() {
+ return company;
+ }
+ ...
+}
+ </programlisting>
+
+ <para>L'attribut <literal>@JoinColumn</literal> est optionnel, la valeur
+ par d�faut est comme l'association un � un, la concat�nation du nom
+ de la relation du c�t� propri�taire, <keycap>_</keycap>
+ (underscore), et le nom de la colonne de la clef primaire du c�t�
+ propri�taire. Dans cet exemple, <literal>company_id</literal> parce que
+ le nom de la propri�t� est <literal>company</literal> et la colonne
+ identifiante de Company est <literal>id</literal>.</para>
+
+ <para><literal>@ManyToOne</literal> a un param�tre nomm�
+ <literal>targetEntity</literal> qui d�crit le nom de l'entit� cible.
+ G�n�ralement, vous ne devriez pas avoir besoin de ce param�tre puisque
+ la valeur par d�faut (le type de la propri�t� qui stocke l'association)
+ est correcte dans la plupart des cas. Il est cependant utile lorsque
+ vous souhaitez retourner une interface plut�t qu'une entit�
+ normale.</para>
+
+ <programlisting>
+@Entity()
+public class Flight implements Serializable {
+ @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE}, <emphasis
+ role="bold">targetEntity=CompanyImpl.class</emphasis> )
+ @JoinColumn(name="COMP_ID")
+ public Company getCompany() {
+ return company;
+ }
+ ...
+}
+
+public interface Company {
+ ...
+ </programlisting>
+
+ <para>Vous pouvez sinon mapper une association plusieurs � un avec une
+ table d'association. Cette association d�crite par l'annotation
+ <literal>@JoinTable</literal> contiendra une clef �trang�re r�f�ren�ant
+ la table de l'entit� (avec
+ <literal>@JoinTable.joinColumns</literal>) et une clef �trang�re
+ r�f�ren�ant la table de l'entit� cible (avec
+ <literal>@JoinTable.inverseJoinColumns</literal>).</para>
+
+ <programlisting>
+@Entity()
+public class Flight implements Serializable {
+ @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
+ <emphasis role="bold">@JoinTable(name="Flight_Company",
+ joinColumns = @JoinColumn(name="FLIGHT_ID"),
+ inverseJoinColumns = @JoinColumns(name="COMP_ID")
+ )</emphasis>
+ public Company getCompany() {
+ return company;
+ }
+ ...
+}
+ </programlisting>
+ </sect3>
+
+ <sect3 id="entity-mapping-association-collections">
+ <title>Collections</title>
+
+ <sect4 id="entity-mapping-association-collections-overview"
+ revision="1">
+ <title>Vue d'ensemble</title>
+
+ <para>Vous pouvez mapper des <classname>Collection</classname>s, des
+ <literal>List</literal>s (ie des listes ordonn�es, pas des listes
+ index�es), des <literal>Map</literal>s et des
+ <classname>Set</classname>s. La sp�cification EJB3 d�crit comment
+ mapper une liste ordonn�e (ie une liste ordonn�e au chargement) en
+ utilisant l'annotation <literal>@javax.persistence.OrderBy</literal> :
+ pour ordonner la collection, cette annotation prend en param�tre une
+ liste de propri�t�s (de l'entit� cible) s�par�es par des virgules
+ (p. ex. <code>firstname asc, age desc</code>) ; si la cha�ne de
+ caract�res est vide, la collection sera ordonn�e par les identifiants.
+ Pour le moment <literal>@OrderBy</literal> fonctionne seulement sur
+ des collections n'ayant pas de table d'association. Pour les
+ v�ritables collections index�es, veuillez vous r�f�rer �
+ <xref linkend="entity-hibspec" />. EJB3 vous permet de mapper des
+ <literal>Map</literal>s en utilisant comme clef une des propri�t�s de
+ l'entit� cible avec <literal>@MapKey(name="myProperty")</literal>
+ (myProperty est un nom de propri�t� de l'entit� cible). Lorsque vous
+ utilisez <literal>@MapKey</literal> sans nom de propri�t�, la clef
+ primaire de l'entit� cible est utilis�e. La clef de la map utilise la
+ m�me colonne que celle point�e par la propri�t� : il n'y a pas de
+ colonne suppl�mentaire d�finie pour la clef de la map, et c'est normal
+ puisque la clef de la map repr�sente en fait un propri�t� de la cible.
+ Faites attention qu'une fois charg�e, la clef n'est plus synchronis�e
+ avec la propri�t�, en d'autres mots, si vous modifiez la valeur de la
+ propri�t�, la clef ne sera pas chang�e automatiquement dans votre
+ mod�le Java (pour une v�ritable prise en charge des maps veuillez vous
+ r�f�rer � <xref linkend="entity-hibspec" />). Beaucoup de gens
+ confondent les capacit�s de <literal><map></literal> et celles
+ de <literal>@MapKey</literal>. Ce sont deux fonctionnalit�s
+ diff�rentes. <literal>@MapKey</literal> a encore quelques limitations,
+ veuillez vous r�f�rer au forum ou au syst�me de suivi de bogues JIRA
+ pour plus d'informations.</para>
+
+ <para>Hibernate a plusieurs notions de collections.</para>
+
+ <para></para>
+
+ <table>
+ <title>S�mantique des collections</title>
+
+ <tgroup cols="3">
+ <colspec colname="c1" />
+
+ <colspec colname="c2" />
+
+ <colspec colname="c3" colnum="2" />
+
+ <thead>
+ <row>
+ <entry>S�mantique</entry>
+
+ <entry>Repr�sentation Java</entry>
+
+ <entry>Annotations</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>S�mantique de Bag</entry>
+
+ <entry>java.util.List, java.util.Collection</entry>
+
+ <entry>@org.hibernate.annotations.CollectionOfElements ou
+ @OneToMany ou @ManyToMany</entry>
+ </row>
+
+ <row>
+ <entry>S�mantique de Bag avec une clef primaire (sans les
+ limitations de la s�mantique de Bag)</entry>
+
+ <entry>java.util.List, java.util.Collection</entry>
+
+ <entry>(@org.hibernate.annotations.CollectionOfElements ou
+ @OneToMany ou @ManyToMany) et @CollectionId</entry>
+ </row>
+
+ <row>
+ <entry>S�mantique de List</entry>
+
+ <entry>java.util.List</entry>
+
+ <entry>(@org.hibernate.annotations.CollectionOfElements ou
+ @OneToMany ou @ManyToMany) et
+ @org.hibernate.annotations.IndexColumn</entry>
+ </row>
+
+ <row>
+ <entry>S�mantique de Set</entry>
+
+ <entry>java.util.Set</entry>
+
+ <entry>@org.hibernate.annotations.CollectionOfElements ou
+ @OneToMany ou @ManyToMany</entry>
+ </row>
+
+ <row>
+ <entry>S�mantique de Map</entry>
+
+ <entry>java.util.Map</entry>
+
+ <entry>(@org.hibernate.annotations.CollectionOfElements ou
+ @OneToMany ou @ManyToMany) et (rien ou
+ @org.hibernate.annotations.MapKey/MapKeyManyToMany pour une
+ v�ritable prise en charge des maps, ou
+ @javax.persistence.MapKey</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <remark>Donc sp�cifiquement, les collections java.util.List sans
+ @org.hibernate.annotations.IndexColumn vont �tre consid�r�es commes
+ des bags.</remark>
+
+ <para>Les collections de types primitifs, de types core ou d'objets
+ embarqu�s ne sont pas prises en charge par la sp�cification EJB3.
+ Cependant Hibernate Annotations les autorise
+ (voir <xref linkend="entity-hibspec" />).</para>
+
+ <programlisting>@Entity public class City {
+ @OneToMany(mappedBy="city")
+ <emphasis role="bold">@OrderBy("streetName")</emphasis>
+ public List<Street> getStreets() {
+ return streets;
+ }
+...
+}
+
+@Entity public class Street {
+ <emphasis role="bold">public String getStreetName()</emphasis> {
+ return streetName;
+ }
+
+ @ManyToOne
+ public City getCity() {
+ return city;
+ }
+ ...
+}
+
+
+@Entity
+public class Software {
+ @OneToMany(mappedBy="software")
+ <emphasis role="bold">@MapKey(name="codeName")</emphasis>
+ public Map<String, Version> getVersions() {
+ return versions;
+ }
+...
+}
+
+@Entity
+@Table(name="tbl_version")
+public class Version {
+ <emphasis role="bold">public String getCodeName()</emphasis> {...}
+
+ @ManyToOne
+ public Software getSoftware() { ... }
+...
+}</programlisting>
+
+ <para>Donc <literal>City</literal> a une collection de
+ <literal>Street</literal>s qui sont ordonn�es par
+ <literal>streetName</literal> (de <literal>Street</literal>) lorsque
+ la collection est charg�e. <literal>Software</literal> a une map de
+ <literal>Version</literal>s dont la clef est
+ <literal>codeName</literal> de <literal>Version</literal>.</para>
+
+ <para>A moins que la collection soit une "generic", vous devrez
+ d�finir <literal>targetEntity</literal>. C'est un attribut de
+ l'annotation qui prend comme valeur la classe de l'entit�
+ cible.</para>
+ </sect4>
+
+ <sect4 id="entity-mapping-association-collection-onetomany"
+ revision="2">
+ <title>One-to-many</title>
+
+ <para>Les associations one-to-many sont d�clar�es au niveau propri�t�
+ avec l'annotation <literal>@OneToMany</literal>. Les associations un
+ � plusieurs peuvent �tre bidirectionnelles.</para>
+
+ <sect5>
+ <title>Relation bidirectionnelle</title>
+
+ <para>Puisque les associations plusieurs � un sont (presque)
+ toujours l'extr�mit� propri�taire de la relation bidirectionnelle
+ dans la sp�cification EJB3, l'association un � plusieurs est
+ annot�e par <literal>@OneToMany(mappedBy=...)</literal>.</para>
+
+ <programlisting>@Entity
+public class Troop {
+ @OneToMany(mappedBy="troop")
+ public Set<Soldier> getSoldiers() {
+ ...
+}
+
+@Entity
+public class Soldier {
+ @ManyToOne
+ @JoinColumn(name="troop_fk")
+ public Troop getTroop() {
+ ...
+} </programlisting>
+
+ <para><classname>Troop</classname> a une relation bidirectionnelle
+ un � plusieurs avec <literal>Soldier</literal> � travers la
+ propri�t� <literal>troop</literal>. Vous ne devez pas d�finir
+ de mapping physique � l'extr�mit� de
+ <literal>mappedBy</literal>.</para>
+
+ <para>Pour mapper une relation bidirectionnelle un � plusieurs, avec
+ l'extr�mit� one-to-many comme extr�mit� propri�taire, vous devez
+ enlever l'�l�ment <literal>mappedBy</literal> et marquer
+ l'annotation <literal>@JoinColumn</literal> de l'extr�mit� plusieurs
+ � un comme ne pouvant pas �tre ins�r�e et ni mise � jour. Cette
+ solution n'est certainement pas optimis�e et produira quelques
+ commandes UPDATE suppl�mentaires.</para>
+
+ <programlisting>@Entity
+public class Troop {
+ @OneToMany
+ @JoinColumn(name="troop_fk") // nous avons besoin de dupliquer l'information physique
+ public Set<Soldier> getSoldiers() {
+ ...
+}
+
+@Entity
+public class Soldier {
+ @ManyToOne
+ @JoinColumn(name="troop_fk", insertable=false, updatable=false)
+ public Troop getTroop() {
+ ...
+}</programlisting>
+ </sect5>
+
+ <sect5>
+ <title>Relation unidirectionnelle</title>
+
+ <para>Une relation un � plusieurs unidirectionnelle utilisant une
+ colonne de clef �trang�re de l'entit� propri�taire n'est pas si
+ commune, r�ellement recommand�e. Nous vous conseillons
+ fortement d'utiliser une table de jointure pour cette sorte
+ d'association (comme expliqu� dans la prochaine section). Cette
+ sorte d'association est d�crite � travers
+ <literal>@JoinColumn</literal>.</para>
+
+ <programlisting>
+@Entity
+public class Customer implements Serializable {
+ @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
+ @JoinColumn(name="CUST_ID")
+ public Set<Ticket> getTickets() {
+ ...
+}
+
+@Entity
+public class Ticket implements Serializable {
+ ... // pas de relation bidirectionnelle
+}
+ </programlisting>
+
+ <para><literal>Customer</literal> d�crit une relation
+ unidirectionnelle avec <literal>Ticket</literal> en utilisant la
+ colonne de jointure <literal>CUST_ID</literal>.</para>
+ </sect5>
+
+ <sect5>
+ <title>Relation unidirectionnel avec une table de jointure</title>
+
+ <para>Une relation unidirectionnelle un � plusieurs avec une table
+ de jointure est largement pr�f�r�e. Cette association est d�crite
+ � travers l'annotation <literal>@JoinTable</literal>.</para>
+
+ <programlisting>
+@Entity
+public class Trainer {
+ @OneToMany
+ @JoinTable(
+ name="TrainedMonkeys",
+ joinColumns = { @JoinColumn( name="trainer_id") },
+ inverseJoinColumns = @JoinColumn( name="monkey_id")
+ )
+ public Set<Monkey> getTrainedMonkeys() {
+ ...
+}
+
+@Entity
+public class Monkey {
+ ... // pas de relation bidirectionnelle
+}
+ </programlisting>
+
+ <para><literal>Trainer</literal> d�crit une relation
+ unidirectionelle avec <classname>Monkey</classname> en utilisant la
+ table de jointure <classname>TrainedMonkeys</classname>, avec une
+ clef �trang�re <literal>trainer_id</literal> vers
+ <literal>Trainer</literal> (<literal>joinColumns</literal>) et une
+ clef �trang�re <literal>monkey_id</literal> vers
+ <literal>Monkey</literal>
+ (<literal>inversejoinColumns</literal>).</para>
+ </sect5>
+
+ <sect5 id="entity-mapping-association-collection-manytomany-default"
+ revision="1">
+ <title>Valeurs par d�faut</title>
+
+ <para>Si aucun mapping physique n'est d�clar�, une relation
+ unidirectionnelle un vers plusieurs utilise une table de jointure.
+ Le nom de la table est la concat�nation du nom de la table
+ propri�taire, <keycap>_</keycap>, et le nom de la table de l'autre
+ extr�mit�. Le nom des colonnes de la clef �trang�re r�f�ren�ant la
+ table propri�taire est la concat�nation de la table propri�taire,
+ <keycap>_</keycap>, et le nom des colonnes de la clef primaire. Le
+ nom des colonnes de la clef �trang�re r�f�ren�ant l'autre extr�mit�
+ est la concat�nation du nom de la propri�t� du propri�taire,
+ <keycap>_</keycap>, et le nom des colonnes de la clef primaire de
+ l'autre extr�mit�. Une contrainte d'unicit� est ajout�e sur la
+ clef �trang�re r�f�ren�ant la table de l'autre extr�mit� pour
+ r�fl�ter le un � plusieurs.</para>
+
+ <programlisting>
+@Entity
+public class Trainer {
+ @OneToMany
+ public Set<Tiger> getTrainedTigers() {
+ ...
+}
+
+@Entity
+public class Tiger {
+ ... // non bidirectionnelle
+}
+ </programlisting>
+
+ <para><classname>Trainer</classname> d�crit une relation
+ unidirectionnelle avec <classname>Tiger</classname> utilisant la
+ table de jointure <literal>Trainer_Tiger</literal>, avec une clef
+ �trang�re <literal>trainer_id</literal> vers
+ <literal>Trainer</literal> (nom de la table, <keycap>_</keycap>,
+ identifiant de trainer) et une clef �trang�re
+ <literal>trainedTigers_id</literal> vers <literal>Monkey</literal>
+ (nom de la propri�t�, <keycap>_</keycap>, colonne de la clef
+ primaire de Tiger).</para>
+ </sect5>
+ </sect4>
+
+ <sect4 id="eentity-mapping-association-collection-manytomany"
+ revision="">
+ <title>Many-to-many</title>
+
+ <sect5>
+ <title>D�finition</title>
+
+ <para>Une association many-to-many est d�finie logiquement en
+ utilisant l'annotation <literal>@ManyToMany</literal>. Vous devez
+ aussi d�crire la table d'association et les conditions de jointure
+ en utilisant l'annotation <literal>@JoinTable</literal>. Si
+ l'association est bidirectionnelle, une extr�mit� doit �tre la
+ propri�taire et l'autre doit �tre marqu�e comme "inverse" (ie
+ qu'elle sera ignor�e lors de la mise � jour des valeurs de la
+ relation dans la table d'association) :</para>
+
+ <programlisting>
+@Entity
+public class Employer implements Serializable {
+ @ManyToMany(
+ targetEntity=org.hibernate.test.metadata.manytomany.Employee.class,
+ cascade={CascadeType.PERSIST, CascadeType.MERGE}
+ )
+ @JoinTable(
+ name="EMPLOYER_EMPLOYEE",
+ joinColumns={@JoinColumn(name="EMPER_ID")},
+ inverseJoinColumns={@JoinColumn(name="EMPEE_ID")}
+ )
+ public Collection getEmployees() {
+ return employees;
+ }
+ ...
+}
+ </programlisting>
+
+ <programlisting>
+@Entity
+public class Employee implements Serializable {
+ @ManyToMany(
+ cascade={CascadeType.PERSIST, CascadeType.MERGE},
+ mappedBy="employees"
+ targetEntity=Employer.class
+ )
+ public Collection getEmployers() {
+ return employers;
+ }
+}
+ </programlisting>
+
+ <para>Nous avons d�j� montr� les d�clarations des relations
+ "many" et d�taill� les attributs de ces associations. Allons
+ plus en profondeur dans la description de
+ <literal>@JoinTable</literal> ; elle d�finit un
+ <literal>name</literal>, un tableau de colonnes de jointure (un
+ tableau dans une annotation est d�fini par {A, B, C}), et un tableau
+ de colonnes de jointure inverse. Ces derni�res sont les colonnes
+ de la table d'association qui r�f�rencent la clef primaire de
+ <classname>Employee</classname> ("l'autre extr�mit�").</para>
+
+ <para>Comme vu pr�c�demment, l'autre extr�mit� ne doit pas d�crire
+ le mapping physique : un simple argument
+ <literal>mappedBy</literal> contenant le nom de la propri�t� de
+ l'extr�mit� propri�taire suffit � relier les deux.</para>
+ </sect5>
+
+ <sect5>
+ <title>Valeurs par d�faut</title>
+
+ <para>Comme d'autres annotations, la plupart des valeurs d'une
+ relation plusieurs � plusieurs sont inf�r�es. Si aucun mapping
+ physique n'est d�crit dans une relation plusieurs � plusieurs
+ unidirectionnelle, alors les r�gles suivantes s'appliquent. Le nom
+ de la table est la concat�nation du nom de la table propri�taire,
+ <keycap>_</keycap> et le nom de la table de l'autre extr�mit�. Le
+ nom des colonnes de la clef �trang�re r�f�ren�ant la table
+ propri�taire est la concat�nation du nom de la table propri�taire,
+ <keycap>_</keycap> et le nom des colonnes de la clef primaire
+ de cette table. Le nom des colonnes de la clef �trang�re r�f�ren�ant
+ l'autre extr�mit� est la concat�nation du nom de la propri�t� du
+ propri�taire, <keycap>_</keycap> et le nom des colonnes de la
+ clef primaire de l'autre extr�mit�. Ce sont les m�mes r�gles que
+ celles utilis�es pour une relation un � plusieurs
+ unidirectionnelle.</para>
+
+ <programlisting>
+@Entity
+public class Store {
+ @ManyToMany(cascade = CascadeType.PERSIST)
+ public Set<City> getImplantedIn() {
+ ...
+ }
+}
+
+@Entity
+public class City {
+ ... // pas de relation bidirectionnelle
+}
+ </programlisting>
+
+ <para>La table <literal>Store_City</literal> est utilis�e comme
+ table de jointure. La colonne <literal>Store_id</literal> est
+ une clef �trang�re vers la table <literal>Store</literal>. La
+ colonne <literal>implantedIn_id</literal> est une clef �trang�re
+ vers la table <literal>City</literal>.</para>
+
+ <para>Si aucun mapping physique n'est d�crit dans une relation
+ plusieurs � plusieurs bidirectionnelle, alors les r�gles suivantes
+ s'appliquent. Le nom de la table est la concat�nation du nom de la
+ table propri�taire, <keycap>_</keycap> et le nom de la table de
+ l'autre extr�mit�. Le nom des colonnes de la clef �trang�re
+ r�f�ren�ant la table propri�taire est la concat�nation du nom de la
+ propri�t� de l'autre extr�mit�, <keycap>_</keycap> et le nom des
+ colonnes de la clef primaire du propri�taire. Le nom des colonnes de
+ la clef �trang�re r�f�ren�ant l'autre extr�mit� est la concat�nation
+ du nom de la propri�t� du propri�taire, <keycap>_</keycap> et le nom
+ des colonnes de la clef primaire de l'autre extr�mit�. Ce sont les
+ m�mes r�gles que celles utilis�es pour une relation un � plusieurs
+ unidirectionnelle.</para>
+
+ <programlisting>
+@Entity
+public class Store {
+ @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
+ public Set<Customer> getCustomers() {
+ ...
+ }
+}
+
+@Entity
+public class Customer {
+ @ManyToMany(mappedBy="customers")
+ public Set<Store> getStores() {
+ ...
+ }
+}
+ </programlisting>
+
+ <para>La table <literal>Store_Customer</literal> est utilis�e comme
+ table de jointure. La colonne <literal>stores_id</literal> est une
+ clef �trang�re vers la table <literal>Store</literal>. La colonne
+ <literal>customers_id</literal> est une clef �trang�re vers la table
+ <literal>Customer</literal>.</para>
+ </sect5>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>Persistance transitive avec les op�rations en cascade</title>
+
+ <para>Vous avez probablement remarqu� l'attribut
+ <literal>cascade</literal> prenant comme valeur un tableau de
+ <classname>CascadeType</classname>s. Le concept de cascade dans EJB3 est
+ similaire � la persistance transitive et les op�rations en cascade dans
+ Hibernate, mais avec une s�mantique l�g�rement diff�rente et les types
+ de cascade suivants :</para>
+
+ <itemizedlist>
+ <listitem>
+ CascadeType.PERSIST : effectue en cascade l'op�ration de
+ persistance (cr�ation) sur les entit�s associ�es si persist() est
+ appel�e ou si l'entit� est supervis�e (par le gestionnaire
+ d'entit�s)
+ </listitem>
+
+ <listitem>
+ CascadeType.MERGE : effectue en cascade l'op�ration de fusion sur
+ les entit�s associ�es si merge() est app�l�e ou si l'entit� est
+ supervis�e
+ </listitem>
+
+ <listitem>
+ CascadeType.REMOVE : effectue en cascade l'op�ration de
+ suppression sur les entit�s associ�es si delete() est appel�e
+ </listitem>
+
+ <listitem>
+ CascadeType.REFRESH : effectue en cascade l'op�ration de
+ rafra�chissement sur les entit�s associ�es si refresh() est appel�e
+ </listitem>
+
+ <listitem>
+ CascadeType.ALL : tous ceux du dessus
+ </listitem>
+ </itemizedlist>
+
+ <para>Veullez vous r�f�rer au chapitre 6.3 de la sp�cification EJB3 pour
+ plus d'informations sur les op�rations en cascade et la s�mantique des
+ op�rations de cr�ation/fusion.</para>
+ </sect3>
+
+ <sect3>
+ <title>R�cup�ration d'associations</title>
+
+ <para>Vous avez la possibilit� de r�cup�rer les entit�s associ�es soit
+ imm�diatement ("eager"), soit � la demande ("lazy"). Le param�tre
+ <literal>fetch</literal> peut �tre positionn� �
+ <literal>FetchType.LAZY</literal> ou �
+ <literal>FetchType.EAGER</literal>. <literal>EAGER</literal> essaiera
+ d'utiliser une jointure externe pour rappatrier l'objet associ�,
+ alors que <literal>LAZY</literal> est la valeur par d�faut et rapportera
+ les donn�es lorsque l'objet associ� sera acc�d� pour la premi�re fois.
+ JPA-QL a aussi un mot clef <literal>fetch</literal> qui vous permet de
+ surcharger le type de r�cup�ration pour une requ�te particuli�re. C'est
+ tr�s utile pour am�liorer les performances et d�cider au cas par
+ cas.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Mapper des clefs primaires et �trang�res compos�es</title>
+
+ <para>Les clefs primaires compos�es utilisent une classe embarqu�e comme
+ repr�sentation de la clef primaire, donc vous devriez utiliser les
+ annotations <literal>@Id</literal> et <literal>@Embeddable</literal>.
+ Alternativement, vous pouvez utiliser l'annotation
+ <literal>@EmbeddedId</literal>. Notez que la classe d�pendante doit �tre
+ s�rialisable et implementer
+ <methodname>equals()</methodname>/<methodname>hashCode()</methodname>.
+ Vous pouvez aussi utiliser <literal>@IdClass</literal> comme d�crit dans
+ <xref linkend="entity-mapping-identifier" />.</para>
+
+ <programlisting>
+@Entity
+public class RegionalArticle implements Serializable {
+
+ @Id
+ public RegionalArticlePk getPk() { ... }
+}
+
+@Embeddable
+public class RegionalArticlePk implements Serializable { ... }
+ </programlisting>
+
+ <para>ou alternativement</para>
+
+ <programlisting>
+@Entity
+public class RegionalArticle implements Serializable {
+
+ @EmbeddedId
+ public RegionalArticlePk getPk() { ... }
+}
+
+public class RegionalArticlePk implements Serializable { ... }
+ </programlisting>
+
+ <para><literal>@Embeddable</literal> h�rite le type d'acc�s de son entit�
+ d'appartenance � moins que l'annotation sp�cifique Hibernate
+ <literal>@AccessType</literal> soit utilis�e. Les clefs �trang�res
+ compos�es (si les valeurs par d�faut ne sont pas utilis�es) sont d�finies
+ sur les associations en utilisant l'�l�ment
+ <literal>@JoinColumns</literal>, lequel est simplement un tableau de
+ <literal>@JoinColumn</literal>s. Il est consid�r� comme une bonne pratique
+ d'exprimer <literal>referencedColumnNames</literal> explicitement. Sinon,
+ Hibernate supposera que vous utilisez le m�me ordre de colonnes que dans
+ la d�claration de la clef primaire.</para>
+
+ <programlisting>
+@Entity
+public class Parent implements Serializable {
+ @Id
+ public ParentPk id;
+ public int age;
+
+ @OneToMany(cascade=CascadeType.ALL)
+ @JoinColumns ({
+ @JoinColumn(name="parentCivility", referencedColumnName = "isMale"),
+ @JoinColumn(name="parentLastName", referencedColumnName = "lastName"),
+ @JoinColumn(name="parentFirstName", referencedColumnName = "firstName")
+ })
+ public Set<Child> children; //unidirectionnelle
+ ...
+}
+ </programlisting>
+
+ <programlisting>
+@Entity
+public class Child implements Serializable {
+ @Id @GeneratedValue
+ public Integer id;
+
+ @ManyToOne
+ @JoinColumns ({
+ @JoinColumn(name="parentCivility", referencedColumnName = "isMale"),
+ @JoinColumn(name="parentLastName", referencedColumnName = "lastName"),
+ @JoinColumn(name="parentFirstName", referencedColumnName = "firstName")
+ })
+ public Parent parent; // unidirectionnelle
+}
+ </programlisting>
+
+ <programlisting>
+@Embeddable
+public class ParentPk implements Serializable {
+ String firstName;
+ String lastName;
+ ...
+}
+ </programlisting>
+
+ <para>Notez l'usage explicite de
+ <literal>referencedColumnName</literal>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Mapper des tables secondaires</title>
+
+ <para>Vous pouvez mapper un simple entity bean vers plusieurs tables en
+ utilisant les annotations de niveau classe
+ <literal>@SecondaryTable</literal> ou
+ <literal>@SecondaryTables</literal>. Pour dire qu'une colonne est dans
+ une table particuli�re, utlisez le param�tre <literal>table</literal> de
+ <literal>@Column</literal> ou <literal>@JoinColumn</literal>.</para>
+
+ <programlisting>
+@Entity
+@Table(name="MainCat")
+<emphasis role="bold">@SecondaryTables({
+ @SecondaryTable(name="Cat1", pkJoinColumns={
+ @PrimaryKeyJoinColumn(name="cat_id", referencedColumnName="id")
+ ),
+ @SecondaryTable(name="Cat2", uniqueConstraints={@UniqueConstraint(columnNames={"storyPart2"})})
+})</emphasis>
+public class Cat implements Serializable {
+
+ private Integer id;
+ private String name;
+ private String storyPart1;
+ private String storyPart2;
+
+ @Id @GeneratedValue
+ public Integer getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ <emphasis role="bold">@Column(table="Cat1")</emphasis>
+ public String getStoryPart1() {
+ return storyPart1;
+ }
+
+ <emphasis role="bold">@Column(table="Cat2")</emphasis>
+ public String getStoryPart2() {
+ return storyPart2;
+ }
+</programlisting>
+
+ <para>Dans cet exemple, <literal>name</literal> sera dans
+ <literal>MainCat</literal>. <literal>storyPart1</literal> sera dans
+ <literal>Cat1</literal> et <literal>storyPart2</literal> sera dans
+ <literal>Cat2</literal>. <literal>Cat1</literal> sera joint �
+ <literal>MainCat</literal> avec <literal>cat_id</literal> comme clef
+ �trang�re, et <literal>Cat2</literal> avec <literal>id</literal> (ie
+ le m�me nom de colonne que la colonne identifiante de
+ <literal>MainCat</literal>). De plus, une contrainte d'unicit� sur
+ <literal>storyPart2</literal> a �t� renseign�e.</para>
+
+ <para>Regardez le tutoriel EJB3 de JBoss ou la suite de tests
+ unitaires d'Hibernate Annotations pour plus d'exemples.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="entity-mapping-query">
+ <title>Mapper des requ�tes</title>
+
+ <sect2 id="entity-mapping-query-hql"
+ revision="1">
+ <title>Mapper des requ�tes JPAQL/HQL</title>
+
+ <para>Vous pouvez mapper des requ�tes JPA-QL/HQL en utilisant les
+ annotations. <literal>@NamedQuery</literal> et
+ <literal>@NamedQueries</literal> peuvent �tre d�finies au niveau de la
+ classe ou dans un fichier JPA XML. Cependant, leurs d�finitions sont
+ globales au scope de la session factory/entity manager factory. Une
+ requ�te nomm�e est d�finie par son nom et la cha�ne de caract�res de la
+ requ�te r�elle.</para>
+
+ <programlisting><entity-mappings>
+ <named-query name="plane.getAll">
+ <query>select p from Plane p</query>
+ </named-query>
+ ...
+</entity-mappings>
+...
+
+@Entity
+@NamedQuery(name="night.moreRecentThan", query="select n from Night n where n.date >= :date")
+public class Night {
+ ...
+}
+
+public class MyDao {
+ doStuff() {
+ Query q = s.getNamedQuery("night.moreRecentThan");
+ q.setDate( "date", aMonthAgo );
+ List results = q.list();
+ ...
+ }
+ ...
+}
+ </programlisting>
+
+ <para>Vous pouvez aussi fournir des indications de fonctionnement � une
+ requ�te � travers un tableau de <literal>QueryHint</literal>s avec
+ l'attribut <literal>hints</literal>.</para>
+
+ <para>Les indications de fonctionnement Hibernate disponibles
+ sont :</para>
+
+ <para></para>
+
+ <table>
+ <title>Indications de fonctionnement d'une requ�te</title>
+
+ <tgroup cols="2">
+ <thead>
+ <colspec colname="c1" />
+
+ <colspec colname="c2" colnum="2" />
+
+ <row>
+ <entry>Indication</entry>
+
+ <entry colname="c2">description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>org.hibernate.cacheable</entry>
+
+ <entry>Indique si la requ�te devrait interagir avec le cache de
+ second niveau (par d�faut � false)</entry>
+ </row>
+
+ <row>
+ <entry>org.hibernate.cacheRegion</entry>
+
+ <entry>Nom de la r�gion du cache (si ind�finie, la valeur par
+ d�faut est utilis�e)</entry>
+ </row>
+
+ <row>
+ <entry>org.hibernate.timeout</entry>
+
+ <entry>Timeout des requ�tes</entry>
+ </row>
+
+ <row>
+ <entry>org.hibernate.fetchSize</entry>
+
+ <entry>Taille des result sets par fetch</entry>
+ </row>
+
+ <row>
+ <entry>org.hibernate.flushMode</entry>
+
+ <entry>Mode de flush utilis� pour cette requ�te</entry>
+ </row>
+
+ <row>
+ <entry>org.hibernate.cacheMode</entry>
+
+ <entry>Mode de cache utilis� pour cette requ�te</entry>
+ </row>
+
+ <row>
+ <entry>org.hibernate.readOnly</entry>
+
+ <entry>Indique si les entit�s charg�es par cette requ�te devraient
+ �tre en lecture seule ou pas (par d�faut � false)</entry>
+ </row>
+
+ <row>
+ <entry>org.hibernate.comment</entry>
+
+ <entry>Commentaire de la requ�te, ajout� au SQL g�n�r�</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 id="entity-mapping-query-native" revision="2">
+ <title>Mapper des requ�tes natives</title>
+
+ <para>Vous pouvez aussi mapper une requ�te native (ie une requ�te SQL).
+ Pour ce faire, vous devez d�crire la structure de l'ensemble de r�sultat
+ SQL en utilisant <literal>@SqlResultSetMapping</literal> (ou
+ <literal>@SqlResultSetMappings</literal> si vous pr�voyez de d�finir
+ plusieurs mappings de r�sultats). Comme <literal>@NamedQuery</literal>, un
+ <literal>@SqlResultSetMapping</literal> peut �tre d�fini au niveau de la
+ classe ou dans un fichier XML JPA. Cependant sa port�e est globale �
+ l'application.</para>
+
+ <para>Comme vous le verrez, un param�tre de
+ <literal>resultSetMapping</literal> est d�fini dans
+ <literal>@NamedNativeQuery</literal>, il repr�sente le nom du
+ <literal>@SqlResultSetMapping</literal> d�fini. Le mapping de l'ensemble
+ des r�sultats d�clare les entit�s r�cup�r�es par cette requ�te native.
+ Chaque champ de l'entit� est li� � un alias SQL (nom de colonne). Tous les
+ champs de l'entit� (dont ceux des classes filles) et les colonnes des
+ clefs �trang�res relatives aux entit�s doivent �tre pr�sents dans la
+ requ�te SQL. Les d�finitions des champs sont optionnelles, si elles ne
+ sont pas fournies, elles mappent le m�me nom de colonne que celui d�clar�
+ sur la propri�t� de la classe.</para>
+
+ <para><programlisting>@NamedNativeQuery(name="night&area", query="select night.id nid, night.night_duration, "
+ + " night.night_date, area.id aid, night.area_id, area.name "
+ + "from Night night, Area area where night.area_id = area.id", <emphasis
+ role="bold">resultSetMapping="joinMapping"</emphasis>)
+@SqlResultSetMapping(name="joinMapping", entities={
+ @EntityResult(entityClass=org.hibernate.test.annotations.query.Night.class, fields = {
+ @FieldResult(name="id", column="nid"),
+ @FieldResult(name="duration", column="night_duration"),
+ @FieldResult(name="date", column="night_date"),
+ @FieldResult(name="area", column="area_id"),
+ discriminatorColumn="disc"
+ }),
+ @EntityResult(entityClass=org.hibernate.test.annotations.query.Area.class, fields = {
+ @FieldResult(name="id", column="aid"),
+ @FieldResult(name="name", column="name")
+ })
+ }
+)</programlisting></para>
+
+ <para>Dans l'exemple ci-dessus, la requ�te nomm�e
+ <literal>night&area</literal> utilise le mapping de r�sultats
+ <literal>joinMapping</literal>. Ce mapping retourne 2 entit�s,
+ <literal>Night</literal> et <literal>Area</literal>, chaque propri�t� est
+ d�clar�e et associ�e � un nom de colonne, en fait le nom de colonne
+ r�cup�r� par la requ�te. Voyons maintenant une d�claration implicite de
+ mapping propri�t�/colonne.</para>
+
+ <programlisting>@Entity
+<emphasis role="bold">@SqlResultSetMapping(name="implicit", entities=(a)EntityResult(entityClass=org.hibernate.test.annotations.query.SpaceShip.class))
+@NamedNativeQuery(name="implicitSample", query="select * from SpaceShip", resultSetMapping="implicit")</emphasis>
+public class SpaceShip {
+ private String name;
+ private String model;
+ private double speed;
+
+ @Id
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Column(name="model_txt")
+ public String getModel() {
+ return model;
+ }
+
+ public void setModel(String model) {
+ this.model = model;
+ }
+
+ public double getSpeed() {
+ return speed;
+ }
+
+ public void setSpeed(double speed) {
+ this.speed = speed;
+ }
+}</programlisting>
+
+ <para>Dans cet exemple, nous d�crivons seulement le membre de l'entit� du
+ mapping de r�sultats. Le mapping de propri�t�/colonne est fait en
+ utilisant les valeurs de mapping de l'entit�. Dans ce cas, la propri�t�
+ <literal>model</literal> est li�e � la colonne
+ <literal>model_txt</literal>. Si l'association � une entit� concern�e
+ implique une clef primaire compos�e, un �l�ment
+ <literal>@FieldResult</literal> devrait �tre utilis� pour chaque colonne
+ de la clef �trang�re. Le nom de <literal>@FieldResult</literal> est
+ compos� du nom de la propri�t� pour la relation, suivi par un point ("."),
+ suivi par le nom ou le champ ou la propri�t� de la clef primaire.</para>
+
+ <programlisting>@Entity
+@SqlResultSetMapping(name="compositekey",
+ entities=(a)EntityResult(entityClass=org.hibernate.test.annotations.query.SpaceShip.class,
+ fields = {
+ @FieldResult(name="name", column = "name"),
+ @FieldResult(name="model", column = "model"),
+ @FieldResult(name="speed", column = "speed"),
+<emphasis role="bold"> @FieldResult(name="captain.firstname", column = "firstn"),
+ @FieldResult(name="captain.lastname", column = "lastn"),</emphasis>
+ @FieldResult(name="dimensions.length", column = "length"),
+ @FieldResult(name="dimensions.width", column = "width")
+ }),
+ columns = { @ColumnResult(name = "surface"),
+ @ColumnResult(name = "volume") } )
+
+@NamedNativeQuery(name="compositekey",
+ query="select name, model, speed, lname as lastn, fname as firstn, length, width, length * width as surface from SpaceShip",
+ resultSetMapping="compositekey")
+} )
+public class SpaceShip {
+ private String name;
+ private String model;
+ private double speed;
+ private Captain captain;
+ private Dimensions dimensions;
+
+ @Id
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @ManyToOne(fetch= FetchType.LAZY)
+ @JoinColumns( {
+ @JoinColumn(name="fname", referencedColumnName = "firstname"),
+ @JoinColumn(name="lname", referencedColumnName = "lastname")
+ } )
+ public Captain getCaptain() {
+ return captain;
+ }
+
+ public void setCaptain(Captain captain) {
+ this.captain = captain;
+ }
+
+ public String getModel() {
+ return model;
+ }
+
+ public void setModel(String model) {
+ this.model = model;
+ }
+
+ public double getSpeed() {
+ return speed;
+ }
+
+ public void setSpeed(double speed) {
+ this.speed = speed;
+ }
+
+ public Dimensions getDimensions() {
+ return dimensions;
+ }
+
+ public void setDimensions(Dimensions dimensions) {
+ this.dimensions = dimensions;
+ }
+}
+
+@Entity
+(a)IdClass(Identity.class)
+public class Captain implements Serializable {
+ private String firstname;
+ private String lastname;
+
+ @Id
+ public String getFirstname() {
+ return firstname;
+ }
+
+ public void setFirstname(String firstname) {
+ this.firstname = firstname;
+ }
+
+ @Id
+ public String getLastname() {
+ return lastname;
+ }
+
+ public void setLastname(String lastname) {
+ this.lastname = lastname;
+ }
+}
+</programlisting>
+
+ <note>
+ <para>Si vous regardez la propri�t� dimension, vous verrez qu'Hibernate
+ prend en charge la notation avec les points pour les objets embarqu�s
+ (vous pouvez m�me avoir des objets embarqu�s imbriqu�s). Les
+ impl�mentations EJB3 n'ont pas � prendre en charge cette fonctionnalit�,
+ mais nous le faisons :-)</para>
+ </note>
+
+ <para>Si vous r�cup�rez une simple entit� et si vous utilisez le mapping
+ par d�faut, vous pouvez utiliser l'attribut <literal>resultClass</literal>
+ � la place de <literal>resultSetMapping</literal> :</para>
+
+ <programlisting><emphasis role="bold">@NamedNativeQuery(name="implicitSample", query="select * from SpaceShip",
+ resultClass=SpaceShip.class)</emphasis>
+public class SpaceShip {</programlisting>
+
+ <para>Dans certaines de vos requ�tes natives, vous devrez retourner des
+ valeurs scalaires, par exemple lors de la construction de requ�tes de
+ rapport. Vous pouvez les mapper dans
+ <literal>@SqlResultsetMapping</literal> avec
+ <literal>@ColumnResult</literal>. En fait, vous pouvez m�me m�langer des
+ retours d'entit�s et de valeurs scalaires dans la m�me requ�te native (ce
+ n'est cependant probablement pas commun).</para>
+
+ <programlisting><emphasis role="bold">@SqlResultSetMapping(name="scalar", columns=@ColumnResult(name="dimension"))
+@NamedNativeQuery(name="scalar", query="select length*width as dimension from SpaceShip", resultSetMapping="scalar")</emphasis></programlisting>
+
+ <para>Une autre indication de fonctionnement sp�cifique aux requ�tes
+ natives a �t� pr�sent�e : <literal>org.hibernate.callable</literal>
+ laquelle peut �tre � true ou � false fausse selon que la requ�te est une
+ proc�dure stock�e ou pas.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="entity-hibspec" xreflabel="Extensions d'Hibernate Annotation">
+ <title>Extensions d'Hibernate Annotation</title>
+
+ <para>Hibernate 3.1 offre une vari�t� d'annotations suppl�mentaires que vous
+ pouvez m�langer/faire correspondre avec des entit�s EJB3. Elles ont �t�
+ con�ues comme une extension naturelle aux annotations EJB3.</para>
+
+ <para>Pour aller plus loin que les capacit�s d'EJB3, Hibernate fournit des
+ annotations sp�cifiques qui correspondent aux fonctionnalit�s d'Hibernate.
+ Le package <classname>org.hibernate.annotations</classname> contient toutes
+ ces extensions d'annotations.</para>
+
+ <sect2 id="entity-hibspec-entity" revision="2">
+ <title>Entit�</title>
+
+ <para>Vous pouvez finement param�trer certaines des actions faites par
+ Hibernate sur les entit�s au-del� de ce qu'offre la sp�cification
+ EJB3.</para>
+
+ <para><classname>@org.hibernate.annotations.Entity</classname> ajoute des
+ m�ta-donn�es suppl�mentaires qui peuvent �tre n�cessaires au-del� de ce
+ qui est d�fini dans l'annotation <literal>@Entity</literal>
+ standard :<itemizedlist>
+ <listitem>
+ mutable : indique si l'entit� est modifiable ou non
+ </listitem>
+
+ <listitem>
+ dynamicInsert : autorise le SQL dynamique pour les insertions
+ </listitem>
+
+ <listitem>
+ dynamicUpdate : autorise le SQL dynamique pour les mise � jour
+ </listitem>
+
+ <listitem>
+ selectBeforeUpdate : sp�cifie qu'Hibernate ne devrait jamais
+ ex�cuter un UPDATE SQL � moins qu'il ne soit certain qu'un objet
+ est r�ellement modifi�
+ </listitem>
+
+ <listitem>
+ polymorphism : indique si le polymorphisme d'entit� est de type
+ PolymorphismType.IMPLICIT (valeur par d�faut) ou
+ PolymorphismType.EXPLICIT
+ </listitem>
+
+ <listitem>
+ persister : autorise la surcharge de l'impl�mentation de
+ persistance fournie par d�faut
+ </listitem>
+
+ <listitem>
+ optimisticLock : strat�gie de verrouillage optmiste
+ (OptimisticLockType.VERSION,
+ OptimisticLockType.NONE, OptimisticLockType.DIRTY ou
+ OptimisticLockType.ALL)
+ </listitem>
+ </itemizedlist></para>
+
+ <para><note>
+ <para>@javax.persistence.Entity est encore obligatoire,
+ @org.hibernate.annotations.Entity ne la remplace pas.</para>
+ </note></para>
+
+ <para>Voici quelques extensions d'annotations Hibernate
+ suppl�mentaires.</para>
+
+ <para><literal>@org.hibernate.annotations.BatchSize</literal> vous permet
+ de d�finir la taille du batch lors de la r�cup�ration d'instances de
+ cette entit� (p. ex. <literal>@BatchSize(size=4)</literal>). Lors du
+ chargement d'une entit� donn�e, Hibernate chargera alors toutes les
+ entit�s non initialis�es du m�me type dans le contexte de la persistance
+ jusqu'� la taille du batch.</para>
+
+ <para><literal>@org.hibernate.annotations.Proxy</literal> d�finit les
+ attributs de chargement de l'entit�. lazy (valeur par d�faut) d�finit si
+ la classe est charg�e � la demande ou non. proxyClassName est l'interface
+ utilis�e pour g�n�rer le proxy (par d�faut, la classe elle-m�me).</para>
+
+ <para><literal>@org.hibernate.annotations.Where</literal> d�finit une
+ clause WHERE SQL optionnelle utilis�e lorsque des instances de cette
+ classe sont r�cup�r�es.</para>
+
+ <para><literal>@org.hibernate.annotations.Check</literal> d�clare une
+ contrainte de v�rification optionnelle d�finie dans l'expression
+ DDL.</para>
+
+ <para><literal>@OnDelete(action=OnDeleteAction.CASCADE)</literal> sur des
+ classes filles jointes : utilise une commande SQL DELETE en cascade lors
+ de la suppression plut�t que le m�canisme habituel d'Hibernate.</para>
+
+ <para><literal>@Table(appliesTo="tableName", indexes = {
+ @Index(name="index1", columnNames={"column1", "column2"} ) } )</literal>
+ cr�e les index d�finis sur les colonnes de la table
+ <literal>tableName</literal>. Cela peut s'appliquer sur une table primaire
+ ou une table secondaire. L'annotation <literal>@Tables</literal> vous
+ permet d'avoir des index sur des tables diff�rentes. Cette annotation est
+ attendue l� o� <literal>@javax.persistence.Table</literal> ou
+ <literal>@javax.persistence.SecondaryTable</literal>(s) sont
+ d�clar�es.</para>
+
+ <note>
+ <para><literal>@org.hibernate.annotations.Table</literal> est un
+ compl�ment, pas un remplacement de
+ <literal>@javax.persistence.Table</literal>. Surtout, si vous souhaitez
+ changer le nom par d�faut d'une table, vous devez utiliser
+ <literal>@javax.persistence.Table</literal>, pas
+ <literal>@org.hibernate.annotations.Table</literal>.</para>
+ </note>
+
+ <para><programlisting>@Entity
+@BatchSize(size=5)
+(a)org.hibernate.annotations.Entity(
+ selectBeforeUpdate = true,
+ dynamicInsert = true, dynamicUpdate = true,
+ optimisticLock = OptimisticLockType.ALL,
+ polymorphism = PolymorphismType.EXPLICIT)
+@Where(clause="1=1")
+(a)org.hibernate.annotations.Table(name="Forest", indexes = { @Index(name="idx", columnNames = { "name", "length" } ) } )
+public class Forest { ... }</programlisting><programlisting>@Entity
+@Inheritance(
+ strategy=InheritanceType.JOINED
+)
+public class Vegetable { ... }
+
+@Entity
+(a)OnDelete(action=OnDeleteAction.CASCADE)
+public class Carrot extends Vegetable { ... }</programlisting></para>
+ </sect2>
+
+ <sect2 id="entity-hibspec-identifier" revision="1">
+ <title>Identifiant</title>
+
+ <para><literal>@org.hibernate.annotations.GenericGenerator</literal> vous
+ permet de d�finir un g�n�rateur d'identifiants Hibernate
+ sp�cifique.</para>
+
+ <para><programlisting>@Id @GeneratedValue(generator="system-uuid")
+@GenericGenerator(name="system-uuid", strategy = "uuid")
+public String getId() {
+
+@Id @GeneratedValue(generator="hibseq")
+@GenericGenerator(name="hibseq", strategy = "seqhilo",
+ parameters = {
+ @Parameter(name="max_lo", value = "5"),
+ @Parameter(name="sequence", value="heybabyhey")
+ }
+)
+public Integer getId() {</programlisting></para>
+
+ <para><literal>strategy</literal> est le nom court de la strat�gie du
+ g�n�rateur Hibernate3 ou le nom pleinement qualifi� de la classe d'une
+ impl�mentation de <classname>IdentifierGenerator</classname>. Vous pouvez
+ ajouter des param�tres avec l'attribut
+ <literal>parameters</literal>.</para>
+
+ <para>Contrairement � son pendant standard,
+ <literal>@GenericGenerator</literal> peut �te utilis�e dans les
+ annotations au niveau du package, en faisant ainsi un g�n�rateur de niveau
+ applicatif (comme s'il �tait dans un fichier JPA XML).</para>
+
+ <programlisting>@GenericGenerator(name="hibseq", strategy = "seqhilo",
+ parameters = {
+ @Parameter(name="max_lo", value = "5"),
+ @Parameter(name="sequence", value="heybabyhey")
+ }
+)
+package org.hibernate.test.model</programlisting>
+ </sect2>
+
+ <sect2 id="entity-hibspec-property" revision="2">
+ <title>Propri�t�</title>
+
+ <sect3>
+ <title>Type d'acc�s</title>
+
+ <para>Le type d'acc�s est d�duit de la position de
+ <literal>@Id</literal> ou de <literal>@EmbeddedId</literal> dans la
+ hi�rarchie de l'entit�. Les entit�s filles, les objets embarqu�s et les
+ entit�s parentes mapp�s h�ritent du type d'acc�s de l'entit�
+ racine.</para>
+
+ <para>Dans Hibernate, vous pouvez surcharger le type d'acc�s
+ pour :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>utiliser une strat�gie d'acc�s personnalis�e</para>
+ </listitem>
+
+ <listitem>
+ <para>param�trer finement le type d'acc�s au niveau de la classe ou
+ au niveau de la propri�t�</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Une annocation @AccessType a �t� pr�sent�e pour prendre en charge
+ ce comportement. Vous pouvez d�finir le type d'acc�s sur :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>une entit�</para>
+ </listitem>
+
+ <listitem>
+ <para>une classe parente</para>
+ </listitem>
+
+ <listitem>
+ <para>un objet embarqu�</para>
+ </listitem>
+
+ <listitem>
+ <para>une propri�t�</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Le type d'acc�s est surcharg� pour l'�l�ment annot�, si surcharg�
+ sur une classe, toutes les propri�t�s de la classe donn�e h�ritent du
+ type d'acc�s. Pour les entit�s racines, le type d'acc�s est consid�r�
+ par d�faut comme celui de la hi�rarchie enti�re (surchargeable au niveau
+ de la classe ou de la propri�t�).</para>
+
+ <para>Si le type d'acc�s est marqu� comme "propri�t�", les getters sont
+ parcourus pour examiner les annotations, si le type d'acc�s est marqu�
+ comme "champ", ce sont les champs qui sont parcourus pour les
+ annotations. Sinon les �l�ments marqu�s avec @Id ou @embeddedId sont
+ scann�s.</para>
+
+ <para>Vous pouvez surcharger une type d'acc�s pour une propri�t�, mais
+ l'�l�ment annot� ne sera pas influenc� : par exemple, une entit� ayant
+ un type d'acc�s <literal>field</literal>, peut annoter un champ avec
+ <literal>@AccessType("property")</literal>, le type d'acc�s sera alors
+ "property" pour cet attribut, des annotations devront encore �tre
+ port�es sur les champs.</para>
+
+ <para>Si une classe parente ou un objet embarquable n'est pas annot�, le
+ type d'acc�s de l'entit� racine est utilis� (m�me si un type d'acc�s a
+ �t� d�fini sur une classe parente ou un objet embarquable
+ interm�diaire). Le principe de la poup�e russe ne s'applique pas.</para>
+
+ <programlisting>@Entity
+public class Person implements Serializable {
+ @Id @GeneratedValue // type d'acc�s "champ"
+ Integer id;
+
+ @Embedded
+ @AttributeOverrides({
+ @AttributeOverride(name = "iso2", column = @Column(name = "bornIso2")),
+ @AttributeOverride(name = "name", column = @Column(name = "bornCountryName"))
+ })
+ Country bornIn;
+}
+
+@Embeddable
+<emphasis role="bold">@AccessType("property")</emphasis> // surcharge le type d'acc�s pour toutes les propri�t�s dans Country
+public class Country implements Serializable {
+ private String iso2;
+ private String name;
+
+ public String getIso2() {
+ return iso2;
+ }
+
+ public void setIso2(String iso2) {
+ this.iso2 = iso2;
+ }
+
+ @Column(name = "countryName")
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Formule</title>
+
+ <para>Parfois, vous voulez effectuer certains calculs par la base de
+ donn�es plut�t que par la JVM, ou vous pourriez aussi vouloir cr�er une
+ sorte de colonne virtuelle. Vous pouvez utilisez un fragment SQL (alias
+ une formule) plut�t que de mapper un propri�t� sur une colonne. Cette
+ sorte de propri�t� est en lecture seule (sa valeur est calcul�e par
+ votre formule).</para>
+
+ <programlisting>@Formula("obj_length * obj_height * obj_width")
+public long getObjectVolume()</programlisting>
+
+ <para>Le fragment SQL peut �tre aussi complexe que vous le souhaitez,
+ m�me avec des sous-selects inclus.</para>
+ </sect3>
+
+ <sect3>
+ <title>Type</title>
+
+ <para><literal>@org.hibernate.annotations.Type</literal> surcharge le
+ type Hibernate utilis� par d�faut : ce n'est g�n�ralement pas n�cessaire
+ puisque le type est correctement inf�r� par Hibernate. Veuillez vous
+ r�f�rer au guide de r�f�rence Hibernate pour plus d'informations sur les
+ types Hibernate.</para>
+
+ <para><literal>@org.hibernate.annotations.TypeDef</literal> et
+ <literal>@org.hibernate.annotations.TypeDefs</literal> vous permettent
+ de d�clarer des d�finitions de type. Ces annotations sont plac�es au
+ niveau de la classe ou du package. Notez que ces d�finitions seront
+ globales pour la session factory (m�me au niveau de la classe) et que la
+ d�finition du type doit �tre d�finie avant n'importe quelle
+ utilisation.</para>
+
+ <programlisting>@TypeDefs(
+ {
+ @TypeDef(
+ name="caster",
+ typeClass = CasterStringType.class,
+ parameters = {
+ @Parameter(name="cast", value="lower")
+ }
+ )
+ }
+)
+package org.hibernate.test.annotations.entity;
+
+...
+public class Forest {
+ @Type(type="caster")
+ public String getSmallText() {
+ ...
+}
+ </programlisting>
+
+ <para>Lors de l'utilisation d'un type utilisateur compos�, vous devrez
+ exprimer les d�finitions des colonnes. L'annotation
+ <literal>@Columns</literal> a �t� mise en place dans ce but.</para>
+
+ <programlisting>@Type(type="org.hibernate.test.annotations.entity.MonetaryAmountUserType")
+@Columns(columns = {
+ @Column(name="r_amount"),
+ @Column(name="r_currency")
+})
+public MonetaryAmount getAmount() {
+ return amount;
+}
+
+
+public class MonetaryAmount implements Serializable {
+ private BigDecimal amount;
+ private Currency currency;
+ ...
+}</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Index</title>
+
+ <para>Vous pouvez d�finir un index sur une colonne particuli�re en
+ utilisant l'annotation <literal>@Index</literal> sur une propri�t� d'une
+ colonne, l'attribut columnNames sera ignor�.</para>
+
+ <programlisting>@Column(secondaryTable="Cat1")
+@Index(name="story1index")
+public String getStoryPart1() {
+ return storyPart1;
+}</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>@Parent</title>
+
+ <para>A l'int�rieur d'un objet embarquable, vous pouvez d�finir
+ une des propri�t�s comme un pointeur vers l'�l�ment
+ propri�taire.</para>
+
+ <programlisting>@Entity
+public class Person {
+ @Embeddable public Address address;
+ ...
+}
+
+@Embeddable
+public class Address {
+ @Parent public Person owner;
+ ...
+}
+
+
+person == person.address.owner</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Propri�t�s g�n�r�es</title>
+
+ <para>Certaines propri�t�s sont g�n�r�es au moment de l'insertion ou de
+ la mise � jour par votre base de donn�es. Hibernate peut traiter de
+ telles propri�t�s et d�clencher un select subs�quent pour lire ces
+ propri�t�s.</para>
+
+ <programlisting>@Entity
+public class Antenna {
+ @Id public Integer id;
+ @Generated(GenerationTime.ALWAYS) @Column(insertable = false, updatable = false)
+ public String longitude;
+
+ @Generated(GenerationTime.INSERT) @Column(insertable = false)
+ public String latitude;
+}</programlisting>
+
+ <para>Quand vous annotez votre propri�t� avec
+ <literal>@Generated</literal>, vous devez vous assurer que l'insertion
+ et la mise � jour n'entreront pas en conflit avec la strat�gie de
+ g�n�ration que vous avez choisie. Lorsque GenerationTime.INSERT est
+ choisi, la propri�t� ne doit pas contenir de colonnes ins�rables ;
+ lorsque GenerationTime.ALWAYS est choisi, la propri�t� ne doit pas
+ contenir de colonnes qui puissent �tre ins�r�es ou mises � jour.</para>
+
+ <para>Les propri�t�s <literal>@Version</literal> ne peuvent pas (par
+ conception) �tre <literal>@Generated(INSERT)</literal>, elles doivent
+ �tre <literal>NEVER</literal> ou <literal>ALWAYS</literal>.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="entity-hibspec-inheritance" revision="1">
+ <title>H�ritage</title>
+
+ <para>SINGLE_TABLE est une strat�gie tr�s puissante mais parfois, et
+ surtout pour des syst�mes pr�-existants, vous ne pouvez pas ajouter une
+ colonne discriminante suppl�mentaire. Pour cela Hibernate a mis en place
+ la notion de formule discriminante :
+ <literal>@DiscriminatorFormula</literal> est une rempla�cant de
+ <literal>@DiscriminatorColumn</literal> et utilise un fragment SQL en tant
+ que formule pour la r�solution du discriminant (pas besoin d'avoir une
+ colonne d�di�e).</para>
+
+ <programlisting>@Entity
+@DiscriminatorForumla("case when forest_type is null then 0 else forest_type end")
+public class Forest { ... }</programlisting>
+
+ <para>Par d�faut, lors du requ�tage sur les entit�s les plus hautes,
+ Hibernate ne met pas de restriction sur la colonne discriminante. Ceci
+ peut �tre un inconv�nient si cette colonne contient des valeurs qui ne sont
+ pas mapp�es dans votre hi�rarchie (avec
+ <literal>@DiscriminatorValue</literal>). Pour contourner ca, vous pouvez
+ utilser <literal>@ForceDiscriminator</literal> (au niveau de la classe,
+ � c�t� de <literal>@DiscriminatorColumn</literal>). Hibernate listera
+ alors les valeurs disponibles lors du chargement des entit�s.</para>
+ </sect2>
+
+ <sect2 id="entity-hibspec-singleassoc">
+ <title>Annotations concernant les simples associations</title>
+
+ <para>Par d�faut, lorsqu'Hibernate ne peut pas r�soudre l'association
+ parce que l'�l�ment associ� attendu n'est pas dans la base de donn�es
+ (mauvais identifiant sur la colonne de l'association), une exception est
+ lev�e par Hibernate. Cela pourrait �tre un inconv�nient pour des sch�mas
+ pr�-existants et mal maintenus. Vous pouvez demander � Hibernate d'ignorer
+ de tels �l�ments plut�t que de lever une exception en utilisant
+ l'annotation <literal>@NotFound</literal>. Cette annotation peut �tre
+ utilis�e sur une association <literal>@OneToOne</literal> (avec une clef
+ �trang�re), <literal>@ManyToOne</literal>, <literal>@OneToMany</literal>
+ ou <literal>@ManyToMany</literal>.</para>
+
+ <programlisting>@Entity
+public class Child {
+ ...
+ @ManyToOne
+ @NotFound(action=NotFoundAction.IGNORE)
+ public Parent getParent() { ... }
+ ...
+}</programlisting>
+
+ <para>Parfois vous voulez d�l�guer � votre base de donn�es la suppression
+ en cascade lorsqu'une entit� donn�e est supprim�e.</para>
+
+ <programlisting>@Entity
+public class Child {
+ ...
+ @ManyToOne
+ @OnDelete(action=OnDeleteAction.CASCADE)
+ public Parent getParent() { ... }
+ ...
+}</programlisting>
+
+ <para>Dans ce cas, Hibernate g�n�re une contrainte de suppression en
+ cascade au niveau de la base de donn�es.</para>
+
+ <para>Les contraintes de clef �trang�re, bien que g�n�r�es par Hibernate,
+ ont un nom justement illisible. Vous pouvez surcharger le nom de la
+ contrainte par l'utilisation de <literal>@ForeignKey</literal>.</para>
+
+ <programlisting>@Entity
+public class Child {
+ ...
+ @ManyToOne
+ <emphasis role="bold">@ForeignKey(name="FK_PARENT")</emphasis>
+ public Parent getParent() { ... }
+ ...
+}
+
+alter table Child add constraint FK_PARENT foreign key (parent_id) references Parent</programlisting>
+
+ <sect3>
+ <title>Options de chargement et modes de r�cup�ration</title>
+
+ <para>EJB3 arrive avec l'option <literal>fetch</literal> pour d�finir
+ le chargement � la demande et les modes de r�cup�ration, cependant
+ Hibernate a beaucoup plus d'options dans ce domaine. Pour finement
+ param�trer le chargement � la demande et les strat�gies de r�cup�ration,
+ quelques annotations suppl�mentaires ont �t� mises en place :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>@LazyToOne</literal> : d�finit l'option de chargement
+ � la demande sur les associations <literal>@ManyToOne</literal> et
+ <literal>@OneToOne</literal>. <literal>LazyToOneOption</literal>
+ peut �tre <literal>PROXY</literal> (ie utiliser un chargement � la
+ demande bas� sur un proxy), <literal>NO_PROXY</literal> (utilise
+ un chargement � la demande sur l'ajout de bytecode - notez qu'un
+ temps de construction du bytecode est n�cessaire) et
+ <literal>FALSE</literal> (association sans chargement � la
+ demande) ;</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>@LazyCollection</literal> : d�finit l'option de
+ chargement � la demande sur les associations
+ <literal>@ManyToMany</literal> et <literal>@OneToMany</literal>.
+ LazyCollectionOption peut �tre <literal>TRUE</literal> (la
+ collection est charg�e � la demande lorsque son �tat est acc�d�),
+ <literal>EXTRA</literal> (la collection est charg�e � la demande et
+ toutes les op�rations essaieront d'�viter le chargement de la
+ collection, c'est surtout utile pour de grosses collections lorsque
+ le chargement de tous les �l�ments n'est pas n�cessaire) et
+ <literal>FALSE</literal> (association sans chargement � la
+ demande) ;</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>@Fetch</literal> : d�finit une strat�gie de
+ r�cup�ration utilis�e pour charger l'association.
+ <literal>FetchMode</literal> peut �tre
+ <literal>SELECT</literal> (un select est d�clench� lorsque
+ l'association a besoin d'�tre charg�e), <literal>SUBSELECT</literal>
+ (disponible uniquement pour des collections, utilise une strat�gie
+ de sous select - veuillez vous r�f�rer � la documentation de
+ r�f�rence d'Hibernate pour plus d'informations) ou
+ <literal>JOIN</literal> (utilise un JOIN SQL pour charger
+ l'association lors du chargement de l'entit� propri�taire).
+ <literal>JOIN</literal> surcharge n'importe quel attribut de
+ chargement � la demande (une association charg�e avec la strat�gie
+ <literal>JOIN</literal> ne peut pas �tre charg�e � la
+ demande).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Les annotations Hibernate surchargent les options de r�cup�ration
+ EJB3.</para>
+
+ <table>
+ <title>Chargement � la demande et options de r�cup�ration
+ �quivalentes</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Annotations</entry>
+
+ <entry>Chargement � la demande</entry>
+
+ <entry>R�cup�ration</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>@[One|Many]ToOne](fetch=FetchType.LAZY)</entry>
+
+ <entry>@LazyToOne(PROXY)</entry>
+
+ <entry>@Fetch(SELECT)</entry>
+ </row>
+
+ <row>
+ <entry>@[One|Many]ToOne](fetch=FetchType.EAGER)</entry>
+
+ <entry>@LazyToOne(FALSE)</entry>
+
+ <entry>@Fetch(JOIN)</entry>
+ </row>
+
+ <row>
+ <entry>@ManyTo[One|Many](fetch=FetchType.LAZY)</entry>
+
+ <entry>@LazyCollection(TRUE)</entry>
+
+ <entry>@Fetch(SELECT)</entry>
+ </row>
+
+ <row>
+ <entry>@ManyTo[One|Many](fetch=FetchType.EAGER)</entry>
+
+ <entry>@LazyCollection(FALSE)</entry>
+
+ <entry>@Fetch(JOIN)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect3>
+ </sect2>
+
+ <sect2 id="entity-hibspec-collection" revision="2">
+ <title>Annotations concernant les collections</title>
+
+ <sect3 id="entity-hibspec-collection-enhance" revision="2">
+ <title>Am�liorer les configurations des collections</title>
+
+ <para>Il est possible de configurer :<itemizedlist>
+ <listitem>
+ la taille des batchs pour les collections en utilisant @BatchSize
+ </listitem>
+
+ <listitem>
+ la clause where, en utilisant @Where (appliqu�e � l'entit� cible)
+ ou @WhereJoinTable (appliqu�e � la table de l'association)
+ </listitem>
+
+ <listitem>
+ la clause de v�rification, en utilsant @Check
+ </listitem>
+
+ <listitem>
+ la clause SQL order by, en utilisant @OrderBy
+ </listitem>
+
+ <listitem>
+ la strat�gie de suppression en cascade avec
+ @OnDelete(action=OnDeleteAction.CASCADE)
+ </listitem>
+ </itemizedlist></para>
+
+ <para>Vous pouvez aussi d�clarer un comparateur de tri, utilisez
+ l'annotation <literal>@Sort</literal>. Exprimez le type de comparateur
+ que vous voulez entre "non tri�" (NdT : unsorted), "ordre naturel"
+ (NdT : natural) ou un comparateur personnalis�. Si vous voulez utilisez
+ votre propre impl�mentation de comparateur, vous devrez indiquer la
+ classe d'impl�mentation en utilisant l'attribut
+ <literal>comparator</literal>. Notez que vous avez besoin d'utiliser
+ l'interface <classname>SortedSet</classname> ou
+ <classname>SortedMap</classname>.</para>
+
+ <programlisting> @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
+ @JoinColumn(name="CUST_ID")
+ @Sort(type = SortType.COMPARATOR, comparator = TicketComparator.class)
+ @Where(clause="1=1")
+ @OnDelete(action=OnDeleteAction.CASCADE)
+ public SortedSet<Ticket> getTickets() {
+ return tickets;
+ }</programlisting>
+
+ <para>Veuillez vous r�f�rer aux descriptions pr�c�dentes de ces
+ annotations pour plus d'informations.</para>
+
+ <para>Les contraintes de clef �trang�re, bien que g�n�r�es par
+ Hibernate, ont un nom illisible. Vous pouvez surcharger le nom de la
+ contrainte en utilisant <literal>@ForeignKey</literal>. Notez que cette
+ annotation doit �tre plac�e du c�t� poss�dant la relation,
+ <literal>inverseName</literal> r�f�ren�ant la contrainte de l'autre
+ c�t�.</para>
+
+ <programlisting>@Entity
+public class Woman {
+ ...
+ @ManyToMany(cascade = {CascadeType.ALL})
+ <emphasis role="bold">@ForeignKey(name = "TO_WOMAN_FK", inverseName = "TO_MAN_FK")</emphasis>
+ public Set<Man> getMens() {
+ return mens;
+ }
+}
+
+alter table Man_Woman add constraint TO_WOMAN_FK foreign key (woman_id) references Woman
+alter table Man_Woman add constraint TO_MAN_FK foreign key (man_id) references Man</programlisting>
+ </sect3>
+
+ <sect3 id="entity-hibspec-collection-extratype" revision="1">
+ <title>Types de collection extra</title>
+
+ <sect4>
+ <title>List</title>
+
+ <para>Outre EJB3, Hibernate Annotations prend en charge les v�ritables
+ <classname>List</classname> et <classname>Array</classname>. Mappez
+ votre collection de la m�me mani�re que d'habitude et ajoutez
+ l'annotation @<literal>IndexColumn</literal>. Cette annotation vous
+ permet de d�crire la colonne qui contiendra l'index. Vous pouvez aussi
+ d�clarer la valeur de l'index en base de donn�es qui repr�sente le
+ premier �l�ment (alias index de base). La valeur habituelle est
+ <literal>0</literal> ou <literal>1</literal>.</para>
+
+ <programlisting>@OneToMany(cascade = CascadeType.ALL)
+@IndexColumn(name = "drawer_position", base=1)
+public List<Drawer> getDrawers() {
+ return drawers;
+}</programlisting>
+
+ <note>
+ <para>Si vous oubliez de positionner
+ <literal>@IndexColumn</literal>, la s�mantique du bag est appliqu�e.
+ Si vous voulez la s�mantique du bag sans ses limitations, consid�rez
+ l'utilisation de <literal>@CollectionId</literal>.</para>
+ </note>
+ </sect4>
+
+ <sect4>
+ <title>Map</title>
+
+ <para>Hibernate Annotations prend aussi en charge le mapping de
+ v�ritables Maps, si <literal>@javax.persistence.MapKey</literal> n'est
+ pas positionn�e, Hibernate mappera l'�l�ment clef ou l'objet
+ embarquable dans ses propres colonnes. Pour surcharger les colonnes
+ par d�faut, vous pouvez utiliser
+ <literal>@org.hibernate.annotations.MapKey</literal> si votre clef est
+ un type de base (par d�faut � <literal>mapkey</literal>) ou un objet
+ embarquable, ou vous pouvez utiliser
+ <literal>@org.hibernate.annotations.MapKeyManyToMany</literal> si
+ votre clef est une entit�.</para>
+ </sect4>
+
+ <sect4 id="entity-hibspec-collection-extratype-indexbidir">
+ <title>Associations bidirectionnelle avec des collections index�es</title>
+
+ <para>Une association bidirectionnelle o� une extr�mit� est
+ repr�sent�e comme une <literal>@IndexColumn</literal> ou une
+ <literal>@org.hibernate.annotations.MapKey[ManyToMany]</literal>
+ requiert une consid�ration sp�ciale. S'il y a une propri�t� de la
+ classe enfante qui mappe la colonne de l'index, pas de probl�me, nous
+ pouvons continuer en utilisant <literal>mappedBy</literal> sur le
+ mapping de la collection :</para>
+
+ <programlisting>@Entity
+public class Parent {
+ @OneToMany(mappedBy="parent")
+ @org.hibernate.annotations.MapKey(columns=@Column(name="name"))
+ private Map<String, Child> children;
+ ...
+}
+
+@Entity
+public class Parent {
+ ...
+ @Basic
+ private String name;
+
+ @ManyToOne
+ @JoinColumn(name="parent_id", nullable=false)
+ private Parent parent;
+ ...
+}</programlisting>
+
+ <para>Mais s'il n'y a pas de telle propri�t� sur la classe enfante,
+ nous ne pouvons pas penser que l'association est vraiment
+ bidirectionnelle (il y a des informations disponibles � une extr�mit�
+ qui ne sont pas disponibles � l'autre). Dans ce cas, nous ne pouvons
+ pas mapper la collection avec <literal>mappedBy</literal>. A la place,
+ nous pourrions utiliser le mapping suivant :</para>
+
+ <programlisting>@Entity
+public class Parent {
+ @OneToMany
+ @org.hibernate.annotations.MapKey(columns=@Column(name="name"))
+ @JoinColumn(name="parent_id", nullable=false)
+ private Map<String, Child> children;
+ ...
+}
+
+@Entity
+public class Parent {
+ ...
+ @ManyToOne
+ @JoinColumn(name="parent_id", insertable=false, updatable=false, nullable=false)
+ private Parent parent;
+ ...
+}</programlisting>
+
+ <para>Notez que dans ce mapping, l'extr�mit� de l'association dont la
+ valeur est une collection est responsable des mises � jour pour la
+ clef �trang�re.</para>
+ </sect4>
+
+ <sect4>
+ <title>Bag avec une clef primaire</title>
+
+ <para>Une autre fonctionnalit� int�ressante est la possibilit� de
+ d�finir une clef primaire subrog�e � une collection bag. Ceci enl�ve
+ pas mal d'inconv�nients des bags : mise � jour et suppression
+ sont efficaces, plus d'un bag <literal>EAGER</literal> par requ�te ou
+ par entit�. Cette clef primaire sera contenue dans une colonne
+ suppl�mentaire de votre table de collection mais ne sea pas visible
+ par l'application Java. @CollectionId est utilis�e pour marquer une
+ collection comme "id bag", ca permet aussi de surcharger les colonnes
+ de la clef primaire, le type de la clef primaire et la strat�gie du
+ g�n�rateur. La strat�gie peut �tre <literal>identity</literal>, ou
+ n'importe quel nom de g�n�rateur d�fini de votre application.</para>
+
+ <programlisting>@Entity
+@TableGenerator(name="ids_generator", table="IDS")
+public class Passport {
+ ...
+
+ @ManyToMany(cascade = CascadeType.ALL)
+ @JoinTable(name="PASSPORT_VISASTAMP")
+ <emphasis role="bold">@CollectionId(
+ columns = @Column(name="COLLECTION_ID"),
+ type=@Type(type="long"),
+ generator = "ids_generator"
+ )</emphasis>
+ private Collection<Stamp> visaStamp = new ArrayList();
+ ...
+}</programlisting>
+ </sect4>
+
+ <sect4>
+ <title>Collection d'�l�ments ou d'�l�ments compos�s</title>
+
+ <para>Hibernate Annotations prend aussi en charge les collections de
+ types core (Integer, String, Enums, ...), les collections d'objets
+ embarquables et m�me les tableaux de types primitifs. Ce sont des
+ collections d'�l�ments.</para>
+
+ <para>Une collection d'�l�ments doit �tre annot�e comme
+ <literal>@CollectionOfElements</literal> (en tant que rempla�ant de
+ <literal>@OneToMany</literal>). Pour d�finir la table de la
+ collection, l'annotation <literal>@JoinTable</literal> est utilis�e
+ sur la propri�t� de l'association, <literal>joinColumns</literal>
+ d�finit les colonnes de jointure entre la table de l'entit� primaire
+ et la table de la collection (inverseJoincolumn est inutile et
+ devrait �tre laiss� � vide). Pour une collection de types core ou un
+ tableau de types primitifs, vous pouvez surcharger la d�finition de la
+ colonne de l'�l�ment en utilisant <literal>@Column</literal> sur la
+ propri�t� de l'association. Vous pouvez aussi surcharger les colonnes
+ d'une collection d'objets embarquables en utilisant
+ <literal>@AttributeOverride</literal>. Pour atteindre l'�l�ment de la
+ collection, vous avez besoin d'ajouter "element" au nom de l'attribut
+ surcharg� (p. ex. "element" pour les types core, ou "element.serial"
+ pour la propri�t� serial d'un �l�ment embarqu�). Pour atteindre
+ l'index/clef d'une collection, ajoutez "key" � la place.</para>
+
+ <programlisting>@Entity
+public class Boy {
+ private Integer id;
+ private Set<String> nickNames = new HashSet<String>();
+ private int[] favoriteNumbers;
+ private Set<Toy> favoriteToys = new HashSet<Toy>();
+ private Set<Character> characters = new HashSet<Character>();
+
+ @Id @GeneratedValue
+ public Integer getId() {
+ return id;
+ }
+
+ <emphasis role="bold">@CollectionOfElements
+ public Set<String></emphasis> getNickNames() {
+ return nickNames;
+ }
+
+ <emphasis role="bold">@CollectionOfElements
+ @JoinTable(
+ table=@Table(name="BoyFavoriteNumbers"),
+ joinColumns = @JoinColumn(name="BoyId")
+ )
+ @Column(name="favoriteNumber", nullable=false)</emphasis>
+ @IndexColumn(name="nbr_index")
+ public int[] getFavoriteNumbers() {
+ return favoriteNumbers;
+ }
+
+ <emphasis role="bold">@CollectionOfElements
+ @AttributeOverride( name="element.serial", column=@Column(name="serial_nbr") )</emphasis>
+ public Set<Toy> getFavoriteToys() {
+ return favoriteToys;
+ }
+
+ <emphasis role="bold">@CollectionOfElements
+ public Set<Character></emphasis> getCharacters() {
+ return characters;
+ }
+ ...
+}
+
+public enum Character {
+ GENTLE,
+ NORMAL,
+ AGGRESSIVE,
+ ATTENTIVE,
+ VIOLENT,
+ CRAFTY
+}
+
+@Embeddable
+public class Toy {
+ public String name;
+ public String serial;
+ public Boy owner;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getSerial() {
+ return serial;
+ }
+
+ public void setSerial(String serial) {
+ this.serial = serial;
+ }
+
+ <emphasis role="bold">@Parent</emphasis>
+ public Boy getOwner() {
+ return owner;
+ }
+
+ public void setOwner(Boy owner) {
+ this.owner = owner;
+ }
+
+ public boolean equals(Object o) {
+ if ( this == o ) return true;
+ if ( o == null || getClass() != o.getClass() ) return false;
+
+ final Toy toy = (Toy) o;
+
+ if ( !name.equals( toy.name ) ) return false;
+ if ( !serial.equals( toy.serial ) ) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = name.hashCode();
+ result = 29 * result + serial.hashCode();
+ return result;
+ }
+}</programlisting>
+
+ <para>Sur une collection d'objets embarquables, l'objet embarquable
+ peut avoir une propri�t� annot�e avec <literal>@Parent</literal>.
+ Cette propri�t� pointera alors vers l'entit� contenant la
+ collection.</para>
+
+ <note>
+ <para>Les versions pr�c�dentes d'Hibernate Annotations utilisaient
+ <literal>@OneToMany</literal> pour marquer une collection
+ d'�l�ments. Suite � des incoh�rences s�mantiques, nous avons mis en
+ place l'annotation <literal>@CollectionOfElements</literal>. Pour
+ marquer des collections d'�l�ments, l'ancienne fa�on fonctionne
+ encore mais elle est consid�r�e comme "deprecated" et ne sera plus
+ prise en charge dans les futures versions.</para>
+ </note>
+ </sect4>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Cache</title>
+
+ <para>Pour optimiser vos acc�s � la base de donn�es, vous pouvez activer
+ le cache de second niveau d'Hibernate. Ce cache est configurable par
+ entit� et par collection.</para>
+
+ <para><literal>@org.hibernate.annotations.Cache</literal> d�finit la
+ strat�gie de cache et la r�gion du cache de second niveau donn�. Cette
+ annotation peut �tre appliqu�e � une entit� racine (pas les entit�s
+ filles), et sur les collections.</para>
+
+ <programlisting>@Entity
+@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
+public class Forest { ... }</programlisting>
+
+ <programlisting> @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
+ @JoinColumn(name="CUST_ID")
+ @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
+ public SortedSet<Ticket> getTickets() {
+ return tickets;
+ }</programlisting>
+
+ <para></para>
+
+ <programlistingco>
+ <areaspec>
+ <area coords="2 55" id="hm1" />
+
+ <area coords="3 55" id="hm2" />
+
+ <area coords="4 55" id="hm3" />
+ </areaspec>
+
+ <programlisting>@Cache(
+ CacheConcurrencyStrategy usage();
+ String region() default "";
+ String include() default "all";
+)</programlisting>
+
+ <calloutlist>
+ <callout arearefs="hm1">
+ <para>usage : la strat�gie de concurrence du cache donn� (NONE,
+ READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL) ;</para>
+ </callout>
+
+ <callout arearefs="hm2">
+ <para>region (optionnel) : la r�gion du cache (par d�faut le nom
+ complet de la classe avec le nom du package, ou le nom complet du
+ r�le de la collection) ;</para>
+ </callout>
+
+ <callout arearefs="hm3">
+ <para><literal>include</literal> (optionnel) : "all" pour inclure
+ toutes les propri�t�s, "non-lazy" pour inclure seulement les
+ propri�t�s qui ne sont pas charg�es � la demande (valeur par
+ d�faut : all).</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ </sect2>
+
+ <sect2 id="entity-hibspec-filters">
+ <title>Filtres</title>
+
+ <para>Hibernate a la capacit� d'appliquer des filtres arbitraires � la
+ partie sup�rieure de vos donn�es. Ces filtres sont appliqu�s au moment de
+ l'ex�cution sur une session donn�e. Vous avez tout d'abord besoin de les
+ d�finir.</para>
+
+ <para><literal>@org.hibernate.annotations.FilterDef</literal> ou
+ <literal>@FilterDefs</literal> d�clarent des d�finitions de filtre
+ utilis�es par les filtres ayant le m�me nom. Une d�finition de filtre a
+ un name() et un tableau de parameters(). Un param�tre vous permettra
+ d'ajuster le comportement du filtre au moment de l'ex�cution. Chaque
+ param�tre est d�fini par une <literal>@ParamDef</literal> qui a un nom et
+ un type. Vous pouvez aussi d�finir un param�tre defaultCondition() pour
+ une <literal>@ParamDef</literal> donn�e pour positionner la condition par
+ d�faut � utiliser lorsqu'aucune n'est d�finie dans chaque
+ <literal>@Filter</literal> individuelle. Une <literal>@FilterDef</literal>
+ peut �tre d�finie au niveau de la classe ou du package.</para>
+
+ <para>Nous avons besoin de d�finir la clause du filtre SQL appliqu� au
+ chargement de l'entit� ou au chargement de la collection.
+ <literal>@Filter</literal> est utilis�e et plac�e sur l'entit� ou
+ l'�l�ment de la collection.</para>
+
+ <para><programlisting>@Entity
+@FilterDef(name="minLength", parameters={ @ParamDef( name="minLength", type="integer" ) } )
+@Filters( {
+ @Filter(name="betweenLength", condition=":minLength <= length and :maxLength >= length"),
+ @Filter(name="minLength", condition=":minLength <= length")
+} )
+public class Forest { ... }</programlisting></para>
+
+ <para>Lorsque la collection utilise une table d'association comme
+ repr�sentation relationnelle, vous pourriez vouloir appliquer la condition
+ du filtre � la table de l'association elle-m�me ou � la table de l'entit�
+ cible. Pour appliquer la contrainte sur l'entit� cible, utilisez
+ l'annotation habituelle <literal>@Filter</literal>. Cependant, si vous
+ voulez ciblez la table d'association, utilisez l'annotation
+ <literal>@FilterJoinTable</literal>.</para>
+
+ <programlisting> @OneToMany
+ @JoinTable
+ // filtre sur la table de l'entit� cible
+ @Filter(name="betweenLength", condition=":minLength <= length and :maxLength >= length")
+ // filtre sur la table d'association
+ @FilterJoinTable(name="security", condition=":userlevel >= requredLevel")
+ public Set<Forest> getForests() { ... }</programlisting>
+ </sect2>
+
+ <sect2 id="entity-hibspec-query">
+ <title>Requ�te</title>
+
+ <para>Puisqu'Hibernate a plus de fonctionnalit�s sur les requ�tes nomm�es
+ que d�finies dans la sp�cification EJB3,
+ <literal>@org.hibernate.annotations.NamedQuery</literal>,
+ <literal>@org.hibernate.annotations.NamedQueries</literal>,
+ <literal>@org.hibernate.annotations.NamedNativeQuery</literal> et
+ <literal>@org.hibernate.annotations.NamedNativeQueries</literal> ont �t�
+ mis en place. Elles ajoutent des attributs � la version standard et
+ peuvent �tre utilis�es comme rempla�ant :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>flushMode : d�finit le mode de flush de la requ�te (Always,
+ Auto, Commit ou Never)</para>
+ </listitem>
+
+ <listitem>
+ <para>cacheable : indique si la requ�te devrait �tre cach�e ou
+ non</para>
+ </listitem>
+
+ <listitem>
+ <para>cacheRegion : r�gion du cache utilis�e si la requ�te est
+ cach�e</para>
+ </listitem>
+
+ <listitem>
+ <para>fetchSize : taille de l'expression de r�cup�ration JDBC pour
+ cette requ�te</para>
+ </listitem>
+
+ <listitem>
+ <para>timeout : timeout de la requ�te</para>
+ </listitem>
+
+ <listitem>
+ <para>callable : pour les requ�tes natives seulement, mettre � true
+ pour les proc�dures stock�es</para>
+ </listitem>
+
+ <listitem>
+ <para>comment : si les commentaires sont activ�s, le commentaire vu
+ lorsque la requ�te est envoy�e vers la base de donn�es</para>
+ </listitem>
+
+ <listitem>
+ <para>cacheMode : mode d'int�raction du cache (get, ignore, normal,
+ put ou refresh)</para>
+ </listitem>
+
+ <listitem>
+ <para>readOnly : indique si les �l�ments r�cup�r�s � partir de la
+ requ�te sont en lecture seule ou pas</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Ces indications de fonctionnement peuvent �tre positionn�es sur
+ les annotations standards <literal>@javax.persistence.NamedQuery</literal>
+ avec l'annotation <literal>@QueryHint</literal>. Un autre avantage clef
+ est la possibilit� de positionner ces annotations au niveau du
+ package.</para>
+ </sect2>
+ </sect1>
+</chapter>
Added: branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/lucene.xml
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/lucene.xml 2006-10-27 19:56:30 UTC (rev 10655)
+++ branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/lucene.xml 2006-10-27 20:03:29 UTC (rev 10656)
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<chapter id="lucene" revision="1">
+ <title>Int�gration de Lucene avec Hibernate</title>
+
+ <para>Lucene est une biblioth�que de la fondation Apache fournissant un moteur
+ de recherche en Java hautement performant. Hibernate Annotations inclut un
+ ensemble d'annotations qui vous permettent de marquer n'importe quel objet
+ du mod�le de donn�es comme indexable et de laisser Hibernate maintenir un
+ index Lucene de toutes les instances persist�es via Hibernate.</para>
+
+ <para>Hibernate Lucene est un projet en cours et de nouvelles fonctionnalit�s
+ sont en pr�paration. Donc attendez-vous � certains changements avec les
+ versions ult�rieures.</para>
+
+ <section id="lucene-mapping">
+ <title>Mapper les entit�s sur l'index</title>
+
+ <para>Tout d'abord, nous devons d�clarer une classe persistante comme
+ �tant indexable. Ceci se fait en annotant la classe avec
+ <literal>@Indexed</literal> :</para>
+
+ <programlisting>@Entity
+@Indexed(index="indexes/essays")
+public class Essay {
+ ...
+}</programlisting>
+
+ <para>L'attribut <literal>index</literal> indique � Hibernate quel est le
+ nom du r�pertoire Lucene (en g�n�ral un r�pertoire de votre syst�me de
+ fichiers). Si vous souhaitez d�finir un r�pertoire de d�part pour tous vos
+ index Lucene, vous pouvez utiliser la propri�t�
+ <literal>hibernate.lucene.default.indexDir</literal> dans votre fichier de
+ configuration.</para>
+
+ <para>Les index Lucene contiennent quatre types de champs :
+ <emphasis>keyword</emphasis>, <emphasis>text</emphasis>,
+ <emphasis>unstored</emphasis> et <emphasis>unindexed</emphasis>. Hibernate
+ Annotations fournit des annotations pour marquer une propri�t� d'une entit�
+ comme �tant d'un des trois premiers types.</para>
+
+ <programlisting>@Entity
+@Indexed(index="indexes/essays")
+public class Essay {
+ ...
+
+ @Id
+ @Keyword(id=true)
+ public Long getId() { return id; }
+
+ @Text(name="Abstract")
+ public String getSummary() { return summary; }
+
+ @Lob
+ @Unstored
+ public String getText() { return text; }
+
+}</programlisting>
+
+ <para>Ces annotations d�finissent un index avec trois champs :
+ <literal>id</literal>, <literal>Abstract</literal> et
+ <literal>text</literal>. Notez que par d�faut le nom du champ n'a plus de
+ majuscules, en suivant la sp�cification JavaBean.</para>
+
+ <para>Note : vous <emphasis>devez</emphasis> sp�cifier
+ <literal>@Keyword(id=true)</literal> sur la propri�t� identifiante de
+ votre entit�.</para>
+
+ <para>Lucene a la notion of <emphasis>boost factor</emphasis>. C'est un
+ moyen de donner plus de poids � un champ ou � un �l�ment index� durant la
+ proc�dure d'indexation. Vous pouvez utiliser <literal>@Boost</literal> au
+ niveau du champ ou de la classe.</para>
+
+ <para>La classe analyste utilis�e pour indexer les �l�ments est
+ configurable par la propri�t�
+ <literal>hibernate.lucene.analyzer</literal>. Si aucune n'est d�finie,
+ <classname>org.apache.lucene.analysis.standard.StandardAnalyzer</classname>
+ est utilis�e par d�faut.</para>
+ </section>
+
+ <section id="lucene-configuration">
+ <title>Configuration</title>
+
+ <section id="lucene-configuration-directory">
+ <title>Configuration du directory</title>
+
+ <para>Lucene a une notion de Directory o� l'index est stock�.
+ L'impl�mentation de Directory peut �tre personnalis�e mais Lucene arrive,
+ avec deux impl�mentations pr�tes � l'emploi compl�tes, une sur un syst�me
+ de fichiers et une en m�moire. Hibernate Lucene a la notion de
+ <literal>DirectoryProvider</literal> qui g�re la configuration et
+ l'initialisation du Directory Lucene.</para>
+
+ <table>
+ <title>Liste des Directory Providers int�gr�s</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry align="center">Classe</entry>
+
+ <entry align="center">Description</entry>
+
+ <entry align="center">Propri�t�s</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>org.hibernate.lucene.store.FSDirectoryProvider</entry>
+
+ <entry>Directory base sur le syst�me de fichiers. Le r�pertoire
+ utilis� sera
+ <indexBase>/<<literal>@Index.name</literal>></entry>
+
+ <entry><literal>indexBase</literal> : r�pertoire de d�part</entry>
+ </row>
+
+ <row>
+ <entry>org.hibernate.lucene.store.RAMDirectoryProvider</entry>
+
+ <entry>Directory utilisant la m�moire, le directory sera
+ uniquement identifi� par l'�l�ment
+ <literal>@Index.name</literal></entry>
+
+ <entry>aucune</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>Si les directory providers int�gr�s ne r�pondent pas � vos besoins,
+ vous pouvez �crire votre propre directory provider en impl�mentant
+ l'interface
+ <classname>org.hibernate.store.DirectoryProvider</classname>.</para>
+
+ <para>Chaque entit� index�e est associ�e � un index Lucene (un index peut
+ �tre partag� par diff�rentes entit�s mais ce n'est pas le cas en g�n�ral).
+ Vous pouvez configurer l'index � travers des propri�t�s pr�fix�es par
+ <literal><literal>hibernate.lucene.<indexname></literal></literal>.
+ Les propri�t�s par d�faut h�rit�es par tous les index peuvent �tre
+ d�finies en utilisant le pr�fixe hibernate.lucene.default.</para>
+
+ <para>Pour d�finir le directory provider d'un index donn�, utilisez
+ <literal>hibernate.lucene.<indexname>.directory_provider</literal>.</para>
+
+ <programlisting>hibernate.lucene.default.directory_provider org.hibernate.lucene.store.FSDirectoryProvider
+hibernate.lucene.default.indexDir=/usr/lucene/indexes
+
+hibernate.lucene.Rules.directory_provider org.hibernate.lucene.store.RAMDirectoryProvider
+</programlisting>
+
+ <para>appliqu� �</para>
+
+ <programlisting>@Indexed(name="Status")
+public class Status { ... }
+
+@Indexed(name="Rules")
+public class Rule { ... }</programlisting>
+
+ <para>Ceci cr�era un directory syst�me de fichiers dans
+ <filename>/usr/lucene/indexes/Status</filename> o� les entit�s Status
+ seront index�es, et utilisera un directory m�moire nomm�
+ <literal>Rules</literal> o� les entit�s Rule seront index�es.</para>
+
+ <para>Donc vous pouvez facilement d�finir des r�gles g�n�rales comme le
+ directory provider et le r�pertoire de d�part, et surcharger ces valeurs
+ par d�faut plus tard pour chaque index.</para>
+
+ <para>En �crivant votre propre DirectoryProvider, vous pouvez aussi
+ b�n�ficier de ce m�canisme de configuration.</para>
+ </section>
+
+ <section id="lucene-configuration-event">
+ <title>Activer l'indexation automatique</title>
+
+ <para>Finalement, nous activons le <literal>LuceneEventListener</literal>
+ pour les trois �v�nements Hibernate qui ont lieu apr�s que les changements
+ sont valid�s dans la base de donn�es.</para>
+
+ <programlisting><hibernate-configuration>
+ ...
+ <event type="post-commit-update"
+ <listener
+ class="org.hibernate.lucene.event.LuceneEventListener"/>
+ </event>
+ <event type="post-commit-insert"
+ <listener
+ class="org.hibernate.lucene.event.LuceneEventListener"/>
+ </event>
+ <event type="post-commit-delete"
+ <listener
+ class="org.hibernate.lucene.event.LuceneEventListener"/>
+ </event>
+</hibernate-configuration></programlisting>
+ </section>
+ </section>
+</chapter>
\ No newline at end of file
Added: branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/setup.xml
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/setup.xml 2006-10-27 19:56:30 UTC (rev 10655)
+++ branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/setup.xml 2006-10-27 20:03:29 UTC (rev 10656)
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<chapter>
+ <title id="setup" revision="1">Configurer un projet avec des annotations</title>
+
+ <section id="setup-requirements">
+ <title>Pr�requis</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>T�l�chargez et installez la distribution Hibernate Annotations �
+ partir du site web d'Hibernate.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Cette version requiert Hibernate 3.2.0.GA ou
+ sup�rieur. N'utilisez pas cette version d'Hibernate Annotations avec
+ une version plus ancienne d'Hibernate 3.x !</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>Cette version est connue pour fonctionner avec le noyau 3.2.0.CR5
+ et 3.2.0.GA d'Hibernate.</para>
+ </listitem>
+
+ <listitem>
+ <para>Assurez-vous que vous avez le JDK 5.0 d'install�. Vous pouvez
+ bien s�r continuer � utiliser XDoclet et avoir certains des avantages
+ des m�ta-donn�es bas�es sur les annotations avec des versions plus
+ anciennes du JDK. Notez que ce document d�crit seulement les annotations
+ du JDK 5.0 et que vous devez vous r�f�rer � la documentation de XDoclet
+ pour plus d'informations.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section id="setup-configuration">
+ <title>Configuration</title>
+
+ <para>Tout d'abord, param�trez votre classpath (apr�s avoir cr�er un nouveau
+ projet dans votre IDE favori) :<itemizedlist>
+ <listitem>
+ <para>Copiez toutes les biblioth�ques du noyau Hibernate3 et toutes
+ les biblioth�ques tierces requises (voir lib/README.txt dans
+ Hibernate).</para>
+ </listitem>
+
+ <listitem>
+ <para>Copiez aussi <filename>hibernate-annotations.jar</filename> et
+ <filename>lib/ejb3-persistence.jar</filename> de la distribution
+ Hibernate Annotations dans votre classpath.</para>
+ </listitem>
+
+ <listitem>
+ <para>Pour utiliser <xref linkend="lucene" />, ajouter le fichier jar
+ de lucene.</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>Nous recommandons aussi un petit wrapper pour d�marrer Hibernate dans
+ un bloc statique d'initialisation, connu en tant que
+ <classname>HibernateUtil</classname>. Vous pourriez avoir vu cette classe
+ sous diverses formes dans d'autres parties de la documentation Hibernate.
+ Pour prendre en charge Annotation vous devez modifier cette classe d'aide
+ de la mani�re suivante :<programlisting>package hello;
+
+import org.hibernate.*;
+import org.hibernate.cfg.*;
+import test.*;
+import test.animals.Dog;
+
+public class HibernateUtil {
+
+private static final SessionFactory sessionFactory;
+
+ static {
+ try {
+
+ sessionFactory = new <emphasis role="bold">AnnotationConfiguration()</emphasis>.buildSessionFactory();
+ } catch (Throwable ex) {
+ // Log exception!
+ throw new ExceptionInInitializerError(ex);
+ }
+ }
+
+ public static Session getSession()
+ throws HibernateException {
+ return sessionFactory.openSession();
+ }
+}
+ </programlisting></para>
+
+ <para>La partie int�ressante ici est l'utilisation de
+ <classname>AnnotationConfiguration</classname>. Les packages et les classes
+ annot�es sont d�clar�s dans votre fichier de configuration XML habituel
+ (g�n�ralement <filename>hibernate.cfg.xml</filename>). Voici un �quivalent
+ de la d�claration ci-dessus :</para>
+
+ <programlisting><!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+ <hibernate-configuration>
+ <session-factory>
+ <emphasis role="bold"><mapping package="test.animals"/>
+ <mapping class="test.Flight"/>
+ <mapping class="test.Sky"/>
+ <mapping class="test.Person"/>
+ <mapping class="test.animals.Dog"/></emphasis>
+<emphasis role="bold"> <mapping resource="test/animals/orm.xml"/></emphasis>
+ </session-factory>
+ </hibernate-configuration>
+ </programlisting>
+
+ <para>Notez que vous pouvez m�langer l'utilisation du fichier hbm.xml et
+ celle des annotations. L'�l�ment de ressource peut �tre un fichier hbm ou
+ un descripteur de d�ploiement XML EJB3. Cette distinction est transparente
+ pour votre proc�dure de configuration.</para>
+
+ <para>Alternativement, vous pouvez d�finir les classes annot�es et des
+ packages en utilisant l'API :</para>
+
+ <programlisting> sessionFactory = new <emphasis role="bold">AnnotationConfiguration()
+ .addPackage("test.animals") // le nom complet du package
+ .addAnnotatedClass(Flight.class)
+ .addAnnotatedClass(Sky.class)
+ .addAnnotatedClass(Person.class)
+ .addAnnotatedClass(Dog.class)</emphasis>
+<emphasis role="bold"> .addResource("test/animals/orm.xml")</emphasis>
+ .buildSessionFactory();</programlisting>
+
+ <para>Vous pouvez aussi utiliser Hibernate EntityManager qui a son propre
+ m�canisme de configuration. Veullez vous r�f�rer � la documentation de ce
+ projet pour plus de d�tails.</para>
+
+ <para>Il n'y a pas d'autres diff�rences dans la fa�on d'utiliser les APIs
+ d'Hibernate, except� ce changement de routine de d�marrage ou le fichier
+ de configuration. Vous pouvez utiliser votre m�thode de configuration
+ favorite pour d'autres propri�t�s (<filename>hibernate.properties</filename>,
+ <filename>hibernate.cfg.xml</filename>, utilisation des APIs, etc). Vous
+ pouvez m�me m�langer les classes persistantes annot�es et des d�clarations
+ <filename>hbm.cfg.xml</filename> classiques avec la m�me
+ <classname>SessionFactory</classname>. Vous ne pouvez cependant pas d�clarer
+ une classe plusieurs fois (soit avec les annotations, soit avec un fichier
+ hbm.xml). Vous ne pouvez pas non plus m�langer des strat�gies de
+ configuration (hbm vs annotations) dans une hi�rarchie d'entit�s
+ mapp�es.</para>
+
+ <para>Pour faciliter la proc�dure de migration de fichiers hbm vers les
+ annotations, le m�canisme de configuration d�tecte la duplication de mappings
+ entre les annotations et les fichiers hbm. Les classes d�crites dans les
+ fichiers hbm se voient alors affecter une priorit� plus grande que les
+ classes annot�es. Vous pouvez changer cette priorit� avec la propri�t�
+ <literal>hibernate.mapping.precedence</literal>. La valeur par d�faut est :
+ <literal>hbm, class</literal> ; la changer en : <literal>class, hbm</literal>
+ donne alors la priorit� aux classes annot�es lorsqu'un conflit
+ survient.</para>
+ </section>
+</chapter>
\ No newline at end of file
Added: branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/validator.xml
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/validator.xml 2006-10-27 19:56:30 UTC (rev 10655)
+++ branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/validator.xml 2006-10-27 20:03:29 UTC (rev 10656)
@@ -0,0 +1,569 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<chapter id="validator">
+ <title>Hibernate Validator</title>
+
+ <para>Les annotations sont une mani�re tr�s commode et �l�gante pour sp�cifier
+ des contraintes invariantes sur un mod�le de donn�es. Vous pouvez, par
+ exemple, indiquer qu'une propri�t� ne devrait pas �tre nulle, que le solde
+ d'un compte devrait �tre strictement positif, etc. Ces contraintes de mod�le
+ de donn�es sont d�clar�es dans le bean lui-m�me en annotant ses propri�t�s.
+ Un validateur peut alors les lire et v�rifier les violations de contraintes.
+ Le m�canisme de validation peut �tre ex�cut� dans diff�rentes couches de
+ votre application (pr�sentation, acc�s aux donn�es) sans devoir dupliquer
+ ces r�gles. Hibernate Validator a �t� con�u dans ce but.</para>
+
+ <para>Hibernate Validator fonctionne sur deux niveaux. D'abord, il est capable
+ de v�rifier des violations de contraintes sur les instances d'une classe en
+ m�moire. Ensuite, il peut appliquer les contraintes au m�ta-mod�le d'Hibernate
+ et les incorporer au sch�ma de base de donn�es g�n�r�.</para>
+
+ <para>Chaque annotation de contrainte est associ�e � l'impl�mentation du
+ validateur responsable de v�rifier la contrainte sur l'instance de l'entit�.
+ Un validateur peut aussi (optionnellement) appliquer la contrainte au
+ m�ta-mod�le d'Hibernate, permettant � Hibernate de g�n�rer le DDL qui
+ exprime la contrainte. Avec le listener d'�v�nements appropri�, vous pouvez
+ ex�cuter l'op�ration de v�rification lors des insertions et des mises � jour
+ effectu�es par Hibernate. Hibernate Validator n'est pas limit� � Hibernate.
+ Vous pouvez facilement l'utiliser n'importe o� dans votre application.</para>
+
+ <para>Lors de la v�rification des instances � l'ex�cution, Hibernate Validator
+ retourne des informations � propos des violations de contraintes dans un
+ tableau de <classname>InvalidValue</classname>s. Parmi d'autres informations,
+ <classname>InvalidValue</classname> contient un message de description
+ d'erreur qui peut inclure les valeurs des param�tres associ�s � l'annotation
+ (p. ex. la limite de taille), et des cha�nes de caract�res qui peuvent �tre
+ externalis�es avec un <classname>ResourceBundle</classname>.</para>
+
+ <sect1 id="validator-constraints">
+ <title>Contraintes</title>
+
+ <sect2>
+ <title>Qu'est-ce qu'une contrainte ?</title>
+
+ <para>Une contrainte est repr�sent�e par une annotation. Une contrainte a
+ g�n�ralement des attributs utilis�s pour param�trer les limites des
+ contraintes. La contrainte s'applique � l'�l�ment annot�.</para>
+ </sect2>
+
+ <sect2>
+ <title>Contraintes int�gr�es</title>
+
+ <para>Hibernate Validator arrive avec des contraintes int�gr�es,
+ lesquelles couvrent la plupart des v�rifications de donn�es de base. Comme
+ nous le verrons plus tard, vous n'�tes pas limit� � celles-ci, vous pouvez
+ �crire vos propres contraintes en une minute.</para>
+
+ <table>
+ <title>Contraintes int�gr�es</title>
+
+ <tgroup cols="4">
+ <colspec align="center" />
+
+ <thead>
+ <row>
+ <entry>Annotation</entry>
+
+ <entry>S'applique �</entry>
+
+ <entry>V�rification � l'ex�cution</entry>
+
+ <entry>Impact sur les m�ta-donn�es d'Hibernate</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>@Length(min=, max=)</entry>
+
+ <entry>propri�t� (String)</entry>
+
+ <entry>v�rifie si la longueur de la cha�ne de caract�res est
+ comprise dans l'intervalle</entry>
+
+ <entry>la longueur de la colonne sera positionn�e � max</entry>
+ </row>
+
+ <row>
+ <entry>@Max(value=)</entry>
+
+ <entry>propri�t� (nombre ou cha�ne de caract�res repr�sentant un
+ nombre)</entry>
+
+ <entry>v�rifie si la valeur est inf�rieure ou �gale � max</entry>
+
+ <entry>ajoute une contrainte de v�rification sur la
+ colonne</entry>
+ </row>
+
+ <row>
+ <entry>@Min(value=)</entry>
+
+ <entry>propri�t� (nombre ou cha�ne de caract�res repr�sentant un
+ nombre)</entry>
+
+ <entry>v�rifie si la valeur est sup�rieure ou �gale � max</entry>
+
+ <entry>ajoute une contrainte de v�rification sur la
+ colonne</entry>
+ </row>
+
+ <row>
+ <entry>@NotNull</entry>
+
+ <entry>propri�t�</entry>
+
+ <entry>v�rifie si la valeur n'est pas nulle</entry>
+
+ <entry>les colonnes sont marqu�es "not null"</entry>
+ </row>
+
+ <row>
+ <entry>@Past</entry>
+
+ <entry>propri�t� (Date ou Calendar)</entry>
+
+ <entry>v�rifie si la date est dans le pass�</entry>
+
+ <entry>ajoute une contrainte de v�rification sur la
+ colonne</entry>
+ </row>
+
+ <row>
+ <entry>@Future</entry>
+
+ <entry>propri�t� (Date ou Calendar)</entry>
+
+ <entry>v�rifie si la date est dans le futur</entry>
+
+ <entry>aucun</entry>
+ </row>
+
+ <row>
+ <entry>@Pattern(regex="regexp", flag=)</entry>
+
+ <entry>propri�t� (String)</entry>
+
+ <entry>v�rifie si la propri�t� correspond � l'expression
+ rationnelle donn�e (pour "flag", voir
+ <classname> java.util.regex.Pattern</classname>)</entry>
+
+ <entry>aucun</entry>
+ </row>
+
+ <row>
+ <entry>@Range(min=, max=)</entry>
+
+ <entry>propri�t� (nombre ou cha�ne de caract�res repr�sentant un
+ nombre)</entry>
+
+ <entry>v�rifie si la valeur est comprise entre min et max
+ (inclus)</entry>
+
+ <entry>ajoute une contrainte de v�rification sur la
+ colonne</entry>
+ </row>
+
+ <row>
+ <entry>@Size(min=, max=)</entry>
+
+ <entry>propri�t� (tableau, collection, map)</entry>
+
+ <entry>v�rifie si la taille de l'�l�ment est comprise entre min et
+ max (inclus)</entry>
+
+ <entry>aucun</entry>
+ </row>
+
+ <row>
+ <entry>@AssertFalse</entry>
+
+ <entry>propri�t�</entry>
+
+ <entry>v�rifie que la m�thode est �valu�e � faux (utile pour les
+ contraintes exprim�es dans le code plut�t que dans les
+ annotations)</entry>
+
+ <entry>aucun</entry>
+ </row>
+
+ <row>
+ <entry>@AssertTrue</entry>
+
+ <entry>propri�t�</entry>
+
+ <entry>v�rifie que la m�thode est �valu�e � vrai (utile pour les
+ contraintes exprim�es dans le code plut�t que dans les
+ annotations)</entry>
+
+ <entry>aucun</entry>
+ </row>
+
+ <row>
+ <entry>@Valid</entry>
+
+ <entry>propri�t� (objet)</entry>
+
+ <entry>ex�cute la validation r�cursivement sur l'objet associ�.
+ Si l'objet est une Collection ou un tableau, les �l�ments sont
+ valid�s r�cursivement. Si l'objet est une Map, les �l�ments
+ valeur sont valid�s r�cursivement.</entry>
+
+ <entry>aucun</entry>
+ </row>
+
+ <row>
+ <entry>@Email</entry>
+
+ <entry>propri�t� (String)</entry>
+
+ <entry>v�rifie si la cha�ne de caract�res est conforme � la
+ sp�cification d'une adresse e-mail</entry>
+
+ <entry>aucun</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 id="validator-constraints-error" xreflabel="Messages d'erreur">
+ <title>Messages d'erreur</title>
+
+ <para>Hibernate Validator arrive avec un ensemble de messages d'erreur par
+ d�faut traduits dans environ dix langues (si la v�tre n'en fait pas
+ partie, veuillez nous envoyer un patch). Vous pouvez surcharger ces
+ messages en cr�ant un <filename>ValidatorMessages.properties</filename>
+ (ou <filename>ValidatorMessages_loc.properties</filename>) et en
+ surchargeant les clefs dont vous avez besoin. Vous pouvez m�me ajouter
+ votre propre ensemble de messages suppl�mentaire lorsque vous �crivez
+ vos annotations de validation. Si Hibernate Validator ne peut pas trouver
+ une clef � partir de votre resourceBundle ou de votre ValidatorMessage,
+ il se repliera sur les valeurs int�gr�es par d�faut.</para>
+
+ <para>Alternativement vous pouvez fournir un
+ <classname>ResourceBundle</classname> pendant la v�rification par
+ programmation des r�gles de validation sur un bean, ou si vous voulez un
+ m�canisme d'interpolation compl�tement diff�rent, vous pouvez fournir une
+ impl�mentation de
+ <literal>org.hibernate.validator.MessageInterpolator</literal> (lisez la
+ JavaDoc pour plus d'informations).</para>
+ </sect2>
+
+ <sect2>
+ <title>Ecrire vos propres contraintes</title>
+
+ <para>Etendre l'ensemble de contraintes int�gr�es est extr�ment facile.
+ N'importe quelle contrainte est constitu�e deux morceaux : le
+ <emphasis>descripteur</emphasis> de contrainte (l'annotation) et le
+ <emphasis>validateur</emphasis> de contrainte (la classe
+ d'impl�mentation). Voici un simple descripteur personnalis� :</para>
+
+ <programlisting>@ValidatorClass(CapitalizedValidator.class)
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface Capitalized {
+ CapitalizeType type() default Capitalize.FIRST;
+ String message() default "has incorrect capitalization";
+}</programlisting>
+
+ <para><literal>type</literal> est un param�tre d�crivant comment la
+ propri�t� devrait �tre mise en majuscule. Ceci est un param�tre
+ utilisateur compl�tement d�pendant du fonctionnement de
+ l'annotation.</para>
+
+ <para><literal>message</literal> est la cha�ne de caract�res par d�faut
+ utilis�e pour d�crire la violation de contrainte et est obligatoire. Vous
+ pouvez mettre la cha�ne de caract�res dans le code ou bien l'externaliser
+ en partie ou compl�tement avec le m�canisme ResourceBundle Java. Les
+ valeurs des param�tres sont inject�es � l'int�rieur du message quand
+ la cha�ne de caract�res <literal>{parameter}</literal> est trouv�e (dans
+ notre exemple <literal>Capitalization is not {type}</literal> g�n�rerait
+ <literal>Capitalization is not FIRST</literal>), externaliser toute la
+ cha�ne dans <filename>ValidatorMessages.properties</filename> est
+ consid�r� comme une bonne pratique. Voir <xref
+ linkend="validator-constraints-error" />.</para>
+
+ <programlisting>@ValidatorClass(CapitalizedValidator.class)
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface Capitalized {
+ CapitalizeType type() default Capitalize.FIRST;
+ String message() default "{validator.capitalized}";
+}
+
+...
+#in ValidatorMessages.properties
+validator.capitalized=<literal>Capitalization is not {type}</literal></programlisting>
+
+ <para>Comme vous pouvez le voir la notation {} est r�cursive.</para>
+
+ <para>Pour lier un descripteur � l'impl�mentation de son validateur, nous
+ utilisons la m�ta-annotation <literal>@ValidatorClass</literal>. Le
+ param�tre de la classe du validateur doit nommer une classe qui impl�mente
+ <literal>Validator<ConstraintAnnotation></literal>.</para>
+
+ <para>Nous devons maintenant impl�menter le validateur (ie
+ l'impl�mentation v�rifiant la r�gle). Une impl�mentation de validation
+ peut v�rifier la valeur d'une propri�t� (en impl�mentant
+ <literal>PropertyConstraint</literal>) et/ou peut modifier les
+ m�ta-donn�es de mapping d'Hibernate pour exprimer la contrainte au niveau
+ de la base de donn�es (en impl�mentant
+ <literal>PersistentClassConstraint</literal>).</para>
+
+ <programlisting>public class CapitalizedValidator
+ implements Validator<Capitalized>, PropertyConstraint {
+ private CapitalizeType type;
+
+ // partie du contrat de Validator<Annotation>,
+ // permet d'obtenir et d'utiliser les valeurs de l'annotation
+ public void initialize(Capitalized parameters) {
+ type = parameters.type();
+ }
+
+ // partie du contrat de la contrainte de la propri�t�
+ public boolean isValid(Object value) {
+ if (value==null) return true;
+ if ( !(value instanceof String) ) return false;
+ String string = (String) value;
+ if (type == CapitalizeType.ALL) {
+ return string.equals( string.toUpperCase() );
+ }
+ else {
+ String first = string.substring(0,1);
+ return first.equals( first.toUpperCase();
+ }
+ }
+}</programlisting>
+
+ <para>La m�thode <literal>isValid()</literal> devrait retourner false si
+ la contrainte a �t� viol�e. Pour plus d'exemples, r�f�rez-vous aux
+ impl�mentations int�gr�es du validateur.</para>
+
+ <para>Nous avons seulement vu la validation au niveau propri�t�, mais vous
+ pouvez �crire une annotation de validation au niveau d'un bean. Plut�t
+ que de recevoir l'instance de retour d'une propri�t�, le bean lui-m�me
+ sera pass� au validateur. Pour activer la v�rification de validation,
+ annotez juste le bean lui-m�me. Un petit exemple peut �tre trouv� dans la
+ suite de tests unitaires.</para>
+ </sect2>
+
+ <sect2>
+ <title>Annoter votre mod�le de donn�es</title>
+
+ <para>Maintenant que vous vous �tes familiaris�s avec les annotations, la
+ syntaxe devrait �tre connue.</para>
+
+ <programlisting>public class Address {
+ private String line1;
+ private String line2;
+ private String zip;
+ private String state;
+ private String country;
+ private long id;
+
+ // une cha�ne non nulle de 20 caract�res maximum
+ @Length(max=20)
+ @NotNull
+ public String getCountry() {
+ return country;
+ }
+
+ // une cha�ne de caract�res non nulle
+ @NotNull
+ public String getLine1() {
+ return line1;
+ }
+
+ // pas de contrainte
+ public String getLine2() {
+ return line2;
+ }
+
+ // une cha�ne non nulle de 3 caract�res maximum
+ @Length(max=3) @NotNull
+ public String getState() {
+ return state;
+ }
+
+ // une cha�ne non nulle de 5 caract�res maximum repr�sentant un nombre
+ // si la cha�ne de caract�res est plus longue, le message sera recherch�
+ // dans le resource bundle avec la clef 'long'
+ @Length(max=5, message="{long}")
+ @Pattern(regex="[0-9]+")
+ @NotNull
+ public String getZip() {
+ return zip;
+ }
+
+ // devrait toujours �tre vrai
+ @AssertTrue
+ public boolean isValid() {
+ return true;
+ }
+
+ // un nombre entre 1 et 2000
+ @Id @Min(1)
+ @Range(max=2000)
+ public long getId() {
+ return id;
+ }
+}</programlisting>
+
+ <para>Bien que l'exemple montre seulement la validation de propri�t�s
+ publiques, vous pouvez aussi annoter des champs avec n'importe quelle
+ visibilit�.</para>
+
+ <programlisting>@MyBeanConstraint(max=45)
+public class Dog {
+ @AssertTrue private boolean isMale;
+ @NotNull protected String getName() { ... };
+ ...
+}</programlisting>
+
+ <para>Vous pouvez aussi annoter des inferfaces. Hibernate Validator
+ v�rifiera toutes les classes parentes et les interfaces h�rit�es ou
+ impl�ment�es par un bean donn� pour lire les annotations appropri�es du
+ validateur.</para>
+
+ <programlisting>public interface Named {
+ @NotNull String getName();
+ ...
+}
+
+public class Dog implements Named {
+
+ @AssertTrue private boolean isMale;
+
+ public String getName() { ... };
+
+}</programlisting>
+
+ <para>La propri�t� "name" sera v�rifi�e pour la nullit� lorsque le bean
+ Dog sera valid�.</para>
+ </sect2>
+ </sect1>
+
+ <sect1>
+ <title>Utiliser le framework Validator</title>
+
+ <para>Hibernate Validator est destin� � �tre utilis� pour impl�menter une
+ validation de donn�es � plusieurs couches, o� nous exprimons des contraintes
+ � un seul endroit (le mod�le de donn�es annot�) et les appliquons aux
+ diff�rents niveaux de l'application.</para>
+
+ <sect2>
+ <title>Validation au niveau du sch�ma de la base de donn�es</title>
+
+ <para>Par d�faut, Hibernate Annotations traduira les contraintes que vous
+ avez d�finies sur vos entit�s en m�ta-donn�es de mapping. Par exemple, si
+ une propri�t� de votre entit� est annot�e avec
+ <literal>@NotNull</literal>, ses colonnes seront d�clar�es comme
+ <literal>not null</literal> dans le sch�ma DDL g�n�r� par
+ Hibernate.</para>
+ </sect2>
+
+ <sect2>
+ <title>La validation bas�e sur les �v�nements Hibernate</title>
+
+ <para>Hibernate Validator a deux listeners d'�v�nements Hibernate
+ int�gr�s. Quand un <literal>PreInsertEvent</literal> ou un
+ <literal>PreUpdateEvent</literal> survient, les listeners v�rifieront
+ toutes les contraintes de l'instance de l'entit� et l�veront une exception
+ si une contrainte est viol�e. Fondamentalement, les objets seront v�rifi�s
+ avant les insertions et avant les mises � jour effectu�es par Hibernate.
+ C'est le plus commode et la mani�re la plus simple d'activer le processus
+ de validation. Sur une violation de contrainte, l'�v�nement l�vera une
+ exception d'ex�cution <classname>InvalidStateException</classname> (NdT :
+ c'est une RuntimeException) laquelle contient un tableau
+ d'<literal>InvalidValue</literal>s d�crivant chaque �chec.</para>
+
+ <programlisting><hibernate-configuration>
+ ...
+ <event type="pre-update">
+ <listener
+ class="org.hibernate.validator.event.ValidatePreUpdateEventListener"/>
+ </event>
+ <event type="pre-insert">
+ <listener
+ class="org.hibernate.validator.event.ValidatePreInsertEventListener"/>
+ </event>
+</hibernate-configuration></programlisting>
+
+ <note>
+ <para>Lors de l'utilisation d'Hibernate Entity Manager, le framework
+ Validation est activ� par d�faut. Si les beans ne sont pas annot�s avec
+ des annotations de validation, il n'y a pas de co�t en terme de
+ performance.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>La validation au niveau applicatif</title>
+
+ <para>Hibernate Validator peut �tre utilis� n'importe o� dans le code de
+ votre application.</para>
+
+ <programlisting>ClassValidator personValidator = new ClassValidator( Person.class );
+ClassValidator addressValidator = new ClassValidator( Address.class, ResourceBundle.getBundle("messages", Locale.ENGLISH) );
+
+InvalidValue[] validationMessages = addressValidator.getInvalidValues(address);</programlisting>
+
+ <para>Les deux premi�res lignes pr�parent Hibernate Validator pour la
+ v�rification de classes. La premi�re s'appuie sur les messages d'erreur
+ int�gr�s � Hibernate Validator (voir
+ <xref linkend="validator-constraints-error" />), la seconde utilise un
+ resource bundle pour ses messages. Il est consid�r� comme une bonne
+ pratique d'ex�cuter ces lignes une fois et de cacher les instances de
+ validateur.</para>
+
+ <para>La troisi�me ligne valide en fait l'instance
+ <literal>Address</literal> et retourne un tableau
+ d'<literal>InvalidValue</literal>s. Votre logique applicative sera alors
+ capable de r�agir aux �checs.</para>
+
+ <para>Vous pouvez aussi v�rifier une propri�t� particuli�re plut�t que
+ tout le bean. Ceci pourrait �tre utile lors d'interactions avec
+ l'utilisateur propri�t� par propri�t�.</para>
+
+ <programlisting>ClassValidator addressValidator = new ClassValidator( Address.class, ResourceBundle.getBundle("messages", Locale.ENGLISH) );
+
+// r�cup�re seulement les valeurs invalides de la propri�t� "city"
+InvalidValue[] validationMessages = addressValidator.getInvalidValues(address, "city");
+
+// r�cup�re seulement les valeurs potentielles invalides de la propri�t� "city"
+InvalidValue[] validationMessages = addressValidator.getPotentialInvalidValues("city", "Paris")</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Informations de validation</title>
+
+ <para>Comme un transporteur d'informations de validation, Hibernate
+ fournit un tableau d'<classname>InvalidValue</classname>s. Chaque
+ <literal>InvalidValue</literal> a un groupe de m�thodes d�crivant les
+ probl�mes individuels.</para>
+
+ <para><methodname>getBeanClass()</methodname> r�cup�re le type du bean
+ ayant �chou�.</para>
+
+ <para><methodname>getBean()</methodname> r�cup�re l'instance du bean ayant
+ �chou� (s'il y en a, c'est-�-dire pas lors de l'utilisation de
+ <methodname>getPotentianInvalidValues()</methodname>).</para>
+
+ <para><methodname>getValue()</methodname> r�cup�re la valeur ayant
+ �chou�e.</para>
+
+ <para><methodname>getMessage()</methodname> r�cup�re le message d'erreur
+ internationalis�.</para>
+
+ <para><methodname>getRootBean()</methodname> r�cup�re l'instance du bean
+ racine ayant g�n�r� le probl�me (utile en conjonction avec
+ <literal>@Valid</literal>), est nulle si getPotentianInvalidValues() est
+ utilis�e.</para>
+
+ <para><literal>getPropertyPath()</literal> r�cup�re le chemin (s�par� par
+ des points) de la propri�t� ayant �chou�e � partir du bean racine.</para>
+ </sect2>
+ </sect1>
+</chapter>
\ No newline at end of file
Added: branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/xml-overriding.xml
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/xml-overriding.xml 2006-10-27 19:56:30 UTC (rev 10655)
+++ branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/modules/xml-overriding.xml 2006-10-27 20:03:29 UTC (rev 10656)
@@ -0,0 +1,413 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<chapter id="xml-overriding">
+ <title>Surcharger des m�ta-donn�es � travers du XML</title>
+
+ <para>La cible primaire pour les m�ta-donn�es dans EJB3 sont les annotations,
+ mais la sp�cification EJB3 fournit un moyen de surcharger ou remplacer les
+ m�ta-donn�es d�finies par des annotations � travers un descripteur de
+ d�ploiement XML. Dans la version courante, seule la surcharge des annotations
+ pure EJB3 est prise en charge. Si vous souhaitez utiliser des caract�ristiques
+ sp�cifiques � Hibernate dans des entit�s, vous devrez utiliser les annotations
+ ou vous replier sur les fichiers hbm. Vous pouvez bien s�r m�langer et faire
+ correspondre des entit�s annot�es et des entit�s d�crites dans des fichiers
+ hbm.</para>
+
+ <para>La suite de test unitaires montre des exemples suppl�mentaires de
+ fichier XML.</para>
+
+ <section id="xml-overriding-principles">
+ <title>Principes</title>
+
+ <para>La structure du descripteur de d�ploiement XML a �t� con�ue pour
+ refl�ter celle des annotations. Donc si vous connaissez la structure des
+ annotations, utiliser le sch�ma XML sera facile pour vous.</para>
+
+ <para>Vous pouvez d�finir un ou plusieurs fichiers XML d�crivant vos
+ m�ta-donn�es, ces fichiers seront fusionn�s par le moteur de surcharge.</para>
+
+ <section>
+ <title>M�ta-donn�es de niveau global</title>
+
+ <para>Vous pouvez d�finir des m�ta-donn�es de niveau global disponibles
+ pour tous les fichiers XML. Vous ne devez pas d�finir ces m�ta-donn�es
+ plus d'une fois par d�ploiement.</para>
+
+ <programlisting><?xml version="1.0" encoding="UTF-8"?>
+
+<entity-mappings
+ xmlns="http://java.sun.com/xml/ns/persistence/orm"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
+ version="1.0">
+
+ <persistence-unit-metadata>
+ <xml-mapping-metadata-complete/>
+ <persistence-unit-defaults>
+ <schema>myschema</schema>
+ <catalog>mycatalog</catalog>
+ <cascade-persist/>
+ </persistence-unit-defaults>
+ </persistence-unit-metadata></programlisting>
+
+ <para><literal>xml-mapping-metadata-complete</literal> signifie que toutes
+ les entit�s, classes m�res mapp�es et m�ta-donn�es devraient �tre
+ r�cup�r�es � partir du XML (c'est-�-dire ignorer les annotations).</para>
+
+ <para><literal>schema / catalog</literal> surchargera toutes les
+ d�finitions par d�faut de sch�ma et de catalogue dans les m�ta-donn�es
+ (XML et annotations).</para>
+
+ <para><literal>cascade-persist</literal> signifie que toutes les
+ associations ont PERSIST comme type de cascade. Nous vous recommandons de
+ ne pas utiliser cette fonctionnalit�.</para>
+ </section>
+
+ <section id="xml-overriding-principles-entity" revision="1">
+ <title>M�ta-donn�es de niveau entit�</title>
+
+ <para>Vous pouvez d�finir ou surcharger des informations de m�ta-donn�es
+ sur une entit� donn�e.</para>
+
+ <programlistingco>
+ <areaspec>
+ <area coords="3 85" id="aa1" />
+
+ <area coords="9 85" id="aa2" />
+
+ <area coords="10 85" id="aa3" />
+
+ <area coords="11 85" id="aa4" />
+
+ <area coords="17 85" id="aa5" />
+
+ <area coords="23 85" id="aa6" />
+
+ <area coords="24 85" id="aa7" />
+
+ <area coords="25 85" id="aa8" />
+
+ <area coords="26 85" id="aa9" />
+
+ <area coords="31 85" id="aa10" />
+ </areaspec>
+
+ <programlisting><?xml version="1.0" encoding="UTF-8"?>
+
+<entity-mappings
+ xmlns="http://java.sun.com/xml/ns/persistence/orm"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
+ version="1.0">
+
+ <package>org.hibernate.test.reflection.java.xml</package>
+ <entity class="Administration" access="PROPERTY" metadata-complete="true">
+ <table name="tbl_admin">
+ <unique-constraint>
+ <column-name>firstname</column-name>
+ <column-name>lastname</column-name>
+ </unique-constraint>
+ </table>
+ <secondary-table name="admin2">
+ <primary-key-join-column name="admin_id" referenced-column-name="id"/>
+ <unique-constraint>
+ <column-name>address</column-name>
+ </unique-constraint>
+ </secondary-table>
+ <id-class class="SocialSecurityNumber"/>
+ <inheritance strategy="JOINED"/>
+ <sequence-generator name="seqhilo" sequence-name="seqhilo"/>
+ <table-generator name="table" table="tablehilo"/>
+ ...
+ </entity>
+
+ <entity class="PostalAdministration">
+ <primary-key-join-column name="id"/>
+ ...
+ </entity>
+</entity-mappings></programlisting>
+
+ <calloutlist>
+ <callout arearefs="aa1">
+ <para><literal>entity-mappings</literal> : entity-mappings est
+ l'�l�ment racine pour tous les fichiers XML. Vous devez d�clarer le
+ sch�ma xml, le fichier du sch�ma est inclus dans le fichier
+ hibernate-annotations.jar, aucun acc�s � internet ne sera effectu�
+ par Hibernate Annotations.</para>
+ </callout>
+
+ <callout arearefs="aa2">
+ <para><literal>package</literal> (optionnel) : package par d�faut
+ utilis� pour tous les noms de classes sans package dans le fichier
+ de descripteur de d�ploiement donn�.</para>
+ </callout>
+
+ <callout arearefs="aa3">
+ <para><literal>entity</literal> : d�crit une entit�.</para>
+
+ <para><literal>metadata-complete</literal> d�finit si la description
+ des m�ta-donn�es pour cet �l�ment est compl�te ou pas (en d'autres
+ mots, si les annotations pr�sentes au niveau de la classe devraient
+ �tre prises en compte ou pas).</para>
+
+ <para>Une entit� doit avoir un attribut <literal>class</literal>
+ r�f�ren�ant une classe java � laquelle s'applique les
+ m�ta-donn�es.</para>
+
+ <para>Vous pouvez surcharger un nom d'entit� avec l'attribut
+ <literal>name</literal>, si aucun n'est d�fini et si une annotation
+ <literal>@Entity.name</literal> est pr�sente, alors elle est
+ utilis�e (et �tablit que les m�ta-donn�es ne sont pas
+ compl�tes).</para>
+
+ <para>Pour un �l�ment avec des m�ta-donn�es compl�tes (voir
+ ci-dessous), vous pouvez d�finir un attribut
+ <literal>access</literal> (soit <literal>FIELD</literal>, soit
+ <literal>PROPERTY</literal> (valeur par d�faut)). Pour un �l�ment
+ avec des m�ta-donn�es incompl�tes, si <literal>access</literal>
+ n'est pas d�fini, la position de @Id permettra de le d�terminer, si
+ <literal>access</literal> est d�fini, sa valeur est utilis�e.</para>
+ </callout>
+
+ <callout arearefs="aa4">
+ <para><literal>table</literal> : vous pouvez d�clarer des propri�t�s
+ de table (nom, sch�ma, catalogue), si aucune n'est d�finie,
+ l'annotation java est utilis�e.</para>
+
+ <para>Vous pouvez d�finir une ou plusieurs contraintes d'unicit�
+ comme dans l'exemple.</para>
+ </callout>
+
+ <callout arearefs="aa5">
+ <para><literal>secondary-table</literal> : d�finit une table
+ secondaire tr�s semblable � une table habituelle except� que vous
+ pouvez d�finir les colonnes de clef primaire / clef �trang�re avec
+ l'�l�ment <literal>primary-key-join-column</literal>. Sur des
+ m�ta-donn�es incompl�tes, les annotations de table secondaire sont
+ utilis�es seulement s'il n'y a pas de <literal>secondary-table</literal>
+ de d�fini, sinon les annotations sont ignor�es.</para>
+ </callout>
+
+ <callout arearefs="aa6">
+ <para><literal>id-class</literal> : d�finit la classe identifiante
+ comme le fait <literal>@IdClass</literal>.</para>
+ </callout>
+
+ <callout arearefs="aa7">
+ <para><literal>inheritance</literal> : d�finit la strat�gie
+ d'h�ritage (<literal>JOINED</literal>,
+ <literal>TABLE_PER_CLASS</literal>,
+ <literal>SINGLE_TABLE</literal>) ; disponible seulement au niveau de
+ l'�l�ment racine.</para>
+ </callout>
+
+ <callout arearefs="aa8">
+ <para><literal>sequence-generator</literal> : d�finit un g�n�rateur
+ de s�quence.</para>
+ </callout>
+
+ <callout arearefs="aa9">
+ <para><literal>table-generator</literal> : d�finit un g�n�rateur de
+ table.</para>
+ </callout>
+
+ <callout arearefs="aa10">
+ <para><literal><literal>primary-key-join-column</literal></literal> :
+ d�finit la colonne de jointure sur la clef primaire pour les
+ entit�s filles lorsque la strat�gie d'h�ritage utilis�e est
+ JOINED.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <programlistingco>
+ <areaspec>
+ <area coords="11 85" id="ab1" />
+
+ <area coords="18 85" id="ab2" />
+
+ <area coords="22 85" id="ab3" />
+
+ <area coords="28 85" id="ab4" />
+
+ <area coords="34 85" id="ab5" />
+ </areaspec>
+
+ <programlisting><?xml version="1.0" encoding="UTF-8"?>
+
+<entity-mappings
+ xmlns="http://java.sun.com/xml/ns/persistence/orm"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
+ version="1.0">
+
+ <package>org.hibernate.test.reflection.java.xml</package>
+ <entity class="Music" access="PROPERTY" metadata-complete="true">
+ <discriminator-value>Generic</discriminator-value>
+ <discriminator-column length="34"/>
+ ...
+ </entity>
+
+ <entity class="PostalAdministration">
+ <primary-key-join-column name="id"/>
+ <named-query name="adminById">
+ <query>select m from Administration m where m.id = :id</query>
+ <hint name="org.hibernate.timeout" value="200"/>
+ </named-query>
+ <named-native-query name="allAdmin" result-set-mapping="adminrs">
+ <query>select *, count(taxpayer_id) as taxPayerNumber
+ from Administration, TaxPayer
+ where taxpayer_admin_id = admin_id group by ...</query>
+ <hint name="org.hibernate.timeout" value="200"/>
+ </named-native-query>
+ <sql-result-set-mapping name="adminrs">
+ <entity-result entity-class="Administration">
+ <field-result name="name" column="fld_name"/>
+ </entity-result>
+ <column-result name="taxPayerNumber"/>
+ </sql-result-set-mapping>
+ <attribute-override name="ground">
+ <column name="fld_ground" unique="true" scale="2"/>
+ </attribute-override>
+ <association-override name="referer">
+ <join-column name="referer_id" referenced-column-name="id"/>
+ </association-override>
+ ...
+ </entity>
+</entity-mappings></programlisting>
+
+ <calloutlist>
+ <callout arearefs="ab1">
+ <para><literal>discriminator-value /
+ discriminator-column</literal> : d�finissent la colonne et la valeur
+ discriminantes lorsque la strat�gie d'h�ritage choisie est
+ SINGLE_TABLE.</para>
+ </callout>
+
+ <callout arearefs="ab2">
+ <para><literal>named-query</literal> : d�finit les requ�tes nomm�es
+ et potentiellement les indices qui leur sont associ�s. Ces
+ d�finitions sont ajout�es � celles d�finies dans les annotations,
+ si deux d�finitions ont le m�me nom, la version XML a la
+ priorit�.</para>
+ </callout>
+
+ <callout arearefs="ab3">
+ <para><literal>named-native-query</literal> : d�finit une requ�te
+ SQL nomm�e et le mapping de son r�sultat. Alternativement, vous
+ pouvez d�finir <literal>result-class</literal>. Ces d�finitions
+ sont ajout�es � celles definies dans les annotations, si deux
+ d�finitions ont le m�me nom, la version XML a la priorit�.</para>
+ </callout>
+
+ <callout arearefs="ab4">
+ <para><literal>sql-result-set-mapping</literal> : d�crit la
+ structure du mapping des r�sultats. Vous pouvez d�finir des mappings
+ de colonnes et d'entit�. Ces d�finitions sont ajout�es � celles
+ d�finies dans les annotations, si deux d�finitions ont le m�me nom,
+ la version XML a la priorit�.</para>
+ </callout>
+
+ <callout arearefs="ab5">
+ <para><literal>attribute-override /
+ association-override</literal> : surcharge la d�finition d'une
+ colonne ou d'une colonne de jointure. Cette surcharge est ajout�e �
+ celle d�finie dans les annotations.</para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>La m�me chose s'applique � <literal><embeddable></literal> et
+ <literal><mapped-superclass></literal>.</para>
+ </section>
+
+ <section>
+ <title>M�ta-donn�es de niveau propri�t�</title>
+
+ <para>Vous pouvez bien s�r d�finir des surcharges XML pour des propri�t�s.
+ Si les m�ta-donn�es sont d�finies comme incompl�tes, alors les propri�t�s
+ suppl�mentaires (c'est-�-dire au niveau Java) seront ignor�es. Toutes les
+ m�ta-donn�es de niveau propri�t� sont d�finies par
+ <literal>entity/attributes</literal>,
+ <literal>mapped-superclass/attributes</literal> ou
+ <literal>embeddable/attributes</literal>.</para>
+
+ <programlisting> <attributes>
+ <id name="id">
+ <column name="fld_id"/>
+ <generated-value generator="generator" strategy="SEQUENCE"/>
+ <temporal>DATE</temporal>
+ <sequence-generator name="generator" sequence-name="seq"/>
+ </id>
+ <version name="version"/>
+ <embedded name="embeddedObject">
+ <attribute-override name"subproperty">
+ <column name="my_column"/>
+ </attribute-override>
+ </embedded>
+ <basic name="status" optional="false">
+ <enumerated>STRING</enumerated>
+ </basic>
+ <basic name="serial" optional="true">
+ <column name="serialbytes"/>
+ <lob/>
+ </basic>
+ <basic name="terminusTime" fetch="LAZY">
+ <temporal>TIMESTAMP</temporal>
+ </basic>
+ </attributes></programlisting>
+
+ <para>Vous pouvez surcharger une propri�t� avec <literal>id</literal>,
+ <literal>embedded-id</literal>, <literal>version</literal>,
+ <literal>embedded</literal> et <literal>basic</literal>. Chacun de ces
+ �l�ments peuvent avoir des sous-�l�ments : <literal>lob</literal>,
+ <literal>temporal</literal>, <literal>enumerated</literal>,
+ <literal>column</literal>.</para>
+ </section>
+
+ <section>
+ <title>M�ta-donn�es au niveau association</title>
+
+ <para>Vous pouvez d�finir des surcharges XML pour les associations. Toutes
+ les m�ta-donn�es de niveau association sont d�finies par
+ <literal>entity/attributes</literal>,
+ <literal>mapped-superclass/attributes</literal> ou
+ <literal>embeddable/attributes</literal>.</para>
+
+ <programlisting> <attributes>
+ <one-to-many name="players" fetch="EAGER">
+ <map-key name="name"/>
+ <join-column name="driver"/>
+ <join-column name="number"/>
+ </one-to-many>
+ <many-to-many name="roads" target-entity="Administration">
+ <order-by>maxSpeed</order-by>
+ <join-table name="bus_road">
+ <join-column name="driver"/>
+ <join-column name="number"/>
+ <inverse-join-column name="road_id"/>
+ <unique-constraint>
+ <column-name>driver</column-name>
+ <column-name>number</column-name>
+ </unique-constraint>
+ </join-table>
+ </many-to-many>
+ <many-to-many name="allTimeDrivers" mapped-by="drivenBuses">
+ </attributes></programlisting>
+
+ <para>Vous pouvez surcharger une association avec
+ <literal>one-to-many</literal>, <literal>one-to-one</literal>,
+ <literal>many-to-one</literal>, et <literal>many-to-many</literal>.
+ Chacun de ces �l�ments peut avoir des sous-�l�ments :
+ <literal>join-table</literal> (qui peut avoir des
+ <literal>join-column</literal>s et des
+ <literal>inverse-join-column</literal>s),
+ <literal><literal>join-column</literal>s</literal>,
+ <literal>map-key</literal>, et <literal>order-by</literal>.
+ <literal>mapped-by</literal> et <literal>target-entity</literal> peuvent
+ �tre d�finis en tant qu'attributs lorsque cela a du sens. Une fois de plus
+ la structure est le reflet de la structure des annotations. Vous pouvez
+ trouver toutes les informations de s�mantique dans le chapitre d�crivant
+ les annotations.</para>
+ </section>
+ </section>
+</chapter>
\ No newline at end of file
Added: branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/fopdf.xsl
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/fopdf.xsl 2006-10-27 19:56:30 UTC (rev 10655)
+++ branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/fopdf.xsl 2006-10-27 20:03:29 UTC (rev 10656)
@@ -0,0 +1,519 @@
+<?xml version="1.0"?>
+
+<!--
+
+ This is the XSL FO configuration file for the Hibernate
+ Reference Documentation. It defines a custom titlepage and
+ the parameters for the A4 sized PDF printable output.
+
+ It took me days to figure out this stuff and fix most of
+ the obvious bugs in the DocBook XSL distribution. Some of
+ the workarounds might not be appropriate with a newer version
+ of DocBook XSL. This file is released as part of Hibernate,
+ hence LGPL licensed.
+
+ christian(a)hibernate.org
+
+-->
+
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY db_xsl_path "../../../../../../Hibernate3/doc/reference/support/docbook-xsl/">
+]>
+
+<xsl:stylesheet
+ version="1.0"
+ xmlns="http://www.w3.org/TR/xhtml1/transitional"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ exclude-result-prefixes="#default">
+
+ <xsl:import href="&db_xsl_path;/fo/docbook.xsl"/>
+
+ <!--###################################################
+ Custom Title Page
+ ################################################### -->
+
+ <xsl:template name="book.titlepage.recto">
+ <fo:block>
+ <fo:table table-layout="fixed" width="175mm">
+ <fo:table-column column-width="175mm"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell text-align="center">
+ <fo:block>
+ <fo:external-graphic src="file:images/hibernate_logo_a.png"/>
+ </fo:block>
+ <fo:block font-family="Helvetica" font-size="22pt" padding-before="10mm">
+ <xsl:value-of select="bookinfo/title"/>
+ </fo:block>
+ <fo:block font-family="Helvetica" font-size="18pt" padding-before="10mm">
+ <xsl:value-of select="bookinfo/subtitle"/>
+ </fo:block>
+ <fo:block font-family="Helvetica" font-size="12pt" padding="10mm">
+ Version:
+ <xsl:value-of select="bookinfo/releaseinfo"/>
+ </fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </fo:block>
+ </xsl:template>
+
+ <!-- Prevent blank pages in output -->
+ <xsl:template name="book.titlepage.before.verso">
+ </xsl:template>
+ <xsl:template name="book.titlepage.verso">
+ </xsl:template>
+ <xsl:template name="book.titlepage.separator">
+ </xsl:template>
+
+ <!--###################################################
+ Header
+ ################################################### -->
+
+ <!-- More space in the center header for long text -->
+ <xsl:attribute-set name="header.content.properties">
+ <xsl:attribute name="font-family">
+ <xsl:value-of select="$body.font.family"/>
+ </xsl:attribute>
+ <xsl:attribute name="margin-left">-5em</xsl:attribute>
+ <xsl:attribute name="margin-right">-5em</xsl:attribute>
+ </xsl:attribute-set>
+
+ <!--###################################################
+ Custom Footer
+ ################################################### -->
+
+ <!-- This footer prints the Hibernate version number on the left side -->
+ <xsl:template name="footer.content">
+ <xsl:param name="pageclass" select="''"/>
+ <xsl:param name="sequence" select="''"/>
+ <xsl:param name="position" select="''"/>
+ <xsl:param name="gentext-key" select="''"/>
+
+ <xsl:variable name="Version">
+ <xsl:choose>
+ <xsl:when test="//releaseinfo">
+ <xsl:text>Hibernate </xsl:text>
+ <xsl:value-of select="//releaseinfo"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- nop -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="$sequence='blank'">
+ <xsl:choose>
+ <xsl:when test="$double.sided != 0 and $position = 'left'">
+ <xsl:value-of select="$Version"/>
+ </xsl:when>
+
+ <xsl:when test="$double.sided = 0 and $position = 'center'">
+ <!-- nop -->
+ </xsl:when>
+
+ <xsl:otherwise>
+ <fo:page-number/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ <xsl:when test="$pageclass='titlepage'">
+ <!-- nop: other titlepage sequences have no footer -->
+ </xsl:when>
+
+ <xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='left'">
+ <fo:page-number/>
+ </xsl:when>
+
+ <xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='right'">
+ <fo:page-number/>
+ </xsl:when>
+
+ <xsl:when test="$double.sided = 0 and $position='right'">
+ <fo:page-number/>
+ </xsl:when>
+
+ <xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='left'">
+ <xsl:value-of select="$Version"/>
+ </xsl:when>
+
+ <xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='right'">
+ <xsl:value-of select="$Version"/>
+ </xsl:when>
+
+ <xsl:when test="$double.sided = 0 and $position='left'">
+ <xsl:value-of select="$Version"/>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <!-- nop -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!--###################################################
+ Custom Toc Line
+ ################################################### -->
+
+ <!-- Improve the TOC. -->
+ <xsl:template name="toc.line">
+ <xsl:variable name="id">
+ <xsl:call-template name="object.id"/>
+ </xsl:variable>
+
+ <xsl:variable name="label">
+ <xsl:apply-templates select="." mode="label.markup"/>
+ </xsl:variable>
+
+ <fo:block text-align-last="justify"
+ end-indent="{$toc.indent.width}pt"
+ last-line-end-indent="-{$toc.indent.width}pt">
+ <fo:inline keep-with-next.within-line="always">
+ <fo:basic-link internal-destination="{$id}">
+
+ <!-- Chapter titles should be bold. -->
+ <xsl:choose>
+ <xsl:when test="local-name(.) = 'chapter'">
+ <xsl:attribute name="font-weight">bold</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:if test="$label != ''">
+ <xsl:copy-of select="$label"/>
+ <xsl:value-of select="$autotoc.label.separator"/>
+ </xsl:if>
+ <xsl:apply-templates select="." mode="titleabbrev.markup"/>
+ </fo:basic-link>
+ </fo:inline>
+ <fo:inline keep-together.within-line="always">
+ <xsl:text> </xsl:text>
+ <fo:leader leader-pattern="dots"
+ leader-pattern-width="3pt"
+ leader-alignment="reference-area"
+ keep-with-next.within-line="always"/>
+ <xsl:text> </xsl:text>
+ <fo:basic-link internal-destination="{$id}">
+ <fo:page-number-citation ref-id="{$id}"/>
+ </fo:basic-link>
+ </fo:inline>
+ </fo:block>
+ </xsl:template>
+
+ <!--###################################################
+ Extensions
+ ################################################### -->
+
+ <!-- These extensions are required for table printing and other stuff -->
+ <xsl:param name="use.extensions">1</xsl:param>
+ <xsl:param name="tablecolumns.extension">0</xsl:param>
+ <!-- FOP provide only PDF Bookmarks at the moment -->
+ <xsl:param name="fop.extensions">1</xsl:param>
+
+ <!--###################################################
+ Table Of Contents
+ ################################################### -->
+
+ <!-- Generate the TOCs for named components only -->
+ <xsl:param name="generate.toc">
+ book toc
+ </xsl:param>
+
+ <!-- Show only Sections up to level 3 in the TOCs -->
+ <xsl:param name="toc.section.depth">3</xsl:param>
+
+ <!-- Dot and Whitespace as separator in TOC between Label and Title-->
+ <xsl:param name="autotoc.label.separator" select="'. '"/>
+
+
+ <!--###################################################
+ Paper & Page Size
+ ################################################### -->
+
+ <!-- Paper type, no headers on blank pages, no double sided printing -->
+ <xsl:param name="paper.type" select="'A4'"/>
+ <xsl:param name="double.sided">0</xsl:param>
+ <xsl:param name="headers.on.blank.pages">0</xsl:param>
+ <xsl:param name="footers.on.blank.pages">0</xsl:param>
+
+ <!-- Space between paper border and content (chaotic stuff, don't touch) -->
+ <xsl:param name="page.margin.top">5mm</xsl:param>
+ <xsl:param name="region.before.extent">10mm</xsl:param>
+ <xsl:param name="body.margin.top">10mm</xsl:param>
+
+ <xsl:param name="body.margin.bottom">15mm</xsl:param>
+ <xsl:param name="region.after.extent">10mm</xsl:param>
+ <xsl:param name="page.margin.bottom">0mm</xsl:param>
+
+ <xsl:param name="page.margin.outer">18mm</xsl:param>
+ <xsl:param name="page.margin.inner">18mm</xsl:param>
+
+ <!-- No intendation of Titles -->
+ <xsl:param name="title.margin.left">0pc</xsl:param>
+
+ <!--###################################################
+ Fonts & Styles
+ ################################################### -->
+
+ <!-- Default Font size -->
+ <xsl:param name="body.font.master">11</xsl:param>
+
+ <!-- Line height in body text -->
+ <xsl:param name="line-height">1.4</xsl:param>
+
+ <!-- Monospaced fonts are smaller than regular text -->
+ <xsl:attribute-set name="monospace.properties">
+ <xsl:attribute name="font-family">
+ <xsl:value-of select="$monospace.font.family"/>
+ </xsl:attribute>
+ <xsl:attribute name="font-size">0.8em</xsl:attribute>
+ </xsl:attribute-set>
+
+ <!--###################################################
+ Tables
+ ################################################### -->
+
+ <!-- The table width should be adapted to the paper size -->
+ <xsl:param name="default.table.width">17.4cm</xsl:param>
+
+ <!-- Some padding inside tables -->
+ <xsl:attribute-set name="table.cell.padding">
+ <xsl:attribute name="padding-left">4pt</xsl:attribute>
+ <xsl:attribute name="padding-right">4pt</xsl:attribute>
+ <xsl:attribute name="padding-top">4pt</xsl:attribute>
+ <xsl:attribute name="padding-bottom">4pt</xsl:attribute>
+ </xsl:attribute-set>
+
+ <!-- Only hairlines as frame and cell borders in tables -->
+ <xsl:param name="table.frame.border.thickness">0.1pt</xsl:param>
+ <xsl:param name="table.cell.border.thickness">0.1pt</xsl:param>
+
+ <!--###################################################
+ Labels
+ ################################################### -->
+
+ <!-- Label Chapters and Sections (numbering) -->
+ <xsl:param name="chapter.autolabel">1</xsl:param>
+ <xsl:param name="section.autolabel" select="1"/>
+ <xsl:param name="section.label.includes.component.label" select="1"/>
+
+ <!-- Label only Sections up to level 2 -->
+ <xsl:param name="local.l10n.xml" select="document('')"/>
+ <l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
+ <l:l10n language="en">
+ <l:context name="title-numbered">
+ <l:template name="sect3" text="%t"/>
+ <l:template name="sect4" text="%t"/>
+ <l:template name="sect5" text="%t"/>
+ </l:context>
+ <l:context name="section-xref-numbered">
+ <l:template name="sect3" text="the section called %t"/>
+ <l:template name="sect4" text="the section called %t"/>
+ <l:template name="sect5" text="the section called %t"/>
+ </l:context>
+ </l:l10n>
+ </l:i18n>
+
+ <!--###################################################
+ Titles
+ ################################################### -->
+
+ <!-- Chapter title size -->
+ <xsl:attribute-set name="chapter.titlepage.recto.style">
+ <xsl:attribute name="text-align">left</xsl:attribute>
+ <xsl:attribute name="font-weight">bold</xsl:attribute>
+ <xsl:attribute name="font-size">
+ <xsl:value-of select="$body.font.master * 1.8"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ </xsl:attribute-set>
+
+ <!-- Why is the font-size for chapters hardcoded in the XSL FO templates?
+ Let's remove it, so this sucker can use our attribute-set only... -->
+ <xsl:template match="title" mode="chapter.titlepage.recto.auto.mode">
+ <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ xsl:use-attribute-sets="chapter.titlepage.recto.style">
+ <xsl:call-template name="component.title">
+ <xsl:with-param name="node" select="ancestor-or-self::chapter[1]"/>
+ </xsl:call-template>
+ </fo:block>
+ </xsl:template>
+
+ <!-- Sections 1, 2 and 3 titles have a small bump factor and padding -->
+ <xsl:attribute-set name="section.title.level1.properties">
+ <xsl:attribute name="space-before.optimum">0.8em</xsl:attribute>
+ <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+ <xsl:attribute name="space-before.maximum">0.8em</xsl:attribute>
+ <xsl:attribute name="font-size">
+ <xsl:value-of select="$body.font.master * 1.5"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
+ <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
+ <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
+ </xsl:attribute-set>
+ <xsl:attribute-set name="section.title.level2.properties">
+ <xsl:attribute name="space-before.optimum">0.6em</xsl:attribute>
+ <xsl:attribute name="space-before.minimum">0.6em</xsl:attribute>
+ <xsl:attribute name="space-before.maximum">0.6em</xsl:attribute>
+ <xsl:attribute name="font-size">
+ <xsl:value-of select="$body.font.master * 1.25"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
+ <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
+ <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
+ </xsl:attribute-set>
+ <xsl:attribute-set name="section.title.level3.properties">
+ <xsl:attribute name="space-before.optimum">0.4em</xsl:attribute>
+ <xsl:attribute name="space-before.minimum">0.4em</xsl:attribute>
+ <xsl:attribute name="space-before.maximum">0.4em</xsl:attribute>
+ <xsl:attribute name="font-size">
+ <xsl:value-of select="$body.font.master * 1.0"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
+ <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
+ <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
+ </xsl:attribute-set>
+
+ <!-- Titles of formal objects (tables, examples, ...) -->
+ <xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing">
+ <xsl:attribute name="font-weight">bold</xsl:attribute>
+ <xsl:attribute name="font-size">
+ <xsl:value-of select="$body.font.master"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="hyphenate">false</xsl:attribute>
+ <xsl:attribute name="space-after.minimum">0.4em</xsl:attribute>
+ <xsl:attribute name="space-after.optimum">0.6em</xsl:attribute>
+ <xsl:attribute name="space-after.maximum">0.8em</xsl:attribute>
+ </xsl:attribute-set>
+
+ <!--###################################################
+ Programlistings
+ ################################################### -->
+
+ <!-- Verbatim text formatting (programlistings) -->
+ <xsl:attribute-set name="verbatim.properties">
+ <xsl:attribute name="space-before.minimum">1em</xsl:attribute>
+ <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
+ <xsl:attribute name="space-before.maximum">1em</xsl:attribute>
+ <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
+ <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
+ <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
+ <xsl:attribute name="border-color">#444444</xsl:attribute>
+ <xsl:attribute name="border-style">solid</xsl:attribute>
+ <xsl:attribute name="border-width">0.1pt</xsl:attribute>
+ <xsl:attribute name="padding-top">0.5em</xsl:attribute>
+ <xsl:attribute name="padding-left">0.5em</xsl:attribute>
+ <xsl:attribute name="padding-right">0.5em</xsl:attribute>
+ <xsl:attribute name="padding-bottom">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-left">0.5em</xsl:attribute>
+ <xsl:attribute name="margin-right">0.5em</xsl:attribute>
+ </xsl:attribute-set>
+
+ <!-- Shade (background) programlistings -->
+ <xsl:param name="shade.verbatim">1</xsl:param>
+ <xsl:attribute-set name="shade.verbatim.style">
+ <xsl:attribute name="background-color">#F0F0F0</xsl:attribute>
+ </xsl:attribute-set>
+
+ <!--###################################################
+ Callouts
+ ################################################### -->
+
+ <!-- We want to use callouts... -->
+ <xsl:param name="callout.extensions">1</xsl:param>
+
+ <!-- Place callout bullets at this column in programmlisting.-->
+ <xsl:param name="callout.defaultcolumn">90</xsl:param>
+
+ <!--
+ No, don't use crappy graphics for the callout bullets. This setting
+ enables some weird Unicode rendering for some fancy bullet points
+ in callouts. By default, this can only count to 10 and produces
+ strange results if you ever have more than 10 callouts for one
+ programlisting. We will fix that next.
+ -->
+ <xsl:param name="callout.graphics">0</xsl:param>
+
+ <!--
+ Again, fun with DocBook XSL: The callout bullets are rendered in
+ two places: In the programlisting itself and in the list below
+ the listing, with the actual callout text. The rendering in the
+ programlisting is some XSL transformer extension (e.g. a Saxon
+ extension), so we can't change that without messing with the
+ extensions. We only can turn it off by setting this limit to
+ zero, then, a simple bracket style like "(3)" and "(4)" will
+ be used in the programlisting.
+ -->
+ <xsl:param name="callout.unicode.number.limit" select="'0'"></xsl:param>
+
+ <!--
+ The callout bullets in the actual callout list will be rendered
+ with an XSL FO template. The default template is broken: limited to 10
+ nice looking Unicode bullet points and then it doesn't print anything,
+ the fallback doesn't work. We implement our own template, which is not
+ as complicated, more ugly, but works. As always, function is more
+ important than form.
+ -->
+ <xsl:template name="callout-bug">
+ <xsl:param name="conum" select='1'/>
+ <fo:inline
+ color="black"
+ padding-top="0.1em"
+ padding-bottom="0.1em"
+ padding-start="0.2em"
+ padding-end="0.2em"
+ baseline-shift="0.1em"
+ font-family="{$monospace.font.family}"
+ font-weight="bold"
+ font-size="75%">
+ <xsl:text>(</xsl:text>
+ <xsl:value-of select="$conum"/>
+ <xsl:text>)</xsl:text>
+ </fo:inline>
+
+ </xsl:template>
+
+ <!--###################################################
+ Misc
+ ################################################### -->
+
+ <!-- Correct placement of titles for figures and examples. -->
+ <xsl:param name="formal.title.placement">
+ figure after
+ example before
+ equation before
+ table before
+ procedure before
+ </xsl:param>
+
+ <!-- Format Variable Lists as Blocks (prevents horizontal overflow). -->
+ <xsl:param name="variablelist.as.blocks">1</xsl:param>
+
+ <!-- The horrible list spacing problems, this is much better. -->
+ <xsl:attribute-set name="list.block.spacing">
+ <xsl:attribute name="space-before.optimum">0.8em</xsl:attribute>
+ <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+ <xsl:attribute name="space-before.maximum">0.8em</xsl:attribute>
+ <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
+ <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
+ <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
+ </xsl:attribute-set>
+
+ <!-- Newer DocBook XSL apparently thinks that some sections are by
+ default "draft" status, and this idiotic thing is by default
+ also set to "maybe", so it spits out a lot of errors with the
+ latest FOP as the XSL/FO styles have references to some draft
+ watermarks, which you actually don't want in the first place.
+ Turn this crap off. If you have to work with the "status"
+ attribute, don't.
+ -->
+ <xsl:param name="draft.mode" select="'no'"/>
+
+</xsl:stylesheet>
Added: branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/html.css
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/html.css 2006-10-27 19:56:30 UTC (rev 10655)
+++ branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/html.css 2006-10-27 20:03:29 UTC (rev 10656)
@@ -0,0 +1,97 @@
+A {
+ color: #003399;
+}
+
+A:active {
+ color: #003399;
+}
+
+A:visited {
+ color: #888888;
+}
+
+P, OL, UL, LI, DL, DT, DD, BLOCKQUOTE {
+ color: #000000;
+}
+
+TD, TH, SPAN {
+ color: #000000;
+}
+
+BLOCKQUOTE {
+ margin-right: 0px;
+}
+
+
+H1, H2, H3, H4, H5, H6 {
+ color: #000000;
+ font-weight:500;
+ margin-top:10px;
+ padding-top:15px;
+}
+
+TABLE {
+ border-collapse: collapse;
+ border-spacing:0;
+ border: 1px thin black;
+ empty-cells: hide;
+}
+
+TD {
+ padding: 4pt;
+}
+
+H1 { font-size: 150%; }
+H2 { font-size: 140%; }
+H3 { font-size: 110%; font-weight: bold; }
+H4 { font-size: 110%; font-weight: bold;}
+H5 { font-size: 100%; font-style: italic; }
+H6 { font-size: 100%; font-style: italic; }
+
+TT {
+font-size: 90%;
+ font-family: "Courier New", Courier, monospace;
+ color: #000000;
+}
+
+PRE {
+font-size: 100%;
+ padding: 5px;
+ border-style: solid;
+ border-width: 1px;
+ border-color: #CCCCCC;
+ background-color: #F4F4F4;
+}
+
+UL, OL, LI {
+ list-style: disc;
+}
+
+HR {
+ width: 100%;
+ height: 1px;
+ background-color: #CCCCCC;
+ border-width: 0px;
+ padding: 0px;
+ color: #CCCCCC;
+}
+
+.variablelist {
+ padding-top: 10;
+ padding-bottom:10;
+ margin:0;
+}
+
+.itemizedlist, UL {
+ padding-top: 0;
+ padding-bottom:0;
+ margin:0;
+}
+
+.term {
+ font-weight:bold;
+}
+
+
+
+
Added: branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/html.xsl
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/html.xsl 2006-10-27 19:56:30 UTC (rev 10655)
+++ branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/html.xsl 2006-10-27 20:03:29 UTC (rev 10656)
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+
+<!--
+
+ This is the XSL HTML configuration file for the Hibernate
+ Reference Documentation.
+
+ It took me days to figure out this stuff and fix most of
+ the obvious bugs in the DocBook XSL distribution. Some of
+ the workarounds might not be appropriate with a newer version
+ of DocBook XSL. This file is released as part of Hibernate,
+ hence LGPL licensed.
+
+ christian(a)hibernate.org
+-->
+
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY db_xsl_path "../../../../../../Hibernate3/doc/reference/support/docbook-xsl/">
+]>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0"
+ xmlns="http://www.w3.org/TR/xhtml1/transitional"
+ exclude-result-prefixes="#default">
+
+<xsl:import href="&db_xsl_path;/html/docbook.xsl"/>
+
+<!--###################################################
+ HTML Settings
+ ################################################### -->
+
+ <xsl:param name="html.stylesheet">../shared/css/html.css</xsl:param>
+
+ <!-- These extensions are required for table printing and other stuff -->
+ <xsl:param name="use.extensions">1</xsl:param>
+ <xsl:param name="tablecolumns.extension">0</xsl:param>
+ <xsl:param name="callout.extensions">1</xsl:param>
+ <xsl:param name="graphicsize.extension">0</xsl:param>
+
+<!--###################################################
+ Table Of Contents
+ ################################################### -->
+
+ <!-- Generate the TOCs for named components only -->
+ <xsl:param name="generate.toc">
+ book toc
+ </xsl:param>
+
+ <!-- Show only Sections up to level 3 in the TOCs -->
+ <xsl:param name="toc.section.depth">3</xsl:param>
+
+<!--###################################################
+ Labels
+ ################################################### -->
+
+ <!-- Label Chapters and Sections (numbering) -->
+ <xsl:param name="chapter.autolabel">1</xsl:param>
+ <xsl:param name="section.autolabel" select="1"/>
+ <xsl:param name="section.label.includes.component.label" select="1"/>
+
+<!--###################################################
+ Callouts
+ ################################################### -->
+
+ <!-- Don't use graphics, use a simple number style -->
+ <xsl:param name="callout.graphics">0</xsl:param>
+
+ <!-- Place callout marks at this column in annotated areas -->
+ <xsl:param name="callout.defaultcolumn">90</xsl:param>
+
+<!--###################################################
+ Misc
+ ################################################### -->
+
+ <!-- Placement of titles -->
+ <xsl:param name="formal.title.placement">
+ figure after
+ example before
+ equation before
+ table before
+ procedure before
+ </xsl:param>
+
+</xsl:stylesheet>
Added: branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/html_chunk.xsl
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/html_chunk.xsl 2006-10-27 19:56:30 UTC (rev 10655)
+++ branches/Branch_3_2/HibernateExt/metadata/doc/reference/fr/styles/html_chunk.xsl 2006-10-27 20:03:29 UTC (rev 10656)
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+
+<!--
+
+ This is the XSL HTML configuration file for the Hibernate
+ Reference Documentation.
+
+ It took me days to figure out this stuff and fix most of
+ the obvious bugs in the DocBook XSL distribution. Some of
+ the workarounds might not be appropriate with a newer version
+ of DocBook XSL. This file is released as part of Hibernate,
+ hence LGPL licensed.
+
+ christian(a)hibernate.org
+-->
+
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY db_xsl_path "../../../../../../Hibernate3/doc/reference/support/docbook-xsl/">
+]>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0"
+ xmlns="http://www.w3.org/TR/xhtml1/transitional"
+ exclude-result-prefixes="#default">
+
+<xsl:import href="&db_xsl_path;/html/chunk.xsl"/>
+
+<!--###################################################
+ HTML Settings
+ ################################################### -->
+
+ <xsl:param name="chunk.section.depth">'5'</xsl:param>
+ <xsl:param name="use.id.as.filename">'1'</xsl:param>
+ <xsl:param name="html.stylesheet">../shared/css/html.css</xsl:param>
+
+ <!-- These extensions are required for table printing and other stuff -->
+ <xsl:param name="use.extensions">1</xsl:param>
+ <xsl:param name="tablecolumns.extension">0</xsl:param>
+ <xsl:param name="callout.extensions">1</xsl:param>
+ <xsl:param name="graphicsize.extension">0</xsl:param>
+
+<!--###################################################
+ Table Of Contents
+ ################################################### -->
+
+ <!-- Generate the TOCs for named components only -->
+ <xsl:param name="generate.toc">
+ book toc
+ </xsl:param>
+
+ <!-- Show only Sections up to level 3 in the TOCs -->
+ <xsl:param name="toc.section.depth">3</xsl:param>
+
+<!--###################################################
+ Labels
+ ################################################### -->
+
+ <!-- Label Chapters and Sections (numbering) -->
+ <xsl:param name="chapter.autolabel">1</xsl:param>
+ <xsl:param name="section.autolabel" select="1"/>
+ <xsl:param name="section.label.includes.component.label" select="1"/>
+
+<!--###################################################
+ Callouts
+ ################################################### -->
+
+ <!-- Don't use graphics, use a simple number style -->
+ <xsl:param name="callout.graphics">0</xsl:param>
+
+ <!-- Place callout marks at this column in annotated areas -->
+ <xsl:param name="callout.defaultcolumn">90</xsl:param>
+
+<!--###################################################
+ Misc
+ ################################################### -->
+
+ <!-- Placement of titles -->
+ <xsl:param name="formal.title.placement">
+ figure after
+ example before
+ equation before
+ table before
+ procedure before
+ </xsl:param>
+
+</xsl:stylesheet>
18 years, 1 month
Hibernate SVN: r10655 - branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2006-10-27 15:56:30 -0400 (Fri, 27 Oct 2006)
New Revision: 10655
Removed:
branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/Shoe.java
branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java
branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/Sneaker.java
Log:
ANN-466 ANN-465 Remove an incorrect test on most databases
Deleted: branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/Shoe.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/Shoe.java 2006-10-26 13:39:23 UTC (rev 10654)
+++ branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/Shoe.java 2006-10-27 19:56:30 UTC (rev 10655)
@@ -1,17 +0,0 @@
-//$Id: $
-package org.hibernate.test.annotations.inheritance.singletable;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-
-/**
- * @author Emmanuel Bernard
- */
-@Entity
-public class Shoe {
- public Integer size;
- @Id
- @GeneratedValue
- public Integer id;
-}
Deleted: branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java 2006-10-26 13:39:23 UTC (rev 10654)
+++ branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java 2006-10-27 19:56:30 UTC (rev 10655)
@@ -1,156 +0,0 @@
-//$Id$
-package org.hibernate.test.annotations.inheritance.singletable;
-
-import java.util.List;
-import java.sql.Statement;
-
-import org.hibernate.Session;
-import org.hibernate.Transaction;
-import org.hibernate.WrongClassException;
-import org.hibernate.test.annotations.TestCase;
-import org.hibernate.test.annotations.inheritance.Apple;
-import org.hibernate.test.annotations.inheritance.Fruit;
-
-/**
- * @author Emmanuel Bernard
- */
-public class SingleTableTest extends TestCase {
- //TODO move the singletable tests here
-
- public void testLongCommonPrefix() throws Exception {
- Session s = openSession();
- Transaction tx = s.beginTransaction();
- Building b = new Building();
- s.persist( b );
- s.flush();
- s.clear();
- s.get( Building.class, b.getId() );
- tx.rollback();
- s.close();
- }
-
- public void testForceDiscriminator() throws Exception {
- Session s = openSession();
- Transaction tx = s.beginTransaction();
- Building b = new Building();
- s.persist( b );
- s.flush();
- Statement statement = s.connection().createStatement();
- statement.executeUpdate( "update Building set discriminator_disc = 'N'");
- statement.close();
- s.clear();
- try {
- assertEquals( 0, s.createQuery( "select b from Building b" ).list().size() );
- }
- catch (WrongClassException e) {
- fail("the wrong discriminator is not filtered");
- }
- tx.rollback();
- s.close();
- }
-
- public void testDefault() throws Exception {
- Session s;
- Transaction tx;
- s = openSession();
- tx = s.beginTransaction();
- Fruit f = new Fruit();
- Apple a = new Apple();
- s.persist( f );
- s.persist( a );
- tx.commit();
- s.close();
-
- s = openSession();
- tx = s.beginTransaction();
- assertEquals( 1l, s.createQuery( "select count(*) from Fruit f where f.class = 'Apple'" ).uniqueResult() );
- List result = s.createCriteria( Fruit.class ).list();
- assertNotNull( result );
- assertEquals( 2, result.size() );
- Fruit f2 = (Fruit) result.get( 0 );
- checkClassType( f2, f, a );
- f2 = (Fruit) result.get( 1 );
- checkClassType( f2, f, a );
- s.delete( result.get( 0 ) );
- s.delete( result.get( 1 ) );
- tx.commit();
- s.close();
- }
-
- public void testDefaultIntegerDiscriminator() throws Exception {
- Session s;
- Transaction tx;
- s = openSession();
- tx = s.beginTransaction();
- Trash t = new Trash();
- PaperTrash pt = new PaperTrash();
- s.persist( t );
- s.persist( pt );
- tx.commit();
- s.close();
-
- s = openSession();
- tx = s.beginTransaction();
- assertEquals(
- 1l, s.createQuery( "select count(*) from Trash f where f.class = :disc" )
- .setString( "disc", String.valueOf( "PaperTrash".hashCode() ) ).uniqueResult()
- );
- List result = s.createCriteria( Trash.class ).list();
- assertNotNull( result );
- s.delete( result.get( 0 ) );
- s.delete( result.get( 1 ) );
- tx.commit();
- s.close();
- }
-
- public void testDefaultDiscriminatorColumn() {
- Session s;
- Transaction tx;
- s = openSession();
- tx = s.beginTransaction();
- Shoe t = new Shoe();
- Sneaker pt = new Sneaker();
- s.persist( t );
- s.persist( pt );
- tx.commit();
- s.close();
-
- s = openSession();
- tx = s.beginTransaction();
- //correct behavior but the test fails on HSQLDB
- //assertEquals( 0, s.createQuery( "select count(*) from Shoe f where f.class = :disc")
- // .setString( "disc", "1234567890123456789012345678901" ).uniqueResult() );
- List result = s.createCriteria( Shoe.class ).list();
- assertNotNull( result );
- s.delete( result.get( 0 ) );
- s.delete( result.get( 1 ) );
- tx.commit();
- s.close();
- }
-
- private void checkClassType(Fruit fruitToTest, Fruit f, Apple a) {
- if ( fruitToTest.getId().equals( f.getId() ) ) {
- assertFalse( fruitToTest instanceof Apple );
- }
- else if ( fruitToTest.getId().equals( a.getId() ) ) {
- assertTrue( fruitToTest instanceof Apple );
- }
- else {
- fail( "Result does not contains the previously inserted elements" );
- }
- }
-
-
- protected Class[] getMappings() {
- return new Class[]{
- Building.class,
- House.class,
- Fruit.class,
- Apple.class,
- Trash.class,
- PaperTrash.class,
- Sneaker.class,
- Shoe.class
- };
- }
-}
Deleted: branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/Sneaker.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/Sneaker.java 2006-10-26 13:39:23 UTC (rev 10654)
+++ branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/Sneaker.java 2006-10-27 19:56:30 UTC (rev 10655)
@@ -1,13 +0,0 @@
-//$Id: $
-package org.hibernate.test.annotations.inheritance.singletable;
-
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-
-/**
- * @author Emmanuel Bernard
- */
-@Entity
-@DiscriminatorValue("123456789012345678901234567890123")
-public class Sneaker extends Shoe {
-}
18 years, 1 month
Hibernate SVN: r10654 - branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-10-26 09:39:23 -0400 (Thu, 26 Oct 2006)
New Revision: 10654
Modified:
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/Classification.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/Zoo.java
Log:
use ordinal value for db value
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/Classification.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/Classification.java 2006-10-26 13:38:50 UTC (rev 10653)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/Classification.java 2006-10-26 13:39:23 UTC (rev 10654)
@@ -64,4 +64,15 @@
public static Classification valueOf(String name) {
return ( Classification ) INSTANCES.get( name );
}
+
+ public static Classification valueOf(Integer ordinal) {
+ if ( ordinal == null ) {
+ return null;
+ }
+ switch ( ordinal.intValue() ) {
+ case 0: return COOL;
+ case 1: return LAME;
+ default: throw new IllegalArgumentException( "unknown classification ordinal [" + ordinal + "]" );
+ }
+ }
}
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java 2006-10-26 13:38:50 UTC (rev 10653)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java 2006-10-26 13:39:23 UTC (rev 10654)
@@ -1,6 +1,5 @@
package org.hibernate.test.hql;
-import org.hibernate.usertype.UserType;
import org.hibernate.usertype.EnhancedUserType;
import org.hibernate.HibernateException;
import org.hibernate.Hibernate;
@@ -12,7 +11,11 @@
import java.io.Serializable;
/**
- * todo: describe ClassificationType
+ * A custom type for mapping {@link org.hibernate.test.hql.Classification} instances
+ * to the respective db column.
+ * </p>
+ * THis is largely intended to mimic JDK5 enum support in JPA. Here we are
+ * using the approach of storing the ordinal values, rather than the names.
*
* @author Steve Ebersole
*/
@@ -43,13 +46,13 @@
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
- String name = ( String ) Hibernate.STRING.nullSafeGet( rs, names[0] );
- return name == null ? null : Classification.valueOf( name );
+ Integer ordinal = ( Integer ) Hibernate.INTEGER.nullSafeGet( rs, names[0] );
+ return Classification.valueOf( ordinal );
}
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
- String name = value == null ? null : ( ( Classification ) value ).name();
- Hibernate.STRING.nullSafeSet( st, name, index );
+ Integer ordinal = value == null ? null : new Integer( ( ( Classification ) value ).ordinal() );
+ Hibernate.INTEGER.nullSafeSet( st, ordinal, index );
}
public Object deepCopy(Object value) throws HibernateException {
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/Zoo.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/Zoo.java 2006-10-26 13:38:50 UTC (rev 10653)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/Zoo.java 2006-10-26 13:39:23 UTC (rev 10654)
@@ -53,4 +53,13 @@
public void setAddress(Address address) {
this.address = address;
}
+
+
+ public Classification getClassification() {
+ return classification;
+ }
+
+ public void setClassification(Classification classification) {
+ this.classification = classification;
+ }
}
18 years, 1 month
Hibernate SVN: r10653 - trunk/Hibernate3/test/org/hibernate/test/hql
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-10-26 09:38:50 -0400 (Thu, 26 Oct 2006)
New Revision: 10653
Modified:
trunk/Hibernate3/test/org/hibernate/test/hql/Classification.java
trunk/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java
trunk/Hibernate3/test/org/hibernate/test/hql/Zoo.java
Log:
use ordinal value for db value
Modified: trunk/Hibernate3/test/org/hibernate/test/hql/Classification.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/hql/Classification.java 2006-10-26 12:34:57 UTC (rev 10652)
+++ trunk/Hibernate3/test/org/hibernate/test/hql/Classification.java 2006-10-26 13:38:50 UTC (rev 10653)
@@ -64,4 +64,15 @@
public static Classification valueOf(String name) {
return ( Classification ) INSTANCES.get( name );
}
+
+ public static Classification valueOf(Integer ordinal) {
+ if ( ordinal == null ) {
+ return null;
+ }
+ switch ( ordinal.intValue() ) {
+ case 0: return COOL;
+ case 1: return LAME;
+ default: throw new IllegalArgumentException( "unknown classification ordinal [" + ordinal + "]" );
+ }
+ }
}
Modified: trunk/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java 2006-10-26 12:34:57 UTC (rev 10652)
+++ trunk/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java 2006-10-26 13:38:50 UTC (rev 10653)
@@ -1,6 +1,5 @@
package org.hibernate.test.hql;
-import org.hibernate.usertype.UserType;
import org.hibernate.usertype.EnhancedUserType;
import org.hibernate.HibernateException;
import org.hibernate.Hibernate;
@@ -12,7 +11,11 @@
import java.io.Serializable;
/**
- * todo: describe ClassificationType
+ * A custom type for mapping {@link org.hibernate.test.hql.Classification} instances
+ * to the respective db column.
+ * </p>
+ * THis is largely intended to mimic JDK5 enum support in JPA. Here we are
+ * using the approach of storing the ordinal values, rather than the names.
*
* @author Steve Ebersole
*/
@@ -43,13 +46,13 @@
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
- String name = ( String ) Hibernate.STRING.nullSafeGet( rs, names[0] );
- return name == null ? null : Classification.valueOf( name );
+ Integer ordinal = ( Integer ) Hibernate.INTEGER.nullSafeGet( rs, names[0] );
+ return Classification.valueOf( ordinal );
}
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
- String name = value == null ? null : ( ( Classification ) value ).name();
- Hibernate.STRING.nullSafeSet( st, name, index );
+ Integer ordinal = value == null ? null : new Integer( ( ( Classification ) value ).ordinal() );
+ Hibernate.INTEGER.nullSafeSet( st, ordinal, index );
}
public Object deepCopy(Object value) throws HibernateException {
Modified: trunk/Hibernate3/test/org/hibernate/test/hql/Zoo.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/hql/Zoo.java 2006-10-26 12:34:57 UTC (rev 10652)
+++ trunk/Hibernate3/test/org/hibernate/test/hql/Zoo.java 2006-10-26 13:38:50 UTC (rev 10653)
@@ -53,4 +53,12 @@
public void setAddress(Address address) {
this.address = address;
}
+
+ public Classification getClassification() {
+ return classification;
+ }
+
+ public void setClassification(Classification classification) {
+ this.classification = classification;
+ }
}
18 years, 1 month
Hibernate SVN: r10652 - trunk/Hibernate3/test/org/hibernate/test/hql
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-10-26 08:34:57 -0400 (Thu, 26 Oct 2006)
New Revision: 10652
Modified:
trunk/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java
Log:
fixed bug in objectToSQLString()
Modified: trunk/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java 2006-10-26 12:13:47 UTC (rev 10651)
+++ trunk/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java 2006-10-26 12:34:57 UTC (rev 10652)
@@ -73,7 +73,7 @@
}
public String objectToSQLString(Object value) {
- return '\'' + extractOrdinalString( value ) + '\'';
+ return extractOrdinalString( value );
}
public String toXMLString(Object value) {
18 years, 1 month
Hibernate SVN: r10651 - branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-10-26 08:13:47 -0400 (Thu, 26 Oct 2006)
New Revision: 10651
Modified:
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java
Log:
fixed bug in objectToSQLString()
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java 2006-10-25 01:18:29 UTC (rev 10650)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java 2006-10-26 12:13:47 UTC (rev 10651)
@@ -73,7 +73,7 @@
}
public String objectToSQLString(Object value) {
- return '\'' + extractOrdinalString( value ) + '\'';
+ return extractOrdinalString( value );
}
public String toXMLString(Object value) {
18 years, 1 month