0

学校用の Web ベースのデータベース フロントエンドを開発しています。しかし、私は多対多の関係に問題があります。コメントアウトすると、サーバーは問題なく起動します。これが起動時のスタックトレースです。

 [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;
 }

多対多関係の 2 番目のクラス。

 @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 の docadmin にアクセスしてください。

    @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();
            }
        }));
    }
4

1 に答える 1

0

エラーはかなり明らかだと思います。この場合、開いたままのセッション内のユーザーで、オブジェクトをロードしています。次に、そのオブジェクトを新しいセッションにアタッチしようとする update を呼び出します。

この行:

user = userDAO.getVfsUserByLogin(login);

ユーザーをロードするには、セッションを開く必要があります。次に、別のセッションを明示的に開き、update を呼び出します。Hibernate はすでに自動的にダーティ チェックを行っているため、ユーザーが既にセッションにアタッチされている場合は、実際に update を呼び出す必要はありません。

于 2012-06-03T02:49:53.753 に答える