2012-06-02 2 views
0

학교용 웹 기반 데이터베이스 프론트 엔드를 개발 중입니다. 하지만 다 대다 관계에 문제가 있습니다. 내가 주석 처리하면 내 서버가 문제없이 시작됩니다. 다음은 시작의 스택 추적입니다.양방향 many-to-many 및 DAO가 HibernateException에서 종료 됨

[java] SCHWERWIEGEND: Exception sending context initialized event to listener instance of class org.docadmin.ContextListener 
[java] org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions 
[java]  at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410) 
[java]  at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:43) 
[java]  at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101) 
[java]  at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61) 
[java]  at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55) 
[java]  at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123) 
[java]  at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:293) 
[java]  at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223) 
[java]  at org.hibernate.event.def.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:33) 
[java]  at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70) 
[java]  at org.hibernate.impl.SessionImpl.fireUpdate(SessionImpl.java:564) 
[java]  at org.hibernate.impl.SessionImpl.update(SessionImpl.java:552) 
[java]  at org.hibernate.impl.SessionImpl.update(SessionImpl.java:544) 
[java]  at org.docadmin.security.DBAuthentication.login(DBAuthentication.java:87) 
[java]  at org.docadmin.ContextListener.contextInitialized(ContextListener.java:74) 
[java]  at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206) 
[java]  at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705) 
[java]  at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:799) 
[java]  at org.apache.catalina.core.ContainerBase.access$000(ContainerBase.java:124) 
[java]  at org.apache.catalina.core.ContainerBase$PrivilegedAddChild.run(ContainerBase.java:146) 
[java]  at java.security.AccessController.doPrivileged(Native Method) 
[java]  at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:777) 
[java]  at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:601) 
[java]  at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:943) 
[java]  at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:778) 
[java]  at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:504) 
[java]  at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1317) 
[java]  at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:324) 
[java]  at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142) 
[java]  at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1065) 
[java]  at org.apache.catalina.core.StandardHost.start(StandardHost.java:840) 
[java]  at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057) 
[java]  at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463) 
[java]  at org.apache.catalina.core.StandardService.start(StandardService.java:525) 
[java]  at org.apache.catalina.core.StandardServer.start(StandardServer.java:754) 
[java]  at org.apache.catalina.startup.Catalina.start(Catalina.java:595) 
[java]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
[java]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
[java]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
[java]  at java.lang.reflect.Method.invoke(Method.java:616) 
[java]  at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) 
[java]  at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) 
[java] 02.06.2012 09:42:54 org.apache.catalina.core.StandardContext listenerStart 
[java] SCHWERWIEGEND: Exception sending context initialized event to listener instance of class org.docadmin.ContextListener 
[java] org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions 
[java]  at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410) 
[java]  at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:43) 
[java]  at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101) 
[java]  at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61) 
[java]  at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55) 
[java]  at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123) 
[java]  at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:293) 
[java]  at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223) 
[java]  at org.hibernate.event.def.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:33) 
[java]  at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70) 
[java]  at org.hibernate.impl.SessionImpl.fireUpdate(SessionImpl.java:564) 
[java]  at org.hibernate.impl.SessionImpl.update(SessionImpl.java:552) 
[java]  at org.hibernate.impl.SessionImpl.update(SessionImpl.java:544) 
[java]  at org.docadmin.security.DBAuthentication.login(DBAuthentication.java:87) 
[java]  at org.docadmin.ContextListener.contextInitialized(ContextListener.java:74) 
[java]  at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206) 
[java]  at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705) 
[java]  at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:799) 
[java]  at org.apache.catalina.core.ContainerBase.access$000(ContainerBase.java:124) 
[java]  at org.apache.catalina.core.ContainerBase$PrivilegedAddChild.run(ContainerBase.java:146) 
[java]  at java.security.AccessController.doPrivileged(Native Method) 
[java]  at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:777) 
[java]  at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:601) 
[java]  at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:943) 
[java]  at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:778) 
[java]  at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:504) 
[java]  at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1317) 
[java]  at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:324) 
[java]  at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142) 
[java]  at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1065) 
[java]  at org.apache.catalina.core.StandardHost.start(StandardHost.java:840) 
[java]  at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057) 
[java]  at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463) 
[java]  at org.apache.catalina.core.StandardService.start(StandardService.java:525) 
[java]  at org.apache.catalina.core.StandardServer.start(StandardServer.java:754) 
[java]  at org.apache.catalina.startup.Catalina.start(Catalina.java:595) 
[java]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
[java]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
[java]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
[java]  at java.lang.reflect.Method.invoke(Method.java:616) 
[java]  at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) 
[java]  at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) 

여기 대다 관계

@Entity 
@Table(name="VFSUSR") 
@NamedQueries({ 
    @NamedQuery(name="org.docadmin.db.persistence.vfsusrById", 
     query="from VfsUser as vfsusr where vfsusr.id = :id"), 
    @NamedQuery(name="org.docadmin.db.persistence.vfsusrByLogin", 
     query="from VfsUser as vfsusr where vfsusr.login = :vfsusrlogin"), 
     }) 
     public class VfsUser 
     extends AbstractBasePersistableObject 
     { 
    /** 
    * the tables id, primary key 
    */ 
    @Id 
    @Column(name="VFSUSR_ID") 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Integer id; 

    /** 
    * foreign key many to many relationship 
    */ 
    @ManyToMany(mappedBy="user") 
    private Set<VfsGroup> group; 
} 

대다 관계의 두 번째 클래스의 첫번째 표이다.

@Entity 
@Table(name="VFSGRP") 
@NamedQueries({ 
    @NamedQuery(name="org.docadmin.db.persistence.vfsgrpById", 
     query="from VfsGroup as vfsgrp where vfsgrp.id = :id"), 
    @NamedQuery(name="org.docadmin.db.persistence.vfsgrpByGroupName", 
     query="from VfsGroup as vfsgrp where vfsgrp.groupName = :vfsgrpgroupname"), 
}) 
public class VfsGroup { 
    /** 
    * the tables id, primary key 
    */ 
    @Id 
    @Column(name="VFSGRP_ID") 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Integer id; 

    /** 
    * foreign key many to many relationship 
    */ 
    @ManyToMany(cascade=CascadeType.ALL) 
    @JoinTable(name="VFSGRPUSR", 
      joinColumns={@JoinColumn(name="VFSUSR")}, 
      inverseJoinColumns={@JoinColumn(name="VFSGRP")}) 
    private Set<VfsGroup> user; 
} 

마지막으로 예외가 발생한 코드입니다.

  /* retrieve some beans */ 
     sessionFactory = (SessionFactory) ApplicationContextProvider.getApplicationContext().getBean("sessionFactory"); 

     /* retrieve user */ 
     user = userDAO.getVfsUserByLogin(login); 

     /* open session and begin transaction */ 
     session = sessionFactory.openSession(); 
     tx = session.beginTransaction(); 

     securityToken = null; 

     try { 

      if(user != null && Arrays.equals(user.getPassword(), passwordStoreManager.getPasswordStore().encryptPassword(password))){ 
       securityToken = generateToken(); 
       user.setToken(securityToken); 
       session.update(user); 
      } 
     } catch (InvalidKeyException e) { 
      e.printStackTrace(); 
      logger.error("couldn't login as user[" + login + "] with password[****]", e); 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
      logger.error("couldn't login as user[" + login + "] with password[****]", e); 
     } catch (NoSuchPaddingException e) { 
      e.printStackTrace(); 
      logger.error("couldn't login as user[" + login + "] with password[****]", e); 
     } catch (IllegalBlockSizeException e) { 
      e.printStackTrace(); 
      logger.error("couldn't login as user[" + login + "] with password[****]", e); 
     } catch (BadPaddingException e) { 
      e.printStackTrace(); 
      logger.error("couldn't login as user[" + login + "] with password[****]", e); 
     }finally{ 
      /* commit transaction */ 
      tx.commit(); 

      /* close session */ 
      session.close(); 
     } 

     return(securityToken); 

당신은 sourceforge.net

@Override 
    public VfsUser getVfsUserByLogin(final String login) { 
     if(login == null){ 
      return(null); 
     } 

     return((VfsUser) getHibernateTemplate().execute(new HibernateCallback() { 
      public Object doInHibernate(Session session) { 
       Query query = getSession().getNamedQuery("org.docadmin.db.persistence.vfsusrByLogin"); 
       query.setString("vfsusrlogin", login); 
       return (VfsUser) query.uniqueResult(); 
      } 
     })); 
    } 

답변

0

나는 오류가 매우 분명하다 말할 것에 docadmin 방문 할 수 있습니다. 이 경우 개체가 열려있는 세션의 개체에로드하고 있습니다. 그런 다음 해당 객체를 새 세션에 첨부하려고하는 update를 호출합니다.

이 줄 :

user = userDAO.getVfsUserByLogin(login); 

은 사용자를로드하기 위해 세션을 열어야합니다. 그런 다음 명시 적으로 다른 세션을 열고 update를 호출하십시오. Hibernate가 이미 자동으로 더티 체크를했기 때문에 사용자가 세션에 이미 연결되어 있다면 실제로 update를 호출 할 필요가 없다.

+0

답장을 보내 주셔서 감사합니다. 그것은 작동하지만 세션 객체를 가져 오는 방법을 알려주거나 최대 절전 모드 콜백 내에서 세션을 닫아야합니까? – weedlight

+0

왜이 문제가 더 이상 정답이 아닌지 확신 할 수 없습니까? 나는 보통 Hibernate를 직접 사용하기 때문에 Hibernate 콜백에 대한 전문가는 아니다. –