/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.engine.spi;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.hibernate.AssertionFailure;
import org.hibernate.internal.util.compare.EqualsHelper;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper;
Uniquely identifies of an entity instance in a particular Session by identifier.
Note that it's only safe to be used within the scope of a Session: it doesn't consider for example the tenantId
as part of the equality definition.
Information used to determine uniqueness consists of the entity-name and the identifier value (see equals
).
Performance considerations: lots of instances of this type are created at runtime. Make sure each one is as small as possible
by storing just the essential needed.
Author: Gavin King, Sanne Grinovero
/**
* Uniquely identifies of an entity instance in a particular Session by identifier.
* Note that it's only safe to be used within the scope of a Session: it doesn't consider for example the tenantId
* as part of the equality definition.
* <p/>
* Information used to determine uniqueness consists of the entity-name and the identifier value (see {@link #equals}).
* <p/>
* Performance considerations: lots of instances of this type are created at runtime. Make sure each one is as small as possible
* by storing just the essential needed.
*
* @author Gavin King
* @author Sanne Grinovero
*/
public final class EntityKey implements Serializable {
private final Serializable identifier;
private final int hashCode;
private final EntityPersister persister;
Construct a unique identifier for an entity class instance.
NOTE : This signature has changed to accommodate both entity mode and multi-tenancy, both of which relate to the Session to which this key belongs. To help minimize the impact of these changes in the future, the SharedSessionContractImplementor.generateEntityKey
method was added to hide the session-specific changes. Params: - id – The entity id
- persister – The entity persister
/**
* Construct a unique identifier for an entity class instance.
* <p/>
* NOTE : This signature has changed to accommodate both entity mode and multi-tenancy, both of which relate to
* the Session to which this key belongs. To help minimize the impact of these changes in the future, the
* {@link SessionImplementor#generateEntityKey} method was added to hide the session-specific changes.
*
* @param id The entity id
* @param persister The entity persister
*/
public EntityKey(Serializable id, EntityPersister persister) {
this.persister = persister;
if ( id == null ) {
throw new AssertionFailure( "null identifier" );
}
this.identifier = id;
this.hashCode = generateHashCode();
}
private int generateHashCode() {
int result = 17;
final String rootEntityName = persister.getRootEntityName();
result = 37 * result + ( rootEntityName != null ? rootEntityName.hashCode() : 0 );
result = 37 * result + persister.getIdentifierType().getHashCode( identifier, persister.getFactory() );
return result;
}
public boolean isBatchLoadable() {
return persister.isBatchLoadable();
}
public Serializable getIdentifier() {
return identifier;
}
public String getEntityName() {
return persister.getEntityName();
}
@Override
public boolean equals(Object other) {
if ( this == other ) {
return true;
}
if ( other == null || EntityKey.class != other.getClass() ) {
return false;
}
final EntityKey otherKey = (EntityKey) other;
return samePersistentType( otherKey )
&& sameIdentifier( otherKey );
}
private boolean sameIdentifier(final EntityKey otherKey) {
return persister.getIdentifierType().isEqual( otherKey.identifier, this.identifier, persister.getFactory() );
}
private boolean samePersistentType(final EntityKey otherKey) {
if ( otherKey.persister == persister ) {
return true;
}
else {
return EqualsHelper.equals( otherKey.persister.getRootEntityName(), persister.getRootEntityName() );
}
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public String toString() {
return "EntityKey" +
MessageHelper.infoString( this.persister, identifier, persister.getFactory() );
}
Custom serialization routine used during serialization of a
Session/PersistenceContext for increased performance.
Params: - oos – The stream to which we should write the serial data.
Throws: - IOException – Thrown by Java I/O
/**
* Custom serialization routine used during serialization of a
* Session/PersistenceContext for increased performance.
*
* @param oos The stream to which we should write the serial data.
*
* @throws IOException Thrown by Java I/O
*/
public void serialize(ObjectOutputStream oos) throws IOException {
oos.writeObject( identifier );
oos.writeObject( persister.getEntityName() );
}
Custom deserialization routine used during deserialization of a
Session/PersistenceContext for increased performance.
Params: - ois – The stream from which to read the entry.
- sessionFactory – The SessionFactory owning the Session being deserialized.
Throws: - IOException – Thrown by Java I/O
- ClassNotFoundException – Thrown by Java I/O
Returns: The deserialized EntityEntry
/**
* Custom deserialization routine used during deserialization of a
* Session/PersistenceContext for increased performance.
*
* @param ois The stream from which to read the entry.
* @param sessionFactory The SessionFactory owning the Session being deserialized.
*
* @return The deserialized EntityEntry
*
* @throws IOException Thrown by Java I/O
* @throws ClassNotFoundException Thrown by Java I/O
*/
public static EntityKey deserialize(ObjectInputStream ois, SessionFactoryImplementor sessionFactory) throws IOException, ClassNotFoundException {
final Serializable id = (Serializable) ois.readObject();
final String entityName = (String) ois.readObject();
final EntityPersister entityPersister = sessionFactory.getEntityPersister( entityName );
return new EntityKey(id, entityPersister);
}
}