-->
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.  [ 1 post ] 
Author Message
 Post subject: NonUniqueObjectException
PostPosted: Thu Jun 17, 2004 2:19 pm 
Newbie

Joined: Wed Jun 16, 2004 9:12 am
Posts: 9
I am having a really strange problem that drives me nuts and I hope to get some help from here...

Imagine the following use case:

You want to store information about books in a database.
A book has an attribute for its contributor, who has a certain role, e.g. "author". In addition, this book offers an attribute to store information about other books that reference this book. These referencing books have the same properties as the new one. They have a contributor, who again has a certain role. The referencing books are already persistent.

When the user wants to create a new book, he / she has to select an author out of a list of already persitent authors (i.e. contributors that have a role (object) "author"). In a next step the user is able to select books that reference the book that the user wants to create. These referencing books are persistent as well. The have the same attributes as the book described above, i.e. the have contributors in roles of authors. The roles are stores within the database in one table. There should be just one row for every role (at least n:1 relation).

When the user selects some referencing books they are loaded from the database and added to the object of the new book that is not persistent yet.

As descibed in the mapping file, the loading process of the persistent books entails the loading of their contributors and the corresponding roles.

This chain of loading procedures results in some problems, when a referencing book has a contributor with the same role as the contributor of the new book. This throws NonUniqueObjectException as soon as you try to save the new book.

I already learned that Hibernate loaded the same database row twice and instanciates two (role) objects within the same session, though it should load it just one and adjust the object references. This is the reason for the exception but I haven't found a solution so far.

AbstractResource Mapping (Inheritance: AbstractResource -> Resource -> Book)
Code:
<hibernate-mapping>
<class name="AbstractResource" table="t_pub_abstractresource">

  <id name="id" column="ResourceID" type="java.lang.Long">
    <generator class="native"/>
  </id>   

  <property name="title" column="Title"/>


  <joined-subclass name="Resource" table="t_pub_resource">
    <key column="ResourceID"/>

    <set name="assignedContributors" table="t_pub_assigned" cascade="save-update">
      <key column="ResourceID"/>

      <composite-element class="AssignedRelation">
        <many-to-one name="role" column="RoleID" class="Role" cascade="save-update"/>
        <many-to-one name="abstractContact" column="AbstractContactID" class="AbstractContact" cascade="save-update"/>   
      </composite-element>
     
    </set>
   
    <joined-subclass name="de.tub.cis.emn.prototype.model.resource.Book" table="t_pub_book" dynamic-insert="true" dynamic-update="true">
      <key column="ResourceID"/>
      <property name="isbn" column="ISBN" type="java.lang.String"/>
    </joined-subclass>
   
    <!-- omit the other subclasses -->
   
  </joined-subclass>

</class>
</hibernate-mapping>


Inserting lazy="true" fixed the problem with this use case but arose new exception at another place. I think I can fix them with a filter opening the session right after the request and close it after the rendering, but this will take some time and I asked myself if there is another solution for this problem.

Role Mapping
Code:
<hibernate-mapping>
<class name="Role" table="m_contributorrole" >
  <id name="id" column="ContributorRoleID" type="java.lang.Long">
    <generator class="native"/>
  </id>
     
  <property name="roleDescription" column="role" type="java.lang.String" />
     
  </class>
</hibernate-mapping>


Java - ResourceService
Code:
[...]
public Resource getResource(int i){

/*
* Get session via ConnectionFactory (Singleton) using SessionFactory
*/         
Session session = ConnectionFactory.getInstance().getSession();

try
{
  Object o = session.load(Resource.class, new Long(i));
  return (Resource)o;
}
[...]


Java - Method Call Add Book
Code:
AbstractResource resContainedIn = ResourceService.getInstance().getAbstractResource(selectedContainedInId);
resource.addReference(resContainedIn);


Java - Method Call Save
Code:
Session session = ConnectionFactory.getInstance().getSession();

try{

  Transaction tx = session.beginTransaction();

  session.clear();
  session.saveOrUpdate(r);
  tx.commit();
   
}


I hope I haven't forgotten too much details - it's just that I am really confused and not to see the woods for the trees.

Finally the technical details:
- Hibernate 2.1.3
- Tomcat 5
- mysql 4.0.18
- Struts

I really appreciate any suggestions...
Thanks,
Florian


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

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.