@Override public void write(ObjectDataOutput out, CacheEntry object) throws IOException { try { Serializable[] disassembledState = (Serializable[]) UNSAFE.getObject(object, DISASSEMBLED_STATE_OFFSET); String subclass = (String) UNSAFE.getObject(object, SUBCLASS_OFFSET); boolean lazyPropertiesAreUnfetched = UNSAFE.getBoolean(object, LAZY_PROPERTIES_ARE_UNFETCHED); Object version = UNSAFE.getObject(object, VERSION_OFFSET); out.writeInt(disassembledState.length); for (Serializable state : disassembledState) { out.writeObject(state); } out.writeUTF(subclass); out.writeBoolean(lazyPropertiesAreUnfetched); out.writeObject(version); } catch (Exception e) { if (e instanceof IOException) { throw (IOException) e; } throw new IOException(e); } }
@Override public CacheEntry read(ObjectDataInput in) throws IOException { try { int length = in.readInt(); Serializable[] disassembledState = new Serializable[length]; for (int i = 0; i < length; i++) { disassembledState[i] = in.readObject(); } String subclass = in.readUTF(); boolean lazyPropertiesAreUnfetched = in.readBoolean(); Object version = in.readObject(); return CACHE_ENTRY_CONSTRUCTOR.newInstance(disassembledState, subclass, lazyPropertiesAreUnfetched, version); } catch (Exception e) { if (e instanceof IOException) { throw (IOException) e; } throw new IOException(e); } }
public Object merge(String mapName, EntryView mergingEntry, EntryView existingEntry) { final Object existingValue = existingEntry != null ? existingEntry.getValue() : null; final Object mergingValue = mergingEntry.getValue(); if (existingValue != null && existingValue instanceof CacheEntry && mergingValue != null && mergingValue instanceof CacheEntry) { final CacheEntry existingCacheEntry = (CacheEntry) existingValue; final CacheEntry mergingCacheEntry = (CacheEntry) mergingValue; final Object mergingVersionObject = mergingCacheEntry.getVersion(); final Object existingVersionObject = existingCacheEntry.getVersion(); if (mergingVersionObject != null && existingVersionObject != null && mergingVersionObject instanceof Comparable && existingVersionObject instanceof Comparable) { final Comparable mergingVersion = (Comparable) mergingVersionObject; final Comparable existingVersion = (Comparable) existingVersionObject; if (mergingVersion.compareTo(existingVersion) > 0) { return mergingValue; } else { return existingValue; } } } return mergingValue; }
@Test public void testAutoregistrationOnHibernate3Available() throws Exception { HazelcastInstance hz = Hazelcast.newHazelcastInstance(); HazelcastInstanceImpl impl = (HazelcastInstanceImpl) ORIGINAL.get(hz); SerializationService ss = impl.getSerializationService(); ConcurrentMap<Class, ?> typeMap = (ConcurrentMap<Class, ?>) TYPE_MAP.get(ss); boolean cacheKeySerializerFound = false; boolean cacheEntrySerializerFound = false; for (Class clazz : typeMap.keySet()) { if (clazz == CacheKey.class) { cacheKeySerializerFound = true; } else if (clazz == CacheEntry.class) { cacheEntrySerializerFound = true; } } assertTrue("CacheKey serializer not found", cacheKeySerializerFound); assertTrue("CacheEntry serializer not found", cacheEntrySerializerFound); }
private boolean put(final Object key, final Object value, final Object currentVersion, final Object previousVersion) throws TimeoutException { if (versionComparator != null) { if (explicitVersionCheckEnabled && value instanceof CacheEntry) { final CacheEntry currentEntry = (CacheEntry) value; final CacheEntry previousEntry = (CacheEntry) getCache().tryLockAndGet(key, 500, TimeUnit.MILLISECONDS); if (previousEntry == null || versionComparator.compare(currentEntry.getVersion(), previousEntry.getVersion()) > 0) { getCache().putAndUnlock(key, value); return true; } else { getCache().unlock(key); return false; } } else if (previousVersion == null || versionComparator.compare(currentVersion, previousVersion) > 0) { return putInToCache(key, value); } return false; } else { return putInToCache(key, value); } }
@Test public void merge_mergingUptodate() { CacheEntry existing = cacheEntryWithVersion(versionOld); CacheEntry merging = cacheEntryWithVersion(versionNew); EntryView entryExisting = entryWithGivenValue(existing); EntryView entryMerging = entryWithGivenValue(merging); assertEquals(merging, policy.merge("map", entryMerging, entryExisting)); }
@Test public void merge_mergingStale() { CacheEntry existing = cacheEntryWithVersion(versionNew); CacheEntry merging = cacheEntryWithVersion(versionOld); EntryView entryExisting = entryWithGivenValue(existing); EntryView entryMerging = entryWithGivenValue(merging); assertEquals(existing, policy.merge("map", entryMerging, entryExisting)); }
@Test public void merge_mergingNull() { CacheEntry existing = null; CacheEntry merging = cacheEntryWithVersion(versionNew); EntryView entryExisting = entryWithGivenValue(existing); EntryView entryMerging = entryWithGivenValue(merging); assertEquals(merging, policy.merge("map", entryMerging, entryExisting)); }
public Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session) throws HibernateException { final Serializable id = session.getContextEntityIdentifier( entity ); final EntityEntry entry = session.getPersistenceContext().getEntry( entity ); if ( entry == null ) { throw new HibernateException( "entity is not associated with the session: " + id ); } if ( log.isTraceEnabled() ) { log.trace( "initializing lazy properties of: " + MessageHelper.infoString( this, id, getFactory() ) + ", field access: " + fieldName ); } if ( hasCache() ) { CacheKey cacheKey = new CacheKey(id, getIdentifierType(), getEntityName(), session.getEntityMode(), getFactory() ); Object ce = getCache().get( cacheKey, session.getTimestamp() ); if (ce!=null) { CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory); if ( !cacheEntry.areLazyPropertiesUnfetched() ) { //note early exit here: return initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry ); } } } return initializeLazyPropertiesFromDatastore( fieldName, entity, session, id, entry ); }
private Object initializeLazyPropertiesFromCache( final String fieldName, final Object entity, final SessionImplementor session, final EntityEntry entry, final CacheEntry cacheEntry ) { log.trace("initializing lazy properties from second-level cache"); Object result = null; Serializable[] disassembledValues = cacheEntry.getDisassembledState(); final Object[] snapshot = entry.getLoadedState(); for ( int j = 0; j < lazyPropertyNames.length; j++ ) { final Object propValue = lazyPropertyTypes[j].assemble( disassembledValues[ lazyPropertyNumbers[j] ], session, entity ); if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) { result = propValue; } } log.trace( "done initializing lazy properties" ); return result; }
public void execute() throws HibernateException { EntityPersister persister = getPersister(); SessionImplementor session = getSession(); Object instance = getInstance(); Serializable id = getId(); boolean veto = preInsert(); // Don't need to lock the cache here, since if someone // else inserted the same pk first, the insert would fail if ( !veto ) { persister.insert( id, state, instance, session ); EntityEntry entry = session.getPersistenceContext().getEntry( instance ); if ( entry == null ) { throw new AssertionFailure( "possible nonthreadsafe access to session" ); } entry.postInsert(); if ( persister.hasInsertGeneratedProperties() ) { persister.processInsertGeneratedProperties( id, instance, state, session ); if ( persister.isVersionPropertyGenerated() ) { version = Versioning.getVersion(state, persister); } entry.postUpdate(instance, state, version); } } final SessionFactoryImplementor factory = getSession().getFactory(); if ( isCachePutEnabled( persister, session ) ) { CacheEntry ce = new CacheEntry( state, persister, persister.hasUninitializedLazyProperties( instance, session.getEntityMode() ), version, session, instance ); cacheEntry = persister.getCacheEntryStructure().structure(ce); final CacheKey ck = new CacheKey( id, persister.getIdentifierType(), persister.getRootEntityName(), session.getEntityMode(), session.getFactory() ); // boolean put = persister.getCache().insert(ck, cacheEntry); boolean put = persister.getCache().insert( ck, cacheEntry, version ); if ( put && factory.getStatistics().isStatisticsEnabled() ) { factory.getStatisticsImplementor() .secondLevelCachePut( getPersister().getCache().getRegionName() ); } } postInsert(); if ( factory.getStatistics().isStatisticsEnabled() && !veto ) { factory.getStatisticsImplementor() .insertEntity( getPersister().getEntityName() ); } }
@SuppressWarnings({"rawtypes", "unchecked"}) public Object merge(String mapName, MapEntry mergingEntry, MapEntry existingEntry) { DataRecordEntry mergingDataEntry = (DataRecordEntry) mergingEntry; if (!mergingDataEntry.isValid()) { return REMOVE_EXISTING; } else { final Object existingObject = existingEntry != null ? existingEntry.getValue() : null; final Object mergingObject = mergingEntry.getValue(); if (existingObject != null && existingObject instanceof CacheEntry && mergingObject != null && mergingObject instanceof CacheEntry) { final CacheEntry existing = (CacheEntry) existingObject; final CacheEntry merging = (CacheEntry) mergingObject; final Object mergingVersionObject = merging.getVersion(); final Object existingVersionObject = existing.getVersion(); if (mergingVersionObject != null && existingVersionObject != null && mergingVersionObject instanceof Comparable && existingVersionObject instanceof Comparable) { final Comparable mergingVersion = (Comparable) mergingVersionObject; final Comparable existingVersion = (Comparable) existingVersionObject; if (mergingVersion.compareTo(existingVersion) > 0) { return mergingDataEntry.getValueData(); } else { return ((DataRecordEntry) existingEntry).getValueData(); } } } return mergingDataEntry.getValueData(); } }
public boolean update(final Object key, final Object value, final Object currentVersion, final Object previousVersion, final SoftLock lock) { if (lock == LOCK_FAILURE) { logger.log(Level.WARNING, "Cache lock could not be acquired!"); return false; } if (versionComparator != null && currentVersion != null) { if (explicitVersionCheckEnabled && value instanceof CacheEntry) { try { final CacheEntry currentEntry = (CacheEntry) value; final CacheEntry previousEntry = (CacheEntry) map.tryLockAndGet(key, tryLockAndGetTimeout, TimeUnit.MILLISECONDS); if (previousEntry == null || versionComparator.compare(currentEntry.getVersion(), previousEntry.getVersion()) > 0) { map.putAndUnlock(key, value); return true; } else { map.unlock(key); return false; } } catch (TimeoutException e) { return false; } } else if (previousVersion == null || versionComparator.compare(currentVersion, previousVersion) > 0) { map.set(key, value, 0, TimeUnit.MILLISECONDS); } return false; } else { map.set(key, value, 0, TimeUnit.MILLISECONDS); return true; } }
@Test public void testAutoregistrationOnHibernate3NonAvailable() throws Exception { Thread thread = Thread.currentThread(); ClassLoader tccl = thread.getContextClassLoader(); Object config = null; Method setClassLoader = null; try { thread.setContextClassLoader(FILTERING_CLASS_LOADER); Class<?> configClazz = FILTERING_CLASS_LOADER.loadClass("com.hazelcast.config.Config"); config = configClazz.newInstance(); setClassLoader = configClazz.getDeclaredMethod("setClassLoader", ClassLoader.class); setClassLoader.invoke(config, FILTERING_CLASS_LOADER); Class<?> hazelcastClazz = FILTERING_CLASS_LOADER.loadClass("com.hazelcast.core.Hazelcast"); Method newHazelcastInstance = hazelcastClazz.getDeclaredMethod("newHazelcastInstance", configClazz); Object hz = newHazelcastInstance.invoke(hazelcastClazz, config); Object impl = ORIGINAL.get(hz); Object serializationService = GET_SERIALIZATION_SERVICE.invoke(impl); //noinspection unchecked ConcurrentMap<Class, ?> typeMap = (ConcurrentMap<Class, ?>) TYPE_MAP.get(serializationService); boolean cacheKeySerializerFound = false; boolean cacheEntrySerializerFound = false; for (Class clazz : typeMap.keySet()) { if (clazz == CacheKey.class) { cacheKeySerializerFound = true; } else if (clazz == CacheEntry.class) { cacheEntrySerializerFound = true; } } hazelcastClazz.getDeclaredMethod("shutdownAll").invoke(impl); assertFalse("CacheKey serializer found", cacheKeySerializerFound); assertFalse("CacheEntry serializer found", cacheEntrySerializerFound); } finally { if (config != null && setClassLoader != null) { setClassLoader.invoke(config, tccl); } thread.setContextClassLoader(tccl); } }
private CacheEntry cacheEntryWithVersion(MockVersion mockVersion) { return new CacheEntry(new Object[]{}, mock(EntityPersister.class), false, mockVersion, mock(SessionImplementor.class), mock(Object.class)); }
/** * Attempts to load the entity from the second-level cache. * * @param event The load event * @param persister The persister for the entity being requested for load * @param options The load options. * @return The entity from the second-level cache, or null. * @throws HibernateException */ protected Object loadFromSecondLevelCache( final LoadEvent event, final EntityPersister persister, final LoadEventListener.LoadType options) throws HibernateException { final SessionImplementor source = event.getSession(); final boolean useCache = persister.hasCache() && source.getCacheMode().isGetEnabled() && event.getLockMode().lessThan(LockMode.READ); if (useCache) { final SessionFactoryImplementor factory = source.getFactory(); final CacheKey ck = new CacheKey( event.getEntityId(), persister.getIdentifierType(), persister.getRootEntityName(), source.getEntityMode(), source.getFactory() ); Object ce = persister.getCache() .get( ck, source.getTimestamp() ); if ( factory.getStatistics().isStatisticsEnabled() ) { if (ce==null) { factory.getStatisticsImplementor().secondLevelCacheMiss( persister.getCache().getRegionName() ); } else { factory.getStatisticsImplementor().secondLevelCacheHit( persister.getCache().getRegionName() ); } } if ( ce != null ) { CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure() .destructure(ce, factory); // Entity was found in second-level cache... return assembleCacheEntry( entry, event.getEntityId(), persister, event ); } } return null; }
private Object assembleCacheEntry( final CacheEntry entry, final Serializable id, final EntityPersister persister, final LoadEvent event) throws HibernateException { final Object optionalObject = event.getInstanceToLoad(); final EventSource session = event.getSession(); final SessionFactoryImplementor factory = session.getFactory(); if ( log.isTraceEnabled() ) { log.trace( "assembling entity from second-level cache: " + MessageHelper.infoString( persister, id, factory ) ); } EntityPersister subclassPersister = factory.getEntityPersister( entry.getSubclass() ); Object result = optionalObject == null ? session.instantiate( subclassPersister, id ) : optionalObject; // make it circular-reference safe TwoPhaseLoad.addUninitializedCachedEntity( new EntityKey( id, subclassPersister, session.getEntityMode() ), result, subclassPersister, LockMode.NONE, entry.areLazyPropertiesUnfetched(), entry.getVersion(), session ); Type[] types = subclassPersister.getPropertyTypes(); Object[] values = entry.assemble( result, id, subclassPersister, session.getInterceptor(), session ); // intializes result by side-effect TypeFactory.deepCopy( values, types, subclassPersister.getPropertyUpdateability(), values, session ); Object version = Versioning.getVersion( values, subclassPersister ); if ( log.isTraceEnabled() ) log.trace( "Cached Version: " + version ); final PersistenceContext persistenceContext = session.getPersistenceContext(); persistenceContext.addEntry( result, Status.MANAGED, values, null, id, version, LockMode.NONE, true, subclassPersister, false, entry.areLazyPropertiesUnfetched() ); subclassPersister.afterInitialize( result, entry.areLazyPropertiesUnfetched(), session ); persistenceContext.initializeNonLazyCollections(); // upgrade the lock if necessary: //lock(result, lockMode); //PostLoad is needed for EJB3 //TODO: reuse the PostLoadEvent... PostLoadEvent postLoadEvent = new PostLoadEvent(session).setEntity(result) .setId(id).setPersister(persister); PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners(); for ( int i = 0; i < listeners.length; i++ ) { listeners[i].onPostLoad(postLoadEvent); } return result; }