Ошибка репозитория Spring Boot JPA

Я пытаюсь использовать весеннюю загрузку с hibernate-mysql для обучения, я следую учебнику по весенней загрузке на youtube и внесу некоторые изменения в jpa hibernate-mysql

Когда запускался как "приложение для весенней загрузки", он работал нормально. При запуске как "пакет maven" в pom.xml, он не был выполнен на "ИСПЫТАНИЯХ"

ошибка:

2015-09-18 10:26:19.599  INFO 8328 --- [           main] demo.DemoApplicationTests                : Starting DemoApplicationTests on Noir with PID 8328 (D:\eclipse\project\demo\target\test-classes started by Phane in D:\eclipse\project\demo)
2015-09-18 10:26:19.667  INFO 8328 --- [           main] o.s.w.c.s.GenericWebApplicationContext   : Refreshing org.springframework.web.context.support.GenericWebApplicationContext@1d0737c8: startup date [Fri Sep 18 10:26:19 SGT 2015]; root of context hierarchy
2015-09-18 10:26:19.768  WARN 8328 --- [           main] o.s.w.c.s.GenericWebApplicationContext   : Exception encountered during context initialization - cancelling refresh attempt

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: file [D:\eclipse\project\demo\target\classes\filmRental\JpaConfig.class]; nested exception is java.lang.annotation.AnnotationFormatError: Invalid default: public abstract java.lang.Class org.springframework.data.jpa.repository.config.EnableJpaRepositories.repositoryBaseClass()
    at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:303)
    at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:248)
    at org.springframework.context.annotation.ComponentScanAnnotationParser.parse(ComponentScanAnnotationParser.java:140)
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:266)
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:230)
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:189)
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:270)
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:230)
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:197)
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:166)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:306)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:239)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:254)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:94)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:606)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:462)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)

это Java-классы:DemoApplication.java

package demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;

import filmRental.Staff;
import filmRental.StaffRepository;
import filmRental.StaffServiceImpl;

@SpringBootApplication

    public class DemoApplication {

        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }

    @ComponentScan ("filmRental")
    @Component
    class StaffCommandLineRunner implements CommandLineRunner
    {

        @Override
        public void run(String... arg0) throws Exception 
        {
            for(Staff staff : this.sf.findAll())
            {
                System.out.println(staff.getStaffID() + " > " + staff.getFirstName());
            }

        }

        @Autowired StaffServiceImpl sf;

    }

StaffRestController

package demo;

import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import filmRental.Staff;
import filmRental.StaffServiceImpl;

@RestController
@ComponentScan ("filmRental")
public class StaffRestController 
{
    @RequestMapping ("/staff")
    public Collection<Staff> listStaff()
    {
        return sf.findAll();
    }

    @Autowired StaffServiceImpl sf;
}

StaffServiceImpl.java

package filmRental;

import java.util.List;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class StaffServiceImpl 
{
//  @PersistenceContext
//  private EntityManager em;

    @Resource
    private StaffRepository sf;

    public List<Staff> findAll()
    {
        return sf.findAll();
    }
}

StaffRepository.java

package filmRental;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public interface StaffRepository extends JpaRepository<Staff, Byte>{}

Staff.java

package filmRental;

import java.sql.Blob;
import java.sql.Timestamp;

import javax.persistence.*;

@Entity
@Table (name ="Staff")
public class Staff 
{
    private byte staffID;
    private String firstName;
    private String lastName;
    private byte[] picture;
    private String email;
    private byte storeID;
    private boolean active;
    private String userName;
    private String password;
    private Timestamp lastUpdate;
    private Address address;

    @Id
    @Column (name="staff_id")
    public byte getStaffID()
    {
        return staffID;
    }

    public void setStaffID(byte staffID) 
    {
        this.staffID = staffID;
    }

    @Column (name = "first_name")
    public String getFirstName() 
    {
        return firstName;
    }

    public void setFirstName(String firstName) 
    {
        this.firstName = firstName;
    }

    @Column (name = "last_name")
    public String getLastName() 
    {
        return lastName;
    }

    public void setLastName(String lastName)
    {
        this.lastName = lastName;
    }

    @Column (name = "picture", columnDefinition="BLOB")
    public byte[] getPicture() 
    {
        return picture;
    }

    public void setPicture(byte[] picture) 
    {
        this.picture = picture;
    }

    @Column (name = "email")
    public String getEmail()
    {
        return email;
    }

    public void setEmail(String email) 
    {
        this.email = email;
    }

    @Column (name = "store_id")
    public byte getStoreID()
    {
        return storeID;
    }

    public void setStoreID(byte storeID) 
    {
        this.storeID = storeID;
    }

    @Column (name = "active")
    public boolean getActive() 
    {
        return active;
    }

    public void setActive(boolean active) 
    {
        this.active = active;
    }

    @Column (name = "username")
    public String getUserName() 
    {
        return userName;
    }

    public void setUserName(String userName)
    {
        this.userName = userName;
    }

    @Column (name = "password")
    public String getPassword() 
    {
        return password;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }

    @Column (name = "last_update")
    public Timestamp getLastUpdate() 
    {
        return lastUpdate;
    }

    public void setLastUpdate(Timestamp lastUpdate) 
    {
        this.lastUpdate = lastUpdate;
    }

    @ManyToOne
    @JoinColumn(name="address_id")
    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

}

JpaConfig.java

package filmRental;

import java.util.Properties;

import javax.annotation.Resource;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.hibernate.ejb.HibernatePersistence;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@PropertySource("classpath:application.properties")
@EnableJpaRepositories
public class JpaConfig 
{

    private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
    private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
    private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
    private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";

    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
    private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";

    @Resource
    private Environment env;


    @Bean
    public DataSource dataSource() 
    {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
        dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
        dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
        dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));

        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() 
    {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);
        entityManagerFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
        entityManagerFactoryBean.setJpaProperties(hibProperties());
        return entityManagerFactoryBean;
    }

    private Properties hibProperties() 
    {
        Properties properties = new Properties();
        properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
        properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
        return properties;
    }

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

}

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>`enter code here`

    <groupId>org.test</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.7</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-ws</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.9.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

Пожалуйста, помогите, спасибо.

1 ответ

Решение

Вы используете Spring Boot, затем используйте Spring Boot также @ComponentScan должен пойти на вашем классе приложения. (удалите его из командной строки и контроллера).

@SpringBootApplication
@ComponentScan ({"demo","filmRental"})
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

@Component
class StaffCommandLineRunner implements CommandLineRunner {

    @Autowired StaffServiceImpl sf;

    @Override
    public void run(String... arg0) throws Exception {
        for(Staff staff : this.sf.findAll()) {
            System.out.println(staff.getStaffID() + " > " + staff.getFirstName());
        }
    }
}

Далее в вашей поме удалить spring-data-jpa, hibernate а также persistence-api зависимости и заменить на spring-boot-starter-data-jpa

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-ws</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
</dependencies>

Теперь у вас есть зависимости, которые работают вместе, вместо того, чтобы пытаться определить рабочую комбинацию.

Spring Boot уже выполняет автоматическую настройку, чтобы вы удалили JpaConfig и поместите следующие свойства в ваш application.properties (автоматически загружается Spring Boot!).

spring.datasource.url=<datasource-url>
spring.datasource.driver-class-name=<driver-class-name>
spring.datasource.username=<username>
spring.datasource.password=<password>

spring.jpa.database-platform=<hibernate-dialect>
spring.jpa.show-sql=<show-sql>

Для сканирования объекта используйте @EntityScan на классе приложения.

@SpringBootApplication
@ComponentScan ({"demo","filmRental"})
@EntityScan("filmRental")
public class DemoApplication { ... }

Spring Boot теперь автоматически настраивает DataSource, EntityManagerFactory, транзакции, обнаруживает Spring Data JPA и включает репозитории. Я бы предложил переместить DemoApplication и все остальное в filmRental пакет таким образом, вы можете удалить @ComponentScan а также @EntityScan от DemoApplication,

Другие вопросы по тегам