2009-04-21 7 views
0

NetBeans에서 최대 절전 모드를 사용 중입니다. NetBeans 용 Hibernate 플러그인과 함께 제공되는 최대 절전 모드 util 클래스를 사용하여 현재 세션을 가져옵니다.최대 절전 모드 세션 문제

this.session = HibernateUtil.getSessionFactory().getCurrentSession(); 

하지만 게으른하려고 할 때이 오류 다음 부여합니다 아무것도 가져 : 나는이 DAO를 사용하고

org.hibernate.LazyInitializationException: failed to lazily initialize a course.

그건 내가 내 현재의 세션을 얻기 위해 다음 코드를 사용하고있다. 하나는 Abstract DAO이고 두 번째는 AbstractDAO를 확장 한 CoutseDAO입니다.

public class CourseDAO extends AbstractDAO<Course>{ 

    public CourseDAO() 
    { 
     super(); 
    } 

    public Course findByID(int cid){ 


     Course crc = null; 
     Transaction tx = null; 
     try { 
      tx = session.beginTransaction(); 
      Query q = session.createQuery("from Course as course where course.cid = "+cid+" "); 
      crc = (Course) q.uniqueResult(); 
      tx.commit(); 
     } 
     catch (HibernateException e) 
     { 
      e.printStackTrace(); 
      tx.rollback(); 
      throw new DataAccessLayerException(e); 
     } 

     finally 
     { 


     } 
     return crc; 
} 


    public List<Course> findAll(){ 

     List lst = null; 
     Transaction tx = null; 
     try { 
      tx = session.beginTransaction(); 
      Query q = session.createQuery("from Course "); 
      lst = q.list(); 
      tx.commit(); 
     } 
     catch (HibernateException e) 
     { 
      e.printStackTrace(); 
      tx.rollback(); 
      throw new DataAccessLayerException(e); 
     } 

     finally 
     { 



     } 
     return (List<Course>)lst ; 
} 







} 
+0

세션을 검색하는 방법뿐만 아니라 DAO를로드하는 데 사용하는 전체 코드를 게시해야합니다. – Elie

+0

이것은 Hibernate가 의도 한 작업을 수행하기 위해 DAO를 잘못 사용하는 것처럼 보입니다. 'createObject (T 객체)', Hibernate가 작업을 수행해야하는 쿼리를 작성하며, 트랜잭션 경계는 DAO 메소드 경계에서 끝납니다. 모든 것이 완전히 잘못되었으므로 절대적인 고비입니다. * 모든 DAO 항목을 제거하고 Hibernate를 직접 사용하십시오. –

답변

-1

'오래된'개체가 희생되었을 수 있습니다. Seam을 사용할 때 주입 된 객체에 대해이 문제가 발생합니다. 우리의 솔루션은 전화처럼 사용하기 전에 기본 개체를 다시 가져왔다 : 당신이 우리의 행동 클래스의 메소드를 호출 할 때마다

getEm().find(MyClass.class, id); 

기본적으로, 당신은 객체가 아니라는 것을 확인하기 위해이 작업을 수행 할 필요가 현재 세션/트랜잭션에서 유효 기간이 만료됩니다.

또한 예외 (catch 된 경우에도)는 현재 세션을 닫아 LazyInitialization 오류를 일으킬 수 있습니다.

+0

문제는 그의 모든 DAO 방법에 대한 퍼팅 TX 경계입니다. 이는 게으른로드 된 객체에 대한 문제를 보장합니다. –

0

게으른 필드 개체를 가져 트랜잭션의 경계 내에서만 액세스 할 수 있습니다를 다음과 같이

public class AbstractDAO<T> { 


    Session session = null; 


    public AbstractDAO() 
    { 
     this.session = HibernateUtil.getSessionFactory().getCurrentSession(); 

    } 

    public void createObject(T object) 
    { 
     Transaction tx = null; 
     try 
     { 

      tx = session.beginTransaction(); 
      session.save(object); 
      tx.commit(); 

     } 
     catch (HibernateException e) 
     { 
      tx.rollback(); 
      throw new DataAccessLayerException(e); 

     } 
     finally 
     { 


     } 
    } 
    public void updateObject(T object) 
    { 
     Transaction tx = null; 
     try 
     { 

      tx = session.beginTransaction(); 
      session.update(object); 
      tx.commit(); 

     } 
     catch (HibernateException e) 
     { 
      tx.rollback(); 
      throw new DataAccessLayerException(e); 

     } 
     finally 
     { 


     } 
    } 

     public void deleteObject(T object) 
    { 
     Transaction tx = null; 
     try 
     { 

      tx = session.beginTransaction(); 
      session.delete(object); 
      tx.commit(); 

     } 
     catch (HibernateException e) 
     { 
      tx.rollback(); 
      throw new DataAccessLayerException(e); 

     } 
     finally 
     { 


     } 
    } 

} 

초 클래스의 사용은 다음과 같이 코드입니다.

+0

내 proplem에 대한 DAO 구현을 제안 할 수 있습니다 – user93796

0

hibernate가 동일한 트랜잭션에서 lazy 페칭에 대한 쿼리를 수행 할 수 있도록 트랜잭션 관리자를 설정해야합니다.

최대 절전 모드 사이트가 다운 보이지만 구글은 최대 절전 모드 구성에서 쓰레드 범위의 전략을 가능하게하려면 cache

있습니다

JPA, EJB 또는 롤링 같은 다른 옵션이 있습니다
set hibernate.transaction.factory_class to org.hibernate.transaction.JDBCTransactionFactory 
set hibernate.current_session_context_class to thread 

너 스스로.

응용 프로그램 서버에서 실행 중이 아니면 다른 방법으로 트랜잭션을 처리하는 다른 방법을 사용하는 경우 코드가 "수동으로"트랜잭션을 시작해야합니다.

try { 
    factory.getCurrentSession().beginTransaction(); 

    // Do some work 
    factory.getCurrentSession().load(...); 
    factory.getCurrentSession().persist(...); 

    factory.getCurrentSession().getTransaction().commit(); 
} 
catch (RuntimeException e) { 
    factory.getCurrentSession().getTransaction().rollback(); 
    throw e; 
} 
+0

어디에서이 옵션을 설정할 수 있습니까? hibernate.cfg.xm 파일. 그렇다면 어떻게? – user93796

+0

이 매개 변수를 설정하려고했지만 동일한 코드로 작업하지 않습니다. – user93796

+0

코드를 수행하기 전에 트랜잭션을 시작해야합니다. 다소 복잡하기 때문에 문서를 읽으십시오. google 캐시 링크를 사용해보십시오. – KarlP

0

이것은 Hibernate가 의도 한 작업을 수행하기 위해 DAO를 오용 한 것 같습니다. Hibernate가 일을 할 수있는

  1. 트랜잭션 경계가
  2. 당신이 긴 형식 쿼리를 작성하지 말아야 있습니다 .. DAO 방식의 경계에서 종료하지 않아야,
  3. findById 메소드()는 단지 세션의 호출해야한다 .load (Course.class, id).
  4. createObject(T object)은 잘못된 이름입니다. '저장'해야합니다.
  5. exception-catching이 잘못 배치되었습니다. Tx 경계에 있어야합니다.

모든 것이 완전히 잘못되었으므로 절대적으로 잘못되었습니다. 작성한 모든 내용이 잘못되었습니다. & 불필요합니다. 천국을 위해서 JDBC & 트랜잭션 관리를 작성하려고합니다.이 작업이 이미 완료되었을 때입니다.

여기에 코드를 이동해야하는 방법은 다음과 같습니다

Session hb = sf.openSession(); // or wherever you get a Session from 

// load by ID 
Course course = (Course) hb.load(Course.class, id); 

// list all courses 
Criteria crit = hb.createCriteria(Course.class); 
List<Course> allCourses = crit.list(); 

// create a new Course 
Course newCourse = new Course("Hibernate 101"); 
hb.save(newCourse); 

// delete the old one 
hb.delete(course); 

// flush & commit all changes, in a transaction. 
Transaction tx = hb.beginTransaction(); 
/* hb.flush() */ 
tx.commit(); 

는 당신이 무슨 일을하는지 알 때까지이 DAO는 쓰레기 & 사용, 직접 최대 절전 모드 모든 제거하십시오. DAO/비즈니스 메소드는 이고 트랜잭션/예외 관리를 시도하지 않아야합니다. 그들은 내에서을 실행합니다.