반응형

git에서 프로젝트를 클론 후 STS로 프로젝트를 열었다.

 

그런데 첫줄에 에러 표시가 있었다!!!...

 

뭐지.. 그냥 가져왔을 뿐인데 에러가 나길래 당황 ㅜ ㅜ

 

하지만 갓글링을 통해 여러가지 방법을 찾아보고 시도했다.

 

먼저 이런 오류가 발생하는 원인은 Eclipse에서 나타나는 버그로 maven이 jar 들을 다운 받으면서 도중에 멈추거나 꼬인 것이라고 한다.

 

1. 해당프로젝트 우클릭 -> Maven -> Update Project

이렇게 하면 해결 된다는 글을 보았지만 내 경우에는 에러가 그대로 남아있었다.

 

2. porm.xml 에서 spring-boot-stater-parent의 version을 변경 (이 방법으로 해결!)

 

처음엔 아래 코드로 되어 있었다.

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.5.RELEASE</version>
</parent>

아래 코드로 변경 후, 저장을 해서 다시 빌드! 하니 오류가 해결됐다.

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.1.4.RELEASE</version>
</parent>

 

3. 해당 프로젝트 우클릭 -> Maven -> Update project 로 들어가서

일부만 캡쳐

해당 프로젝트 체크 후 아래 부분은 위 사진과 같이 체크 후 OK.

 

4. porm.xml에서 

<properties>
	<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
    <java.version>1.8</java.version>
</properties>

위와같은 properties를 찾고 메이븐 플러그인을 다운그레이드 한 후 

다시 프로젝트 우클릭 -> Maven ->Update 해주면 해결 된다고 한다.

나는 1,3,4 번을 먼저 시도했지만 안됐고, 2번을 통해 해결했다!

반응형
반응형

Spring boot 를 학습하던 도중

 

AWS에 올리려다 git에 노출되면 안되는 값이 있어 외부 yml 파일을 만들고

 

application.yml 파일에 include 해서 data를 사용하려 했다.

 

그런데 데이터 주입이 되지 않았다.

 

myval:
	value: hi

이렇게 yml 파일이 설정 되어 있다고 가정 한다.

 

1. static 변수에 주입해서 사용했다

@Value("${myval.value}")
private static String val;

이런 식으로 사용 하였는데 데이터가 주입되지 않았다.

 

기존에 구현했던 클래스는 상수에 값을 때려 박고 그 값을 static 메소드에서 사용하도록 했었다.

 

그 점을 인지 못하고 그냥 변수 부분만 바꾸면 되겠지 하고 사용했지만, 실패!

 

2. static 키워드를 제거하고 new MyClass();와 같이 인스턴스 생성해서 사용했다.

 

@Component
@ConfigurationProperties(prefix="myval")
@Getter
@Setter
public class MyClass{
	private String value;
}

 

new MyClass(); 로 생성해서 value값을 출력하는 메소드를 만들고 호출해 봤지만

 

null 값이 나온다. 실패!

 

3. (2)번 처럼 만든 클래스를 @Autowired로 주입 시켜 사용했다.

public class TestMain{
	
    @Autowired
    private MyClass myclass;
    
    public void test(){
    	myclass.출력메소드();
    }
}

 

yml 파일의 데이터를 사용하는 클래스를 호출하는 곳에서 출력 메소드를 호출해 봤고 성공했다!

 

@Autowired, @Inject, @Resource, @Value 어노테이션들은 스프링의 BeanPostProcessor 구현체가 처리한다. 이는 (무엇이든간에) 자신만의 BeanPostProcessor나 BeanFactoryPostProcessor 타입내에서는 이러한 어노테이션들을 적용할 수 없다는 의미이다. 이러한 타입들은 반드시 명시적으로 XML이나 스프링의 @Bean 메서드를 사용해서 '연결해야' 한다.

 

구글링을 해서 찾아봤지만 위와같은 글만 있고 정확한 원인은 찾을 수 없었다..

 

혹시 왜 그런지 알고 계시면 답변 부탁드립니다~~!

 

그리고 yml 또는 properties 파일에서 값을 읽어오는 Class에는 setter 메소드가 꼭 있어야 한다.!!!!!!

 

--------------------------------------추가--------------------------------

좀 더 알아본 결과 Property 값 주입은 Bean 컨테이너 즉 ApplicationConetxt가 하는데, 서버가 올라가고 ServletContext가 Initialize 되면 onRefresh 메서드에 의해 Bean이 초기화 된다. 이 때 Bean을 스캐닝해서 의존이 있다면 의존을 주입한다. 이 과정에서 플레이스 홀더에 값을 채워주는 것이다!..

그렇기 때문에 임의로 new를 이용해 인스턴스를 생성하게 되면 값 주입이 이루어 지지 않는 것이다.

 

중요한 것은 @Autowired가 아니라 플레이스 홀더가 있는 클래스가 Bean이면서 동시에 context refresh에 의해 처리 되는가 아닌가의 차이이다.

자세한 것은 Spring.io에 Properties 관련 항목을 보면 나와있다.

반응형
반응형

RestController 에서 Josn 형식으로 값을 잘 받아오던게 갑자기 안된다.

No serializer found for class org.hibernate

이런 에러가 나온다.

 

@ManyToOne에서 fetch=FetchType.LAZY 전략을 써서 

Hibernate에서 LAZY 로딩으로 인한 JSON Serialization에러가 발생한 것이라고 한다.

 

그런데 나는 fetch 설정을 한적이 없다..

심지어 @ManyToOne에서 fetch의 default 값은 EAGER 이다

 

default값

OneToMany: LAZY

ManyToOne: EAGER

ManyToMany: LAZY

OneToOne: EAGER

 

해결은

해당 Object를 JSON으로 변환하지 않는다면, @JsonIgnore 어노테이션을 nested 객체에 붙인다

@JsonIgnoreProperties({"hibernateLazyInitializer","handler"})

 

이 방법으로 해결했다..

 

다른 방법으로는 application.properties 에 spring.jackson.serialization.fail-on-empty-beans=false

이 설정을 추가 하면 된다.

 

그런데 에러를 보이지 않게만 하는 방식이라 어떤 위험이 있을지는 모르겠다..

 

반응형
반응형

SpringBoot를 이용해 개발을 하며 test 케이스를 작성하고 실행을 하였다

 

그리고 각 테스트 케이스 마다 영향을 주지 않기 위해

 

@After 어노테이션으로 각 repository.deleteAll() 메소드를 실행하도록 하였다.

 

그런데 ?? 

 

org.hibernate.exception.ConstraintViolationException: could not execute statement

이런 에러가 발생하였다.

 

https://stackoverflow.com/questions/49595852/deleteall-in-repository-randomly-causes-constraintviolationexception

 

deleteAll() in Repository randomly causes ConstraintViolationException

I have tests that do CRUD operations on an API. Before each test the test data in the API gets recreated. Meaning deleting all data in the database and inserting the test data again. public void

stackoverflow.com

여기에 어느정도 잘 나와있는 것 같다.

 

Hibernate를 사용하여 테스트 하는 환경에서 나타나는 일반적인 에러란다~

 

원인은 코드의 쿼리가 순차적으로 즉시 수행되는 것이 아니기 때문이다.

 

그래서 deleteAll() 대신 deleteAllInBatch()를 사용해서 해결했다.

 

deleteAll()은 delete를 여러번 실행하며 모두 삭제하는 것이고, deleteAllInBatch()는 한번의 실행으로 전부를 삭제하는 것이다.

반응형
반응형

 

하아...

 

Entity에 @ManyToOne 어노테이션을 이용해서 참조 관계를 만들고 데이터 저장을 테스트 하던중

 

이상하게도 자꾸 참조키(외래키)의 값이 null 이라고 에러가 뜨면서 저장이 되지 않았다...

 

처어어언천히 Entity의 설정을 살펴보니

 

@JoinColumn(... insertable=false ,updatable=false) 이런 설정값이 들어가 있었다

 

뭐지? 하고 찾아봤는데

 

insertable : 엔티티 저장시 이 필드도 같이 저장한다. false로 설정하면 데이터베이스에 저장하지 않는다. 읽기 전용일때 사용한다.
updatable : 위와 동일한 하지만 수정일때 해당 된다.

 

....

 

그래서 값이 저장되지 않았고 id가 null 이라는 메세지가 자꾸 나온 것이다!!!!

 

하... 

반응형
반응형

Springboot에 댓글 기능을 구현하던 중 이유모를 ? 에러가 발생했다.

 

위와 같이 Query 문을 작성 했는데 

QuerySyntaxException: comments is not mapped [SELECT c FROM comments c ORDER BY c.id DESC]

이런 에러가 발생했다...

 

구글링을 했다... 흑...

 

(http://stackoverflow.com/questions/8230309/jpa-mapping-querysyntaxexception-foobar-is-not-mapped)

스택오버플로우에 명확한 해결법이 나와있었다 ~~ 호우!

 

Query문을 작성할 때는 Table의 대소문자를 주의해야 한다!!

 

즉 도메인 클래스를 작성할 때 @Table(name="comments") 라고 하더라도 

 

도메인 클래스의 클래스명을 테이블명으로 작성해야 한다는 것이다!!

 

즉 나는 Select c FROM Comments 로 했어야 했다.

 

 

반응형

'Spring Framework' 카테고리의 다른 글

JPA 기본 사용법  (0) 2019.06.24
JPA(Java Persistance API) 개념  (0) 2019.06.24
(STS) Spring Framework-Lombok 설치  (0) 2019.06.23
Spring MVC 라이프 사이클  (0) 2019.06.20
반응형

error executing ddl via jdbc statement 

spring boot + jpa  환경에서

 

jpa 엔티티를 생성하고 테스트 하는 도중 에러가 발생하였다.

엔터티 설정중 @Column 어노테이션을 이용해서 컬럼 타입이나 기타 정보를 입력하지 않은 상태에서 실행하면

alert table 문장이 문법에 맞지 않은게 생성이 되서 오류가 났다.

 

spring:
  profiles: local
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update

이렇게  ddl-auto: update 옵션을 추가하여 해결하였다.

엔터티에서 변동이 일어나면 자동으로 ddl 명령을 실행해 테이블을 변경하겠금 설정했을시에

컬럼이 추가 되거나 컬럼속성이 변경되면 실행된다

 

반응형
반응형

SpringBoot 프로젝트는 자동으로 프로젝트에 properties 파일이 생성되고 

 

이 파일로 local , real ,test 환경을 셋팅할 수 있다.

 

근데 test/resources/ 폴더에 properties 파일 또는 yml 파일이 없으면 자동으로

 

main/resources/ 폴더에 있는 properties 또는 yml 파일을 참조하게 된다.

 

실제 운영하는 코드와 테스트 환경을 분리해야 되는게 맞기 때문에 설정 파일을 따로 작성해야 된다.

 

그래서 test/resources/ 에 applicationt.yml을 작성 했다.

 

그런데 Junit 테스트를 실행하면 자꾸 main/resources/에 있는 설정 파일을 참조하는 것이다...

 

구글링을 통해 여러방법을 시도해 보았지만 안됐고..

 

@TestPropertySource("classpath:applicationtest.yml")

 

테스트 클래스에 위에 코드를 작성하니 정상적으로 참조가 됐다..

 

다른 분들은 자동으로 test/resources/*.properties 를 참조하게 된다던데 ㅜ ㅜ 왜 난 안될까... 

 


위에 썼던 것대로 하면 안된다 .. . . . .

 

그래서 별 xx을 다해봤고 방법은

application-local.yml -- 로컬 PC

application-dev.yml -- 개발서버

application-uat.yml -- UAT(Staging)

application-live.yml -- Live(운영)

이런식으로 나누어서 사용한단다...

 

그래성 @TestPropertySource(properties = { "spring.config.location=classpath:application-test.yml" })

이런식으로 참조한단다..

 

나는 이렇게 했을 때 

@Test
public void Profile확인() {
   //when
   String profile =this.restTemplate.getForObject("/profile",String.class);

   //then
   assertThat(profile).isEqualTo("local");
}

이 코드를 실행하면 UnsatisfiedDependencyException 이런 오류를 던진다.. 

는 @SpringBootTest(webEnvironment =WebEnvironment.RANDOM_PORT)

이 webEnvironment를 설정 안해줘서 글탕.. 

 

결론

@TestPropertySource(properties = { "spring.config.location=classpath:application-test.yml" })

로 다른 yml을 참조하도록

반응형

+ Recent posts