Affects: 5.3.20+
Before 5.3.20 the following code worked as intended (note the use of <util:property-path path="abcEntityManagerFactory.sessionFactory" />
: sessionFactory
property is accessible in abcEntityManagerFactory
bean)
<bean id="abcEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" lazy-init="true">
... providing the relevant properties ...
</bean>
<bean id="abcHibernateStatisticsMBeanExporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="server" ref="mbeanServer" />
<property name="beans">
<map>
<entry key="org.example:name=abcHibernateStatistics">
<bean class="org.hibernate.stat.internal.StatisticsImpl">
<constructor-arg name="sessionFactory">
<util:property-path path="abcEntityManagerFactory.sessionFactory" />
</constructor-arg>
<property name="statisticsEnabled" value="true"/>
</bean>
</entry>
</map>
</property>
</bean>
After upgrading from Spring 5.3.18 to 5.3.23 the system fails on startup with the following exception:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'util:property-path#61ffe4cf': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.NotReadablePropertyException: Invalid property 'sessionFactory' of bean class [com.sun.proxy.$Proxy231]: Bean property 'sessionFactory' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:176)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:135)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:377)
... 72 more
Caused by: org.springframework.beans.NotReadablePropertyException: Invalid property 'sessionFactory' of bean class [com.sun.proxy.$Proxy231]: Bean property 'sessionFactory' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:627)
at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:617)
at org.springframework.beans.factory.config.PropertyPathFactoryBean.getObject(PropertyPathFactoryBean.java:223)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:169)
... 74 more
This is caused by #28445 which is a part of 5.3.20.
SessionFactory
property is no longer accessible: its type is org.hibernate.engine.spi.SessionFactoryImplementor
which is AutoCloseable
. And according to the new isInvalidReadOnlyPropertyType
method added in #28445 it is filtered out of the bean's PropertyDescriptors
.
Comment From: jhoeller
I see your point, and there might be a way to fine-tune that rule towards accepting AutoCloseable property types on declaring classes that are AutoCloseable themselves.
That said, there are other ways to express such a dereference in configuration scenarios, e.g. using SpEL:
<constructor-arg name="sessionFactory" value="#{abcEntityManagerFactory.sessionFactory}"/>
Or alternatively, using an intermediate bean definition:
<constructor-arg name="sessionFactory">
<bean factory-bean="abcEntityManagerFactory" factory-method="getSessionFactory"/>
</constructor-arg>
I would generally recommend either of the two over a JavaBeans property for such purposes.