기존의 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
- 답변 # 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 : 아마도 스프링 부트로 시작할 수 있습니다)
관련 자료
- java - 컨트롤러의 핸들러 메서드에서 @Valid없이 Validator 인터페이스를 구현하지 않고 Spring Validation?
- 사용자 로그온없이 안전한 스프링 부트 앱
- rest - 요청 본문이없는 개체에 대한 Spring Boot RestClient 게시로 인해 잘못된 요청이 발생 함
- java - 이름으로 Bean을 가져 오기 위해 ApplicationContext를 사용하지 않고 Spring이 아닌 객체에서 autowire하는 방법
- 스프링 부트 추가 오류 메시지는 예외를 발생시키지 않고 응답을 유지하지만 입력 된 응답을 유지합니다
- java - AbstractSecurityWebApplicationInitializer없이 스프링 보안 활성화
- 직접 연결하지 않고 두 개의 Git 리포지토리 동기화
- java - 스프링없이 구성 파일 (* yaml * properties)을 읽는 방법
- 특정 시간 간격으로 배치 작업 실행 테이블을 폴링하지 않고 스프링 배치 작업 상태의 변경 사항을 듣는 방법은 무엇입니까?
- java : 상위 행을 삭제하거나 업데이트 할 수 없음 : 외래 키 제약 조건이 실패하고 엔티티 계층이 변경되면 안됩니다.
- java : 커스텀 Hibernate 유효성 검사기에서 Spring 의존성 주입 사용
- java : 클래스 경로 자원에 정의 된 이름이 'entityManagerFactory'인 Bean 작성 오류 : init 메소드 호출 실패
- java : import org.hibernate.validator.ClassValidator를 확인할 수없고 import org.hibernate.validator.InvalidValue를 확인할 수 없습니다.
- java : 왜 최대 절전 쿼리 메서드 (저장소 인터페이스에 정의 됨)를 사용할 수 없습니까?
- java : 필드 'record_id'에 기본값이 없습니다-Spring JPA 오류
- java : spring-data /jpa로 '중복 항목'예외를 무시하는 방법
- java : Spring Boot Actuator가 작동하지 않음-Whitelabel 오류 페이지
- java : CompletableFuture allof (..). join () 대 CompletableFuture.join ()
- java : S3에서 파일을 다운로드 할 때 파일 크기를 기록하기 위해 MeterRegistry를 사용하여 지표를 생성하려면 어떻게해야합니까?
컴포넌트 스캔에 테스트 패키지 ru.testproject.db.hibernate.repository를 추가하지 않은 것 같습니다.