11- ANEXOS
11.2. Red de senderos
Following is a list of all available Hibernate identifier generator strategies, their options, and our usage recommendations. If you don’t want to read the whole list now, enable GenerationType.AUTO and check what Hibernate defaults to for your database dialect. It’s most likely sequence or identity—a good but maybe not the most efficient or portable choice. If you require consistent portable behavior, and identifier values to be available before INSERTs, use enhanced-sequence, as shown in the previous section. This is a portable, flexible, and modern strategy, also offering various optimizers for large datasets.
We also show the relationship between each standard JPA strategy and its native Hibernate equivalent. Hibernate has been growing organically, so there are now two sets of mappings between standard and native strategies; we call them Old and New in the list. You can switch this mapping with the hibernate.id.new_generator_mappings
setting in your persistence.xml file. The default is true; hence the New mapping. Soft- ware doesn’t age quite as well as wine:
native—Automatically selects other strategies, such as sequence or identity, depending on the configured SQL dialect. You have to look at the Javadoc (or even the source) of the SQL dialect you configured in persistence.xml. Equiva- lent to JPA GenerationType.AUTO with the Old mapping.
sequence—Uses a native database sequence named HIBERNATE_SEQUENCE. The sequence is called before each INSERT of a new row. You can customize the sequence name and provide additional DDL settings; see the Javadoc for the class org.hibernate.id.SequenceGenerator.
sequence-identity—Generates key values by calling a database sequence on insertion: for example, insert into ITEM(ID) values (HIBERNATE_SEQUENCE .nextval). The key value is retrieved after INSERT, the same behavior as the identity strategy. Supports the same parameters and property types as the sequence strategy; see the Javadoc for the class org.hibernate.id.Sequence- IdentityGenerator and its parent.
enhanced-sequence—Uses a native database sequence when supported; other- wise falls back to an extra database table with a single column and row, emulating a sequence. Defaults to name HIBERNATE_SEQUENCE. Always calls the database “sequence” before an INSERT, providing the same behavior independently of whether the DBMS supports real sequences. Supports an org.hibernate .id.enhanced.Optimizer to avoid hitting the database before each INSERT; defaults to no optimization and fetching a new value for each INSERT. You can find more examples in chapter 20. For all parameters, see the Javadoc for the class org.hibernate.id.enhanced.SequenceStyleGenerator. Equivalent to JPA GenerationType.SEQUENCE and GenerationType.AUTO with the New mapping enabled, most likely your best option of the built-in strategies.
seqhilo—Uses a native database sequence named HIBERNATE_SEQUENCE, opti- mizing calls before INSERT by combining hi/lo values. If the hi value retrieved Generating identifiers before or after INSERT: what’s the difference?
An ORM service tries to optimize SQL INSERTs: for example, by batching several at the JDBC level. Hence, SQL execution occurs as late as possible during a unit of work, not when you call entityManager.persist(someItem). This merely queues the insertion for later execution and, if possible, assigns the identifier value. But if you now call someItem.getId(), you might get null back if the engine wasn’t able to generate an identifier before the INSERT. In general, we prefer pre-insertgenera- tion strategies that produce identifier values independently, before INSERT. A com- mon choice is a shared and concurrently accessible database sequence. Auto- incremented columns, column default values, or trigger-generated keys are only avail- able after the INSERT.
from the sequence is 1, the next 9 insertions will be made with key values 11, 12, 13, …, 19. Then the sequence is called again to obtain the next hi value (2 or higher), and the procedure repeats with 21, 22, 23, and so on. You can config- ure the maximum lo value (9 is the default) with the max_lo parameter. Unfor- tunately, due to a quirk in Hibernate’s code, you can not configure this strategy in @GenericGenerator. The only way to use it is with JPA Generation- Type.SEQUENCE and the Old mapping. You can configure it with the standard JPA @SequenceGenerator annotation on a (maybe otherwise empty) class. See the Javadoc for the class org.hibernate.id.SequenceHiLoGenerator and its parent for more information. Consider using enhanced-sequence instead, with an optimizer.
hilo—Uses an extra table named HIBERNATE_UNIQUE_KEY with the same algo- rithm as the seqhilo strategy. The table has a single column and row, holding the next value of the sequence. The default maximum lo value is 32767, so you most likely want to configure it with the max_lo parameter. See the Javadoc for the class org.hibernate.id.TableHiLoGenerator for more information. We don’t recommend this legacy strategy; use enhanced-sequence instead with an optimizer.
enhanced-table—Uses an extra table named HIBERNATE_SEQUENCES, with one row by default representing the sequence, storing the next value. This value is selected and updated when an identifier value has to be generated. You can configure this generator to use multiple rows instead: one for each generator; see the Javadoc for org.hibernate.id.enhanced.TableGenerator. Equivalent to JPA GenerationType.TABLE with the New mapping enabled. Replaces the outdated but similar org.hibernate.id.MultipleHiLoPerTableGenerator, which is the Old mapping for JPA GenerationType.TABLE.
identity—Supports IDENTITY and auto-increment columns in DB2, MySQL, MS SQL Server, and Sybase. The identifier value for the primary key column will be generated on INSERT of a row. Has no options. Unfortunately, due to a quirk in Hibernate’s code, you can not configure this strategy in @GenericGenerator. The only way to use it is with JPA GenerationType.IDENTITY and the Old or New mapping, making it the default for GenerationType.IDENTITY.
increment—At Hibernate startup, reads the maximum (numeric) primary key column value of each entity’s table and increments the value by one each time a new row is inserted. Especially efficient if a non-clustered Hibernate application has exclusive access to the database; but don’t use it in any other scenario.
select—Hibernate won’t generate a key value or include the primary key col- umn in an INSERT statement. Hibernate expects the DBMS to assign a (default in schema or by trigger) value to the column on insertion. Hibernate then retrieves the primary key column with a SELECT query after insertion. Required parameter is key, naming the database identifier property (such as id) for the
SELECT. This strategy isn’t very efficient and should only be used with old JDBC drivers that can’t return generated keys directly.
uuid2—Produces a unique 128-bit UUID in the application layer. Useful when you need globally unique identifiers across databases (say, you merge data from several distinct production databases in batch runs every night into an archive). The UUID can be encoded either as a java.lang.String, a byte[16], or a java .util.UUID property in your entity class. Replaces the legacy uuid and uuid .hex strategies. You configure it with an org.hibernate.id.UUIDGeneration- Strategy; see the Javadoc for the class org.hibernate.id.UUIDGenerator for more details.
guid—Uses a globally unique identifier produced by the database, with an SQL function available on Oracle, Ingres, MS SQL Server, and MySQL. Hibernate calls the database function before an INSERT. Maps to a java.lang.String identifier property. If you need full control over identifier generation, config- ure the strategy of @GenericGenerator with the fully qualified name of a class that implements the org.hibernate.id.IdentityGenerator interface. To summarize, our recommendations on identifier generator strategies are as follows:
In general, we prefer pre-insert generation strategies that produce identifier values independently before INSERT.
Use enhanced-sequence, which uses a native database sequence when sup- ported and otherwise falls back to an extra database table with a single column and row, emulating a sequence.
We assume from now on that you’ve added identifier properties to the entity classes of your domain model and that after you complete the basic mapping of each entity and its identifier property, you continue to map the value-typed properties of the entities. We talk about value-type mappings in the next chapter. Read on for some special options that can simplify and enhance your class mappings.