John Joe
John Joe

Reputation: 12803

Use EntityManager in Springboot

I want to use EntityManager in SpringBoot.

Application

@Configuration
@EnableRetry // To enable Spring retry
@EnableJpaRepositories
@EnableAspectJAutoProxy(proxyTargetClass=true)
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }    
}

MailConfig

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "mailEntityManager",
        transactionManagerRef = "mailTransactionManager",
        basePackageClasses = MmcMonitoringLog.class)

public class MailConfig {

    @Autowired(required = false)
    private PersistenceUnitManager persistenceUnitManager;

    @Bean
    @ConfigurationProperties("app.order.jpa")
    public JpaProperties orderJpaProperties() {
        return new JpaProperties();
    }

    @Bean
    @ConfigurationProperties(prefix = "app.order.datasource")
    public DataSource orderDataSource() {
        return (DataSource) DataSourceBuilder.create().type(DataSource.class).build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean orderEntityManager(
            JpaProperties orderJpaProperties) {
        EntityManagerFactoryBuilder builder = createEntityManagerFactoryBuilder(orderJpaProperties);
        return builder
                .dataSource(orderDataSource())
                .packages(MmcMonitoringLog.class)
                .persistenceUnit("ordersDs")
                .build();
    }

    @Bean
    public JpaTransactionManager orderTransactionManager(EntityManagerFactory orderEntityManager) {
        return new JpaTransactionManager(orderEntityManager);
    }

    private EntityManagerFactoryBuilder createEntityManagerFactoryBuilder(JpaProperties customerJpaProperties) {
        JpaVendorAdapter jpaVendorAdapter = createJpaVendorAdapter(customerJpaProperties);
        return new EntityManagerFactoryBuilder(jpaVendorAdapter,
                customerJpaProperties.getProperties(), this.persistenceUnitManager);
    }

    private JpaVendorAdapter createJpaVendorAdapter(JpaProperties jpaProperties) {
        AbstractJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setShowSql(jpaProperties.isShowSql());
        adapter.setDatabase(jpaProperties.getDatabase());
        adapter.setDatabasePlatform(jpaProperties.getDatabasePlatform());
        adapter.setGenerateDdl(jpaProperties.isGenerateDdl());
        return adapter;
    }

}

MailService

public class MailService extends TaskAdaptor implements Runnable {

    @Autowired
    MmcMonitoringLogRepository mmcMonitoringLogRepository;

    @Override
    public void run() {

   List<MmcMonitoringLog> list = mmcMonitoringLogRepository.findByMonitoringLog("1");
   ......
}

appication.properties

spring.datasource.url= jdbc:mysql://xxxx:3306/adb?autoReconnect=true&useSSL=false
spring.datasource.username=xxx
spring.datasource.password=xxx


# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = none

I try to implement following https://github.com/snicoll-demos/demo-multi-entity-managers/blob/master/src/main/java/demo/order/OrderConfig.java, but my SpringBoot stop straight away without throwing any exception. If I remove MailConfig, Springboot can start. What's the problem ? Am I on the right path ?

Upvotes: 5

Views: 13190

Answers (3)

Christian Meyer
Christian Meyer

Reputation: 625

As Mukesh Dharajiya's answer provides:

@Autowired EntityManagerFactory factory;

private manageEntities(){

    // javadoc: Create a new application-managed EntityManager. 
    // This method returns a new EntityManager instance each time it is invoked. 
    EntityManager em = emFactory.createEntityManager();

}

Edit: Actually your using LocalContainerEntityManagerFactoryBean, I just noticed, so the info below may not apply..

In your solution you trying to create a bean that would override the entityManagerFactory that springboot has already autoconfigured.

I'm not 100% sure about this, but I believe to do that you would need to either:

  1. Exclude the autoconfiguration (@EnableJpaRepositories may not work until jpa is configured):
@SpringBootApplication(exclude = {
        DataSourceAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class})
public class Application {
    public static void main(String[] args) {
        // Now spring will not autoconfigure jpa for you, so there should not already be a factory bean
        // If you do this you will need to implement all of the steps missed in the autoconfig to get jpa functioning again
        SpringApplication.run(Application.class, args);
    }
}
  1. (maybe? - did not test) Set spring.main.allow-bean-definition-overriding=true or name the bean, and autowire it using @Qualified, in properties so that you can override the existing factory bean.

Upvotes: 1

Mukesh Dharajiya
Mukesh Dharajiya

Reputation: 21

You do not need bean configuration in spring boot, it internally manages this type of configuration. You can use the EntityManagerFactory class of JPA like

@Autowired
 EntityManagerFactory emf;

Upvotes: 2

Abhilekh Singh
Abhilekh Singh

Reputation: 2943

I think you have not set the values of datasource. You will need to set "app.order.jpa" and "app.order.datasource" properties in application.properties to get the example working.

About configuration properties you can read here:

http://www.baeldung.com/configuration-properties-in-spring-boot

See the example here:

https://github.com/snicoll-demos/demo-multi-entity-managers/blob/master/src/main/resources/application.properties

app.customer.datasource.url=jdbc:h2:mem:customers;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
app.customer.datasource.driver-class-name=org.h2.Driver
app.customer.jpa.properties.hibernate.hbm2ddl.auto=create

app.order.datasource.url=jdbc:h2:mem:orders;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
app.order.datasource.driver-class-name=org.h2.Driver
app.order.jpa.properties.hibernate.hbm2ddl.auto=create

Upvotes: 4

Related Questions