2012-06-02 4 views
0

Я разрабатываю веб-интерфейс базы данных для школы. Но у меня проблемы со многими отношениями. Когда я его комментирую, мой сервер запускается без проблем. Вот трассировка стека запуска.двунаправленное много-ко-многим и 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); 

Вы можете посетить docadmin на 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

Я бы сказал, что ошибка довольно очевидна. Вы загружаете объект, в этом случае у пользователя в сеансе, который остается открытым. Затем вы вызываете обновление, которое пытается присоединить этот объект к новому сеансу.

Эта линия:

user = userDAO.getVfsUserByLogin(login); 

должен открыть сессию для загрузки пользователя. Затем вы явно открываете другой сеанс и вызываете обновление. На самом деле вам не нужно называть обновление, если пользователь уже подключен к сеансу, так как Hibernate уже автоматически загрязняет его.

+0

Благодарим вас за ответ. Это сработало, но я мог сказать, как получить объект сеанса или лучше закрыть сессию в обратном вызове спящего режима? – weedlight

+0

Я не уверен, почему это уже не правильный ответ, учитывая, что он объяснил вашу проблему? Я не эксперт в обратном вызове Hibernate, так как я обычно использую Hibernate напрямую. –

 Смежные вопросы

  • Нет связанных вопросов^_^