我最近正在使用Spring Data JPA开发一个Spring Web应用程序
我遇到了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中使用的bean,我遇到了与hibernate相同的问题(sessionFactory bean没有创建,也不能在transactionManager方法中使用)
编辑2
我摆脱了这个问题(这是因为一个错误的属性文件)但现在我发现了另一个错误:
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
答案 0 :(得分: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.xml
,afterPropertiesSet()
和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;
}
编辑(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");
然而,我开始认为这可能是一个完全不相关的问题。
答案 1 :(得分: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();
}
}