@Override public void write(final ObjectDataOutput out, final CacheEntry object) throws IOException { try { out.writeBoolean(object.isReferenceEntry()); if (object.isReferenceEntry()) { // Reference entries are not disassembled. Instead, to be serialized, they rely entirely on // the entity itself being Serializable. This is not a common thing (Hibernate is currently // very restrictive about what can be cached by reference), so it may not be worth dealing // with at all. This is just a naive implementation relying on the entity's serialization. writeReference(out, object); } else { writeDisassembled(out, object); } } catch (Exception e) { throw rethrow(e); } }
@Override public Object merge(final String mapName, final EntryView mergingEntry, final 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; }
@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); } }
@Override public void write(ObjectDataOutput out, CacheEntry object) throws IOException { try { out.writeBoolean(object.isReferenceEntry()); if (object.isReferenceEntry()) { // Reference entries are not disassembled. Instead, to be serialized, they rely entirely on // the entity itself being Serializable. This is not a common thing (Hibernate is currently // very restrictive about what can be cached by reference), so it may not be worth dealing // with at all. This is just a naive implementation relying on the entity's serialization. writeReference(out, object); } else { writeDisassembled(out, object); } } catch (Exception e) { throw rethrow(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 testAutoregistrationOnHibernate4Available() 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 Class<?> getSubclassName(Object cacheEntry, boolean useStructuredCache) { String subclassName = null; if (useStructuredCache) { @SuppressWarnings("unchecked") Map structuredCacheEntry = (Map) cacheEntry; subclassName = (String) structuredCacheEntry.get(STRUCTURED_CACHE_ENTRY_SUBCLASS_KEY); } else { subclassName = ((CacheEntry) cacheEntry).getSubclass(); } Class<?> clazz; try { clazz = Class.forName(subclassName); } catch (ClassNotFoundException e) { throw new IllegalArgumentException(subclassName + " class is not found.", e); } return clazz; }
@Test public void put_classVersionApplicable_true() throws Exception { givenRegionWithDefaultProperties(); String key = "greeting"; CacheEntry cacheEntry = mock(CacheEntry.class); when(cacheEntry.getSubclass()).thenReturn(String.class.getName()); ArgumentCaptor<CacheItem> cacheItemArgumentCaptor = ArgumentCaptor.forClass(CacheItem.class); generalDataMemcachedRegion.put(key, cacheEntry); verify(memcachedAdapter).set(eq(cacheNamespace), eq(refineKey(key)), cacheItemArgumentCaptor.capture(), eq(generalDataMemcachedRegion.getExpiryInSeconds())); CacheItem cacheItem = cacheItemArgumentCaptor.getValue(); assertThat(cacheItem.getCacheEntry()).isEqualTo(cacheEntry); assertThat(cacheItem.getTargetClassName()).isEqualTo(String.class.getName()); }
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.tracev( "Initializing lazy properties of: {0}, field access: {1}", MessageHelper.infoString( this, id, getFactory() ), fieldName ); } if ( session.getCacheMode().isGetEnabled() && hasCache() ) { final CacheKey cacheKey = session.generateCacheKey( id, getIdentifierType(), getEntityName() ); final Object ce = CacheHelper.fromSharedCache( session, cacheKey, getCacheAccessStrategy() ); if ( ce != null ) { final 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; }
@Override public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SessionImplementor session) { return new StandardCacheEntryImpl( state, persister, persister.hasUninitializedLazyProperties( entity ), version, session, entity ); }
@Override public CacheEntry read(final ObjectDataInput in) throws IOException { try { if (in.readBoolean()) { return readReference(in); } return readDisassembled(in); } catch (Exception e) { throw rethrow(e); } }
private static CacheEntry readDisassembled(final ObjectDataInput in) throws IOException, IllegalAccessException, InvocationTargetException, InstantiationException { int length = in.readInt(); Serializable[] disassembledState = new Serializable[length]; for (int i = 0; i < length; i++) { disassembledState[i] = in.readObject(); } String subclass = in.readUTF(); Object version = in.readObject(); return CACHE_ENTRY_CONSTRUCTOR.newInstance(disassembledState, subclass, version); }
private static void writeDisassembled(final ObjectDataOutput out, final CacheEntry object) throws IOException { Serializable[] disassembledState = object.getDisassembledState(); out.writeInt(disassembledState.length); for (Serializable state : disassembledState) { out.writeObject(state); } out.writeUTF(object.getSubclass()); out.writeObject(object.getVersion()); }
private static CacheEntry readDisassembled(final ObjectDataInput in) throws IOException, IllegalAccessException, InvocationTargetException, InstantiationException { 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); }
private static void writeDisassembled(final ObjectDataOutput out, final CacheEntry object) throws IOException { Serializable[] disassembledState = object.getDisassembledState(); out.writeInt(disassembledState.length); for (Serializable state : disassembledState) { out.writeObject(state); } out.writeUTF(object.getSubclass()); out.writeBoolean(object.areLazyPropertiesUnfetched()); out.writeObject(object.getVersion()); }
@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)); }
private static CacheEntry readDisassembled(final ObjectDataInput in) throws IOException, IllegalAccessException, InstantiationException { int length = in.readInt(); Serializable[] disassembledState = new Serializable[length]; for (int i = 0; i < length; i++) { disassembledState[i] = in.readObject(); } String subclass = in.readUTF(); Object version = in.readObject(); return new CacheEntryImpl(disassembledState, subclass, version); }
@Override public CacheEntry read(ObjectDataInput in) throws IOException { try { if (in.readBoolean()) { return readReference(in); } return readDisassembled(in); } catch (Exception e) { throw rethrow(e); } }
private static CacheEntry readDisassembled(ObjectDataInput in) throws IOException, IllegalAccessException, InvocationTargetException, InstantiationException { 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); }
private static void writeDisassembled(ObjectDataOutput out, CacheEntry object) throws IOException { Serializable[] disassembledState = object.getDisassembledState(); out.writeInt(disassembledState.length); for (Serializable state : disassembledState) { out.writeObject(state); } out.writeUTF(object.getSubclass()); out.writeBoolean(object.areLazyPropertiesUnfetched()); out.writeObject(object.getVersion()); }
private static String getSubclassFromValueOf(Object object){ if(object instanceof Item){ return ((Item) object).getSubclass(); } else if(object instanceof CacheEntry){ return ((CacheEntry) object).getSubclass(); } return null; }
/** * Check if class version comparable. */ public static boolean checkIfClassVersionApplicable(Object cacheEntry, boolean useStructuredCache) { if (!useStructuredCache && cacheEntry instanceof CacheEntry) { return true; } if (useStructuredCache && cacheEntry instanceof Map) { return true; } return false; }
/** * The entity instance is not in the session cache */ private Object instanceNotYetLoaded( final ResultSet rs, final int i, final Loadable persister, final String rowIdAlias, final EntityKey key, final LockMode lockMode, final EntityKey optionalObjectKey, final Object optionalObject, final List hydratedObjects, final SessionImplementor session) throws HibernateException, SQLException { final String instanceClass = getInstanceClass( rs, i, persister, key.getIdentifier(), session ); // see if the entity defines reference caching, and if so use the cached reference (if one). if ( session.getCacheMode().isGetEnabled() && persister.canUseReferenceCacheEntries() ) { final Object cachedEntry = CacheHelper.fromSharedCache( session, session.generateCacheKey( key.getIdentifier(), persister.getEntityMetamodel().getEntityType(), key.getEntityName() ), persister.getCacheAccessStrategy() ); if ( cachedEntry != null ) { CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( cachedEntry, factory ); return ( (ReferenceCacheEntryImpl) entry ).getReference(); } } final Object object; if ( optionalObjectKey != null && key.equals( optionalObjectKey ) ) { //its the given optional object object = optionalObject; } else { // instantiate a new instance object = session.instantiate( instanceClass, key.getIdentifier() ); } //need to hydrate it. // grab its state from the ResultSet and keep it in the Session // (but don't yet initialize the object itself) // note that we acquire LockMode.READ even if it was not requested LockMode acquiredLockMode = lockMode == LockMode.NONE ? LockMode.READ : lockMode; loadFromResultSet( rs, i, object, instanceClass, key, rowIdAlias, acquiredLockMode, persister, session ); //materialize associations (and initialize the object) later hydratedObjects.add( object ); return object; }
@Override public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SessionImplementor session) { return cacheEntryHelper.buildCacheEntry( entity, state, version, session ); }
@Override public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SessionImplementor session) { return new ReferenceCacheEntryImpl( entity, persister ); }
@Override public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SessionImplementor session) { throw new HibernateException( "Illegal attempt to build cache entry for non-cached entity" ); }
/** * 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. */ protected Object loadFromSecondLevelCache( final LoadEvent event, final EntityPersister persister, final LoadEventListener.LoadType options) { final SessionImplementor source = event.getSession(); final boolean useCache = persister.hasCache() && source.getCacheMode().isGetEnabled() && event.getLockMode().lessThan( LockMode.READ ); if ( !useCache ) { // we can't use cache here return null; } final SessionFactoryImplementor factory = source.getFactory(); final CacheKey ck = source.generateCacheKey( event.getEntityId(), persister.getIdentifierType(), persister.getRootEntityName() ); final Object ce = CacheHelper.fromSharedCache( source, ck, persister.getCacheAccessStrategy() ); if ( factory.getStatistics().isStatisticsEnabled() ) { if ( ce == null ) { factory.getStatisticsImplementor().secondLevelCacheMiss( persister.getCacheAccessStrategy().getRegion().getName() ); } else { factory.getStatisticsImplementor().secondLevelCacheHit( persister.getCacheAccessStrategy().getRegion().getName() ); } } if ( ce == null ) { // nothing was found in cache return null; } CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( ce, factory ); Object entity = convertCacheEntryToEntity( entry, event.getEntityId(), persister, event ); if ( !persister.isInstance( entity ) ) { throw new WrongClassException( "loaded object was of wrong class " + entity.getClass(), event.getEntityId(), persister.getEntityName() ); } return entity; }