【问题标题】:Use EntityManager in Springboot在 Spring Boot 中使用 EntityManager
【发布时间】:2018-02-12 12:29:53
【问题描述】:

我想在SpringBoot 中使用EntityManager

应用程序

@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();
    }    
}

邮件配置

@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;
    }

}

邮件服务

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

我尝试实现以下https://github.com/snicoll-demos/demo-multi-entity-managers/blob/master/src/main/java/demo/order/OrderConfig.java,但我的 SpringBoot 立即停止,没有抛出任何异常。如果我删除 MailConfig,Springboot 可以启动。有什么问题 ?我走对了吗?

【问题讨论】:

  • 你为什么要自己配置所有东西,而不是使用 Spring 配置。因此,基本上你所有的spring.datasourcespring.jpa 属性都是无用的。我会说使用框架而不是围绕它工作。
  • @M.Deinum 我应该改变什么才能在 mailService 中使用 EntityManager ?
  • 删除您的MailConfig,从您的应用程序类中删除@EnableJpaRepositories@EnableAspectJAutoProxy@Configuration。 Spring Boot 已经为您完成了所有这些工作。
  • @M.Deinum 完成。由于没有persistenceUnit,我怎么能添加EM?
  • 为什么?使用repository.save

标签: java spring jpa spring-boot


【解决方案1】:

我认为你没有设置数据源的值。您需要在 application.properties 中设置“app.order.jpa”和“app.order.datasource”属性以使示例正常运行。

关于配置属性你可以在这里阅读:

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

请看这里的例子:

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

【讨论】:

  • 是的,它会起作用的。您已经在 @ConfigurationProperties(prefix = "app.order.datasource") 中使用它们但没有设置它们。
  • 不明白>
  • 你可以参考这个链接stackoverflow.com/questions/26308035/…
【解决方案2】:

spring boot 中不需要 bean 配置,它在内部管理这种类型的配置。 您可以使用 JPA 的 EntityManagerFactory 类,如

@Autowired
 EntityManagerFactory emf;

【讨论】:

    【解决方案3】:

    正如 Mukesh Dharajiya 的回答所提供的:

    @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();
    
    }
    

    编辑:实际上你使用LocalContainerEntityManagerFactoryBean,我刚刚注意到,所以下面的信息可能不适用..

    在您的解决方案中,您尝试创建一个 bean 来覆盖 springboot 已经自动配置的 entityManagerFactory。

    我对此不是 100% 确定,但我相信您需要这样做:

    1. 排除自动配置(@EnableJpaRepositories 在配置 jpa 之前可能无法工作):
    @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. (也许?- 未测试)设置 spring.main.allow-bean-definition-overriding=true 或命名 bean,并在属性中使用 @Qualified 自动装配它,以便您可以覆盖现有的工厂 bean。

    【讨论】:

      猜你喜欢
      • 2020-03-16
      • 1970-01-01
      • 2016-01-09
      • 2018-09-21
      • 2014-12-13
      • 2019-07-21
      • 2015-08-11
      • 2019-10-21
      • 2015-11-08
      相关资源
      最近更新 更多