[英]Spring Boot NOT to make JPA database connection on statup
I have a Spring Boot + Groovy application that requires the Database Connection to be made per-session or per-tenant basis. 我有一个Spring Boot + Groovy应用程序,它要求按会话或按租户建立数据库连接。 When implementing the solution using Hibernate only it works, however when adding spring-boot-starter-data-jpa and switching to JPA a database connection is attempted on start up which fails because there is no connection settings defined yet. 当使用Hibernate实现解决方案时,它只能工作,但是当添加spring-boot-starter-data-jpa并切换到JPA时,尝试在启动数据库连接,但由于尚未定义连接设置而失败。
I have a gradle dependencies block that looks like this: 我有一个gradle依赖项块,看起来像这样:
dependencies {
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.boot:spring-boot-starter-data-jpa"
compile "org.codehaus.groovy:groovy-all:2.3.3"
compile "org.springframework:spring-core:${springVersion}"
compile "org.springframework:spring-webmvc:${springVersion}"
compile "org.springframework:spring-orm:${springVersion}"
compile "org.springframework:spring-aop:${springVersion}"
compile "org.springframework:spring-context-support:${springVersion}"
compile "org.hibernate:hibernate-entitymanager:${hibernateVersion}"
compile "com.oracle:ojdbc7:12.1.0.1"
compile "org.apache.commons:commons-dbcp2:2.0.1"
compile "cglib:cglib:3.1"
...
}
And my Application.groovy looks like this: 我的Application.groovy看起来像这样:
@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableTransactionManagement
class Application
{
final Logger aLog = Logger.getLogger(Application.class)
@Autowired
DatabaseSettings dbSettings
@Bean(destroyMethod="close")
@Lazy
public DataSource dataSource()
{
aLog.info ">>>>>>>>>>>>> CREATING DATA SOURCE <<<<<<<<<<<<<<<"
new BasicDataSource(driverClassName: dbSettings.driverClassName,
url: dbSettings.dbUrl, username: dbSettings.dbUser, password: dbSettings.dbPass,
maxTotal: 10, maxWaitMillis: 10000, maxIdle:10, defaultAutoCommit:false)
}
@Bean
@Lazy
public LocalContainerEntityManagerFactoryBean entityManagerFactory()
{
Properties hqlProps = ['hibernate.dialect': this.dbSettings.dialect, 'hibernate.temp.use_jdbc_metadata_defaults': false,
'hibernate.show_sql': this.dbSettings.showSql, 'hibernate.format_sql': this.dbSettings.formatSql,
'hibernate.use_sql_comments': this.dbSettings.useSqlComments] as Properties
aLog.info ">>>>>>>>>>>>> CREATING ENTITY MANAGER FACTORY <<<<<<<<<<<<<<<"
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean()
em.setDataSource(dataSource())
em.setPackagesToScan(this.dbSettings.getPackagesToScan())
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter())
em.setJpaProperties(hqlProps)
em
}
@Bean
@Lazy
public JpaTransactionManager transactionManager()
{
aLog.info ">>>>>>>>>>>>> CREATING TRANSACTION MANAGER <<<<<<<<<<<<<<<"
new JpaTransactionManager(entityManagerFactory: entityManagerFactory().getObject())
}
static void main(args) throws Exception
{
ApplicationContext appCtx = SpringApplication.run(Application.class, args)
}
}
I have removed the Scopes configuration for simplicity. 为了简单起见,我删除了Scopes配置。
The point is that all relevant Beans are annotated as @Lazy, however at start up I see the messages regarding the Data Source and Entity Manager being created. 关键是所有相关的Bean都标注为@Lazy,但是在启动时,我看到有关正在创建的数据源和实体管理器的消息。
Debugging the code looks like at some point HibernateJpaAutoConfigurer is called and this class have @Autowired the DataSource in thus causing the instantiation of these beans on start up. 调试代码看起来像在某个时候调用了HibernateJpaAutoConfigurer,并且此类已经@Autowired了DataSource,从而导致这些bean在启动时实例化。
My question is: How can I prevent Spring Boot to attempt a Database Connection on start up? 我的问题是:如何防止Spring Boot在启动时尝试进行数据库连接?
Thanks in advance 提前致谢
I think I found a work around: 我想我找到了一种解决方法:
Looking at spring-boot-starte-data-jpa's pom.xml I found that it depends on spring-data-jpa, so I decided to replace the starter-data-jpa with just spring-data-jpa with partial results. 通过查看spring-boot-starte-data-jpa的pom.xml,我发现它依赖于spring-data-jpa,因此我决定仅将springer-data-jpa替换为starter-data-jpa,并得到部分结果。 Still I couldn't get session scopes or custom scopes to delay the initialization of components, it wouldn't even compile actually. 仍然我无法获得会话作用域或自定义作用域来延迟组件的初始化,它甚至无法实际编译。 So in order to get everything to work nice I needed to all aspectjweaver too. 因此,为了使一切正常工作,我也需要所有aspectjweaver。
So now my dependencies look like: 所以现在我的依赖项看起来像:
dependencies {
compile "org.springframework.boot:spring-boot-starter-web"
//
compile "org.springframework.data:spring-data-jpa:1.7.1.RELEASE"
compile "org.aspectj:aspectjweaver:1.8.4"
compile "org.codehaus.groovy:groovy-all:2.3.3"
... }
So, if now I annotate DataSource creation with @Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS) or even with a Custom Scope, the instantiation happens after the startup process, as expected. 因此,如果现在我使用@Scope(value =“ session”,proxyMode = ScopedProxyMode.TARGET_CLASS或什至使用Custom Scope注释数据源的创建,则实例化将在启动过程之后如期进行。
However it feels like defeating the purpose of using SpringBoot, I still think there should be a way to configure SpringBoot in such a way that I can achieve same results. 但是,这感觉像击败了使用SpringBoot的目的,我仍然认为应该有一种方法可以配置SpringBoot,使我可以达到相同的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.