Tag Archives: Java

JAVA – Serializable

Serializable은 왜 사용하는가?

자바의 직렬화 기능을 사용하는 객체를 명시적으로 알려준다. 이것을 안쓰면 직렬화가 안된다.
라고 알고 있었는데

이 기회에 알아보려고 좀 찾아봤다.

 

 

기존에는이 객체는 데이터 오브젝트이다 라는 것을 명시하기 위해 사용했었다.
ajax, rest api 등등에 사용하는 DTO(VO..) 객체에 그냥 붙였다. gson/jackson을 이용한 serialization에는 필수적이지는 않지만 그냥 확실히 표시 해 주기 위해서..
AjaxWrapper<T extends Serializable> 을 명시해서 Serializable가 선언된 DTO만 들어올 수 있도록

이경우 MAP을 사용할 수 없지만 -> 이 설계를 잡을 때 명시적인 도메인을 쓰고 map을 쓰지 않는게 원래 목표였으니 잘된건가?

 

Serializable 인터페이스에 대해 알아보기 위해.. 먼저 

Serialization하고 붙어다니는 serialVersionUID
이게 선언되어 있지 않으면 jvm에서 자동으로 생성을 한다고 한다.
http://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html#4100

The stream-unique identifier is a 64-bit hash of the class name, interface class names, methods, and fields. The value must be declared in all versions of a class except the first. It may be declared in the original class but is not required. The value is fixed for all compatible classes. If the SUID is not declared for a class, the value defaults to the hash for that class. The serialVersionUID for dynamic proxy classes and enum types always have the value 0L. Array classes cannot declare an explicit serialVersionUID, so they always have the default computed value, but the requirement for matching serialVersionUID values is waived for array classes.

영어로 서너번 읽은 것 같은데.. 정확히 이해가 안간다.
첫번째 생성한 클래스.. 변경이 없었다면 0L이 기본으로 셋팅이 될테니 꼭 선언을 할 필요가 없다는것 같다.
클래스에 변경이 있었다면 구버전과 비교를 위해 이 넘버를 명시하는게 필수적이 된다는 거시다.(아마도)

 

Serializable에 대단한 기능이나 의미가 있는 것은 아닌 것 같다.
그냥 JVM에서 제공하는 직렬화를 사용한다고 명시하는 것. JVM에서 기본적으로 제공하는 직렬화/역직렬화 기능을 쓸 때 필수적이고, 내가 예전에 썼던것처럼 그냥 json으로 변환할 오브젝트에다가도 대충 갖다가 써또 되지 않을까 싶다. 그래서 계속 쓰던대로 쓰면 될 것 같다.

 

샘플코드를 작성한다면

Book(v0.1) without uid
Book(v0.2) without uid

Book(v0.1) with uid 1
Book(v0.2) with uid 2

Book(v0.1) without uid
Book(v0.2) with uid 2

이렇게 해서 비교해보면 될 것 같다

이건 간략예제

 

[ERROR] DB 커넥션이 알 수 없는 이유로 닫히는 경우

 

단순한 실수로 발생할 확률이 높고 의외로 해결에 시간이 오래 걸린다.

내 코드가 잘못됐다고 생각하지 않고 보통 다른데서 문제를 찾다보니 한참 걸린다.

 

이건 보통 transaction이나 connection close를 적절한 곳에서 해 주지 않아서 발생한다.

아마도…. 다른 이유였다면 검색하면서 시간 버리지 않고 금방 해결했을거다.

 

여태까지 여러 삽질을 해왔는데…
라이브러리의 문제로 오류가 발생했던 경험이 두어번정도 있었고 나머지는 다 내 코드 문제였다.

avro 자바-파이썬 에서 숫자자료형길이 호환안되는 문제 : 파이썬은 숫자자료형길이가 무제한

닷넷에서 뭐였는데… 스텍오버플로우에서 그거 닷넷버그라고 회피해서 사용하는법을 알려줬던 것 같다.

아 그리고… 오라클은 좀 많았던것같다.  아예 먹통은 아니고 의존성 문제였지만(문제있는 라이브러리는 패치를 하던가 삭제를 하던가.. 다운받게 공개를 해놔가지고)

 

몇년이나 일하면서 서너번이면 많지는 않으니

으~ 오라클 – Call Stored Procedure from Java Code 하는중에 생긴 중대한 호환성 오류

제목은 영어지만 내용은 한국어로

http://viralpatel.net/blogs/java-passing-array-to-oracle-stored-procedure

좋은 샘플 발견해고 코드 수정해서 돌려봤는데…

아무리 해도 응답값이 ARRAY.lengh() == 빵트루

뭐가 잘못된건가 싶어서 할 수 있는 모든코드에 디버깅을 돌려봤지만…

오라클은 디버깅이 안되지…

 

이런경우가 오랜만이라 쓸데없이 디버깅 하느라 반나절을 날려먹었다.

Solution : http://stackoverflow.com/questions/14998299/oracle-array-filled-with-null-data-in-java

 

이걸 항상 명심해야하는데말이지

알 수도 없고 디버깅 해도 안되는 오류는… 블랙박스 라이브러리의 버전 문제다.
이 프로젝트에는 오라클 ojdbc14.jar을 쓰고 있었는데
ojdbc6.jar + orai18n 이걸로 교체 해 주니 해결됐다.
코드에는 문제가 없었던걸로…

자바 개발을 하다보면 오픈소스만 쓰다보니 모든걸 직접 디버깅하고 오류를 발견할 수 있으리라는 착각에 빠지게 된다. 라이브러리도 정 맘에안드는 부분은 소스 수정하고 jar 패키징 다시해서 쓰기도 하고 하니까… github forking 해서 쓰기도 하고

오라클이나 SAP 등등 상용툴과 마주하게 되면 다른 개발습관이 필요한데

 

w3c xml 생성 변경 코드

작업중 필요없어져서 삭제하려다가 저장

Xml 이용해서 정보 저장하는코드.  오브젝트 네임을 바꿨는데 이 과정에서 오류가 약간 있을수도..

 

BCrypt 암호화 방식

비밀번호 저장에 특화된 암호화로 매 실행시마다 값이 변경된다.

글자수 제한이 있는것이 특징

자세한건 검색으로

테스트코드 첨부

 

[JAVA]시간변환 유틸 TimeUnit

이전에는 interval 기준으로 1000*x초 라는식으로 변환해서 계산을 했을데 이걸로 쓰면 좀 더 명확해서 좋은듯.

java.Validator 부족한 부분

상황을 지정할 수 있으면 어떨까

@NotNull
private String name;

@NotNull(scene = 1)
private String email;

 

위 두개의 필드가 있는 dto에서

상황 0 : 모두 동작
name, email notnull을 모두 체크

상황1 : 1만 동작
email만 체크

상황2 : 기본만 동작
name만 체크

 

이렇게 하면 validator에서 여러 상황을 복수로 셋팅할 수 있게됨

 

 

Jpa의 @ManyToMany 조인에서 구조상의 문제점

이런 구조의 Account 엔티티가 있다면

위의 groups에 3개 authorities에 2개의 데이터가 있다면 총 6개의 로우가 생성되서 출력이 되는 문제가 발생한다.
이것은 Hibernate에서 자동생성되는 다음과 같은 형태의 쿼리때문에 발생하는데
EAGER인 경우 쿼리를 묶어서 한번에 출력하려고 1개의 쿼리를 만들어내고

이것을 해결하려면

1 Set을 사용해서 중복이 제거되도록 하거나
이 경우 쿼리에서 데이터가 6개가 출력이 될 수도 있지만 중복을 자동으로 제거하게 된다. 이렇게 처리할 경우에는 ManyToMany 조인테이블에서 unique_index가 없어서 중복으로 들어가는게 가능한데 이렇게 데이터가 진짜로 중복으로 들어있는 경우가 발생하는것과 구분이 불가능하다.
2 ManyToMany가 두개이상 사용되는 경우 EAGER를 뺀다.
EAGER를 빼면 getGroups(), getAuthorities()가 실행될 때 별도의 쿼리를 실행시켜서 데이터 중복문제가 해결된다.

 

 

java 순차적으로 다른값을 입력시키는 setter 형태.

이런 형태로 결과값이 나오는 경우가 있다.

이 값을 responseDto형태의 클래스를 미리 선언해서 받는 경우

orderedSet형태로 선언을 해두면 그냥 세터선언해서 foreach로 받는다.