Skip to content

Partially populated PersistentEntity instances not properly removed from cache (1st nesting level edge case) #2329

Closed
@tomspendier

Description

@tomspendier

This bug relates to #2000 where it has been overlooked to also cover the following edge case within the fix (@odrotbohm FYI):

The bug was supposed to get (entirely) fixed in #2000 by cleaning up the cache (AbstractMappingContext#persistentEntities) on any kind of RuntimeException (instead of originally only MappingException, see the already fixed version:
https://github.com/spring-projects/spring-data-commons/blob/2.2.0.RC3/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java#L383

However, this doesn't cover the edge case when an Exception is thrown outside of the inner try block in AbstractMappingContext#addPersistentEntity().
As it turned out we ran into a TypeNotPresentException when invoking BeanUtils.getPropertyDescriptors(type)

As AbstractMappingContext#addPersistentEntity() is invoked recursively to traverse the whole object tree of the persistent entity, the fix applied in #2000 doesn't clean up the cache when an Exception is thrown where the traversal is still on the first nesting level of the persistent entity.

How to fix it:
To also cover this case the outer try block should get catched by a RuntimeException as well (currently only BeansException is catched) - so to cover also a TypeNotPresentException. In addition this catch block needs to also clear the cache with
persistentEntities.remove(typeInformation) before rethrowing.

I have created a reproduction covering this edge case (where documents get wrongfully inserted to MongoDB - in the same way corrupted as documented in #2000). Applying the before mentioned fix solved the issue. Unfortunately our reproduction includes many dependencies and the fix can also not get property unit tested without performing a refactoring of AbstractMappingContext.

Applying this fix essentially makes the inner catch block in AbstractMappingContext#addPersistentEntity() obsolete.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions