Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When @Cache.usage changes, casting exception is thrown #1

Closed
rica-v3 opened this issue Feb 6, 2021 · 2 comments
Closed

When @Cache.usage changes, casting exception is thrown #1

rica-v3 opened this issue Feb 6, 2021 · 2 comments
Assignees
Labels
bug Something isn't working

Comments

@rica-v3
Copy link
Member

rica-v3 commented Feb 6, 2021

After changing "CacheConcurrencyStrategy" READ_ONLY to READ_WRITE, getting entity occurs the exception below.

Cause:

The cached entity is StandardCacheEntryImpl but current entity should be AbstractReadWriteAccess$Lockable

org.hibernate.HibernateException: Unable to perform afterTransactionCompletion callback: org.hibernate.cache.spi.entry.StandardCacheEntryImpl cannot be cast to org.hibernate.cache.spi.support.AbstractReadWriteAccess$Lockable

	at org.hibernate.engine.spi.ActionQueue$AfterTransactionCompletionProcessQueue.afterTransactionCompletion(ActionQueue.java:990)
	at org.hibernate.engine.spi.ActionQueue.afterTransactionCompletion(ActionQueue.java:513)
	at org.hibernate.internal.SessionImpl.afterTransactionCompletion(SessionImpl.java:2404)
	at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.afterTransactionCompletion(JdbcCoordinatorImpl.java:454)
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.afterCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:203)
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$400(JdbcResourceLocalTransactionCoordinatorImpl.java:40)
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:283)
	at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
	at hibernate.CollectionCacheTest.testCollectionCache_whenCollectionCacheIsPut_thenCollectionCacheShouldBeHitForTheNextGet(CollectionCacheTest.java:98)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.hibernate.testing.junit4.ExtendedFrameworkMethod.invokeExplosively(ExtendedFrameworkMethod.java:45)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
	at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:298)
	at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:292)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassCastException: org.hibernate.cache.spi.entry.StandardCacheEntryImpl cannot be cast to org.hibernate.cache.spi.support.AbstractReadWriteAccess$Lockable
	at org.hibernate.cache.spi.support.EntityReadWriteAccess.afterInsert(EntityReadWriteAccess.java:85)
	at org.hibernate.action.internal.EntityInsertAction.cacheAfterInsert(EntityInsertAction.java:257)
	at org.hibernate.action.internal.EntityInsertAction.doAfterTransactionCompletion(EntityInsertAction.java:239)
	at org.hibernate.engine.spi.ActionQueue$AfterTransactionCompletionProcessQueue.afterTransactionCompletion(ActionQueue.java:983)
	... 23 more

Solution:

When changing CacheConcurrencyStrategy, regionName should be modified together not to reuse same cache items

@rica-v3
Copy link
Member Author

rica-v3 commented Feb 11, 2021

To resolve the casting exception, EntityReadWriteAccess needs to be overridden by handling Casting Exception

package org.hibernate.cache.spi.support;
public class EntityReadWriteAccess extends AbstractReadWriteAccess implements EntityDataAccess

	@Override
	public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value, Object version) {
		try {
			writeLock().lock();
			* Lockable item = (Lockable) getStorageAccess().getFromCache( key, session ); // <--- casting exception point #1
			if ( item == null ) {
				getStorageAccess().putIntoCache(
						key,
						new Item( value, version, getRegion().getRegionFactory().nextTimestamp() ),
						session
				);
				return true;
			}
			else {
				return false;
			}
		}
		finally {
			writeLock().unlock();
		}
	}
	@Override
	public boolean afterUpdate(
			SharedSessionContractImplementor session,
			Object key,
			Object value,
			Object currentVersion,
			Object previousVersion,
			SoftLock lock) {
		try {
			writeLock().lock();
			* Lockable item = (Lockable) getStorageAccess().getFromCache( key, session ); // <--- casting exception point #2

			if ( item != null && item.isUnlockable( lock ) ) {
				SoftLockImpl lockItem = (SoftLockImpl) item;
				if ( lockItem.wasLockedConcurrently() ) {
					decrementLock( session, key, lockItem );
					return false;
				}
				else {
					getStorageAccess().putIntoCache(
							key,
							new Item( value, currentVersion, getRegion().getRegionFactory().nextTimestamp() ),
							session
					);
					return true;
				}
			}
			else {
				handleLockExpiry(session, key, item );
				return false;
			}
		}
		finally {
			writeLock().unlock();
		}
	}

@rica-v3
Copy link
Member Author

rica-v3 commented Feb 11, 2021

This is not a bug, but is intended by hibernate-orm

Solution:

When changing CacheConcurrencyStrategy, regionName should be modified together not to reuse same cache items

@rica-v3 rica-v3 self-assigned this Feb 11, 2021
@rica-v3 rica-v3 added the bug Something isn't working label Feb 11, 2021
@rica-v3 rica-v3 closed this as completed Feb 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant