3030 * @author Emmanuel Bernard
3131 */
3232public class HibernateTraversableResolver implements TraversableResolver {
33- private Set <String > associations ;
33+ private final ConcurrentHashMap < Class <?>, Set <String >> associationsPerEntityClass = new ConcurrentHashMap <>() ;
3434
35- public HibernateTraversableResolver (
36- EntityPersister persister ,
37- ConcurrentHashMap <EntityPersister , Set <String >> associationsPerEntityPersister ,
38- SessionFactoryImplementor factory ) {
39- associations = associationsPerEntityPersister .get ( persister );
40- if ( associations == null ) {
41- associations = new HashSet <>();
42- addAssociationsToTheSetForAllProperties ( persister .getPropertyNames (), persister .getPropertyTypes (), "" , factory );
43- associationsPerEntityPersister .put ( persister , associations );
35+ public void addPersisterIfNecessary (EntityPersister persister , SessionFactoryImplementor factory ) {
36+ Class <?> javaTypeClass = persister .getEntityMappingType ().getMappedJavaType ().getJavaTypeClass ();
37+ if ( !associationsPerEntityClass .containsKey ( javaTypeClass ) ) {
38+ Set <String > associations = new HashSet <>();
39+ addAssociationsToTheSetForAllProperties ( persister .getPropertyNames (), persister .getPropertyTypes (), "" , factory , associations );
40+ associationsPerEntityClass .put ( javaTypeClass , associations );
4441 }
4542 }
4643
47- private void addAssociationsToTheSetForAllProperties (
48- String [] names , Type [] types , String prefix , SessionFactoryImplementor factory ) {
44+ private static void addAssociationsToTheSetForAllProperties (
45+ String [] names , Type [] types , String prefix , SessionFactoryImplementor factory , Set < String > associations ) {
4946 final int length = names .length ;
5047 for ( int index = 0 ; index < length ; index ++ ) {
51- addAssociationsToTheSetForOneProperty ( names [index ], types [index ], prefix , factory );
48+ addAssociationsToTheSetForOneProperty ( names [index ], types [index ], prefix , factory , associations );
5249 }
5350 }
5451
55- private void addAssociationsToTheSetForOneProperty (
56- String name , Type type , String prefix , SessionFactoryImplementor factory ) {
52+ private static void addAssociationsToTheSetForOneProperty (
53+ String name , Type type , String prefix , SessionFactoryImplementor factory , Set < String > associations ) {
5754 if ( type instanceof CollectionType collectionType ) {
58- addAssociationsToTheSetForOneProperty ( name , collectionType .getElementType ( factory ), prefix , factory );
55+ addAssociationsToTheSetForOneProperty ( name , collectionType .getElementType ( factory ), prefix , factory , associations );
5956 }
6057 //ToOne association
6158 else if ( type instanceof EntityType || type instanceof AnyType ) {
@@ -66,7 +63,8 @@ else if ( type instanceof ComponentType componentType ) {
6663 componentType .getPropertyNames (),
6764 componentType .getSubtypes (),
6865 ( prefix .isEmpty () ? name : prefix + name ) + '.' ,
69- factory
66+ factory ,
67+ associations
7068 );
7169 }
7270 }
@@ -102,6 +100,6 @@ public boolean isCascadable(Object traversableObject,
102100 Class <?> rootBeanType ,
103101 Path pathToTraversableObject ,
104102 ElementType elementType ) {
105- return !associations .contains ( getStringBasedPath ( traversableProperty , pathToTraversableObject ) );
103+ return !associationsPerEntityClass . getOrDefault ( rootBeanType , Set . of () ) .contains ( getStringBasedPath ( traversableProperty , pathToTraversableObject ) );
106104 }
107105}
0 commit comments