|
|||||||||
The Custom Identifier GeneratorHibernate uses identifier generators to allocate identifiers for new objects. It normally retrieves a new identifier from the database or an internal cache immediately before persisting an object for the first time. You've already seen how object generation changes this behavior to assign an identifier upon object creation (see thegenerateEntity
method listed earlier).
However, generating identifiers during object creation is only part of a full solution. The identifier strategy must work properly whether it's dealing with a newly created object or an existing one that's been retrieved from the database. No single strategy can accomplish this without introducing unnecessary overhead. The solution is to create an identifier generator with a split personality. On the one hand, it behaves like an "assigned" generator when it detects a generated entity. On the other hand, it behaves like the entity's natural identifier generator when a new identifier is needed or when it's working with an existing persistent object. The result is a class that aggregates two generators and intelligently selects between the two.
Listing 6 is the source code for the
An example Hibernate descriptor helps explain how this code works. The following descriptor snippet highlights the relevant portion for the sample User class. Notice that the generator tag names the new custom class while the original generator, a sequence in this case, has been moved to its "delegate" parameter:
The
The
The Custom InterceptorThe solution described thus far will work with no additional infrastructure. However, you'll pay a slight performance penalty when persisting newly created objects. Most generators use a null identifier as their cue that an object is transient, but this doesn't work with generated entities whose identifiers are assigned before they're made persistent. It's a subtle nuance, but with an identifier already assigned, Hibernate has no way of knowing whether the object already exists in the database. It's forced to issue an additional query to find out.To eliminate this overhead, you introduce a very minimal interceptor. Interceptors are used to customize Hibernate's behavior and are ideally suited to the task at hand.
Listing 7 contains the source for the
With the interceptor installed, Hibernate can now efficiently save generated entities using the appropriate INSERT or UPDATE statement.
|
|||||||||
|