-->
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.  [ 6 posts ] 
Author Message
 Post subject: Use Hashcode value as @id
PostPosted: Wed Aug 28, 2013 3:24 am 
Newbie

Joined: Wed Aug 28, 2013 3:06 am
Posts: 3
Hello,
I have an Account Class and a Product Class with Many-to-Many relationship. In order to avoid duplicate rows in db for the Product Class, I am thinking to use the value of hashcode() as a primary key. I have implemented hashcode (Eclipse default) to return an integer regarding the fields of my object. For the Account I have a generated id, but for the product class, each object is a unique strictly depends on it fields.Do I will have a problem with it??Is there any better solution?
thank you in advance.


Top
 Profile  
 
 Post subject: Re: Use Hashcode value as @id
PostPosted: Fri Aug 30, 2013 5:14 am 
Hibernate Team
Hibernate Team

Joined: Fri Sep 09, 2011 3:18 am
Posts: 295
You might have problems if you need to update a field of a particular product because this will change the corresponding ID.
It can also be difficult to do any kind of SQL operation on the DB if you need to.

Any reason for not defining unique constraints or using the columns as id?


Top
 Profile  
 
 Post subject: Re: Use Hashcode value as @id
PostPosted: Fri Aug 30, 2013 8:39 am 
Newbie

Joined: Wed Aug 28, 2013 3:06 am
Posts: 3
Thank for your reply.Well the root problem is same as https://forum.hibernate.org/viewtopic.php?f=1&t=991973&start=0
I have a transient product (the id is null and auto-generated) but it has a corresponding row in the db. I don't want to insert again the same whole product but only the primary key of the product in the relationship with the other Entity. Well I have try this in order to obtain the id from the db and set it to the transient product:
Code:
      //Cascade.ALL is enabled
   Product persistent =query.load(NaturalId);
       Product transient.SetId(persistent.getId());
     session.saveOrUpdate(transient) //NonUniqueObjectException here

BUT i got Exception .Why is that?? The transient and the persistent object is "equal" (according to hashcode/equal implementation) .

I have found other solution but still i dont know if it is the correct. I just ignore the transient product and uses the corresponding loaded product! But I think all of these are bad implementation, why i have to re-load the same product or check the database?


Top
 Profile  
 
 Post subject: Re: Use Hashcode value as @id
PostPosted: Fri Aug 30, 2013 12:02 pm 
Hibernate Team
Hibernate Team

Joined: Fri Sep 09, 2011 3:18 am
Posts: 295
Reading the documentation (http://docs.jboss.org/hibernate/orm/4.2/manual/en-US/html_single/#objectstate-saveorupdate):
Code:
saveOrUpdate() does the following:
    ...
    if another object associated with the session has the same identifier, throw an exception
   ...


I don't know very well your use case but I can think of two options:

1) Apply the new values to the persistent object
Code:
    Product transient = ...
    Product persistent = query.load( NaturalId );
    persistent.setAttributeValue( transient.getAttributeValue() );


2) Evict the object once you have loaded it:
Code:
    Product persistent = query.load( NaturalId );
    Product transient.SetId( persistent.getId() );
    session.evict( persistent ); // This will remove the object from the session without touching the DB
    session.saveOrUpdate( transient );


Let me know if this has helped.
Cheers


Top
 Profile  
 
 Post subject: Re: Use Hashcode value as @id
PostPosted: Fri Aug 30, 2013 12:41 pm 
Hibernate Team
Hibernate Team

Joined: Fri Sep 09, 2011 3:18 am
Posts: 295
Another solution:
3) Retrieve the id with a query instead of loading the whole object

Code:
    Long productId = session.createQuery( "SELECT id FROM Product WHERE naturalId = ?" ).setParameter(0, naturalId).uniqueResult();
    Product transient.SetId( productId );
    session.saveOrUpdate( transient );


Top
 Profile  
 
 Post subject: Re: Use Hashcode value as @id
PostPosted: Mon Sep 02, 2013 6:37 am 
Newbie

Joined: Wed Aug 28, 2013 3:06 am
Posts: 3
Well, my use case is very simple. I have an Employee that manages many Orders. In addition, an Order can have many Products.There are two kind of products, these that are stored already and others (custom products)that could be created in anytime.So my problem is what to do, if the same product already exists.
So something like that:
Order order= new Order();
order.add(new product()); //loop here in order to add many products
Employee.add(order);
It will just add duplicate records for Products.

davided80 wrote:
Another solution:
3) Retrieve the id with a query instead of loading the whole object

Code:
    Long productId = session.createQuery( "SELECT id FROM Product WHERE naturalId = ?" ).setParameter(0, naturalId).uniqueResult();
    Product transient.SetId( productId );
    session.saveOrUpdate( transient );


Thank You!That works.This is the most straightforward solution in my opinion. The other solution is 2. but i think is slower than 3.
It would be convenient, that hibernate automatically does that only by checking the natural id. Especially if i have a large collection of transient objects.


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