Solved: Bean property ‘configurationClass’ is not writable or has an invalid setter method

Every developer has those moments where a seemingly simple task turns into a head-scratching puzzle. This error, encountered while trying to configure a custom LocalSessionFactoryBean in Spring Boot, is a perfect example of a subtle type mismatch causing a cryptic failure.


The Scenario and the Error

The goal was to set up a custom SessionFactory bean using Spring’s LocalSessionFactoryBean. The initial, problematic configuration was:

@Configuration
public class HibernateConfig {
    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        // โ€ฆ set data source, hibernate properties โ€ฆ
        
        // This line caused the error!
        sessionFactory.setConfigurationClass(org.hibernate.cfg.Configuration.class); 
        
        return sessionFactory;
    }
}

This configuration resulted in the following exception upon application startup:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': 
Bean property 'configurationClass' is not writable or has an invalid setter method. 
Does the parameter type of the setter match the return type of the getter?

Understanding the Core Problem

The error message, “Bean property ‘configurationClass’ is not writable or has an invalid setter method,” is a classic Spring message indicating a type mismatch when the container attempts to apply property values using the JavaBeans convention.

The Setter’s Expectation

The property in question is defined in AbstractSessionFactoryBean (the parent of LocalSessionFactoryBean):

// From org.springframework.orm.hibernate5.AbstractSessionFactoryBean
@Nullable private Class<? extends Configuration> configurationClass; // The property type

public void setConfigurationClass(@Nullable Class<? extends Configuration> configurationClass) {
    this.configurationClass = configurationClass;
}

The setConfigurationClass method expects a Class object that is a subclass of org.hibernate.cfg.Configuration.

The Mistake: Confusing Instance vs. Type

The mistake was assuming that the method was missing or invalid. It turns out the error was in the usage:

  • Intention: The developer likely intended to use the default Hibernate Configuration or perhaps set configuration properties.
  • The Setter’s Role (setConfigurationClass): This method is for specifying a custom subclass of org.hibernate.cfg.Configuration for Spring to use when creating the actual configuration.
  • The Misleading Argument: The argument passed was org.hibernate.cfg.Configuration.class, which is syntactically a Class object, but it’s redundant, as this is the default class used by LocalSessionFactoryBean. The error may occur if the Spring container’s reflection mechanism doesn’t perfectly resolve the generic type Class<? extends Configuration>.

The core takeaway is: LocalSessionFactoryBean expects a Class type for setConfigurationClass, and an instance of Configuration for setConfiguration.


The Solution: Correct Configuration Methods

There are two correct approaches, depending on what you truly need to achieve:

Option 1: Providing a Configured Configuration Instance

If you need to programmatically build and provide a fully configured org.hibernate.cfg.Configuration instance, use setConfiguration(Configuration configuration):

import org.hibernate.cfg.Configuration; // Ensure this is org.hibernate.cfg.Configuration

// ... inside the @Bean method ...
// OPTION 2: If you want to provide an already instantiated Configuration object
Configuration hibernateConfiguration = new Configuration();
// Add specific properties and settings to the instance here...
sessionFactory.setConfiguration(hibernateConfiguration); 

Option 2: The Recommended Spring Boot Approach (Properties)

In most modern Spring/Hibernate applications, you typically let LocalSessionFactoryBean use its default Configuration class and provide settings using the dedicated setHibernateProperties method and setPackagesToScan. This is much cleaner and is usually what is required for granular control outside of Spring Boot’s automatic configuration.

@Configuration
public class HibernateConfig {
    @Bean
    public LocalSessionFactoryBean sessionFactory(/* inject DataSource dataSource */) {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        // sessionFactory.setDataSource(dataSource); 

        // Configure Hibernate properties directly:
        Properties hibernateProperties = new Properties();
        hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "update");
        hibernateProperties.setProperty("hibernate.show_sql", "true");
        // ... more properties ...
        
        // This is the correct way to set configuration settings
        sessionFactory.setHibernateProperties(hibernateProperties); 
        
        // Essential for Annotation-based entities
        sessionFactory.setPackagesToScan("com.ankurm.model"); 
        
        // No need to call setConfigurationClass or setConfiguration!
        return sessionFactory;
    }
}

The key to resolving the Bean property 'configurationClass' is not writable error is to avoid calling setConfigurationClass unless you genuinely have a custom subclass of org.hibernate.cfg.Configuration. For all other configuration needs, use setHibernateProperties or setConfiguration.

Frequently Asked Questions

Q1: When would I legitimately need to call setConfigurationClass()?

Only when you have a custom subclass of org.hibernate.cfg.Configuration that overrides internal Hibernate behaviour โ€” for example, a subclass that adds custom type mappings or interceptors at the configuration level. In that case, pass your class: sessionFactory.setConfigurationClass(MyCustomConfig.class). For all standard use cases, leave it unset and use setHibernateProperties instead.

Q2: Is this error related to Hibernate version compatibility?

Sometimes. In Spring 6 + Hibernate 6/7, the LocalSessionFactoryBean class is from the spring-orm module. If you are mixing a Spring 5 version of LocalSessionFactoryBean (which used javax.persistence) with Hibernate 7 (which uses jakarta.persistence), you will get class-loading failures. Ensure your spring-orm version matches your Spring Boot version.

Q3: Should I use LocalSessionFactoryBean or let Spring Boot auto-configure the SessionFactory?

For most Spring Boot applications, rely on Spring Boot’s auto-configuration (via spring-boot-starter-data-jpa). This auto-creates an EntityManagerFactory and exposes it as a SessionFactory if needed. Only use LocalSessionFactoryBean explicitly when you need the Hibernate-native Session API, multiple data sources, or configuration that Spring Boot’s auto-config cannot express through application.properties.

Q4: What is the difference between setConfiguration() and setHibernateProperties()?

setConfiguration(Configuration config) accepts a fully pre-built org.hibernate.cfg.Configuration instance that you have constructed and configured manually. setHibernateProperties(Properties props) is the standard declarative approach โ€” you pass a Properties map and Spring builds the configuration internally using those settings plus auto-discovered entities. For most applications, setHibernateProperties is simpler and less error-prone.

Q5: How do I configure multiple SessionFactories in the same Spring Boot app?

Define multiple LocalSessionFactoryBean beans, each with a distinct @Qualifier, pointing to different DataSource beans. Use setPackagesToScan to direct each factory to its own entity package, preventing cross-database entity scanning. In your repositories and services, inject the specific factory using @Qualifier("primarySessionFactory") or @Qualifier("secondarySessionFactory").

Conclusion

This error is a subtle type-mismatch caused by confusing setConfigurationClass(Class) โ€” which expects a subclass type reference โ€” with setConfiguration(Configuration) โ€” which expects an instance. In practice, most Spring Boot applications should not call either method; instead use setHibernateProperties for configuration values and setPackagesToScan for entity discovery, and let Spring’s LocalSessionFactoryBean handle the rest. Only reach for setConfigurationClass if you genuinely have a custom Configuration subclass.

Further Reading & Cross-References

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.