spring jpa - 必须至少存在一个 JPA 元模型* [英] spring jpa - At least one JPA metamodel must be present*

查看:26
本文介绍了spring jpa - 必须至少存在一个 JPA 元模型*的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人知道为什么它不起作用吗?

Anybody know why it doesn't work?

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 中定义了实体:

I defined entities in 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;     
    }

}

我为 spring 定义了我的 datasource 条目定义:

I definied my datasource entry definition for spring:

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 是:

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 是:

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);
}

我尝试使用 spring 的 CrudRepository 接口将 CSV 文件写入数据库:

I try to write CSV file to database using CrudRepository interface of spring:

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 应用程序

I DO NOT use main class but a class which extend SpringBootServletInitializer because i want to run it on both standalone tomcat and Tomcat installation as WAR application

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 项目.

All properties file are in classpath resources because it's a maven project.

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 实体?

What's the problem, why doesn't it find JPA entities when I run WebApplicationAware class?

推荐答案

Spring 没有找到任何 JPA 实体,因此没有创建 JPA 元模型,这就是您面临异常的原因.

Spring does not find any JPA Entities, so no JPA Meta Model is created, that is why you face the exception.

这个问题的原因可能是你的类路径上的persistence-api版本错误.

The cause of this problem may be a wrong persistence-api version on your class path.

您正在使用

<dependency> 
    <groupId>javax.persistence</groupId> 
    <artifactId>persistence-api</artifactId> 
    <version>1.0.2</version> 
</dependency> 

但我很确定你的 spring 版本使用了持久性 API 版本 2.

but I am pretty shure your spring version uses persistence-api version 2.

难道,您使用的是版本 1 中的 @Entity 注释吗?在运行时,sp​​ring 使用版本 2,这只是使用版本 2 中的 @Entity 搜索实体!

Could it be, you are using @Entity annotation from version 1 ? At runtime spring uses version 2, and this is searching for Entites using @Entity from version 2 only !

删除依赖

<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 依赖项.

This will give you all JPA dependencies in the right version.

这篇关于spring jpa - 必须至少存在一个 JPA 元模型*的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆