-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: net.sf.hibernate.NonUniqueObjectException!?
PostPosted: Tue Dec 30, 2003 9:01 am 
Pro
Pro

Joined: Wed Oct 08, 2003 10:31 am
Posts: 247
I'm getting the following error:

net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: pt.comseal.arsol.vo.VersaoDocumentoPK@b113c7[id=1,documento=pt.comseal.arsol.vo.Documento@1cf662f[id=2]], of class: pt.comseal.arsol.vo.VersaoDocumento
at net.sf.hibernate.impl.SessionImpl.checkUniqueness(SessionImpl.java:1605)
( ... )

To try to solve this I did a "session.evict(doc_aux);" below in the "Method code" section but with no success.
I also tried to use a second Session and going a "get" on the Documento with that session instance and still with no success.
I first do a "get" on Documento to see if it exists and then I do a "get on VersaoDocumento to see if it exists also. The second "get" is the one that's throwing the exception because VersaoDocumento has a composite-id VersaoDocumentoPK which has a Documento as one of its components.

Please help. Don't understand the error.


------------------------------------------
Mapping files (generated with R3)
------------------------------------------
Documento
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
   
<hibernate-mapping>
<!--
    Created by Middlegen Hibernate plugin

    http://boss.bekk.no/boss/middlegen/
    http://hibernate.sourceforge.net/
-->

<class
    name="vo.Documento"
    table="documento"
>

    <id
        name="id"
        type="long"
        column="id"
    >
        <generator class="increment" />
    </id>

    <property
        name="nome"
        type="java.lang.String"
        column="nome"
        length="-1"
    />

    <!-- associations -->
    <!-- bi-directional one-to-many association to VersaoDocumento -->
    <set
        name="versaoDocumentos"
        lazy="true"
        inverse="true"
    >
        <key>
            <column name="documento_fk" />
        </key>
        <one-to-many
            class="vo.VersaoDocumento"
        />
    </set>

</class>
</hibernate-mapping>


VersaoDocumento
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
   
<hibernate-mapping>
<!--
    Created by Middlegen Hibernate plugin

    http://boss.bekk.no/boss/middlegen/
    http://hibernate.sourceforge.net/
-->

<class
    name="vo.VersaoDocumento"
    table="versao_documento"
>

    <composite-id name="comp_id" class="vo.VersaoDocumentoPK">
        <key-property
            name="id"
            column="id"
            type="long"
            length="8"
        />
        <!-- bi-directional many-to-one association to Documento -->
        <key-many-to-one
           name="documento"
           class="vo.Documento"
       >
           <column name="documento_fk" />
       </key-many-to-one>
    </composite-id>   

    <property
        name="descricao"
        type="java.lang.String"
        column="descricao"
        length="-1"
    />

    <!-- associations -->

</class>
</hibernate-mapping>


-------------------
Method code
-------------------

Code:
( ... )
SessionFactory sessionFactory = HibernateFactory.createFactory();   
session = sessionFactory.openSession();
transaction = session.beginTransaction();
         
Documento doc_aux = (Documento)session.get(Documento.class, documento.getId());
if(doc_aux == null) {
   throw new ObjectoNaoEncontradoException("Error.");
}

VersaoDocumento versao_doc = (VersaoDocumento)documento.getVersaoDocumentos().iterator().next();
session.evict(doc_aux);
         
if((VersaoDocumento)session.get(VersaoDocumento.class, versao_doc.getComp_id()) == null) {
   throw new ObjectoNaoEncontradoException("Error.");
}

session.saveOrUpdate(documento);
session.saveOrUpdate(versao_doc);

transaction.commit();
session.close();
( ... )


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 30, 2003 9:19 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Thats pretty logical:

VersaoDocumento versao_doc = (VersaoDocumento)documento.getVersaoDocumentos().iterator().next();
session.evict(doc_aux); This

if((VersaoDocumento)session.get(VersaoDocumento.class, versao_doc.getComp_id()) == null) {
throw new ObjectoNaoEncontradoException("Error.");
} Is the same as loaded here

Why do you do the second load anyways? If you want to refresh the object from the db, use session.refresh()

The whole thing looks strange to me, first you get an object out of a collection loaded from the db, and then you want to check again if it exists in the db?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 30, 2003 9:29 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Are equals and hashCode properly implemented for VersaoDocumento and it's PK.

Wht you're doing is :
    load Documento and associated VersaoDocumento
    get 1st VersaoDocumento
    evict documento (and probably it's associated VersaoDocumento, not sure)
    load another copy of the 1st VersaoDocumento (by your (VersaoDocumento)session.get(VersaoDocumento.class, versao_doc.getComp_id()))
    Associate your transient VersatoDocumento to the session while a copy has already been copied

the exception is expected

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 30, 2003 10:43 am 
Pro
Pro

Joined: Wed Oct 08, 2003 10:31 am
Posts: 247
gloeglm wrote:
Thats pretty logical:

VersaoDocumento versao_doc = (VersaoDocumento)documento.getVersaoDocumentos().iterator().next();
session.evict(doc_aux); This

if((VersaoDocumento)session.get(VersaoDocumento.class, versao_doc.getComp_id()) == null) {
throw new ObjectoNaoEncontradoException("Error.");
} Is the same as loaded here

...


I do the second test because I can have the following test code:
Code:
Documento documento = new Documento();
documento.setId(new Long(2));
documento.setNome("xpto");
      
HashSet versao_docs = new HashSet();
VersaoDocumento versao_doc = new VersaoDocumento();
VersaoDocumentoPK versao_doc_pk = new VersaoDocumentoPK();
versao_doc_pk.setId(1); // <-------- (1)
versao_doc_pk.setDocumento(documento);
versao_doc.setComp_id(versao_doc_pk);
      
versao_doc.setDescricao("smith");
      
versao_docs.add(versao_doc);
documento.setVersaoDocumentos(versao_docs);

// execute method for to update "documento"


And the client side can in fact, in (1) can do a "versao_doc_pk.setId();" to a value that could not exist. That's why I'm doing the second "get". And the first "get" doesn't tell me if the associated VersaoDocumento exists.
Another thing: I don't want to refresh the object from the DB. Just want to see if it exists. I may be misunderstanding something...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.