diff --git a/documentation/manual/es-ES/src/main/docbook/content/association_mapping.xml b/documentation/manual/es-ES/src/main/docbook/content/association_mapping.xml index f238160d9b..2974877348 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/association_mapping.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/association_mapping.xml @@ -332,6 +332,45 @@ create table Person ( personId bigint not null primary key, addressId bigint not create table Address ( addressId bigint not null primary key ) ]]> + + UNTRANSLATED! + If you use a List (or other indexed collection) you need + to set the key column of the foreign key to not null, + and let Hibernate manage the association from the collections side to maintain the index + of each element (making the other side virtually inverse by setting + update="false" and insert="false"): + + + + + ... + + + + + + ... + + + + + + ]]> + + UNTRANSLATED! + It is important that you define not-null="true" on the + <key> element of the collection mapping if the + underlying foreign key column is NOT NULL. Don't only + declare not-null="true" on a possible nested + <column> element, but on the <key> + element. + + + diff --git a/documentation/manual/es-ES/src/main/docbook/content/basic_mapping.xml b/documentation/manual/es-ES/src/main/docbook/content/basic_mapping.xml index 7bf55dd395..1773fe2c79 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/basic_mapping.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/basic_mapping.xml @@ -111,7 +111,59 @@ búsquedas del DTD usando una conexión de Internet, chequea tu declaración de DTD contra la contenida en el classpath. - + + UNTRANSLATED! EntityResolver + + As mentioned previously, Hibernate will first attempt to resolve DTDs in its classpath. The + manner in which it does this is by registering a custom org.xml.sax.EntityResolver + implementation with the SAXReader it uses to read in the xml files. This custom + EntityResolver recognizes two different systemId namespaces. + + + + + a hibernate namespace is recognized whenever the + resolver encounteres a systemId starting with + http://hibernate.sourceforge.net/; the resolver + attempts to resolve these entities via the classlaoder which loaded + the Hibernate classes. + + + + + a user namespace is recognized whenever the + resolver encounteres a systemId using a classpath:// + URL protocol; the resolver will attempt to resolve these entities + via (1) the current thread context classloader and (2) the + classloader which loaded the Hibernate classes. + + + + + An example of utilizing user namespacing: + + + + ]> + + + + + ... + + + &types; + ]]> + + Where types.xml is a resource in the your.domain + package and contains a custom typedef. + + + + hibernate-mapping @@ -758,6 +810,21 @@ + + + UNTRANSLATED! sequence-identity + + + a specialized sequence generation strategy which utilizes a + database sequence for the actual value generation, but combines + this with JDBC3 getGeneratedKeys to actually return the generated + identifier value as part of the insert statement execution. This + strategy is only known to be supported on Oracle 10g drivers + targetted for JDK 1.4. Note comments on these insert statements + are disabled due to a bug in the Oracle drivers. + + + @@ -877,6 +944,172 @@ + + Enhanced identifier generators + + + Starting with release 3.2.3, there are 2 new generators which represent a re-thinking of 2 different + aspects of identifier generation. The first aspect is database portability; the second is optimization + (not having to query the database for every request for a new identifier value). These two new + generators are intended to take the place of some of the named generators described above (starting + in 3.3.x); however, they are included in the current releases and can be referenced by FQN. + + + + The first of these new generators is org.hibernate.id.enhanced.SequenceStyleGenerator + which is intended firstly as a replacement for the sequence generator and secondly as + a better portability generator than native (because native + (generally) chooses between identity and sequence which have + largely different semantics which can cause subtle isssues in applications eyeing portability). + org.hibernate.id.enhanced.SequenceStyleGenerator however achieves portability in + a different manner. It chooses between using a table or a sequence in the database to store its + incrementing values depending on the capabilities of the dialect being used. The difference between this + and native is that table-based and sequence-based storage have the same exact + semantic (in fact sequences are exactly what Hibernate tries to emmulate with its table-based + generators). This generator has a number of configuration parameters: + + + + sequence_name (optional, defaults to hibernate_sequence): + The name of the sequence (or table) to be used. + + + + + initial_value (optional, defaults to 1): The initial + value to be retrieved from the sequence/table. In sequence creation terms, this is analogous + to the clause typical named "STARTS WITH". + + + + + increment_size (optional, defaults to 1): The value by + which subsequent calls to the sequence/table should differ. In sequence creation terms, this + is analogous to the clause typical named "INCREMENT BY". + + + + + force_table_use (optional, defaults to false): Should + we force the use of a table as the backing structure even though the dialect might support + sequence? + + + + + value_column (optional, defaults to next_val): Only + relevant for table structures! The name of the column on the table which is used to + hold the value. + + + + + optimizer (optional, defaults to none): + See + + + + + + The second of these new generators is org.hibernate.id.enhanced.TableGenerator which + is intended firstly as a replacement for the table generator (although it actually + functions much more like org.hibernate.id.MultipleHiLoPerTableGenerator) and secondly + as a re-implementation of org.hibernate.id.MultipleHiLoPerTableGenerator utilizing the + notion of pluggable optimiziers. Essentially this generator defines a table capable of holding + a number of different increment values simultaneously by using multiple distinctly keyed rows. This + generator has a number of configuration parameters: + + + + table_name (optional, defaults to hibernate_sequences): + The name of the table to be used. + + + + + value_column_name (optional, defaults to next_val): + The name of the column on the table which is used to hold the value. + + + + + segment_column_name (optional, defaults to sequence_name): + The name of the column on the table which is used to hold the "segement key". This is the + value which distinctly identifies which increment value to use. + + + + + segment_value (optional, defaults to default): + The "segment key" value for the segment from which we want to pull increment values for + this generator. + + + + + segment_value_length (optional, defaults to 255): + Used for schema generation; the column size to create this segment key column. + + + + + initial_value (optional, defaults to 1): + The initial value to be retrieved from the table. + + + + + increment_size (optional, defaults to 1): + The value by which subsequent calls to the table should differ. + + + + + optimizer (optional, defaults to ): + See + + + + + + + + Identifier generator optimization + + For identifier generators which store values in the database, it is inefficient for them to hit the + database on each and every call to generate a new identifier value. Instead, you'd ideally want to + group a bunch of them in memory and only hit the database when you have exhausted your in-memory + value group. This is the role of the pluggable optimizers. Currently only the two enhanced generators + ( support this notion. + + + + none (generally this is the default if no optimizer was specified): This + says to not perform any optimizations, and hit the database each and every request. + + + + + hilo: applies a hi/lo algorithm around the database retrieved values. The + values from the database for this optimizer are expected to be sequential. The values + retrieved from the database structure for this optimizer indicates the "group number"; the + increment_size is multiplied by that value in memory to define a group + "hi value". + + + + + pooled: like was discussed for hilo, this optimizers + attempts to minimize the number of hits to the database. Here, however, we simply store + the starting value for the "next group" into the database structure rather than a sequential + value in combination with an in-memory grouping algorithm. increment_size + here refers to the values coming from the database. + + + + + + composite-id @@ -920,6 +1153,53 @@ compuesto está implementado como una clase separada en . Los atributos descriptos debajo solamente se aplican a este enfoque alternativo: + + + A second approach is what we call a mapped composite identifier, + where the identifier properties named inside the <composite-id> + element are duplicated on both the persistent class and a separate identifier class. + + + + + + ]]> + + + In this example, both the composite identifier class, MedicareId, + and the entity class itself have properties named medicareNumber + and dependent. The identifier class must override + equals() and hashCode() and implement. + Serializable. The disadvantage of this approach is quite + obvious—code duplication. + + + + The following attributes are used to specify a mapped composite identifier: + + + + + + mapped (optional, defaults to false): + indicates that a mapped composite identifier is used, and that the contained + property mappings refer to both the entity class and the composite identifier + class. + + + + + class (optional, but required for a mapped composite identifier): + The class used as a composite identifier. + + + + + + We will describe a third, even more convenient approach where the composite identifier + is implemented as a component class in . The + attributes described below apply only to this alternative approach: + @@ -927,6 +1207,11 @@ name (opcional): Una propiedad de tipo componente que tiene el identificador compuesto (ver siguiente sección). + + + access (optional - defaults to property): + The strategy Hibernate should use for accessing the property value. + @@ -934,20 +1219,12 @@ por reflección): La clase del componente usado como identificador compuesto (ver siguiente sección). - - - unsaved-value (opcional - por defecto a undefined): - Indica que las instancias transitorias deben ser consideradas como recién instanciadas, - si se establece a any, o separadas, si se establece a none. - Lo mejor - - Indicates that transient instances should be considered newly instantiated, if set - to any, or detached, if set to none. - Lo mejor en todos los casos es dejar el valor por defecto. - - + - + + This third approach, an identifier component is the one we recommend + for almost all applications. + @@ -1099,6 +1376,21 @@ propiedad identificadora.) + + UNTRANSLATED! + generated (optional - defaults to never): + Specifies that this version property value is actually generated by the database. + See the discussion of generated properties. + + + + UNTRANSLATED! + insert (optional - defaults to true): + Specifies whether the version column should be included in SQL insert statements. + May be set to false if and only if the database column + is defined with a default value of 0. + + @@ -1172,7 +1464,26 @@ (undefined especifica que debe usarse el valor de la propiedad identificadora.) - + + UNTRANSLATED! + source (optional - defaults to vm): + From where should Hibernate retrieve the timestamp value? From the database, + or from the current JVM? Database-based timestamps incur an overhead because + Hibernate must hit the database in order to determine the "next value", + but will be safer for use in clustered environments. Note also, that not + all Dialects are known to support retrieving of the + database's current timestamp, while others might be unsafe for usage + in locking due to lack of precision (Oracle 8 for example). + + + + UNTRANSLATED! + generated (optional - defaults to never): + Specifies that this timestamp property value is actually generated by the database. + See the discussion of generated properties. + + + @@ -1295,6 +1606,12 @@ de un bloqueo optimista. En otras palabras, determina si debe ocurrir un incremento de versión cuando la propiedad este sucia (desactualizada). + + UNTRANSLATED! + generated (optional - defaults to never): + Specifies that this property value is actually generated by the database. + See the discussion of generated properties. + @@ -1580,6 +1897,9 @@ Si la clave única referenciada abarca múltiples propiedades de la entidad asociada, debes mapear las propiedades dentro de un elemento <properties>. + UNTRANSLATED! + If the referenced unique key is the property of a component, you may specify a property path: + @@ -1686,6 +2006,10 @@ la aplicación de proxies es imposible e Hibernate traerá temprano la asociación! + + + entity-name (optional): The entity name of the associated class. + @@ -2075,33 +2399,13 @@ - - Cada subclase debe declarar sus propias propiedades persistentes y subclases. - Se asume que las propiedades <version> y <id> - son heredadas de la clase raíz. Cada subclase en una jerarquía debe - definir un discriminator-value único. Si no se especifica ninguno, - se usa el nombre completamente cualificado de clase Java. + UNTRANSLATED! + Each subclass should declare its own persistent properties and subclasses. + <version> and <id> properties + are assumed to be inherited from the root class. Each subclass in a heirarchy must + define a unique discriminator-value. If none is specified, the + fully qualified Java class name is used. - - - Es posible definir mapeos subclass, union-subclass, - y joined-subclass en documentos de mapeo separados, directamente debajo - de hibernate-mapping. Esto te permite extender una jerarquía de clases - con sólo agregar un nuevo fichero de mapeo. Debes especificar un atributo - extends en el mapeo de la subclase, mencionando una superclase previamente mapeada. - Nota: Previamente esta funcionalidad hacía importante el orden de los documentos de mapeo. - Desde Hibernate3, el orden de los ficheros de mapeo no importa cuando se usa la palabra reservada - extends. El orden dentro de un mismo fichero de mapeo todavía necesita ser definido como - superclases antes de subclases. - - - - - - -]]> - Para información acerca de mapeos de herencia, ver . @@ -2871,7 +3175,24 @@ ser malo e inconsistente). - + + + UNTRANSLATED! imm_date, imm_time, imm_timestamp, imm_calendar, imm_calendar_date, + imm_serializable, imm_binary + + + + Type mappings for what are usually considered mutable Java types, where + Hibernate makes certain optimizations appropriate only for immutable + Java types, and the application treats the object as immutable. For + example, you should not call Date.setTime() for an + instance mapped as imm_timestamp. To change the + value of the property, and have that change made persistent, the + application must assign a new (nonidentical) object to the property. + + + + diff --git a/documentation/manual/es-ES/src/main/docbook/content/batch.xml b/documentation/manual/es-ES/src/main/docbook/content/batch.xml index 7c28309d4e..0bb0908ba5 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/batch.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/batch.xml @@ -31,14 +31,20 @@ session.close();]]> - + + UNTRANSLATED! Note that Hibernate disables insert batching at the JDBC level transparently if you + use an identiy identifier generator. + Podrías además querer hacer este tipo de trabajo en un proceso donde la interacción con el caché de segundo nivel esté completamente deshabilitado: - + UNTRANSLATED! + However, this is not absolutely necessary, since we can explicitly set the + CacheMode to disable interaction with the second-level cache. + Inserciones en lote @@ -96,7 +102,57 @@ tx.commit(); session.close();]]> - + + + UNTRANSLATED! The StatelessSession interface + + Alternatively, Hibernate provides a command-oriented API that may be used for + streaming data to and from the database in the form of detached objects. A + StatelessSession has no persistence context associated + with it and does not provide many of the higher-level life cycle semantics. + In particular, a stateless session does not implement a first-level cache nor + interact with any second-level or query cache. It does not implement + transactional write-behind or automatic dirty checking. Operations performed + using a stateless session do not ever cascade to associated instances. Collections + are ignored by a stateless session. Operations performed via a stateless session + bypass Hibernate's event model and interceptors. Stateless sessions are vulnerable + to data aliasing effects, due to the lack of a first-level cache. A stateless + session is a lower-level abstraction, much closer to the underlying JDBC. + + + + + + Note that in this code example, the Customer instances returned + by the query are immediately detached. They are never associated with any persistence + context. + + + + The insert(), update() and delete() operations + defined by the StatelessSession interface are considered to be + direct database row-level operations, which result in immediate execution of a SQL + INSERT, UPDATE or DELETE respectively. Thus, + they have very different semantics to the save(), saveOrUpdate() + and delete() operations defined by the Session + interface. + + + + + update/delete en masa @@ -125,14 +181,17 @@ session.close();]]> - Puede haber sólo una clase mencionada en la cláusula-from, y no puede - tener un alias. + There can only be a single entity named in the from-clause; it can optionally be + aliased. If the entity name is aliased, then any property references must + be qualified using that alias; if the entity name is not aliased, then it is + illegal for any property references to be qualified. - No puede especificarse ningún join (bien implícito o explícito) en una consulta masiva de HQL. - Pueden usarse subconsultas en la cláusula-where. + No joins (either implicit or explicit) + can be specified in a bulk HQL query. Sub-queries may be used in the where-clause; + the subqueries, themselves, may contain joins. @@ -144,24 +203,50 @@ session.close();]]> Como un ejemplo, para ejecutar un UPDATE HQL, usa el - método Query.executeUpdate(): + método Query.executeUpdate()(the method is named for + those familiar with JDBC's PreparedStatement.executeUpdate()): - + + + + + HQL UPDATE statements, by default do not effect the + version + or the timestamp property values + for the affected entities; this is in keeping with the EJB3 specification. However, + you can force Hibernate to properly reset the version or + timestamp property values through the use of a versioned update. + This is achieved by adding the VERSIONED keyword after the UPDATE + keyword. + + + + + Note that custom version types (org.hibernate.usertype.UserVersionType) + are not allowed in conjunction with a update versioned statement. + - Para ejecutar un DELETE HQL, usa el mismo método Query.executeUpdate() - (el método está nombrado para aquellos familiarizados con - PreparedStatement.executeUpdate() de JDBC): + Para ejecutar un DELETE HQL, usa el mismo método Query.executeUpdate(): - + optimistic-lock (opcional - por defecto a true): Especifica que los cambios de estado de la colección resultan en incrementos de versión de la entidad dueña. (Para asociaciones uno a muchos, frecuentemente es razonable deshabilitar esta opción.) + + + + mutable (optional - defaults to true): + A value of false specifies that the elements of the + collection never change (a minor performance optimization in some cases). + @@ -555,7 +562,13 @@ kittens = cat.getKittens(); // Okay, kittens collection is a Set entity-name (opcional): El nombre de entidad de la clase asociada, como una alternativa a class. - + + UNTRANSLATED! + property-ref: (optional) The name of a property of the associated + class that is joined to this foreign key. If not specified, the primary key of + the associated class is used. + + @@ -841,7 +854,7 @@ kittens = cat.getKittens(); // Okay, kittens collection is a Set - + ... diff --git a/documentation/manual/es-ES/src/main/docbook/content/configuration.xml b/documentation/manual/es-ES/src/main/docbook/content/configuration.xml index 8dbbac0934..5026de505b 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/configuration.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/configuration.xml @@ -392,11 +392,25 @@ hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]> Escribe todas las sentencias SQL a la consola. - - ej. - true | false + This is an alternative + to setting the log category org.hibernate.SQL + to debug. + + eg. + true | false + + + hibernate.format_sql + + + Pretty print the SQL in the log and console. + + eg. + true | false + + @@ -715,6 +729,13 @@ hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]> ej. on_close (por defecto)| after_transaction | after_statement | auto + + Note that this setting only affects Sessions returned from + SessionFactory.openSession. For Sessions + obtained through SessionFactory.getCurrentSession, the + CurrentSessionContext implementation configured for use + controls the connection release mode for those Sessions. + See @@ -928,7 +949,7 @@ hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]> De habilitarse, la sesión será cerrada automáticamente durante la fase posterior a la compleción de la transacción. - (Muy útil cuando se usa Hibernate con CMT). + (Muy útil cuando se usa Hibernate con CMT). ej. true | false @@ -950,7 +971,22 @@ hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]> Propósito - + + + hibernate.current_session_context_class + + + Supply a (custom) strategy for the scoping of the "current" + Session. See + for more + information about the built-in strategies. + + eg. + jta | thread | + managed | custom.Class + + + hibernate.query.factory_class @@ -1636,7 +1672,10 @@ hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]> de arranque (o clase de utilidad) en tu aplicación, a menos qie uses el despliegue JMX con el HibernateService (discutido luego). - + UNTRANSLATED! + If you use a JNDI SessionFactory, an EJB or any other class may + obtain the SessionFactory using a JNDI lookup. + Si usas una SessionFactory de JNDI, un EJB o cualquier otra clase puede obtener la SessionFactory usando una búsqueda @@ -1651,36 +1690,27 @@ hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]> Ligado automático de JTA y Session - - Para entornos no manejados hemos sugerido HibernateUtil con una - SessionFactory estática, y administración de la - Session de Hibernate. Este enfoque no es fácil de usar - en un entorno EJB, al poder ejecutarse muchos EJBs dentro de la misma transacción - pero no en la misma hebra. Recomendados que ligues la SessionFactory - a JNDI en un entorno manejado. + UNTRANSLATED! + The easiest way to handle Sessions and transactions is + Hibernates automatic "current" Session management. + See the discussion of current sessions. + Using the "jta" session context, if there is no Hibernate + Session associated with the current JTA transaction, one will + be started and associated with that JTA transaction the first time you call + sessionFactory.getCurrentSession(). The Sessions + retrieved via getCurrentSession() in "jta" context + will be set to automatically flush before the transaction completes, close + after the transaction completes, and aggressively release JDBC connections + after each statement. This allows the Sessions to + be managed by the life cycle of the JTA transaction to which it is associated, + keeping user code clean of such management concerns. Your code can either use + JTA programmatically through UserTransaction, or (recommended + for portable code) use the Hibernate Transaction API to set + transaction boundaries. If you run in an EJB container, declarative transaction + demarcation with CMT is preferred. - - En vez de rodar tu propia utilidad de ThreadLocal, - usa el método getCurrentSession() en la - SessionFactory para obtener una Session - de Hibernate. Si no hubiese una Session de Hibernate en la - transacción JTA actual, se arrancará y asignará una. - Ambas opciones de configuración hibernate.transaction.flush_before_completion - y hibernate.transaction.auto_close_session, serán establecidas - automáticamente para cada Session que obtengas con - getCurrentSession(), de modo que éstas serán - limpiadas (flushed) y cerradas automáticamente cuando el contenedor complete - las transacciones JTA. - - - Si tu, por ejemplo, usas el patrón de diseño DAO para escribir tu - capa de persistencia, todos los DAO's buscan la SessionFactory - cuando se necesite y abren la sesión "actual". No hay necesidad de pasar - las instancias de SessionFactory o Session - alrededor entre el código de control y el código DAO. - diff --git a/documentation/manual/es-ES/src/main/docbook/content/events.xml b/documentation/manual/es-ES/src/main/docbook/content/events.xml index 4252acc3ac..f535652512 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/events.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/events.xml @@ -22,7 +22,10 @@ creado y actualiza la propiedad lastUpdateTimestamp cuando un Auditable es acutalizado. - + UNTRANSLATED! + You may either implement Interceptor directly or (better) extend + EmptyInterceptor. + - - El interceptor podría ser especificado cuando se crea la sesión: + UNTRANSLATED! + Interceptors come in two flavors: Session-scoped and + SessionFactory-scoped. + + + UNTRANSLATED! + A Session-scoped interceptor is specified + when a session is opened using one of the overloaded SessionFactory.openSession() + methods accepting an Interceptor. - - - - Puedes además establecer un interceptor a un nivel global, usando la Configuration: + UNTRANSLATED! + A SessionFactory-scoped interceptor is registered with the Configuration + object prior to building the SessionFactory. In this case, the supplied interceptor + will be applied to all sessions opened from that SessionFactory; this is true unless + a session is opened explicitly specifying the interceptor to use. SessionFactory-scoped + interceptors must be thread safe, taking care to not store session-specific state since multiple + sessions will use this interceptor (potentially) concurrently. @@ -218,7 +231,11 @@ cfg.getSessionEventListenerConfig().setLoadEventListener( new MyLoadListener() ) ]]> - + UNTRANSLATED! + Note that <listener type="..." class="..."/> is just a shorthand + for <event type="..."><listener class="..."/></event> + when there is exactly one listener for a particular event type. + Seguido, aún en hibernate.cfg.xml, liga los permisos a roles: diff --git a/documentation/manual/es-ES/src/main/docbook/content/inheritance_mapping.xml b/documentation/manual/es-ES/src/main/docbook/content/inheritance_mapping.xml index 40d7d80cf9..026fe2957f 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/inheritance_mapping.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/inheritance_mapping.xml @@ -42,6 +42,24 @@ + + UNTRANSLATED! + It is possible to define subclass, union-subclass, + and joined-subclass mappings in separate mapping documents, directly beneath + hibernate-mapping. This allows you to extend a class hierachy just by adding + a new mapping file. You must specify an extends attribute in the subclass mapping, + naming a previously mapped superclass. Note: Previously this feature made the ordering of the mapping + documents important. Since Hibernate3, the ordering of mapping files does not matter when using the + extends keyword. The ordering inside a single mapping file still needs to be defined as superclasses + before subclasses. + + + + + + + ]]> Es posible usar estrategias de mapeo diferentes para diferentes ramificaciones de la misma jerarquía de herencia, y entonces usar @@ -258,7 +276,12 @@ de unión de subclase, de hecho la semilla de clave primaria tiene que ser compartida a través de todas las subclases unidas de una jerarquía. - + UNTRANSLATED! + If your superclass is abstract, map it with abstract="true". + Of course, if it is not abstract, an additional table (defaults to + PAYMENT in the example above) is needed to hold instances + of the superclass. + diff --git a/documentation/manual/es-ES/src/main/docbook/content/performance.xml b/documentation/manual/es-ES/src/main/docbook/content/performance.xml index 100c0d2c70..4a270fc870 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/performance.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/performance.xml @@ -68,6 +68,20 @@ Recuperación perezosa de colecciones - se recupera una colección cuando la aplicación invoca una operación sobre la colección. (Esto es por defecto para las colecciones.) + + + "Extra-lazy" collection fetching - individual + elements of the collection are accessed from the database as needed. + Hibernate tries not to fetch the whole collection into memory unless + absolutely needed (suitable for very large collections) + + + + + Proxy fetching - a single-valued association is + fetched when a method other than the identifier getter is invoked + upon the associated object. + @@ -186,9 +200,17 @@ Integer accessLevel = (Integer) permissions.get("accounts"); // Error!]]> las consultas de Criteria + + + HQL queries if subselect fetching is used + - + + No matter what fetching strategy you use, the defined non-lazy graph is guaranteed + to be loaded into memory. Note that this might result in several immediate selects + being used to execute a particular HQL query. + Usualmente, no usamos el documento de mapeo para personalizar la recuperación. En cambio, mantenemos el comportamiento por defecto, y lo sobrescribimos para una transacción en particular, usando @@ -353,7 +375,12 @@ Cat fritz = (Cat) iter.next();]]> Hibernate detectará las clase persistentes que sobrescriban equals() o hashCode(). - + UNTRANSLATED!!! + By choosing lazy="no-proxy" instead of the default + lazy="proxy", we can avoid the problems associated with typecasting. + However, we will require buildtime bytecode instrumentation, and all operations + will result in immediate proxy initialization. + @@ -673,7 +700,8 @@ Cat fritz = (Cat) iter.next();]]> - + + nonstrict-read-write o read-only - + + + region (optional, defaults to the class or + collection role name) specifies the name of the second level cache + region + + + + + include (optional, defaults to all) + non-lazy specifies that properties of the entity mapped + with lazy="true" may not be cached when attribute-level + lazy fetching is enabled + + diff --git a/documentation/manual/es-ES/src/main/docbook/content/persistent_classes.xml b/documentation/manual/es-ES/src/main/docbook/content/persistent_classes.xml index 1052c9ebcc..34bf9732ae 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/persistent_classes.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/persistent_classes.xml @@ -470,6 +470,71 @@ dynamicSession.close() representación XML en . + + + UNTRANSLATED!!! Tuplizers + + + org.hibernate.tuple.Tuplizer, and its sub-interfaces, are responsible + for managing a particular representation of a piece of data, given that representation's + org.hibernate.EntityMode. If a given piece of data is thought of as + a data structure, then a tuplizer is the thing which knows how to create such a data structure + and how to extract values from and inject values into such a data structure. For example, + for the POJO entity mode, the correpsonding tuplizer knows how create the POJO through its + constructor and how to access the POJO properties using the defined property accessors. + There are two high-level types of Tuplizers, represented by the + org.hibernate.tuple.entity.EntityTuplizer and org.hibernate.tuple.component.ComponentTuplizer + interfaces. EntityTuplizers are responsible for managing the above mentioned + contracts in regards to entities, while ComponentTuplizers do the same for + components. + + + + Users may also plug in their own tuplizers. Perhaps you require that a java.util.Map + implementation other than java.util.HashMap be used while in the + dynamic-map entity-mode; or perhaps you need to define a different proxy generation strategy + than the one used by default. Both would be achieved by defining a custom tuplizer + implementation. Tuplizers definitions are attached to the entity or component mapping they + are meant to manage. Going back to the example of our customer entity: + + + + + + + + + + + + + ... + + + + + public class CustomMapTuplizerImpl + extends org.hibernate.tuple.entity.DynamicMapEntityTuplizer { + // override the buildInstantiator() method to plug in our custom map... + protected final Instantiator buildInstantiator( + org.hibernate.mapping.PersistentClass mappingInfo) { + return new CustomMapInstantiator( mappingInfo ); + } + + private static final class CustomMapInstantiator + extends org.hibernate.tuple.DynamicMapInstantitor { + // override the generateMap() method to return our custom map... + protected final Map generateMap() { + return new CustomMap(); + } + } + }]]> + + diff --git a/documentation/manual/es-ES/src/main/docbook/content/query_hql.xml b/documentation/manual/es-ES/src/main/docbook/content/query_hql.xml index 04feab8ba6..94762ee94f 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/query_hql.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/query_hql.xml @@ -182,6 +182,65 @@ + + + UNTRANSLATED!!! Forms of join syntax + + + HQL supports two forms of association joining: implicit and explicit. + + + + The queries shown in the previous section all use the explicit form where + the join keyword is explicitly used in the from clause. This is the recommended form. + + + + The implicit form does not use the join keyword. Instead, the + associations are "dereferenced" using dot-notation. implicit joins + can appear in any of the HQL clauses. implicit join result + in inner joins in the resulting SQL statement. + + + + + + + Refering to identifier property + + + There are, generally speaking, 2 ways to refer to an entity's identifier property: + + + + + The special property (lowercase) id may be used to reference the identifier + property of an entity provided that entity does not define a non-identifier property + named id. + + + + + If the entity defines a named identifier property, you may use that property name. + + + + + + References to composite identifier properties follow the same naming rules. If the + entity has a non-identifier property named id, the composite identifier property can only + be referenced by its defined named; otherwise, the special id property + can be used to rerference the identifier property. + + + + Note: this has changed significantly starting in version 3.2.2. In previous versions, + id always referred to the identifier property no + matter what its actual name. A ramification of that decision was that non-identifier + properties named id could never be referenced in Hibernate queries. + + + La cláusula select @@ -843,56 +902,38 @@ order by count(kitten) asc, sum(kitten.weight) desc]]> SQL). Incluso se permiten subconsultas correlacionadas (subconsultas que hacen referencia a un alias en la consulta exterior). - - ( - select avg(cat.weight) from DomesticCat cat -)]]> - - - - - - - - - Para las subconsultas con más de una expresión en la lista de selección, puedes usar un constructor - de tuplas: - - - - - - Nota que en algunas bases de datos (pero no en Oracle o HSQL), puedes usar constructores de tuplar en - otros contextos, por ejemplo al consultar componentes o tipos de usuario compuestos: - - - - - - Que es equivalente a la más verborrágica: - - - - - - Existen dos buenas razones por las cuales podrías no querer hacer este tipo de cosa: primero, no es - completamente portable entre plataformas de base de datos; segundo, la consulta ahora es dependiente - del orden de propiedades en el documento de mapeo. - - + + ( + select avg(cat.weight) from DomesticCat cat + )]]> + + + + + + + + + + + Note that HQL subqueries may occur only in the select or where clauses. + + + + Note that subqueries can also utilize row value constructor syntax. See + for more details. + diff --git a/documentation/manual/es-ES/src/main/docbook/content/query_sql.xml b/documentation/manual/es-ES/src/main/docbook/content/query_sql.xml index 69c9d9d6ce..649b805c2f 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/query_sql.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/query_sql.xml @@ -15,98 +15,388 @@ Hibernate3 te permite especificar SQL escrito a mano (incluyendo procedimientos almacenados) para todas las operaciones de creación, actualización, borrado y carga. - - - Creando una <literal>Query</literal> de SQL nativo - - - Las consultas SQL se controlan por medio de la interface SQLQuery, que se obtiene - llamando a Session.createSQLQuery(). - - - - - - Esta consulta especificada: - - - - - - la cadena de consulta SQL, con un lugar para que Hibernate inyecte los alias de columnas - - - - - la entidad devuelta por la consulta, y sus alias de tablas SQL - - - - - El método addEntity() asocia alias de tablas SQL con clases de entidad, - y determina la forma del conjunto resultado de la consulta. - - - - El método addJoin() puede ser usado para cargar asociaciones a otras entidades y - colecciones. - - - - - - Una consulta SQL nativa podría devolver un valor escalar simple o una combinación de escalares y entidades. - - - - - + + Using a <literal>SQLQuery</literal> + + Execution of native SQL queries is controlled via the + SQLQuery interface, which is obtained by calling + Session.createSQLQuery(). The following describes how + to use this API for querying. + + + Scalar queries + + The most basic SQL query is to get a list of scalars + (values). + + + + These will both return a List of Object arrays (Object[]) with + scalar values for each column in the CATS table. Hibernate will use + ResultSetMetadata to deduce the actual order and types of the returned + scalar values. + + To avoid the overhead of using + ResultSetMetadata or simply to be more explicit in + what is returned one can use addScalar(). + + + + This query specified: + + + + the SQL query string + + + + the columns and types to return + + + + This will still return Object arrays, but now it will not use + ResultSetMetdata but will instead explicitly get the + ID, NAME and BIRTHDATE column as respectively a Long, String and a Short + from the underlying resultset. This also means that only these three + columns will be returned, even though the query is using + * and could return more than the three listed + columns. + + It is possible to leave out the type information for all or some + of the scalars. + + + + This is essentially the same query as before, but now + ResultSetMetaData is used to decide the type of NAME + and BIRTHDATE where as the type of ID is explicitly specified. + + How the java.sql.Types returned from ResultSetMetaData is mapped + to Hibernate types is controlled by the Dialect. If a specific type is + not mapped or does not result in the expected type it is possible to + customize it via calls to registerHibernateType in + the Dialect. + + + + Entity queries + + The above queries were all about returning scalar values, + basically returning the "raw" values from the resultset. The following + shows how to get entity objects from a native sql query via + addEntity(). + + + + This query specified: + + + + the SQL query string + + + + the entity returned by the query + + + + Assuming that Cat is mapped as a class with the columns ID, NAME + and BIRTHDATE the above queries will both return a List where each + element is a Cat entity. + + If the entity is mapped with a many-to-one to + another entity it is required to also return this when performing the + native query, otherwise a database specific "column not found" error + will occur. The additional columns will automatically be returned when + using the * notation, but we prefer to be explicit as in the following + example for a many-to-one to a + Dog: + + + + This will allow cat.getDog() to function properly. + + + + Handling associations and collections + + It is possible to eagerly join in the Dog to + avoid the possible extra roundtrip for initializing the proxy. This is + done via the addJoin() method, which allows you to + join in an association or collection. + + + + In this example the returned Cat's will have + their dog property fully initialized without any + extra roundtrip to the database. Notice that we added a alias name + ("cat") to be able to specify the target property path of the join. It + is possible to do the same eager joining for collections, e.g. if the + Cat had a one-to-many to Dog + instead. + + + + + At this stage we are reaching the limits of what is possible with native queries without starting to + enhance the sql queries to make them usable in Hibernate; the problems starts to arise when returning + multiple entities of the same type or when the default alias/column names are not enough. + + + + + Returning multiple entities + + Until now the result set column names are assumed to be the same + as the column names specified in the mapping document. This can be + problematic for SQL queries which join multiple tables, since the same + column names may appear in more than one table. + + Column alias injection is needed in the following query (which + most likely will fail): + + + + The intention for this query is to return two Cat instances per + row, a cat and its mother. This will fail since there is a conflict of + names since they are mapped to the same column names and on some + databases the returned column aliases will most likely be on the form + "c.ID", "c.NAME", etc. which are not equal to the columns specificed in + the mappings ("ID" and "NAME"). + + The following form is not vulnerable to column name + duplication: + + + + This query specified: + + + + the SQL query string, with placeholders for Hibernate to + inject column aliases + + + + the entities returned by the query + + + + The {cat.*} and {mother.*} notation used above is a shorthand for + "all properties". Alternatively, you may list the columns explicity, but + even in this case we let Hibernate inject the SQL column aliases for + each property. The placeholder for a column alias is just the property + name qualified by the table alias. In the following example, we retrieve + Cats and their mothers from a different table (cat_log) to the one + declared in the mapping metadata. Notice that we may even use the + property aliases in the where clause if we like. + + + + + Alias and property references + + For most cases the above alias injection is needed, but for + queries relating to more complex mappings like composite properties, + inheritance discriminators, collections etc. there are some specific + aliases to use to allow Hibernate to inject the proper aliases. + + The following table shows the different possibilities of using + the alias injection. Note: the alias names in the result are examples, + each alias will have a unique and probably different name when + used. + + + Alias injection names + + + + + + + + + + + Description + + Syntax + + Example + + + + + + A simple property + + {[aliasname].[propertyname] + + A_NAME as {item.name} + + + + A composite property + + {[aliasname].[componentname].[propertyname]} + + CURRENCY as {item.amount.currency}, VALUE as + {item.amount.value} + + + + Discriminator of an entity + + {[aliasname].class} + + DISC as {item.class} + + + + All properties of an entity + + {[aliasname].*} + + {item.*} + + + + A collection key + + {[aliasname].key} + + ORGID as {coll.key} + + + + The id of an collection + + {[aliasname].id} + + EMPID as {coll.id} + + + + The element of an collection + + {[aliasname].element} + + XID as {coll.element} + + + + roperty of the element in the collection + + {[aliasname].element.[propertyname]} + + NAME as {coll.element.name} + + + + All properties of the element in the collection + + {[aliasname].element.*} + + {coll.element.*} + + + + All properties of the the collection + + {[aliasname].*} + + {coll.*} + + + +
+
+
+ + + Returning non-managed entities + + It is possible to apply a ResultTransformer to native sql queries. Allowing it to e.g. return non-managed entities. + + + + This query specified: + + + + the SQL query string + + + + a result transformer + + + + + The above query will return a list of CatDTO which has been instantiated and injected the values of NAME and BIRTHNAME into its corresponding + properties or fields. + + + + + Handling inheritance + + Native sql queries which query for entities that is mapped as part + of an inheritance must include all properties for the baseclass and all + it subclasses. + + + + Parameters + + Native sql queries support positional as well as named + parameters: + + + + + +
- - - Alias y referencias de propiedad - - - La notación {cat.*} usada arriba es un atajo para "todas las propiedades". - Alternativamente, puedes listar las columnas explícitamente, pero incluso en este caso dejamos - que Hibernate inyecte los alias de columnas SQL para cada propiedad. El lugar para un alias de columna - es sólo el nombre de propiedad cualificado por el alias de la tabla. En el siguiente ejemplo, - recuperamos Cats de una tabla diferente (cat_log) a una - declarada en los metadatos de mapeo. Nota que podríamos incluso usar los alias de propiedad en la - cláusula where si quisieramos. - - - La sintáxis {} no es requerida para consultas con nombre. - Ver - - - - - - Nota: si listas cada propiedad explícitamente, ¡debes incluir todas las - propiedades de la clase y sus subclases! - - - Consultas SQL con nombre @@ -164,7 +454,38 @@ List loggedCats = sess.createSQLQuery(sql) p.AGE AS age, FROM PERSON p WHERE p.NAME LIKE 'Hiber%' ]]> +You can externalize the resultset mapping informations in a + <resultset> element to either reuse them accross + several named queries or through the + setResultSetMapping() API. + + + + + + + SELECT person.NAME AS {person.name}, + person.AGE AS {person.age}, + person.SEX AS {person.sex}, + address.STREET AS {address.street}, + address.CITY AS {address.city}, + address.STATE AS {address.state}, + address.ZIP AS {address.zip} + FROM PERSON person + JOIN ADDRESS address + ON person.ID = address.PERSON_ID AND address.TYPE='MAILING' + WHERE person.NAME LIKE :namePattern + ]]> + +You can alternatively use the resultset mapping information in your + hbm files directly in java code. + + Usando return-property para especificar explícitamente nombres de columna/alias diff --git a/documentation/manual/es-ES/src/main/docbook/content/session_api.xml b/documentation/manual/es-ES/src/main/docbook/content/session_api.xml index 43d9ebebf1..24004310e7 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/session_api.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/session_api.xml @@ -101,7 +101,28 @@ Long generatedId = (Long) sess.save(fritz);]]> usar persist() en vez de save(), con la semántica definida en el temprano borrador de EJB3. - + + + UNTRANSLATED!!! + persist() makes a transient instance persistent. + However, it doesn't guarantee that the identifier value will be assigned to + the persistent instance immediately, the assignment might happen at flush time. + persist() also guarantees that it will not execute an + INSERT statement if it is called outside of transaction + boundaries. This is useful in long-running conversations with an extended + Session/persistence context. + + + + + save() does guarantee to return an identifier. If an INSERT + has to be executed to get the identifier ( e.g. "identity" generator, not + "sequence"), this INSERT happens immediately, no matter if you are inside or + outside of a transaction. This is problematic in a long-running conversation + with an extended Session/persistence context. + + + Alternativamente, puedes asignar el identificador usando una versión sobrecargada de save(). @@ -312,8 +333,8 @@ while ( iter.hasNext() ) { while ( kittensAndMothers.hasNext() ) { Object[] tuple = (Object[]) kittensAndMothers.next(); - Cat kitten = (Cat) tuple[0]; - Cat mother = (Cat) tuple[1]; + Cat kitten = (Cat) tuple[0]; + Cat mother = (Cat) tuple[1]; .... }]]> @@ -485,7 +506,13 @@ List cats = q.list();]]> usado; puedes además definir consultas SQL nativas en metadatos, o migrar consultas existentes a Hibernate colocándolas en ficheros de mapeo. - + UNTRANSLATED! + Also note that a query declaration inside a <hibernate-mapping> + element requires a global unique name for the query, while a query declaration inside a + <class> element is made unique automatically by prepending the + fully qualified name of the class, for example + eg.Cat.ByNameAndMaximumWeight. + @@ -567,16 +594,16 @@ List cats = crit.list();]]> Hibernate, debes encerrar los alias de SQL entre llaves: - - - + + + Las consultas SQL pueden contener parámetros con nombre y posicionales, al igual que @@ -1187,7 +1214,14 @@ tx.commit(); // flush occurs]]> - + UNTRANSLATED!!! + Finally, note that cascading of operations can be applied to an object graph at + call time or at flush time. All operations, + if enabled, are cascaded to associated entities reachable when the operation is + executed. However, save-upate and delete-orphan + are transitive for all associated entities reachable during flush of the + Session. + diff --git a/documentation/manual/es-ES/src/main/docbook/content/toolset_guide.xml b/documentation/manual/es-ES/src/main/docbook/content/toolset_guide.xml index 294ca5cec4..5d810dfd64 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/toolset_guide.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/toolset_guide.xml @@ -77,45 +77,68 @@ Con este atributo puedes establecer el tamaño de una columna. (O, para tipos de datos numéricos/decimales, la precisión.) - + ]]> + ]]> Algunas etiquetas también aceptan un atributo not-null (para generar una restricción NOT NULL en columnas de tablas) y y un atributo unique (para generar restricciones UNIQUE en columnas de tablas). + ]]> + + ]]> + + + A unique-key attribute may be used to group columns in + a single unique key constraint. Currently, the specified value of the + unique-key attribute is not used + to name the constraint in the generated DDL, only to group the columns in + the mapping file. + + + +]]> + + An index attribute specifies the name of an index that + will be created using the mapped column or columns. Multiple columns may be + grouped into the same index, simply by specifying the same index name. + - - Algunas etiquetas aceptan un atributo index para especificar el nombre de un índice - para esa columna. Se puede usar un atributo unique-key para agrupar columnas en una - restricción de clave de una sola unidad. Actualmente, el valor especificado del atributo - unique-key no es usado para nombrar la restricción, sólo para - agrupar las columnas en el fichero de mapeo. - - - - Ejemplos: - + + ]]> - + + A foreign-key attribute may be used to override the name + of any generated foreign key constraint. + - +]]> -]]> + + Many mapping elements also accept a child <column> element. + This is particularly useful for mapping multi-column types: + - - Alternativamente, estos elementos aceptan tambíen un elemento hijo <column>. - Esto es particularmente útil para tipos multicolumnas: - - - - + + + + ]]> - - - - -]]> + + The default attribute lets you specify a default value for + a column (you should assign the same value to the mapped property before + saving a new instance of the mapped class). + + + + + ]]> + + + + ]]> + El atributo sql-type permite al usuario sobrescribir el mapeo por defecto de @@ -155,7 +178,16 @@ number largo de columna/precisión decimal - + + precision + number + column decimal precision + + + scale + number + column decimal scale + not-null true|false especifica que la columna debe ser no nulable @@ -180,8 +212,9 @@ foreign_key_name especifica el nombre de la restricción de clave foránea generada por una - asociación, úsalo en los elementos de mapeo <one-to-one>, <many-to-one>, - <key>, y <many-to-many>. Nota que los lados + asociación, úsalo e <one-to-one>, + <many-to-one>, <key>, + or <many-to-many> . Nota que los lados inverse="true" no serán considerados por SchemaExport. @@ -193,6 +226,12 @@ sobrescribe el tipo de columna por defecto (sólo atributo del elemento <column>) + + default + SQL expression + + specify a default value for the column + check @@ -260,6 +299,9 @@ --drop sólo desechar las tablas + + --create + only create the tables --text @@ -268,6 +310,9 @@ --output=my_schema.ddl enviar la salida del guión ddl a un fichero + + --naming=eg.MyNamingStrategy + select a NamingStrategy --config=hibernate.cfg.xml @@ -415,10 +460,20 @@ new SchemaExport(cfg).create(false, true);]]> --quiet no enviar a salida estándar el guión + + --text + don't export the script to the database + + + --naming=eg.MyNamingStrategy + select a NamingStrategy --properties=hibernate.properties lee las propiedades de base de datos de un fichero + + --config=hibernate.cfg.xml + specify a .cfg.xml file diff --git a/documentation/manual/es-ES/src/main/docbook/content/transactions.xml b/documentation/manual/es-ES/src/main/docbook/content/transactions.xml index 6cb588b440..2610063451 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/transactions.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/transactions.xml @@ -14,7 +14,13 @@ Básicamente, usa Hibernate como usarías JDBC directo (o JTA/CMT) con tus recursos de base de datos. - + + Hibernate does not lock objects in memory. Your application can expect the behavior as + defined by the isolation level of your database transactions. Note that thanks to the + Session, which is also a transaction-scoped cache, Hibernate + provides repeatable reads for lookup by identifier and entity queries (not + reporting queries that return scalar values). + Sin embargo, además del versionado automático, Hibernate ofrece una API (menor) para bloqueo pesimista de filas, usando la sintáxis SELECT FOR UPDATE. @@ -90,22 +96,37 @@ aplicaciones. - - El desafío yace en la implementación: no sólo tienen que comenzarse y terminarse correctamente - la Session y la transacción, sino que además tienen que estar accesibles - para las operaciones de acceso a datos. La demarcación de una unidad de trabajo se implementa - idealmente usando un interceptor que se ejecuta cuando una petición llama al servidor y anter que - la respuesta sea enviada (es decir, un ServletFilter). Recomendamos ligar la - Session a la hebra que atiende la petición, usando una variable - ThreadLocal. Esto permite un fácil acceso (como acceder a una variable static) - en tódo el código que se ejecuta en esta hebra. Dependiendo del mecanismo de demarcación de - transacciones de base de datos que elijas, podrías mantener también el contexto de la transacción - en una variable ThreadLocal. Los patrones de implementación para esto son - conocidos como Sesión Local de Hebra (ThreadLocal Session) y - Sesión Abierta en Vista (Open Session in View). Puedes extender fácilmente - la clase de ayuda HibernateUtil mostrada anteriormente para encontrar - una forma de implementar un interceptor e instalarlo en tu entorno. Ver el sitio web de Hibernate - para consejos y ejemplos. + + The challenge lies in the implementation. Hibernate provides built-in management of + the "current session" to simplify this pattern. All you have to do is start a + transaction when a server request has to be processed, and end the transaction + before the response is send to the client. You can do this in any way you + like, common solutions are ServletFilter, AOP interceptor with a + pointcut on the service methods, or a proxy/interception container. An EJB container + is a standardized way to implement cross-cutting aspects such as transaction + demarcation on EJB session beans, declaratively with CMT. If you decide to + use programmatic transaction demarcation, prefer the Hibernate Transaction + API shown later in this chapter, for ease of use and code portability. + + + + Your application code can access a "current session" to process the request + by simply calling sessionFactory.getCurrentSession() anywhere + and as often as needed. You will always get a Session scoped + to the current database transaction. This has to be configured for either + resource-local or JTA environments, see . + + + + Sometimes it is convenient to extend the scope of a Session and + database transaction until the "view has been rendered". This is especially useful + in servlet applications that utilize a separate rendering phase after the request + has been processed. Extending the database transaction until view rendering is + complete is easy to do if you implement your own interceptor. However, it is not + easily doable if you rely on EJBs with container-managed transactions, as a + transaction will be completed when an EJB method returns, before rendering of any + view can start. See the Hibernate website and forum for tips and examples around + this Open Session in View pattern. @@ -421,9 +442,7 @@ finally { No tienes que limpiar con flush() la Session explícitamente - la llamada a commit() automáticamente dispara la sincronización. - - - + Una llamada a close() marca el fin de una sesión. La principal implicación de close() es que la conexión JDBC será abandonada por la sesión. @@ -624,6 +643,50 @@ Session sess = factory.getCurrentSession(); + + + Transaction timeout + + + One extremely important feature provided by a managed environment like EJB + that is never provided for non-managed code is transaction timeout. Transaction + timeouts ensure that no misbehaving transaction can indefinitely tie up + resources while returning no response to the user. Outside a managed (JTA) + environment, Hibernate cannot fully provide this functionality. However, + Hibernate can at least control data access operations, ensuring that database + level deadlocks and queries with huge result sets are limited by a defined + timeout. In a managed environment, Hibernate can delegate transaction timeout + to JTA. This functioanlity is abstracted by the Hibernate + Transaction object. + + + + + + Note that setTimeout() may not be called in a CMT bean, + where transaction timeouts must be defined declaratively. + + + + @@ -700,7 +763,7 @@ session.close();]]> La Session se desconecta de cualquier conexión JDBC subyacente al esperar por una interacción del usuario. Este enfoque es el más eficiente en términos de acceso a base de datos. La aplicación no necesita tratar por sí misma con el chequeo de - versiones, ni re-uniendo instancias separadas, ni tiene que recargar instancias en cada + versiones, ni re-uniendo instancias separadas, ni tiene que recargar instancias en cadatransactions-demarcation-timeout transacción de base de datos. @@ -742,7 +805,12 @@ session.disconnect(); // Return JDBC connection ]]> Session y no transferirla a la capa web para almacenarla en la HttpSession (ni incluso serializarla a una capa separada). - + UNTRANSLATED!!! + The extended session pattern, or session-per-conversation, is + more difficult to implement with automatic current session context management. + You need to supply your own implementation of the CurrentSessionContext + for this, see the Hibernate Wiki for examples. + diff --git a/documentation/manual/es-ES/src/main/docbook/content/tutorial.xml b/documentation/manual/es-ES/src/main/docbook/content/tutorial.xml index 3f2c2babd5..620664d430 100644 --- a/documentation/manual/es-ES/src/main/docbook/content/tutorial.xml +++ b/documentation/manual/es-ES/src/main/docbook/content/tutorial.xml @@ -19,6 +19,10 @@ Michael Gloegl. Las bibliotecas de terceros que mencionamos son para JDK 1.4 y 5.0. Podrías necesitar otras para JDK 1.3. + UNTRANSLATED!!! + The source code for the tutorial is included in the distribution in the + doc/reference/tutorial/ directory. +
@@ -785,18 +789,40 @@ else if (args[0].equals("list")) { a la base de datosy poblará los objetos Event con datos. Puedes, por supuesto, crear consultas más complejas con HQL. - - - Si ahora llamas a Ant con -Daction=list, debes ver los eventos - que has almacenado hasta ahora. Puede sorprenderte que esto no funcione, al menos - si has seguido este tutorial paso por paso; el resultado siempre estará - vacío. La razon de esto es la opción hbm2ddl.auto - en la configuración de Hibernate: Hibernate recreará la base de datos - en cada ejecución. Deshabilítala quitando la opción, y verás - resultados en tu listado después que llames a la acción store - unas cuantas veces. La generación y exportación de esquema es útil - mayormente en testeo unitario. + + + Now, to execute and test all of this, follow these steps: + + + + Run ant run -Daction=store to store something into the database + and, of course, to generate the database schema before through hbm2ddl. + + + + + Now disable hbm2ddl by commenting out the property in your hibernate.cfg.xml + file. Usually you only leave it turned on in continous unit testing, but another + run of hbm2ddl would drop everything you have stored - the + create configuration setting actually translates into "drop all + tables from the schema, then re-create all tables, when the SessionFactory is build". + + + + + If you now call Ant with -Daction=list, you should see the events + you have stored so far. You can of course also call the store action a few + times more. + + + + Note: Most new Hibernate users fail at this point and we see questions about + Table not found error messages regularly. However, if you follow the + steps outlined above you will not have this problem, as hbm2ddl creates the database + schema on the first run, and subsequent application restarts will use this schema. If + you change the mapping and/or database schema, you have to re-enable hbm2ddl once again. + @@ -1119,11 +1145,25 @@ public void setEmailAddresses(Set emailAddresses) { direcciones de email duplicadas por persona, que es exactamente la semántica que necesitamos para un conjunto en Java. - + Puedes ahora intentar y agregar elementos a esta colección, al igual que - hicimos antes enlazando personas y eventos. Es el mismo código en Java. - + hicimos antes enlazando personas y eventos. Es el mismo código en Java. + This time we didnt' use a fetch query to initialize the collection. + Hence, the call to its getter method will trigger an additional select to initialize + it, so we can add an element to it. Monitor the SQL log and try to optimize this with + an eager fetch. @@ -1246,7 +1286,279 @@ public void removeFromEvent(Event event) { --> -
+ + Let's turn this into a small web application. + + + + + Part 3 - The EventManager web application + + + A Hibernate web application uses Session and Transaction + almost like a standalone application. However, some common patterns are useful. We now write + an EventManagerServlet. This servlet can list all events stored in the + database, and it provides an HTML form to enter new events. + + + + Writing the basic servlet + + + Create a new class in your source directory, in the events + package: + + + + + + The servlet handles HTTP GET requests only, hence, the method + we implement is doGet(): + + + + + + The pattern we are applying here is called session-per-request. + When a request hits the servlet, a new Hibernate Session is + opened through the first call to getCurrentSession() on the + SessionFactory. Then a database transaction is started—all + data access as to occur inside a transaction, no matter if data is read or written + (we don't use the auto-commit mode in applications). + + + + Do not use a new Hibernate Session for + every database operation. Use one Hibernate Session that is + scoped to the whole request. Use getCurrentSession(), so that + it is automatically bound to the current Java thread. + + + + Next, the possible actions of the request are processed and the response HTML + is rendered. We'll get to that part soon. + + + + Finally, the unit of work ends when processing and rendering is complete. If any + problem occured during processing or rendering, an exception will be thrown + and the database transaction rolled back. This completes the + session-per-request pattern. Instead of the transaction + demarcation code in every servlet you could also write a servlet filter. + See the Hibernate website and Wiki for more information about this pattern, + called Open Session in View—you'll need it as soon + as you consider rendering your view in JSP, not in a servlet. + + + + + + Processing and rendering + + + Let's implement the processing of the request and rendering of the page. + + + Event Manager"); + + // Handle actions + if ( "store".equals(request.getParameter("action")) ) { + + String eventTitle = request.getParameter("eventTitle"); + String eventDate = request.getParameter("eventDate"); + + if ( "".equals(eventTitle) || "".equals(eventDate) ) { + out.println("Please enter event title and date."); + } else { + createAndStoreEvent(eventTitle, dateFormatter.parse(eventDate)); + out.println("Added event."); + } + } + + // Print page + printEventForm(out); + listEvents(out, dateFormatter); + + // Write HTML footer + out.println(""); + out.flush(); + out.close();]]> + + + Granted, this coding style with a mix of Java and HTML would not scale + in a more complex application—keep in mind that we are only illustrating + basic Hibernate concepts in this tutorial. The code prints an HTML + header and a footer. Inside this page, an HTML form for event entry and + a list of all events in the database are printed. The first method is + trivial and only outputs HTML: + + + Add new event:"); + out.println("
"); + out.println("Title:
"); + out.println("Date (e.g. 24.12.2009):
"); + out.println(""); + out.println("
"); + }]]>
+ + + The listEvents() method uses the Hibernate + Session bound to the current thread to execute + a query: + + + 0) { + out.println("

Events in database:

"); + out.println(""); + out.println(""); + out.println(""); + out.println(""); + out.println(""); + for (Iterator it = result.iterator(); it.hasNext();) { + Event event = (Event) it.next(); + out.println(""); + out.println(""); + out.println(""); + out.println(""); + } + out.println("
Event titleEvent date
" + event.getTitle() + "" + dateFormatter.format(event.getDate()) + "
"); + } + }]]>
+ + + Finally, the store action is dispatched to the + createAndStoreEvent() method, which also uses + the Session of the current thread: + + + + + + That's it, the servlet is complete. A request to the servlet will be processed + in a single Session and Transaction. As + earlier in the standalone application, Hibernate can automatically bind these + ojects to the current thread of execution. This gives you the freedom to layer + your code and access the SessionFactory in any way you like. + Usually you'd use a more sophisticated design and move the data access code + into data access objects (the DAO pattern). See the Hibernate Wiki for more + examples. + + +
+ + + Deploying and testing + + + To deploy this application you have to create a web archive, a WAR. Add the + following Ant target to your build.xml: + + + + + + + + + + + ]]> + + + This target creates a file called hibernate-tutorial.war + in your project directory. It packages all libraries and the web.xml + descriptor, which is expected in the base directory of your project: + + + + + + + Event Manager + events.EventManagerServlet + + + + Event Manager + /eventmanager + + ]]> + + + Before you compile and deploy the web application, note that an additional library + is required: jsdk.jar. This is the Java servlet development kit, + if you don't have this library already, get it from the Sun website and copy it to + your library directory. However, it will be only used for compliation and excluded + from the WAR package. + + + + To build and deploy call ant war in your project directory + and copy the hibernate-tutorial.war file into your Tomcat + webapp directory. If you don't have Tomcat installed, download + it and follow the installation instructions. You don't have to change any Tomcat + configuration to deploy this application though. + + + + Once deployed and Tomcat is running, access the application at + http://localhost:8080/hibernate-tutorial/eventmanager. Make + sure you watch the Tomcat log to see Hibernate initialize when the first + request hits your servlet (the static initializer in HibernateUtil + is called) and to get the detailed output if any exceptions occurs. + + + + +
+ Summary