簡體   English   中英

Spring 4 @Configuration設置JPA的命令

[英]Spring 4 @Configuration order for setting up JPA

我在Spring 4上具有有效的Jersey 2.2應用程序,其中使用Eclipselink作為JPA實現。

應用程序的配置如下所示:

@Configuration
@ComponentScan(value = "com.nws.vedica", lazyInit = true)
@PropertySource({"classpath:swagger.properties", "classpath:vedica.properties"})
@ApplicationPath("/api")

public class VedicaConfig extends ResourceConfig {

public VedicaConfig() {
    packages("com.nws.vedica");
    property(ServletProperties.FILTER_FORWARD_ON_404, true);
    register(MultiPartFeature.class);
    register(JacksonFeature.class);
    register(ValidationFeature.class);
    register(ValidationConfigurationContextResolver.class);
    register(PropertySourcesPlaceholderConfigurer.class);

    register(ApiListingResource.class);
    register(SwaggerSerializers.class);
}
}

JPA配置類:

@Configuration
@EnableTransactionManagement
public class JPAConfig {

private Map<String, String> properties;

@Value("${db.url}")
private String dbConnectionURL;

@Value("${db.user}")
private String dbUser;

@Value("${db.pass}")
private String dbPassword;

@PostConstruct
public void init() {
    properties = new HashMap<>();
    properties.put("javax.persistence.jdbc.url", dbConnectionURL);
    properties.put("javax.persistence.jdbc.user", dbUser);
    properties.put("javax.persistence.jdbc.password", dbPassword);
    properties.put("javax.persistence.jdbc.driver", "org.postgresql.Driver");
    properties.put("javax.persistence.target-database", "PostgreSQL");
    properties.put("eclipselink.cache.shared.default", "true");
    properties.put("eclipselink.ddl-generation", "none");
    properties.put("eclipselink.logging.level.sql", "fine");
    properties.put("eclipselink.logging.parameters", "true");
    properties.put("eclipselink.deploy-on-startup", "true");
    properties.put("eclipselink.ddl-generation.output-mode", "database");
}

@Bean
public JpaTransactionManager jpaTransMan(){
    JpaTransactionManager jtManager = new JpaTransactionManager(
            getEntityManagerFactoryBean().getObject());
    return jtManager;
}

@Bean
public LocalEntityManagerFactoryBean getEntityManagerFactoryBean() {
    LocalEntityManagerFactoryBean lemfb = new LocalEntityManagerFactoryBean();
    lemfb.setJpaPropertyMap(properties);
    lemfb.setPersistenceUnitName(Vedantas.PU_NAME);
    lemfb.setPersistenceProviderClass(org.eclipse.persistence.jpa.PersistenceProvider.class);
    return lemfb;
}
}

現在,這很好。 啟動時,將首先加載應用程序配置類,以便注冊“ PropertySourcesPlaceholderConfigurer”,並且我可以在jpa配置類中使用@Value(...)批注,該批注將作為SECOND加載。

今天,我已經決定將Hibernate替換為Eclipselink,因為它具有審核功能。

我在pom.xml中添加了:

<dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.2.9.Final</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.1-api</artifactId>
        <version>1.0.0.Final</version>
    </dependency>


    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-envers</artifactId>
        <version>5.2.9.Final</version>
    </dependency>

並將jpa config類更改為:

@Configuration
@EnableTransactionManagement
public class JPAConfig {

private Map<String, String> properties;

@Value("${db.url}")
private String dbConnectionURL;

@Value("${db.user}")
private String dbUser;

@Value("${db.pass}")
private String dbPassword;

@PostConstruct
public void init() {
    properties = new HashMap<>();
    properties.put("javax.persistence.jdbc.url", dbConnectionURL);
    properties.put("javax.persistence.jdbc.user", dbUser);
    properties.put("javax.persistence.jdbc.password", dbPassword);
    properties.put("javax.persistence.jdbc.driver", "org.postgresql.Driver");
    properties.put("javax.persistence.target-database", "PostgreSQL");
    properties.put("hibernate.hbm2ddl.auto", "create");
    properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
}

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(emf);

    return transactionManager;
}

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
    return new PersistenceExceptionTranslationPostProcessor();
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setPackagesToScan(new String[]{"com.nws.vedica.model"});
    em.setPersistenceUnitName(Vedantas.PU_NAME);

    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    em.setJpaPropertyMap(properties);

    return em;
}
}

現在,令我驚訝的是,應用程序配置和jpa config類的加載/執行順序已互換,因此先加載jpa config,然后第二次進行應用程序配置,這會導致在jpa config類加載時未注冊“ PropertySourcesPlaceholderConfigurer”,因此@value注釋不工作!

我真的很想知道為什么會這樣? 為什么要交換執行順序?

我知道我可以通過不將jpa config calass聲明為@Configuration來欺騙它,而只是將其注冊為bean,例如:

    @Bean
    public JPAConfig setUpJpaHibernate() {
        return new JPAConfig();
    }

但是,我想知道,這里正在發生什么?

順序更改的原因是在JPAConfig類中引入了PersistenceExceptionTranslationPostProcessor bean。

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
    return new PersistenceExceptionTranslationPostProcessor();
}

將其移至VedicaConfig類可以為我解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM