Whiteship's Note


Hibernate 에러 공유 1

모하니?/Coding : 2008.03.24 21:46


2008-03-24 12:35:49,674 WARN [org.hibernate.util.JDBCExceptionReporter] - <SQL Error: 0, SQLState: null>
2008-03-24 12:35:49,674 ERROR [org.hibernate.util.JDBCExceptionReporter] - <Batch entry 0 insert into Material (cdate, itemcnt, itemtypecnt, month, purprice, suppid, udate, materialid) values (2008-03-24 12:35:49.659000 +00:00:00, 0, 0, 200802, 0.0, 1, 2008-03-24 12:35:49.659000 +00:00:00, 89) was aborted.  Call getNextException to see the cause.>
2008-03-24 12:35:49,674 WARN [org.hibernate.util.JDBCExceptionReporter] - <SQL Error: 0, SQLState: 23505>
2008-03-24 12:35:49,674 ERROR [org.hibernate.util.JDBCExceptionReporter] - <ERROR: duplicate key violates unique constraint "=========">
2008-03-24 12:35:49,674 ERROR [org.hibernate.event.def.AbstractFlushingEventListener] - <Could not synchronize database state with session>
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:41)
    at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:969)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1562)
    at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
   
    at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:374)
    at org.springframework.orm.hibernate3.HibernateTemplate.executeFind(HibernateTemplate.java:343)
   
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)

Caused by: java.sql.BatchUpdateException: Batch entry 0 insert into ====  Call getNextException to see the cause.
    at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2534)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1328)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:352)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2596)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)


이것 때문에 이제 퇴근합니다. 더 늦게가면 운동 할 때 너무 추워서;; 삽질은 한 번으로 끝내자꾸나!!

위와 비슷한 에러를 만나시면, save()를 호출하기 전에 flushAndClear()를 호출해보세요.

외국인들을 위해 영어로도 한 마디..

If you meet this kind errors, just try sychnonize with DB(flushAndClear() or flush())before write(save(), saveOrUpdate()) any data to DB.
top

Write a comment.


하이버네이트 API : Persistence context 관리하기

Hibernate/Chapter 9 : 2008.03.11 15:07


Persistence Context 캐시 제어하기

  • Persistent 객체들의 스냅샷들을 캐시에 복사해둔다.
  • 이 캐시들을 사용하여 dirty checking을 하여 persistent 객체들의 변경 사항들을 찾아낸다.
  • 수천개의 객체들을 로딩하면, OutOfMemoryException을 내고 죽어버릴 수가 있다.
  • 캐시를 줄이거나 메모리 공간을 제약하려면 다음과 같이 해야 한다.
    1. 필요한 객체만 Persistent 상태로 유지하라. 전체 객체 그래프를 모두 끌어오다가는...
    2. session.evict(object)를 사용해서 persistent 상태의 객체를 명시적으로 detached 시킬 수 있다.
    3. session.clear()를 사용해서 Persistent Context에 있는 모든 객체를 detached로 만들 수 있다. 이 녀석들은 dirty checking하지 않는다.
    4. session.setReadOnly(object, true)를 사용해서 특정 객체에 대해서는 dirty checking을 하지 않도록 설정할 수 있다. false를 주면 다시 한다. 객체의 상태는 바꾸지 않는다.

Persistent Context flushing 하기

  • 하이버는 Persistent 객체들에 대한 변경 사항을 바로바로 DB에 반영하지 않는다.
    1. DB 요청을 최소화 할 수 있다.
    2. DB 롹킹 기간을 최소화 한다.
    3. JDBC batch API의 장점을 취할 수 있다.
  • flush(): DB와 Persistent Context의 동기화
    1. Transaction(하이버의 API)이 commit() 될 때.
    2. 쿼리를 실행하기 전에..
    3. session.flush()를 호출 할 때.
  • session.setFlushMode()를 사용할 수 있다. 기본값은 FlushMode.AUTO.
  • FlushMode.COMMIT으로 설정하면
    1. 쿼리를 실행하기 전에.. 동기화를 하지 않는다.
    2. 오직 Transaction.commit()과 session.flush()를 할때 만 동기화한다.
    3. 쿼리 -> 수정 -> 쿼리 -> 수정. 이런 경우에 FlushMode를 Commit으로 설정해주면 효율적이다.
  • FlushMode.MONUAL로 설정하면
    1. 오직 session.flush()를 호출 할 때만 동기화한다.
  • FlushMode 제어는 나중에 Persistent Context를 Conversation으로 확장할 때 사용할 것이다.
  • 중요한 것은 flush 처리의 성능은 persistent context의 크기에 따라 달라진다는 것이다.
top

Write a comment.