Skip to Content
2
Nov 10, 2022 at 02:24 PM

Hybris 2205_5 RelationInvalidationListener Calls TypePKsExtractor Causing Invalidation Error

829 Views Last edit Nov 10, 2022 at 04:39 PM 3 rev

Hi, Hybris 2205 has introduced RelationCache. But there is also a bug introduced by RelationInvaidationListener during transaction invalidation phase.

How to reproduce

(1) run ant yunitinit. It imports some essential data for junit tenant, If the essential data contains for example

INSERT_UPDATE Currency ; isocode[unique = true] ; conversion ; digits ; symbol
                       ; EUR                    ; 1          ; 2      ; €    

(2) run one integration test use ant alltests -Dtestclasses.extensions=blabla -Dtestclasses.packages=blabla

(3) in the integration test, run one impex which contains the same content as previous

INSERT_UPDATE Currency ; isocode[unique = true] ; conversion ; digits ; symbol
                       ; EUR                    ; 1          ; 2      ; €    

What happens internally with hybris is that even though nothing has changed for the Currency. But it still add this Currency to the invalidation set for the current transaction

addingtocurrenttransaction.png

When the test finishes, the TransactionRunListener will try to invalidate the added keys. RelationInvalidationListener will start to run which generate exceptions like the following

InvalidationTopic[hjmp, entity] via listener de.hybris.platform.cache.relation.RelationInvalidationListener@5cc78f68<br> [yunitint]  java.lang.IllegalStateException: The transaction is performing invalidatins after commit / rollback. You cannot access the database in this phase.<br> [yunitint]    at de.hybris.platform.tx.Transaction.getTXBoundConnection(Transaction.java:1900) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.jdbcwrapper.DataSourceImpl.getFromPool(DataSourceImpl.java:484) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.jdbcwrapper.DataSourceImpl.doGetConnection(DataSourceImpl.java:465) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.jdbcwrapper.DataSourceImpl.getConnection(DataSourceImpl.java:456) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.jdbcwrapper.DataSourceImpl.getConnection(DataSourceImpl.java:410) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.persistence.type.ComposedType_HJMPWrapper$FindByTypeCode1FinderResult.getFromDatabase(ComposedType_HJMPWrapper.java:1348) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.persistence.type.ComposedType_HJMPWrapper$FindByTypeCode1FinderResult.compute(ComposedType_HJMPWrapper.java:1336) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.AbstractCacheUnit.privateGetNoLock(AbstractCacheUnit.java:297) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.AbstractCacheUnit.privateGet(AbstractCacheUnit.java:270) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.AbstractCacheUnit.get(AbstractCacheUnit.java:172) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.persistence.type.ComposedType_HJMPWrapper$FindByTypeCode1FinderResult.getFinderResult(ComposedType_HJMPWrapper.java:1308) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.persistence.type.ComposedType_HJMPWrapper.ejbFindByTypeCode(ComposedType_HJMPWrapper.java:1381) ~[coreserver.jar:?]<br> [yunitint]    at jdk.internal.reflect.GeneratedMethodAccessor619.invoke(Unknown Source) ~[?:?]<br> [yunitint]    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]<br> [yunitint]    at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]<br> [yunitint]    at de.hybris.platform.util.Utilities.callMethod(Utilities.java:1021) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.util.Utilities.callMethod(Utilities.java:1011) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.persistence.framework.HomeInvocationHandler.invokeMethod(HomeInvocationHandler.java:105) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.persistence.framework.HomeInvocationHandler.invoke(HomeInvocationHandler.java:55) ~[coreserver.jar:?]<br> [yunitint]    at jdk.proxy2.$Proxy241.findByTypeCode(Unknown Source) ~[?:?]<br> [yunitint]    at de.hybris.platform.persistence.type.TypeManagerEJB.getRootComposedType(TypeManagerEJB.java:445) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.jalo.type.TypeManager.getRootComposedType(TypeManager.java:338) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.relation.TypePKsExtractor.getTypePKs(TypePKsExtractor.java:62) ~[coreserver.jar:?]<br> [yunitint]    at java.util.Optional.map(Optional.java:260) ~[?:?]<br> [yunitint]    at de.hybris.platform.cache.relation.TypePKsExtractor.lambda$extractTypePKs$1(TypePKsExtractor.java:32) ~[coreserver.jar:?]<br> [yunitint]    at java.util.Optional.or(Optional.java:313) ~[?:?]<br> [yunitint]    at de.hybris.platform.cache.relation.TypePKsExtractor.extractTypePKs(TypePKsExtractor.java:32) ~[coreserver.jar:?]<br> [yunitint]    at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) ~[?:?]<br> [yunitint]    at de.hybris.platform.cache.relation.CachingRelationAttributesProvider.extractTypePKs(CachingRelationAttributesProvider.java:40) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.relation.CachingRelationAttributesProvider.lambda$getTypePKs$0(CachingRelationAttributesProvider.java:35) ~[coreserver.jar:?]<br> [yunitint]    at java.util.Optional.orElseGet(Optional.java:364) ~[?:?]<br> [yunitint]    at de.hybris.platform.cache.relation.CachingRelationAttributesProvider.getTypePKs(CachingRelationAttributesProvider.java:35) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.relation.CachingRelationAttributesProvider.getRelationAttributes(CachingRelationAttributesProvider.java:30) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.relation.ConfigurableRelationAttributesProvider.getRelationAttributes(ConfigurableRelationAttributesProvider.java:38) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.relation.DefaultRelationsCache.getAllCacheableAttributes(DefaultRelationsCache.java:77) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.relation.RelationInvalidationListener.getCacheableAttributes(RelationInvalidationListener.java:96) ~[coreserver.jar:?]<br> [yunitint]    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[?:?]<br> [yunitint]    at java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:411) ~[?:?]<br> [yunitint]    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[?:?]<br> [yunitint]    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[?:?]<br> [yunitint]    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) ~[?:?]<br> [yunitint]    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) ~[?:?]<br> [yunitint]    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]<br> [yunitint]    at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[?:?]<br> [yunitint]    at de.hybris.platform.cache.relation.RelationInvalidationListener.invalidateByTypeIds(RelationInvalidationListener.java:86) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.relation.RelationInvalidationListener.invalidateByTypeCode(RelationInvalidationListener.java:76) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.relation.RelationInvalidationListener.keyInvalidated(RelationInvalidationListener.java:53) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.InvalidationTopic.invalidateLocally(InvalidationTopic.java:149) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.InvalidationTopic.invalidateLocally(InvalidationTopic.java:159) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.tx.InvalidationSet$InvalidationManagerProcessor.invalidateLocally(InvalidationSet.java:716) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.tx.InvalidationSet.executeDelayedInvalidationsLocally(InvalidationSet.java:308) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.tx.InvalidationSet.executeDelayedRollbackInvalidationsLocally(InvalidationSet.java:296) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.tx.Transaction.notifyRollback(Transaction.java:1142) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.tx.Transaction.clearTxBoundConnectionAndNotify(Transaction.java:935) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.tx.Transaction.clearTxBoundConnectionAndNotifyRollback(Transaction.java:909) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.tx.Transaction.rollbackOuter(Transaction.java:1110) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.tx.Transaction.rollback(Transaction.java:1053) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.testframework.runlistener.TransactionRunListener.rollbackTestTx(TransactionRunListener.java:140) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.testframework.runlistener.TransactionRunListener.transactionalTestFinished(TransactionRunListener.java:71) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.testframework.runlistener.TransactionRunListener.testFinished(TransactionRunListener.java:51) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.testframework.ChainingRunNotifierWrapper$7.notifyListener(ChainingRunNotifierWrapper.java:220) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.testframework.ChainingRunNotifierWrapper$ReverseSafeNotifier.run(ChainingRunNotifierWrapper.java:306) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.testframework.ChainingRunNotifierWrapper.fireTestFinished(ChainingRunNotifierWrapper.java:222) ~[coreserver.jar:?]<br> [yunitint]    at org.junit.internal.runners.model.EachTestNotifier.fireTestFinished(EachTestNotifier.java:38) ~[junit-4.13.2.jar:4.13.2]

The exception is caused by the following call

 [yunitint]    at de.hybris.platform.persistence.type.TypeManagerEJB.getRootComposedType(TypeManagerEJB.java:445) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.jalo.type.TypeManager.getRootComposedType(TypeManager.java:338) ~[coreserver.jar:?]<br> [yunitint]    at de.hybris.platform.cache.relation.TypePKsExtractor.getTypePKs(TypePKsExtractor.java:62) ~[coreserver.jar:?]

TypeManagerEJB.getRootComposedType will use FindByTypeCode1FinderResult which has never being called before(not cached). So it tries to get database connection during the invalidation phase.

Attachments