>

기존의 spring 4 프로젝트 (mvc, jdbc 등)를 가지고 있으며 스프링 부트로 이식하려고했지만 할 수 없습니다. (많은 의존성 문제, 아무도 내가 어떻게 할 수 있는지 설명 할 수 없습니다). 그러나 이제는 기존 프로젝트에서 Spring Data JPA를 사용하고 싶습니다. 그것은 주요 pom 의존성입니다 :

<properties>
        <jetty.version>9.3.5.v20151012</jetty.version>
        <spring.version>4.3.12.RELEASE</spring.version>
        <spring.boot.version>1.5.8.RELEASE</spring.boot.version>
        <spring.security.version>4.2.3.RELEASE</spring.security.version>
        <quartz.version>2.2.1</quartz.version>
        <slf4j.version>1.7.5</slf4j.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <hibernate-version>5.3.3.Final</hibernate-version>
    </properties>
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
            <version>${spring.boot.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-validation</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.jboss.logging</groupId>
                    <artifactId>jboss-logging</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-databind</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-annotations</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.hibernate</groupId>
                    <artifactId>hibernate-validator</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>2.0.5.RELEASE</version>
        </dependency>
<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate-version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate-version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>
<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>4.2.1.RELEASE</version>
        </dependency>

EntityManagerFactory Bean (모든 예제에서 사용)으로 완성한 기존 구성이 있습니다. DBConfig :

@Configuration
@ComponentScan("ru.testproject.*")
@EnableTransactionManagement
@EnableJpaRepositories("ru.testproject.*")
public class DatabaseConfig {
    @Value("${postgresql.address}")
    String address;
    @Value("${postgresql.database}")
    String database;
    @Value("${postgresql.user}")
    String user;
    @Value("${postgresql.password}")
    String password;
    @Value("${db.type}")
    String dbType;
    @Bean
    public DataSource dataSource() {
        if (DB_TYPE_POSTGRESQL.equalsIgnoreCase(dbType)) {
            return postresqlDataSource();
        } else {
            return derbyDataSource();
        }
    }
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource) {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }
    private HikariDataSource derbyDataSource() {
        try {
            String appHome = System.getProperty(Property.APP_HOME);
            Path path = Paths.get(appHome, DATABASE_NAME);
            String databaseName = path.toString();
            databaseName = StringUtils.replaceChars(databaseName, '\\', '/');
            Class.forName(DB.DB_DRIVER_DERBY).newInstance();
            EmbeddedDataSource embeddedDataSource = new EmbeddedDataSource();
            String dbName = databaseName;
            embeddedDataSource.setDatabaseName(dbName);
            embeddedDataSource.setCreateDatabase("create");
            embeddedDataSource.setUser("application");
            embeddedDataSource.setPassword("");
            HikariConfig config = new HikariConfig();
            config.setDataSource(embeddedDataSource);
            config.setMaximumPoolSize(10);
            config.setAutoCommit(true);
            HikariDataSource hikariDataSource = new HikariDataSource(config);
            return hikariDataSource;
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            throw new IllegalStateException("error connection Derby");
        }
    }
    private HikariDataSource postresqlDataSource() {
        if (StringUtils.isBlank(address)
                || StringUtils.isBlank(database)
                || StringUtils.isBlank(user)
                || StringUtils.isBlank(password)) {
            throw new IllegalStateException("error params Postgresql");
        }
        HikariConfig config = new HikariConfig();
        String jdbcUrl = MessageFormat.format(POSTGRESQL, address, database);
        config.setJdbcUrl(jdbcUrl);
        config.setUsername(user);
        config.setPassword(password);
        config.setMaximumPoolSize(10);
        config.setAutoCommit(false);
        return new HikariDataSource(config);
    }
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws SQLException {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("ru.testproject.hibernate.*");
        factory.setDataSource(dataSource());
        factory.afterPropertiesSet();
        factory.setPersistenceUnitName("test");
        return factory;
    }
}

테스트에 사용되는 더비 데이터베이스. 그러나 주요 데이터베이스 유형은 HikariCP를 사용한 PostgreSQL입니다. 이미 프로젝트에 HQL 지원을 추가하고 있으며 정상적으로 작동합니다. 그러나 JAP 리포지토리 지원을 추가하려고하면 많은 문제가 있습니다. 엔티티가 있습니다 :

@Entity
@Table(name = "users", schema = "public", catalog = "test")
public class Users {
    private int id;
    private String username;
    private String password;
    private String email;
    @Id
    @Column(name = "id", nullable = false)
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    @Basic
    @Column(name = "username", nullable = false, length = 64)
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    @Basic
    @Column(name = "password", nullable = false, length = 64)
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Basic
    @Column(name = "email", nullable = false, length = 128)
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Users that = (Users) o;
        return id == that.id &&
                Objects.equals(username, that.username) &&
                Objects.equals(password, that.password) &&
                Objects.equals(email, that.email);
    }
    @Override
    public int hashCode() {
        return Objects.hash(id, username, password, email);
    }
}

그리고 저장소 :

@Repository
public interface UsersRepository extends CrudRepository<Users, Long> {
    @Query("select b from Users b where b.username = :username")
    Users findByName(@Param("username") String username);
}

CrudRepository를 확장 한 테스트 저장소 일뿐입니다. 해당 리포지토리를 사용하기 위해 구현하여 서비스를 만들었습니다.

@Service
public interface UserService {
    void delete(long id);
    Users getByName(String name);
    Optional<Users> getById(Long id);
    Users editUsers(Users user);
}
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UsersRepository usersRepository;
//    @PersistenceContext(unitName = "test")
//    private EntityManager em;
    @Override
    public void delete(long id) {
        usersRepository.deleteById(id);
    }
    @Override
    public Optional<Users> getById(Long id) {
        return usersRepository.findById(id);
    }
    @Override
    public Users getByName(String name) {
        return usersRepository.findByName(name);
    }
    @Override
    public Users editUsers(Users user) {
        return usersRepository.save(user);
    }
}

그리고 저런 저장소를 사용하고 있습니다 :

@Autowired
    private UserService service;
...
Users entry = service.getById(1L).get();

그게 다야. 스프링 부트를 사용하지 않고 (위에서 언급 한 바와 같이) 오류가 발생하여 응용 프로그램이 실패했을 때 시작합니다.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ru.testproject.config.DBConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.NoSuchFieldError: parallelCapableClassLoaderAvailable
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587)

@EnableJpaRepositories 주석에 주석을 달면 다음 오류가 발생합니다.

Unsatisfied dependency expressed through field 'userServiceImpl'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userServiceImpl': Unsatisfied dependency expressed through field 'usersRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'ru.testproject.db.hibernate.repository.UsersRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

두 번째 시나리오 리포지토리가 null입니다. JPA 리포지토리가 비활성화되었습니다. 도와주세요! 내가 뭘 잘못하고 어떻게 작동합니까? Google 및 인터넷 임대 관련 문제를 해결할 수 없습니다. 근본 문제가 무엇인지 이해하지 못했을 수도 있습니다.


  • 답변 # 1

    컴포넌트 스캔에 테스트 패키지 ru.testproject.db.hibernate.repository를 추가하지 않은 것 같습니다.

  • 답변 # 2

    도움이 필요합니다! 다음 변경 사항으로 문제를 해결했습니다. 1) 우선-최신 버전으로 스프링 컨텍스트 종속성을 업데이트했습니다.

    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.4.RELEASE</version>
        </dependency>
    
    

    java.lang.NoClassDefFoundError : org/springframework/context/index/CandidateComponentsIndexLoader error를 해결합니다. CandidateComponentsIndexLoader는 spring-context 5.0.0 이후에 나타납니다.

    2) 나는

    @EnableJpaRepositories(basePackages = {
            "ru.testproject.hibernate"
    })
    @PropertySource("classpath:testproject.properties")
    @ComponentScan("ru.testproject.hibernate")
    
    

    주석. 이전 변경 사항은 긍정적 인 변경 사항에는 영향을 미치지 않았습니다. 1)으로 entityManagerFactory 오류가 발생하여 해결할 수 있습니다.

    3) entityManagerFactory에 대한 packgeToScan 설정

    entityManagerFactoryBean.setPackagesToScan("ru.testproject.hibernate.entity");
    
    

    엔터티 경로가있는 경우 (이 경우 사용자)

    그게 다야. 이제 리포지토리가 완벽하게 작동합니다. 모두 감사합니다 !!!

    ps : 아마도 스프링 부트로 시작할 수 있습니다)

  • 이전 javascript - HTML 속성에서 Vue 데이터를 작성하는 방법은 무엇입니까?
  • 다음 web applications - Visual Studio 2017 업데이트 후 WebConfig에서 더 이상 미리보기 변환이 작동하지 않습니다