2014-08-27 70 views
1

我正在使用Spring數據JPA彈簧web應用程序最近春數據JPA配置

我在與persistanceConfiguration

@Configuration 
@EnableTransactionManagement 
@PropertySource({ "/resources/hibernate.properties" }) 
@EnableJpaRepositories(basePackages = "com.servmed.repositories") 

public class PersistenceConfig { 

    @Autowired 
    private Environment env; 


    Properties jpaProperties() { 
     return new Properties() { 
      { 
       setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); 
       setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); //allows Hibernate to generate SQL optimized for a particular relational database. 
       setProperty("hibernate.show_sql",env.getProperty("hibernate.show_sql")); 
      } 
     }; 
    } 

    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() 
    { 
     HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
     vendorAdapter.setGenerateDdl(true); 
     vendorAdapter.setShowSql(true); 

     LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 
     factory.setDataSource(dataSource()); 
     factory.setJpaVendorAdapter(vendorAdapter); 
     factory.setJpaProperties(jpaProperties()); 
     factory.setPackagesToScan("com.servmed.models"); 

     factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver()); 
     return factory; 
    } 

    @Bean 
    public PlatformTransactionManager transactionManager() 
    { 
     EntityManagerFactory factory = entityManagerFactory().getObject(); 
     return new JpaTransactionManager(factory); 
    } 

    @Bean 
    public HibernateExceptionTranslator hibernateExceptionTranslator(){ 
     return new HibernateExceptionTranslator(); 
    } 


    @Bean 
    public DataSource dataSource() { 
     BasicDataSource dataSource = new BasicDataSource(); 
     dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName")); 
     dataSource.setUrl(env.getProperty("jdbc.url")); 
     dataSource.setUsername(env.getProperty("jdbc.user")); 
     dataSource.setPassword(env.getProperty("jdbc.pass")); 

     return dataSource; 
    } 
} 

問題,這是我的pom.xml的

<dependencies> 
     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>3.8.1</version> 
      <scope>test</scope> 
     </dependency> 

     <!--Spring dependencies--> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-webmvc</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-core</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-web</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-context</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-aop</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-expression</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-orm</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-jdbc</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-dao</artifactId> 
      <version>2.0.8</version> 
     </dependency> 


     <!-- spring security--> 
     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-web</artifactId> 
      <version>${spring-security.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-core</artifactId> 
      <version>${spring-security.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-config</artifactId> 
      <version>${spring-security.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-taglibs</artifactId> 
      <version>${spring-security.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjweaver</artifactId> 
      <version>${aspectj.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjrt</artifactId> 
      <version>${aspectj.version}</version> 
     </dependency> 

     <!-- Spring Data JPA dependencies --> 
     <dependency> 
      <groupId>org.springframework.data</groupId> 
      <artifactId>spring-data-jpa</artifactId> 
      <version>1.6.1.RELEASE</version> 
     </dependency> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-entitymanager</artifactId> 
      <version>${hibernate.version}</version> 
     </dependency> 


     <!--com.mysema.querydsl dependencies--> 
     <dependency> 
      <groupId>com.mysema.querydsl</groupId> 
      <artifactId>querydsl-sql</artifactId> 
      <version>${com.mysema.querydsl.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>com.mysema.querydsl</groupId> 
      <artifactId>querydsl-jpa</artifactId> 
      <version>${com.mysema.querydsl.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>com.mysema.querydsl</groupId> 
      <artifactId>querydsl-core</artifactId> 
      <version>${com.mysema.querydsl.version}</version> 
     </dependency> 


     <!--Hibernate dependencies--> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-core</artifactId> 
      <version>${hibernate.version}</version> 
     </dependency> 

     <!--db--> 
     <dependency> 
      <groupId>mysql</groupId> 
      <artifactId>mysql-connector-java</artifactId> 
      <version>5.1.23</version> 
     </dependency> 
     <dependency> 
      <groupId>commons-dbcp</groupId> 
      <artifactId>commons-dbcp</artifactId> 
      <version>1.4</version> 
     </dependency> 

     <!--connection pool--> 
     <dependency> 
      <groupId>org.apache.tomcat</groupId> 
      <artifactId>tomcat-dbcp</artifactId> 
      <version>8.0.9</version> 
     </dependency> 


     <!--thymeleaf and servlet api--> 
     <dependency> 
      <groupId>org.thymeleaf</groupId> 
      <artifactId>thymeleaf-spring4</artifactId> 
      <version>2.1.2.RELEASE</version> 
     </dependency> 
     <dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>servlet-api</artifactId> 
      <version>2.5</version> 
     </dependency> 

    </dependencies> 
    <build> 
     <finalName>${project.artifactId}</finalName> 
    </build> 

它似乎並沒有爲我工作,我得到這個錯誤:

Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration.transactionAdvisor()] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionInterceptor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'transactionManager' is required 

有什麼想法爲什麼?

編輯

它似乎並不EntityManagerFactory的方法是否正確創造transactionManager在使用的豆,我曾與休眠同樣的問題(未創建SessionFactory的豆,並且不能在transactionManager的方法使用)

EDIT 2

我擺脫這個問題(這是因爲一個錯誤的屬性文件),但現在我Gey中另一個錯誤:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [com/servmed/configuration/PersistenceConfig.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory 

回答

2

這是我如何定義我的事務管理器:

@Bean 
    public Object transactionManager() { 
    return new org.springframework.orm.jpa.JpaTransactionManager(); 
    } 

,而不是調用entityFactory方法和,你也許應該把它注射:這將避免entityManagerFactory依賴注入的錯誤。

@Bean 
public PlatformTransactionManager transactionManager(EntityManagerFactory factory) 
{ 
    return new JpaTransactionManager(factory); 
} 

編輯

除了persistence.xmlafterPropertiesSet()setLoadTimeWeaver的號召,我們有相同的代碼。

@Bean 
public LocalContainerEntityManagerFactoryBean entityManagerFactory() 
{ 
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
    vendorAdapter.setGenerateDdl(true); 
    vendorAdapter.setShowSql(true); 

    Properties jpaProperties = new Properties(); 
    jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); 
    jpaProperties.put("hibernate.dialect"  , env.getProperty("hibernate.dialect")); 
    jpaProperties.put("hibernate.show_sql" , pgadenv.getProperty("hibernate.show_sql")); 

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 
    factory.setDataSource(dataSource()); 
    factory.setJpaVendorAdapter(vendorAdapter); 
    factory.setJpaProperties(jpaProperties); 
    factory.setPackagesToScan("com.servmed.models"); 

    // factory.afterPropertiesSet(); <-- why ? 
    // does it work without Weaving ? 
    factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver()); 
    return factory; 
} 

EDIT(2)

我沒有時間回答你,這裏是一個樣本persistence.xml

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.1" 
    xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
    <!-- transaction-type="JTA" --> 
    <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> 

    <!-- Your probably won't need it. --> 
    <!-- <class>com.servmed.models.YourClass</class> --> 
    <exclude-unlisted-classes>false</exclude-unlisted-classes> 
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode> 

    <properties> 
     <property name="javax.persistence.schema-generation.database.action"  value="none" /> 
     <property name="javax.persistence.schema-generation.scripts.action"  value="none" /> 
     <!-- <property name="javax.persistence.schema-generation.scripts.create-target" value="" /> --> 
     <!-- <property name="javax.persistence.schema-generation.scripts.drop-target" value=""/> --> 
    </properties> 
    </persistence-unit> 
</persistence> 

你可能不會需要列出類(如在評論的例子中),否則列出它們。

而且在Spring配置,添加:

factory.setPersistenceXmlLocation("classpath:META-INF/persistence.xml"); 
factory.setPersistenceUnitName("persistenceUnit"); 

不過,我開始認爲這可能是一個完全無關的問題。

+0

感謝您的答覆,但我仍然得到了同樣的錯誤,我嘗試添加'@ Autowied',但它seemes EntityManagerFactory的豆不能(甚至@Resource)進行檢測,任何想法,爲什麼? – Aissasa 2014-08-27 14:07:37

+0

你使用了一個persistence.xml嗎?如果是的話,你有'transaction-type =「RESOURCE_LOCAL」'?如果我沒有錯,其他事務類型(JTA)僅在使用JTA DataSource時有效 – NoDataFound 2014-08-27 14:42:57

+0

我使用的是xml-less配置,所以在我的項目中沒有xml – Aissasa 2014-08-27 14:52:56

0

@ Aissasa - 你可以使用類似的JPA配置類,你也不必有任何xm文件。

 Code ::: 

         import java.util.HashMap; 
         import java.util.Map; 
         import java.util.Properties; 
         import javax.persistence.EntityManagerFactory; 
         import javax.sql.DataSource; 
         import org.eclipse.persistence.config.BatchWriting; 
         import org.eclipse.persistence.config.PersistenceUnitProperties; 
         import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 
         import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration; 
         import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; 
         import org.springframework.context.annotation.Bean; 
         import org.springframework.context.annotation.Configuration; 
         import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 
         import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 
         import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter; 
         import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter; 
         import org.springframework.transaction.PlatformTransactionManager; 
         import org.springframework.transaction.annotation.EnableTransactionManagement; 
         import com.zaxxer.hikari.HikariConfig; 
         import com.zaxxer.hikari.HikariDataSource; 

         @Configuration 
         @EnableTransactionManagement 
         @EnableAutoConfiguration 
         @EnableJpaRepositories(basePackages = "com.subu") 
         public class JpaConfiguration extends JpaBaseConfiguration { 

          @Bean 
          public LocalContainerEntityManagerFactoryBean entityManagerFactory(final EntityManagerFactoryBuilder builder) { 
           final LocalContainerEntityManagerFactoryBean ret = 
             builder.dataSource(dataSource()) 
               .packages("com.subu") 
               .properties(jpaProperties()) 
               .persistenceUnit("com.subu") 
               .build(); 
           return ret; 
          } 

          @Bean 
          public DataSource dataSource() { 
           // In classpath from spring-boot-starter-web 
           final Properties props = new Properties(); 
           props.put("driverClassName", "com.mysql.jdbc.Driver"); 
           props.put("jdbcUrl", "jdbc:mysql://localhost:3306/master?createDatabaseIfNotExist=false"); 
           props.put("username", "root"); 
           props.put("password", "mysql"); 
           HikariConfig hc = new HikariConfig(props); 
           HikariDataSource ds = new HikariDataSource(hc); 
           return ds; 
          } 

          @Bean 
          public Map<String, String> jpaProperties() { 
           Map<String, String> props = new HashMap<>(); 
           props.put("eclipselink.weaving", "false"); 
           props.put("eclipselink.logging.level.sql", "FINE"); 
           props.put("eclipselink.logging.parameters", "true"); 
           props.put("javax.persistence.schema-generation.database.action", "create"); 
           //props.put("javax.persistence.sql-load-script-source", "sql/import.sql"); 
           return props; 
          } 
          @Bean 
          public PlatformTransactionManager transactionManager(EntityManagerFactory emf) { 
           final MultiTenantJpaTransactionManager transactionManager = new MultiTenantJpaTransactionManager(); 
           transactionManager.setEntityManagerFactory(emf); 
           return transactionManager; 
          } 

          @Override 
          protected AbstractJpaVendorAdapter createJpaVendorAdapter() { 
           return new EclipseLinkJpaVendorAdapter(); 
          } 



          @Override 
          protected Map<String, Object> getVendorProperties() { 
           final Map<String, Object> ret = new HashMap<>(); 
           ret.put(PersistenceUnitProperties.BATCH_WRITING, BatchWriting.JDBC); 
           return ret; 
          } 


         } 





         =================================================================================================================================== 





         import java.io.Serializable; 
         import javax.persistence.EntityManager; 
         import org.springframework.orm.jpa.EntityManagerHolder; 
         import org.springframework.orm.jpa.JpaTransactionManager; 
         import org.springframework.transaction.TransactionDefinition; 
         import org.springframework.transaction.support.TransactionSynchronizationManager; 

         public class MultiTenantJpaTransactionManager extends JpaTransactionManager { 

          @Override 
          protected void doBegin(final Object transaction, final TransactionDefinition definition) { 
           super.doBegin(transaction, definition); 
           final EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager 
             .getResource(getEntityManagerFactory()); 
           final EntityManager em = emHolder.getEntityManager(); 

          } 
         }