-->
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.  [ 7 posts ] 
Author Message
 Post subject: Using the object's id as map key
PostPosted: Fri Jul 27, 2007 12:30 am 
Newbie

Joined: Sat Jul 14, 2007 11:50 am
Posts: 12
Location: the Burgh
Hi I was wondering how I'd use an object's id as a map key...

Right now I have a bunch of Sets and whenever I want to access one by it's id one I have to iterate through the entire set checking the id of each one. I thought I could just fetch the object by id, but that makes 2 instances of the same item (cause one's in the Set).

I'd like to use the object's id as it's index, but I object's ids aren't populated until they're made persistent... and I wouldn't be able to put a new item into it's map without knowing it's id...

So I'd like to turn this:

Code:
<set name="items" table="USER_ITEM" inverse="true" cascade="all-delete-orphan">
   <key column="USER_ID"/>
   <one-to-many class="beans.Item"/>
</set>


Into something that allows me to do this:

user.getItems().get(item_id);
user.getItems().remove(item_id);

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 27, 2007 5:18 am 
Newbie

Joined: Fri Jul 27, 2007 4:39 am
Posts: 7
Hi Tomisina,

Quote:
Right now I have a bunch of Sets and whenever I want to access one by it's id one I have to iterate through the entire set checking the id of each one. I thought I could just fetch the object by id, but that makes 2 instances of the same item (cause one's in the Set).

This is what queries are for. I'd suggest you use a criteria query for associations. With a criteria query combined with a projection this should just work fine. If you have the reverse mapping (from Item to User), you could look up the item with a simple query along the lines of
Code:
Criteria c = session.createCriteria(Item.class);
c.add(Restrictions.eq("user", user));
c.add(Restrictions.eq("<idColname>", item_id));

It's even easier if the id is unique for all items:
Code:
Criteria c = session.createCriteria(Item.class);
c.add(Restrictions.idEq("id", item_id));

Quote:
I'd like to use the object's id as it's index, but I object's ids aren't populated until they're made persistent... and I wouldn't be able to put a new item into it's map without knowing it's id...

If it's possible, you could let the DB generate the key. That depends on how Item is mapped.

Quote:
user.getItems().remove(item_id);

Sorry, for that one I don't really know.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 27, 2007 11:35 am 
Newbie

Joined: Sat Jul 14, 2007 11:50 am
Posts: 12
Location: the Burgh
Sorry, but that doesn't work... If I use the db to look up the item by it's id then you'll get 2 instances of the same object in the same session. That throws an error.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 27, 2007 12:08 pm 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
tomisina wrote:
Sorry, but that doesn't work... If I use the db to look up the item by it's id then you'll get 2 instances of the same object in the same session. That throws an error.


I guess you haven't actually tried that? Because if it were true, hibernate would also throw an exception when you execute to arbitrary queries, which happen to return at least on commen object. Hibernate will get the object from the cache included in the session, so instead of not working, it should actually work without accessing the database.

Jens


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 27, 2007 12:37 pm 
Newbie

Joined: Sat Jul 14, 2007 11:50 am
Posts: 12
Location: the Burgh
No it just throws one exception... I tried it:

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 30, 2007 5:32 pm 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
Thats really strange, either I got something wrong or this really should not happen.

:-(

Jens


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 30, 2007 6:38 pm 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
There's something odd going on here if you get a NonUniqueObjectException when loading an entity that already exists in another entity's collection. I've built a simple test case to verify that hibernate returns the same java object through load() when that object has already been retrieved in a collection. Try and narrow down your problem and post the resultant mappings and java files.

My test (using annotations):

Child.java
Code:
package test.collection;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity
@Table(uniqueConstraints = {@UniqueConstraint(columnNames={"uniqueName"})})
public class Child {

   private Long id;
   private String uniqueName;
   private Parent parent;
   
   @ManyToOne
   @JoinColumn(name="parent_fk", insertable=false, updatable=false)
   public Parent getParent() {
      return parent;
   }
   public void setParent(Parent parent) {
      this.parent = parent;
   }

   @Id @GeneratedValue(strategy=GenerationType.AUTO)
   public Long getId() {
      return id;
   }

   public void setId(Long id) {
      this.id = id;
   }

   public String getUniqueName() {
      return uniqueName;
   }

   public void setUniqueName(String uniqueName) {
      this.uniqueName = uniqueName;
   }
}


Parent.java
Code:
package test.collection;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;

@Entity
public class Parent {

   private Long id1;
   private List<Child> children;

   @Id @GeneratedValue(strategy=GenerationType.AUTO)
   public Long getId1() {
      return id1;
   }

   public void setId1(Long id) {
      this.id1 = id;
   }

   @OneToMany(cascade=CascadeType.ALL)
   @JoinColumn(name="parent_fk")
   public List<Child> getChildren() {
      return children;
   }

   public void setChildren(List<Child> children) {
      this.children = children;
   }
   
}


TestIt.java
Code:
package test.collection;

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;

import org.hibernate.Session;

public class TestIt extends TestCase {

   public void testIt() {
      createTestObjects();

      Session session = HibernateUtil.getSession();

      // Load the parent object.
      Parent p = (Parent)session.createCriteria(Parent.class).uniqueResult();
      
      // Get a child reference from the collection in parent.
      Child child = p.getChildren().get(0);
      
      // Load the same child with session.load().
      Child sameChild = (Child)session.load(Child.class, child.getId());
      
      // Hibernate should return the same instance of the child object.
      assertTrue(child == sameChild);

      session.close();
   }

   private void createTestObjects() {
      Session session = HibernateUtil.getSession();
      session.beginTransaction();
   
      List<Child> children = new ArrayList<Child>();
      Child c1 = new Child();
      c1.setUniqueName("c1");
      children.add(c1);

      Child c2 = new Child();
      c2.setUniqueName("c2");
      children.add(c2);

      Parent parent = new Parent();
      parent.setChildren(children);
      session.save(parent);
      
      session.getTransaction().commit();
      session.close();
   }
}


HibernateUtil.java
Code:
package test.collectionbug;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

    private static SessionFactory factory;

    static {
       Configuration config = new AnnotationConfiguration()
          .addAnnotatedClass(Parent.class)
          .addAnnotatedClass(Child.class)
          
// HSQLDB configuration
          .setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect")
         .setProperty("hibernate.connection.driver_class", "org.hsqldb.jdbcDriver")
         .setProperty("hibernate.connection.url", "jdbc:hsqldb:mem:test")
          .setProperty("hibernate.connection.username", "sa")
          .setProperty("hibernate.connection.password", "")
          .setProperty("hibernate.hbm2ddl.auto", "create-drop")
          
// MYSQL configuration
//          .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect")
//         .setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver")
//         .setProperty("hibernate.connection.url", "jdbc:mysql://localhost/test")
//         .setProperty("hibernate.connection.username", "root")
//         .setProperty("hibernate.connection.password", "password")
//         .setProperty("hibernate.hbm2ddl.auto", "create-drop")
      
// Common properties
         .setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider")
         .setProperty("hibernate.show_sql", "true");

        HibernateUtil.setSessionFactory(config.buildSessionFactory());
    }

    public static synchronized Session getSession() {
        if (factory == null) {
            factory = new Configuration().configure().buildSessionFactory();
        }
        return factory.openSession();
    }

    public static void setSessionFactory(SessionFactory factory) {
        HibernateUtil.factory = factory;
    }
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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.