Package org.hibernate.cache.spi

Source Code of org.hibernate.cache.spi.NaturalIdCacheKey

/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors.  All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA  02110-1301  USA
*/
package org.hibernate.cache.spi;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Arrays;

import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.util.ValueHolder;
import org.hibernate.internal.util.compare.EqualsHelper;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.Type;

/**
* Defines a key for caching natural identifier resolutions into the second level cache.
*
* @author Eric Dalquist
* @author Steve Ebersole
*/
public class NaturalIdCacheKey implements Serializable {
  private final Serializable[] naturalIdValues;
  private final String entityName;
  private final String tenantId;
  private final int hashCode;
  private transient ValueHolder<String> toString;

  /**
   * Construct a new key for a caching natural identifier resolutions into the second level cache.
   * Note that an entity name should always be the root entity name, not a subclass entity name.
   *
   * @param naturalIdValues The naturalIdValues associated with the cached data
   * @param persister The persister for the entity
   * @param session The originating session
   */
  public NaturalIdCacheKey(
      final Object[] naturalIdValues,
      final EntityPersister persister,
      final SessionImplementor session) {

    this.entityName = persister.getRootEntityName();
    this.tenantId = session.getTenantIdentifier();

    this.naturalIdValues = new Serializable[naturalIdValues.length];

    final SessionFactoryImplementor factory = session.getFactory();
    final int[] naturalIdPropertyIndexes = persister.getNaturalIdentifierProperties();
    final Type[] propertyTypes = persister.getPropertyTypes();

    final int prime = 31;
    int result = 1;
    result = prime * result + ( ( this.entityName == null ) ? 0 : this.entityName.hashCode() );
    result = prime * result + ( ( this.tenantId == null ) ? 0 : this.tenantId.hashCode() );
    for ( int i = 0; i < naturalIdValues.length; i++ ) {
      final int naturalIdPropertyIndex = naturalIdPropertyIndexes[i];
            final Type type = propertyTypes[naturalIdPropertyIndex];
      final Object value = naturalIdValues[i];
     
      result = prime * result + (value != null ? type.getHashCode( value, factory ) : 0);
     
      this.naturalIdValues[i] = type.disassemble( value, session, null );
    }
   
    this.hashCode = result;
    initTransients();
  }
 
  private void initTransients() {
      this.toString = new ValueHolder<String>(
                new ValueHolder.DeferredInitializer<String>() {
                    @Override
                    public String initialize() {
                        //Complex toString is needed as naturalIds for entities are not simply based on a single value like primary keys
                        //the only same way to differentiate the keys is to included the disassembled values in the string.
                        final StringBuilder toStringBuilder = new StringBuilder( entityName ).append( "##NaturalId[" );
                        for ( int i = 0; i < naturalIdValues.length; i++ ) {
                            toStringBuilder.append( naturalIdValues[i] );
                            if ( i + 1 < naturalIdValues.length ) {
                                toStringBuilder.append( ", " );
                            }
                        }
                        toStringBuilder.append( "]" );

                        return toStringBuilder.toString();
                    }
                }
        );
  }

  @SuppressWarnings( {"UnusedDeclaration"})
  public String getEntityName() {
    return entityName;
  }

  @SuppressWarnings( {"UnusedDeclaration"})
  public String getTenantId() {
    return tenantId;
  }

  @SuppressWarnings( {"UnusedDeclaration"})
  public Serializable[] getNaturalIdValues() {
    return naturalIdValues;
  }

  @Override
  public String toString() {
    return toString.getValue();
  }
 
  @Override
  public int hashCode() {
    return this.hashCode;
  }

  @Override
  public boolean equals(Object o) {
    if ( o == null ) {
      return false;
    }
    if ( this == o ) {
      return true;
    }

    if ( hashCode != o.hashCode() || !( o instanceof NaturalIdCacheKey ) ) {
      //hashCode is part of this check since it is pre-calculated and hash must match for equals to be true
      return false;
    }

    final NaturalIdCacheKey other = (NaturalIdCacheKey) o;
    return EqualsHelper.equals( entityName, other.entityName )
        && EqualsHelper.equals( tenantId, other.tenantId )
        && Arrays.deepEquals( this.naturalIdValues, other.naturalIdValues );
  }
 
    private void readObject(ObjectInputStream ois)
            throws ClassNotFoundException, IOException {
        ois.defaultReadObject();
        initTransients();
    }
}
TOP

Related Classes of org.hibernate.cache.spi.NaturalIdCacheKey

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.