행복한 아빠

JPA 에서 Blob 처리 본문

잡다한기록

JPA 에서 Blob 처리

행복한아빠 2009. 12. 3. 12:33

지난 번에 "Spring과 Hibernate에서 Blob Object 처리하기"에서 파일같은 바이너리를 database에 blob으로 저장하기 위한 방법을 살펴봤습니다. 이 글에서 왜 파일같은 바이너리를 java 객체의 멤버로 byte[]를 쓰면 위험한지도 설명했습니다. 그런데 Spring에서 hibernate를 JPA로 사용하려다보니, hibernate sessionFactory에 lobHandler를 설정(inject)해야 하는데 JPA에서는 entityManager 설정만 있어 lobHandler를 JPA 엔진인 hibernate에 전달할 방법이 마땅치 않았습니다.

JPA 표준 API로 작업하려다 보니 hibernate와 같은 벤더 특정 기능이나 API를 사용하는데 어려움이 있네요. 그래서 JPA에서 blob을 스트림으로 처리하기 위해서 다음과 같이 했습니다.

표준 API를 이용하자

Java 객체(JPA를 사용하니 entity bean이 되겠네요)의 binary 부분을 Blob 타입으로 정의합니다.

	@Lob
	@Column(name = "PHOTO")
	private Blob photo;

	/**
	 * @return the photo
	 */
	public Blob getPhoto() {
		return photo;
	}

	/**
	 * @param photo the photo to set
	 */
	public void setPhoto(Blob photo) {
		this.photo = photo;
	}
	
	/**
	 * Returns the photo Input Stream.
	 * @return InputStream 
	 * @throws SQLException e
	 */
	public InputStream getPhotoContent() throws SQLException {
		if (getPhoto() == null) {
			return null;
		}
		
		return getPhoto().getBinaryStream();
	}
	
	/**
	 * 
	 * @param sourceStream - Photo source input stream
	 * @throws IOException e
	 */
	public void setPhotoContent(InputStream sourceStream) throws IOException {
		setPhoto(Hibernate.createBlob(sourceStream));
	}



EntityManager로 저장합니다.

...
MyFileContent fileContent = new MyFileContent();
fileContent.setPhotoContent(new FileInputStream(file));
em.persist(fileContent);
...


도메인 객체에 java.sql 패키지라니...

POJO를 지향하는 사람들은 위의 Java 객체의 멤버로 java.sql.Blob 타입을 사용하는 것에 불편함을 느낄수도 있을 겁니다. 그 이유는 JPA나 hibernate와 같이 저장을 위한 객체를 순수한 도메인 객체로 보는 시각때문인데, 도메인 객체에 java.sql 과 같은 기술적인 패키지가 들어와 오염시키는 것 때문에 불편할 겁니다.

그러나 저장을 위한 객체를 진정한 의미의 도메인 객체인지 생각해 볼 필요가 있습니다. 그리고 도메인 객체가 뭘 의미하는 것도 생각해 볼 필요가 있습니다.

Entity Bean이나 hibernate annotation이 잔뜩 붙은 java 객체는 database 저장이 주 목적인 객체입니다. 특히 관계형 DB에 저장하는 것이 주된 목적이죠. 이런 객체에 더 많은 의미(핵심 비즈니스)를 넣으려는 시도는 슈퍼 울트라 객체를 하나 더 탄생시킬 뿐입니다. 그냥 그 목적에 충실하게 쓰는 편이 좋습니다.

진짜 핵심 비즈니스를 함축한 도메인 객체를 만들기 위해서는 database든 ui든 확실히 분리시키는 것이 좋습니다. ORM을 이용하면 도메인 객체가 자동으로 나온다는 환상은 버리는 편이 좋습니다. 훌륭한 도메인 객체는 훌륭한 프레임워크나 API를 사용하면 나오는게 아니고 훌륭한 설계나 아이디어에서 나옵니다.

 

1 Comments
  • 프로필사진 xperad 2012.12.17 05:06 좋은 정보 감사합니다.
    JPA사용하고, blob타입으로 파일을 저장할 때, Hibernate 4 버젼?에서는 Hibernate.createBlob() 메소드가 없습니다. 3버젼에서 쓴다고 하더라도 해당메소드가 deprecated 된 듯합니다. Hibernate.getLobCreator(Session session).createBlob(InputStream) 방법이 있긴 합니다만, JPA에서는 하이버네이트의 세션을 별로 관여하지 않는 것 같아서요.
    좋은 방법이 있을까요.
댓글쓰기 폼