2014-03-10

JPA - Hibernate Specific WTF Rules

JPA 구현 중 가장 널리 쓰이는 것들이 EclipseLink와 Hibernate이다.
JPA 2.0 이후로는 EclipseLink가 레퍼런스 구현임에도 일단 한국에서는 EclipseLink보다는 Hibernate를 더 많이 쓰는데, Hibernate가 아무래도 역사도 오래됐고 속도는 느리지만 그만큼 편의기능이 많아서 그렇지 않나 싶다.
한국에서 EclipseLink 미는 사람은 저밖에 없는듯?

여기서는 Hibernate 특유의 정신나간 특징들을 내 맘대로 (...) 찝어보겠다.
  1. SEQUENCE를 지원하지 않는 DBMS(예를 들면 MSSQL이나 MySQL)를 타겟으로 @GeneratedValue(strategy = GenerationType.SEQUENCE)를 사용하면 좆된다.
  2. Spring에서 엔티티를 @SessionAttribute로 물릴 경우 @ElementCollection의 fetch 속성을 EAGER로 설정해야 한다.
    안그러면 나중에 엔티티 값을 수정할 때 초기화 되지 않았다고 뭐라 그런다.
  3. @ElementCollection의 fetch 속성을 EAGER로 설정했으면 Hibernate에서 제공하는 @Fetch로 긁어올 방식을 설정해 주어야 한다.
    안붙여주면 처음 실행할 때부터 테이블 Alias가 없네 하면서 정신줄 놓는다.
일단은 여기까지.
더 밝혀낸 것이 있으면 계속 업데이트될 지도 모른다.
Share:

2013-11-04

java.io.IOException: error=12, Cannot allocate memory? WTF?!

자바의 유서깊은(?) 골칫거리로, 자바에서 fork() + exec() 하는 방식에 문제가 있기 때문이다.
(자세한 내용은 여기를 참고하면 좋다.)

위 링크에서 4가지 해결책이 나온다.
  1. 닥치고 메모리 증설
  2. fork() 호출시 swapfile을 추가하도록 꼼수 사용
  3. 리눅스: sysctl의 vm.overcommit_memory 속성을 1로 설정
  4. POSIX 호환 시스템: fork() + exec() 대신 posix_spawn() 사용하기

리눅스라면 vm.overcommit_memory=1 이 아무래도 빠르고 편하겠지만, 동작방식이 후덜덜하므로 overcommit이 일어날 때 커널에서 노는 메모리를 수거하는데, 이 때 어떠한 확인도 없이 막무가내로 수거하므로 잠자고 있는 멀쩡한 다른 프로세스의 메모리를 수거할 수 있다! 미션 크리티컬한 시스템에는 그냥 하지마라. 그런 시스템이라면 2웨이 이상일테니 그냥 닥치고 1번이 더 정신건강에 좋을 것이다. 돈은 좀 많이 깨지겠지만 내가 알 게 뭐야...

또한 자바의 fork() + exec()를 posix_spawn()으로 교체해주는 java_posix_spawn이 개발되어 있으므로, 이를 고려해보는 것도 좋을 것이다. 하지만 실제로는 posix_spawn()을 사용하지 않는다는게 함정. vfork() 쓴댄다.

덤

vm.overcommit_memory 관련 문서는 레드햇 문서와 노벨 문서를 보면 대략 좋다.


2015-02-23:
리눅스에 zram이라는게 있는데, 써본 결과 매우 좋소!
zram 쓰기 전에는 메모리 10그램으로도 헥헥대던게, zram 쓰고 난 다음부터는 메모리에 여유가 생겼다.
물논 CPU가 그만큼 일을 더 하게 되지만 내가 알 게 뭐야...
Share:

2013-11-01

bash로 git의 빈 디렉토리 컨트롤하기

(2014-11-19: 좀 더 깔끔하게 수정)


git의 유일한 단점은 빈 디렉토리를 관리 할 수 없다는 것이다. 따라서 빈 디렉토리를 강제로 관리하려면 대충 아무 파일이나 던져놓는 수 밖에 없다.
MarkEmptyDirs라는 툴이 있기는 하지만, 깔기 귀찮다. 그냥 bash 있는거 쓰고 말지…

본문

find . -name ".emptydir" -delete; find -empty -type d | while read x; do touch "$x/.emptydir"; done

참 쉽죠?

주의: 이 스크립트에는 버그가 있지만 여백이 부족하므로 더 이상의 자세한 설명은 생략한다. 차마 귀찮아서라고는 못하겠다. 예제를 수정하면서 더이상은 naver!

해설

  1. 먼저 하위 디렉토리에서 .emptydir 파일을 찾아서 제거한다.
  2. 그 다음 빈 디렉토리를 찾아서 크기가 0인 .emptydir 파일을 생성한다.
참 쉽죠? (2)

응용

이클립스에 올려서 프로젝트에 먹일 수도 있다.

Run → External Tools → External Tools Configuration... 에 가서 새 프로그램 항목을 만든다.

  1. 이름은 적절하게 등록한다.
  2. Location: /bin/bash
  3. Working Directory: ${project_loc}
  4. Arguments: -c "find . -name \".emptydir\" -delete; find -empty -type d | while read x; do touch \"$x/.emptydir\"; done"

그 다음 Run → External Tools → Organize Favorites... 에서 방금 만든 것을 선택하면 툴바에서 한 방에 실행할 수 있다.

참 쉽죠? (3)
Share: