有人知道为什么它不起作用吗?
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. 06/04/2017 14:11:24.732 ERROR [main] - org.springframework.boot.SpringApplication: Application startup failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: At least one JPA metamodel must be present! at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:742) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) at com.cadit.web.WebApplicationAware.main(WebApplicationAware.java:19) Caused by: java.lang.IllegalArgumentException: At least one JPA metamodel must be present! at org.springframework.util.Assert.notEmpty(Assert.java:277) at org.springframework.data.jpa.mapping.JpaMetamodelMappingContext.<init>(JpaMetamodelMappingContext.java:52) at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:71) at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:26) at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:134) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ... 16 common frames omitted
我在定义实体com.cadit.entities:
com.cadit.entities
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="TEST") public class GenericBeans implements BeanType, IEntity<Long> { /** * */ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = "TEST_PAID") protected Long id; @Column(name = "SOCIETA") private String SocietaCod; @Column(name = "CONTO_INTERMEDIARIO") private String contoInt; @Column(name = "TIPO_OPERAZIONE") private String tipoOpe; public GenericBeans(String societaCod, String contoInt, String tipoOpe) { SocietaCod = societaCod; this.contoInt = contoInt; this.tipoOpe = tipoOpe; } public GenericBeans() { } public String getSocietaCod() { return SocietaCod; } public void setSocietaCod(String societaCod) { SocietaCod = societaCod; } public String getContoInt() { return contoInt; } public void setContoInt(String contoInt) { this.contoInt = contoInt; } public String getTipoOpe() { return tipoOpe; } public void setTipoOpe(String tipoOpe) { this.tipoOpe = tipoOpe; } @Override public String toString() { return "CSV [SocietaCod=" + SocietaCod + ", contoInt=" + contoInt + ", tipoOpe=" + tipoOpe + "]"; } @Override public Long getId() { return this.id; } @Override public void setId(Long id) { this.id=id; } }
我datasource为spring定义了入口定义:
datasource
import org.apache.log4j.Logger; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @ComponentScan @EntityScan("com.cadit.entities") //@EnableJpaRepositories("com.cadit.entities") @EnableTransactionManagement @PropertySource("classpath:db-config.properties") public class DbAutoConfiguration { static final Logger logger = Logger.getLogger(DbAutoConfiguration.class); public DbAutoConfiguration() { } @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource(){ //DataSource ds =new EmbeddedDatabaseBuilder().addScript("classpath:sql/schema.sql").addScript("classpath:testdb/data.sql").build(); DataSourceBuilder ds = DataSourceBuilder.create(); logger.info("dataSource = " + ds); return ds.build(); } }
我的db-config.properties是:
db-config.properties
spring.jpa.hibernate.ddl-auto: validate spring.jpa.hibernate.naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy #spring.jpa.database: SQL spring.jpa.show-sql: true spring.datasource.driverClassName=net.sourceforge.jtds.jdbc.Driver spring.datasource.url=jdbc:jtds:sqlserver://localhost:1433;databaseName=example spring.datasource.username=xxx spring.datasource.password=xxx
IEntity 是:
IEntity
public interface IEntity <I extends Serializable> extends Serializable{ /** * Property rappresenta la primary key. */ String P_ID = "id"; /** * restituisce la primary key * @return */ I getId(); /** * imposta la primary key * @param id */ void setId(I id); }
我尝试使用CrudRepositoryspring的接口将CSV文件写入数据库:
CrudRepository
import java.io.File; import java.util.Collections; import java.util.LinkedList; import java.util.List; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.data.repository.CrudRepository; import com.cadit.entities.GenericBeans; import com.csvreader.CsvReader; public class CsvReaders { static final Logger logger = Logger.getLogger(CsvReader.class); @Autowired public CrudRepository<GenericBeans,Long> _entitymanager; public List loadDataFromCsv(String fileName) { try { File file = new ClassPathResource(fileName).getFile(); CsvReader csv = new CsvReader(file.getAbsoluteFile().getPath(),';'); csv.readHeaders(); List l = new LinkedList(); GenericBeans b = new GenericBeans (); while (csv.readRecord()) { b.setSocietaCod(csv.get(0)); b.setContoInt(csv.get(1)); b.setTipoOpe(csv.get(2)); _entitymanager.save(b); //persist on db l.add(b); b = new GenericBeans(); } b=null; return l; } catch (Exception e) { logger.error("Error occurred while loading object list from file " + fileName, e); return Collections.emptyList(); } } }
我不使用main类,而是使用扩展的类,SpringBootServletInitializer因为我想在单独的tomcat和Tomcat安装上将其作为WAR应用程序运行
main
SpringBootServletInitializer
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages={"com.cadit.entities","com.cadit.beans"}) @EnableAutoConfiguration public class WebApplicationAware extends SpringBootServletInitializer { private static Class<WebApplicationAware> applicationClass = WebApplicationAware.class; public static void main(String[] args) { SpringApplication.run(applicationClass, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(applicationClass); } }
所有属性文件都在类路径资源中,因为它是一个Maven项目。
pom.xml:
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.springframework</groupId> <artifactId>xxxx</artifactId> <version>0.1.0</version> <packaging>war</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.jayway.jsonpath</groupId> <artifactId>json-path</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>1.11.1.RELEASE</version> </dependency> <dependency> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> <version>1.0.2</version> </dependency> <!-- altre dipendenze non spring --> <!-- https://mvnrepository.com/artifact/net.sourceforge.javacsv/javacsv --> <dependency> <groupId>net.sourceforge.javacsv</groupId> <artifactId>javacsv</artifactId> <version>2.0</version> </dependency> <!-- per jpa solo se si usa il Tomcat embedded --> <dependency> <groupId>net.sourceforge.jtds</groupId> <artifactId>jtds</artifactId> <version>1.3.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <!-- end --> <!-- dipendenze logback --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.5</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.5</version> <scope>runtime</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> <scope>compile</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.1.7</version> </dependency> <!-- fine dip logback --> </dependencies> <properties> <start-class>hello.WebApplicationAware</start-class> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build> <repositories> <repository> <id>spring-releases</id> <url>https://repo.spring.io/libs-release</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-releases</id> <url>https://repo.spring.io/libs-release</url> </pluginRepository> </pluginRepositories> </project>
有什么问题,为什么在运行WebApplicationAware类时找不到JPA实体?
Spring找不到任何JPA实体,因此没有创建JPA元模型,这就是您要面对异常的原因。
造成此问题的原因可能是您的类路径上的persistence-api版本错误。
您正在使用
<dependency> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> <version>1.0.2</version> </dependency>
但我很确定您的spring版本使用的是persistence-api版本2。
可能是您正在使用版本1中的@Entity注释吗?在运行时,spring使用版本2,并且仅使用版本2中的@Entity搜索实体!
删除依赖项
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>1.11.1.RELEASE</version> </dependency>
而是添加
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
这将为您提供正确版本的所有JPA依赖项。