Search in sources :

Example 6 with NaturalIdDataAccess

use of org.hibernate.cache.spi.access.NaturalIdDataAccess in project hibernate-orm by hibernate.

the class NaturalIdXrefDelegate method findCachedNaturalIdResolution.

/**
 * Given a persister and natural-id value(s), find the locally cross-referenced primary key.  Will return
 * {@link PersistenceContext.NaturalIdHelper#INVALID_NATURAL_ID_REFERENCE} if the given natural ids are known to
 * be invalid (see {@link #stashInvalidNaturalIdReference}).
 *
 * @param persister The persister representing the entity type.
 * @param naturalIdValues The natural id value(s)
 *
 * @return The corresponding cross-referenced primary key,
 * 		{@link PersistenceContext.NaturalIdHelper#INVALID_NATURAL_ID_REFERENCE},
 * 		or {@code null} if none
 */
public Serializable findCachedNaturalIdResolution(EntityPersister persister, Object[] naturalIdValues) {
    persister = locatePersisterForKey(persister);
    validateNaturalId(persister, naturalIdValues);
    NaturalIdResolutionCache entityNaturalIdResolutionCache = naturalIdResolutionCacheMap.get(persister);
    Serializable pk;
    final CachedNaturalId cachedNaturalId = new CachedNaturalId(persister, naturalIdValues);
    if (entityNaturalIdResolutionCache != null) {
        pk = entityNaturalIdResolutionCache.naturalIdToPkMap.get(cachedNaturalId);
        // Found in session cache
        if (pk != null) {
            if (LOG.isTraceEnabled()) {
                LOG.trace("Resolved natural key -> primary key resolution in session cache: " + persister.getRootEntityName() + "#[" + Arrays.toString(naturalIdValues) + "]");
            }
            return pk;
        }
        // if we did not find a hit, see if we know about these natural ids as invalid...
        if (entityNaturalIdResolutionCache.containsInvalidNaturalIdReference(naturalIdValues)) {
            return PersistenceContext.NaturalIdHelper.INVALID_NATURAL_ID_REFERENCE;
        }
    }
    // Session cache miss, see if second-level caching is enabled
    if (!persister.hasNaturalIdCache()) {
        return null;
    }
    // Try resolution from second-level cache
    final NaturalIdDataAccess naturalIdCacheAccessStrategy = persister.getNaturalIdCacheAccessStrategy();
    final Object naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey(naturalIdValues, persister, session());
    pk = CacheHelper.fromSharedCache(session(), naturalIdCacheKey, naturalIdCacheAccessStrategy);
    // Found in second-level cache, store in session cache
    final SessionFactoryImplementor factory = session().getFactory();
    if (pk != null) {
        if (factory.getStatistics().isStatisticsEnabled()) {
            factory.getStatistics().naturalIdCacheHit(StatsHelper.INSTANCE.getRootEntityRole(persister), naturalIdCacheAccessStrategy.getRegion().getName());
        }
        if (LOG.isTraceEnabled()) {
            // protected to avoid Arrays.toString call unless needed
            LOG.tracef("Found natural key [%s] -> primary key [%s] xref in second-level cache for %s", Arrays.toString(naturalIdValues), pk, persister.getRootEntityName());
        }
        if (entityNaturalIdResolutionCache == null) {
            entityNaturalIdResolutionCache = new NaturalIdResolutionCache(persister);
            NaturalIdResolutionCache existingCache = naturalIdResolutionCacheMap.putIfAbsent(persister, entityNaturalIdResolutionCache);
            if (existingCache != null) {
                entityNaturalIdResolutionCache = existingCache;
            }
        }
        entityNaturalIdResolutionCache.pkToNaturalIdMap.put(pk, cachedNaturalId);
        entityNaturalIdResolutionCache.naturalIdToPkMap.put(cachedNaturalId, pk);
    } else if (factory.getStatistics().isStatisticsEnabled()) {
        factory.getStatistics().naturalIdCacheMiss(StatsHelper.INSTANCE.getRootEntityRole(persister), naturalIdCacheAccessStrategy.getRegion().getName());
    }
    return pk;
}
Also used : Serializable(java.io.Serializable) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) NaturalIdDataAccess(org.hibernate.cache.spi.access.NaturalIdDataAccess)

Example 7 with NaturalIdDataAccess

use of org.hibernate.cache.spi.access.NaturalIdDataAccess in project hibernate-orm by hibernate.

the class MetamodelImpl method initialize.

/**
 * Prepare the metamodel using the information from the collection of Hibernate
 * {@link PersistentClass} models
 *
 * @param mappingMetadata The mapping information
 * @param jpaMetaModelPopulationSetting Should the JPA Metamodel be built as well?
 */
public void initialize(MetadataImplementor mappingMetadata, JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting) {
    this.imports.putAll(mappingMetadata.getImports());
    primeSecondLevelCacheRegions(mappingMetadata);
    final PersisterCreationContext persisterCreationContext = new PersisterCreationContext() {

        @Override
        public SessionFactoryImplementor getSessionFactory() {
            return sessionFactory;
        }

        @Override
        public MetadataImplementor getMetadata() {
            return mappingMetadata;
        }
    };
    final PersisterFactory persisterFactory = sessionFactory.getServiceRegistry().getService(PersisterFactory.class);
    for (final PersistentClass model : mappingMetadata.getEntityBindings()) {
        final NavigableRole rootEntityRole = new NavigableRole(model.getRootClass().getEntityName());
        final EntityDataAccess accessStrategy = sessionFactory.getCache().getEntityRegionAccess(rootEntityRole);
        final NaturalIdDataAccess naturalIdAccessStrategy = sessionFactory.getCache().getNaturalIdCacheRegionAccessStrategy(rootEntityRole);
        final EntityPersister cp = persisterFactory.createEntityPersister(model, accessStrategy, naturalIdAccessStrategy, persisterCreationContext);
        entityPersisterMap.put(model.getEntityName(), cp);
        if (cp.getConcreteProxyClass() != null && cp.getConcreteProxyClass().isInterface() && !Map.class.isAssignableFrom(cp.getConcreteProxyClass()) && cp.getMappedClass() != cp.getConcreteProxyClass()) {
            if (cp.getMappedClass().equals(cp.getConcreteProxyClass())) {
                // this part handles an odd case in the Hibernate test suite where we map an interface
                // as the class and the proxy.  I cannot think of a real life use case for that
                // specific test, but..
                log.debugf("Entity [%s] mapped same interface [%s] as class and proxy", cp.getEntityName(), cp.getMappedClass());
            } else {
                final String old = entityProxyInterfaceMap.put(cp.getConcreteProxyClass(), cp.getEntityName());
                if (old != null) {
                    throw new HibernateException(String.format(Locale.ENGLISH, "Multiple entities [%s, %s] named the same interface [%s] as their proxy which is not supported", old, cp.getEntityName(), cp.getConcreteProxyClass().getName()));
                }
            }
        }
    }
    for (final Collection model : mappingMetadata.getCollectionBindings()) {
        final NavigableRole navigableRole = new NavigableRole(model.getRole());
        final CollectionDataAccess accessStrategy = sessionFactory.getCache().getCollectionRegionAccess(navigableRole);
        final CollectionPersister persister = persisterFactory.createCollectionPersister(model, accessStrategy, persisterCreationContext);
        collectionPersisterMap.put(model.getRole(), persister);
        Type indexType = persister.getIndexType();
        if (indexType != null && indexType.isAssociationType() && !indexType.isAnyType()) {
            String entityName = ((AssociationType) indexType).getAssociatedEntityName(sessionFactory);
            Set<String> roles = collectionRolesByEntityParticipant.get(entityName);
            if (roles == null) {
                roles = new HashSet<>();
                collectionRolesByEntityParticipant.put(entityName, roles);
            }
            roles.add(persister.getRole());
        }
        Type elementType = persister.getElementType();
        if (elementType.isAssociationType() && !elementType.isAnyType()) {
            String entityName = ((AssociationType) elementType).getAssociatedEntityName(sessionFactory);
            Set<String> roles = collectionRolesByEntityParticipant.get(entityName);
            if (roles == null) {
                roles = new HashSet<>();
                collectionRolesByEntityParticipant.put(entityName, roles);
            }
            roles.add(persister.getRole());
        }
    }
    // after *all* persisters and named queries are registered
    entityPersisterMap.values().forEach(EntityPersister::generateEntityDefinition);
    for (EntityPersister persister : entityPersisterMap.values()) {
        persister.postInstantiate();
        registerEntityNameResolvers(persister, entityNameResolvers);
    }
    collectionPersisterMap.values().forEach(CollectionPersister::postInstantiate);
    if (jpaMetaModelPopulationSetting != JpaMetaModelPopulationSetting.DISABLED) {
        MetadataContext context = new MetadataContext(sessionFactory, mappingMetadata.getMappedSuperclassMappingsCopy(), jpaMetaModelPopulationSetting);
        for (PersistentClass entityBinding : mappingMetadata.getEntityBindings()) {
            locateOrBuildEntityType(entityBinding, context);
        }
        handleUnusedMappedSuperclasses(context);
        context.wrapUp();
        this.jpaEntityTypeMap.putAll(context.getEntityTypeMap());
        this.jpaEmbeddableTypeMap.putAll(context.getEmbeddableTypeMap());
        this.jpaMappedSuperclassTypeMap.putAll(context.getMappedSuperclassTypeMap());
        this.jpaEntityTypesByEntityName.putAll(context.getEntityTypesByEntityName());
        applyNamedEntityGraphs(mappingMetadata.getNamedEntityGraphs().values());
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) HibernateException(org.hibernate.HibernateException) PersisterFactory(org.hibernate.persister.spi.PersisterFactory) NaturalIdDataAccess(org.hibernate.cache.spi.access.NaturalIdDataAccess) CollectionDataAccess(org.hibernate.cache.spi.access.CollectionDataAccess) PersisterCreationContext(org.hibernate.persister.spi.PersisterCreationContext) AccessType(org.hibernate.cache.spi.access.AccessType) ManagedType(javax.persistence.metamodel.ManagedType) MappedSuperclassType(javax.persistence.metamodel.MappedSuperclassType) EntityType(javax.persistence.metamodel.EntityType) AssociationType(org.hibernate.type.AssociationType) EmbeddableType(javax.persistence.metamodel.EmbeddableType) Type(org.hibernate.type.Type) CollectionPersister(org.hibernate.persister.collection.CollectionPersister) AssociationType(org.hibernate.type.AssociationType) NavigableRole(org.hibernate.metamodel.model.domain.NavigableRole) Collection(org.hibernate.mapping.Collection) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) PersistentClass(org.hibernate.mapping.PersistentClass) EntityDataAccess(org.hibernate.cache.spi.access.EntityDataAccess)

Aggregations

NaturalIdDataAccess (org.hibernate.cache.spi.access.NaturalIdDataAccess)7 DomainDataRegion (org.hibernate.cache.spi.DomainDataRegion)4 ExtendedStatisticsSupport (org.hibernate.cache.spi.ExtendedStatisticsSupport)3 Region (org.hibernate.cache.spi.Region)3 HibernateException (org.hibernate.HibernateException)2 CollectionDataAccess (org.hibernate.cache.spi.access.CollectionDataAccess)2 EntityDataAccess (org.hibernate.cache.spi.access.EntityDataAccess)2 Serializable (java.io.Serializable)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 EmbeddableType (javax.persistence.metamodel.EmbeddableType)1 EntityType (javax.persistence.metamodel.EntityType)1 ManagedType (javax.persistence.metamodel.ManagedType)1 MappedSuperclassType (javax.persistence.metamodel.MappedSuperclassType)1 CollectionDataCachingConfig (org.hibernate.cache.cfg.spi.CollectionDataCachingConfig)1 DomainDataRegionConfig (org.hibernate.cache.cfg.spi.DomainDataRegionConfig)1 EntityDataCachingConfig (org.hibernate.cache.cfg.spi.EntityDataCachingConfig)1