반응형
반응형

Mssql을 사용하여, 대부분의 로직이 Stored Procedure에 들어있는 상황으로, 웹서버는 게이트웨이 역할로 사용하고, 최대한 자동화가 되도록 구성함. 그러다보니, 클라이언트가 보내는 파라미터 조차도 자동화되어, 바로 DB로 넘어가버렸고, 파라미터 검증 절차가 없으니, 유효하지 않은 파라미터가 와도, 서버단에서 에러코드를 리턴해버리는 게 아니라, 무조건 DB 통신을 하는 것이 문제였음.

(물론, mssql이라도 CRUD만 할 뿐, 로직은 최대한 서버단으로 빼는 게 맞고, 이후 프로젝트부터는 그렇게 진행중)

 

DB통신을 막아보자 하여, 웹에서 검증할 수 있는 코드를 추가함.

 

1. Spring Framework의 Argument Resolver단에서 파라미터를 받아와서, 파싱하여 일일히 비교. (현재 구조가, Argument Resolver를 커스터마이징해서 모든 요청들이 들어올 수 있도록 되어 있는 구조) 

 - 예외상황이 너무나도 많으며, 심지어 검증 코드상에 문제가 있는 경우가 많아서 다른 방법을 찾아보도록 함.

 

2. 그러다보니, javax.validation-api에서 지원하는 Annotation만으로 간단하게 값들을 검증할 수 있는 매우 강력한 라이브러리 발견  

 - Hibernate Validator!! (http://hibernate.org/validator/

 

3. 별다른 고민 없이, 1에서 작성한 코드는 싹 날려버리고, Pojo클래스들을 작성하여 어노테이션들을 적용.

 - 서버에서 라이브러리 로딩도 잘 했고, 서버 Start에 성공했지만, 테스트 결과 fail

 

4. Servlet 설정에서 LocalValidatorFactoryBean을 Bean으로 등록해주고, 해당 validator를 불러와서 validate 메소드를 실행

 - validation에 실패한 개수만큼 Set<ConstraintViolation<T>>형식으로 리턴이 되며, 에러처리 등을 위해서는 size로 비교하니, 원하는대로 동작함.

 

5. @NotNull의 경우 String은 잘되지만, primitive type에서는 동작하지 않음.

 - 정상적인 현상이며, primitive type은 default가 0이기 때문에, Null이 될 수 없으므로, 해당 값의 Null 체크를 위해서는

  int -> Integer, long -> Long 등 과 같이 reference type으로 변경해 주어야 함. 

 

 

성능상에도 큰 문제는 없는 것 같고, 잘 사용중 ㅎㅎ. 파라미터 검증이나 값 검증이 필요한 분들은 도입해보시는걸 추천드립니다. 

반응형

'개발 > JPA, Hibernate' 카테고리의 다른 글

[Hibernate] Custom Validator  (0) 2016.06.11
[Hibernate] ddl-auto  (0) 2016.06.11
[Hibernate] Entity 선언 시 주의점  (0) 2016.06.11
[Spring Data Jpa] limit와 ordering  (1) 2016.06.11
[Spring Data Jpa] custom query 적용  (0) 2016.06.11
,
반응형

Hibernate Validator에는 javax.validator에서 지원하는 기능 + 내부적으로 추가로 지원하는 기능이 있지만,

값 여러개를 지정해두고, 그 값에 포함이 되어 있는지 검사하는 기능은 없었다.

 

이런 경우 customizing을 해야 하는데,

Annotation하나를 만들고, 그 annotation에 validator을 등록 해준뒤에,  

그 annotation을 field등에서 가져다가 쓰기만 하면 된다.

 

이미 만들어져 있는 contraint annotation을 찾아보면,

기본적으로 가지고 있는 형식이 있다. (message, groups, payload)

 

보통은 message만 지정해서 많이 사용하는 것 같다.

message는 validation에 실패했을 때, 로그에 찍힐 메시지를 의미함. 

 

저 3개는 필수로 지정해주고, 나머지는 필요로 하는 값을 선언한다.

여기서는 여러개의 값에 대한 비교이므로, Object[] 같은 것으로 하나 넣어둔다.

 

그리고 가장 중요한..  

방금 생성한 Annotation상단에 @Constraint(validatedBy = ???Validator.class)을 넣어줌으로써,

이 Annotation이 선언된 곳은 지정된 Validator를 사용한다라고 명시해준다. 

 

Validator구현은 ConstraintValidator interface를 구현하면 끝난다.

내부적으로 initialize, isValid를 구현해야 하는데, 메소드명이 너무 명시적이어서 따로 설명은 필요 없을것 같다. 

반응형

'개발 > JPA, Hibernate' 카테고리의 다른 글

[Hibernate] Hibernate Validator  (0) 2016.06.11
[Hibernate] ddl-auto  (0) 2016.06.11
[Hibernate] Entity 선언 시 주의점  (0) 2016.06.11
[Spring Data Jpa] limit와 ordering  (1) 2016.06.11
[Spring Data Jpa] custom query 적용  (0) 2016.06.11
,
반응형

Spring Boot에 hibernate, jpa 를 설정하다보면 spring.jpa.hibernate.ddl-auto라는 옵션이 있는데,

create, create-drop, update, validate라는 4가지 옵션을 지원한다.


ddl-auto 기능에 대해 간단히 설명하자면,

java언어에서 Object를 선언해두고, @Entity만 붙이면, 

WebApplication이 올라갈 때 (정확히는 hibernate의 sesseionFactory가 올라갈 때)DataSource에 접근을 해서 

DBMS의 스키마를 자동으로 Alter를 하거나 지우고 다시 만들거나 검증하거나 하는 역할을 해준다.


WebApplication이 올라갈 때 DBMS 스키마에 무슨 행위를 할 것인가에 대해 정하는 정책이라고 보면 쉽다.


4가지 옵션에 대해 알아보자.


create : SessionFactory가 올라갈 때 테이블을 지우고 새로 만듬. (sql문을 별도로 만들어서 데이터를 넣는 용도로도 사용가능하다.)


create-drop : create와 동일하지만, SessionFactory가 내려가면 해당 테이블을 drop시킨다.


update : SessionFactory가 올라갈 때 Object를 검사하여 테이블을 alter 시킨다. 데이터는 유지됨.


validate : update처럼 Object를 검사하지만, 스키마는 아무것도 건드리지 않고, Object와 스키마의 정보가 다르다면 에러를 발생시킨다.


create, create-drop은 개발 환경에서 사용하면 편리하지만, live에서 사용은 조금 위험할 수 있을 것 같다.

live환경에서는 update나 validate를 잘 사용하면 좋을 것 같다.

반응형

'개발 > JPA, Hibernate' 카테고리의 다른 글

[Hibernate] Hibernate Validator  (0) 2016.06.11
[Hibernate] Custom Validator  (0) 2016.06.11
[Hibernate] Entity 선언 시 주의점  (0) 2016.06.11
[Spring Data Jpa] limit와 ordering  (1) 2016.06.11
[Spring Data Jpa] custom query 적용  (0) 2016.06.11
,
반응형

요즘 Getter, Setter와 모든 property가 포함된 Constructor의 경우는 기본적으로 lombok을 사용하여 설정을 하므로,

모든 클래스 위에 @Getter, @Setter, @AllArgsConstructor를 선언해서 사용을 한다.


Entity의 경우도 위와 같은 기능이 있으면, 편리하기 때문에 습관처럼 작성하고

repository interface를 만들어서 개발을 했는데, Default Constructor가 없다는 에러가 발생을 하였다.


Hibernate 내부적으로 Entity를 관리할 때 Default Constructor로 Object를 생성하는 것으로 보인다.


Default Constructor를 하나 선언해주니, 정상적으로 동작한다.

반응형

'개발 > JPA, Hibernate' 카테고리의 다른 글

[Hibernate] Hibernate Validator  (0) 2016.06.11
[Hibernate] Custom Validator  (0) 2016.06.11
[Hibernate] ddl-auto  (0) 2016.06.11
[Spring Data Jpa] limit와 ordering  (1) 2016.06.11
[Spring Data Jpa] custom query 적용  (0) 2016.06.11
,
반응형

최근 로그성 데이터를 수집하여, RDB에 넣어놓고

내림차순하여 일정량의 데이터를 보여주어야 하는 API를 만들일이 생겼다.


그냥 날쿼리나 mybatis를 사용하면 간단하겠지만, 귀찮으므로 spring jpa를 이용해서 해결해보기로 하였다.


요구사항은 두가지


1. 데이터량 제한 (limit or top)

2. 내림차순 (order by asc | desc)


저 두 가지 요구사항 모두 Spring JPA의 JpaRepository를 구현한 인터페이스에 메소드 명 정책만 맞춰주면 해결이 된다.


// 시퀀스 기준으로 내림차순한 결과를 300개만 가져오는 메소드명

public List<?> findTop300ByOrderBySeqDesc();

구글링을 해보면, 보통 findTop300 다음에 조건문을 넣기 위해 컬럼명을 넣게 되는데,

필요없는 경우에는 컬럼명을 생략이 가능하다. (이런 예제가 없어서 하루종일 헤맴;;)


Order By는 그냥 쿼리 작성하듯이 자연스럽게 작성해주면 된다.


역시 jpa는 편리하군

반응형

'개발 > JPA, Hibernate' 카테고리의 다른 글

[Hibernate] Hibernate Validator  (0) 2016.06.11
[Hibernate] Custom Validator  (0) 2016.06.11
[Hibernate] ddl-auto  (0) 2016.06.11
[Hibernate] Entity 선언 시 주의점  (0) 2016.06.11
[Spring Data Jpa] custom query 적용  (0) 2016.06.11
,
반응형

JpaRepository를 상속받은 후, @Query라는 Annotation을 이용해서 custom query를 작성 가능한데,

이 Annotation의 property중 nativeQuery라는 게 있다.


커스터마이징한 쿼리의 결과가 JpaRepository 상속 시 선언된 Object의 클래스형과 동일하거나 해당 Object에 포함된 컬럼이라면,

@Query에 커스텀 쿼리만 작성을 하면 되지만, 쿼리에서 컬럼에 alias를 걸어서 이리저리 지지고 볶는 경우에는 분명히 리턴 값이 달라지게 된다.


이런 경우에는 nativeQuery를 true로 잡아주지 않으면, 서버가 올라가면서 테이블이 매핑되지 않았다고 뭐라뭐라한다.


여기까지하면 서버 올라갈때 문제는 없는데, 직접 쿼리 실행할 때 주의할 점이 있는데..

@Query에 value로 쿼리를 넣을 때 쿼리가 길면 정리하고 싶어지게 마련인데.. 띄어쓰기 같은거 다 체크하는거 같음.. 왠만하면 보기싫어도 그냥 쭉 길게 쓰는걸 추천.. (hsqldb에서만 그런걸지도;;)


전반적으로 jpa가 편하긴 한데, 국내에 사용하는 사람이 별로 없어서인지 몰라도 예외상황이 발생하면, 자료 찾기가 너무 힘들다; 

반응형

'개발 > JPA, Hibernate' 카테고리의 다른 글

[Hibernate] Hibernate Validator  (0) 2016.06.11
[Hibernate] Custom Validator  (0) 2016.06.11
[Hibernate] ddl-auto  (0) 2016.06.11
[Hibernate] Entity 선언 시 주의점  (0) 2016.06.11
[Spring Data Jpa] limit와 ordering  (1) 2016.06.11
,
반응형