Daimon
Daimon

Reputation: 375

Spring boot inject EntityManagerFactory in configuration class

I'm using spring boot and i want to integrate spring with hibernate. I want to make a Session Factory bean for further using. But I can't autowire EntityManagerFactory, I can't autowire it only in the configuration class, in other classes it works. Can you help, please?

Configuration class

package kz.training.springrest.configuration;

@Configuration
@EnableTransactionManagement
public class DatabaseConfiguration {

    @Autowired
    private EntityManagerFactory entityManagerFactory;

    @Bean
    public SessionFactory getSessionFactory() {
        if (entityManagerFactory.unwrap(SessionFactory.class) == null) {
            throw new NullPointerException("factory is not a hibernate factory");
        }
        return entityManagerFactory.unwrap(SessionFactory.class);
    }
}

dependencies

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.2.2</version>
        </dependency
    </dependencies>

Upvotes: 1

Views: 12004

Answers (2)

Naros
Naros

Reputation: 21153

I'm not exactly sure why you want to expose both beans because as @chrylis points out, you can easily unwrap the EMF into a SF where needed.

// Some spring component
@Component
public class MyFancyComponent {
  @PersistenceContext
  private EntityManager entityManager;

  public void doSomethingFancy() {
    // public SessionFactory API
    final SessionFactory sf = entityManager
         .unwrap( Session.class ).getFactory();

    // public SessionFactoryImplementor SPI
    final SessionFactoryImplementor sfi = entityManager
         .unwrap( SessionImplementor.class ).getFactory();
  }
}

Upvotes: 0

Chris
Chris

Reputation: 449

When you say

But I can't autowire EntityManagerFactory

does it fail to compile or throw an exception at run-time? If the latter, what does the stack-trace say?

One possible solution/work around might be to inject an em into the configuration instead of the em factory, using the @PersistenceContext annotation:

@Configuration
@EnableTransactionManagement
public class DatabaseConfiguration {

    @PersistenceContext
    private EntityManager entityManager;

    @Bean
    public SessionFactory getSessionFactory() {
        // no need to check for null here because if the unwrap fails, it will do
        // so by throwing a PersistenceException rather than returning null.
        return entityManager.unwrap( Session.class ).getFactory();
    }
}

Upvotes: 3

Related Questions