-->
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.  [ 14 posts ] 
Author Message
 Post subject: Hibernate silently omits many2many associations created.BUG?
PostPosted: Sun Sep 05, 2004 1:40 pm 
Regular
Regular

Joined: Wed May 05, 2004 8:01 am
Posts: 53
Hibernate version:
2.1.6
Data model:
Code:
very shortened :

public class Contractor extends Persistent {
   /**
    * @hibernate.set lazy="true" inverse="true" cascade="all"
    * @hibernate.collection-key column="contractor"
    * @hibernate.collection-one-to-many class="com.xxx.model.Region"
    */
   public Set getRegions() {
      return regions;
   }
}

public class Region extends Persistent implements Comparable {
   /**
    * @hibernate.set
    *      lazy="true"
    *      cascade="none"
    *       table="Region2Depot"
    * @hibernate.collection-key
    *      column = "region"
    * @hibernate.collection-many-to-many
    *      column="depot"
    *      class = "com.xxx.model.Depot"
    */
   public Set getDepots() {
      return depots;
   }
}

public class Net extends Persistent {
   /**
    * @hibernate.set lazy="true" inverse="true" cascade="all"
    * @hibernate.collection-key column="net"
    * @hibernate.collection-one-to-many class="com.xxx.model.Depot"
    */
   public Set getDepots() {
      return depots;
   }
}

public class Depot extends Persistent implements Comparable {
   /**
    * @hibernate.many-to-one not-null="true"
    * @return
    */
   public Net getNet() {
      return net;
   }

   public void setNet( Net net ) {
      this.net = net;
   }
}


The meaning behind this is:

There is a net of shops (malls). A shop is called a Depot here. There is some producer that sells goods in these depots.
The producer is a Contractor entity here. The contractor divides depots into own defined regions. There may be many contractors
each having a different set of regions and depots assigned to them. That is why I used many to many relation ship.


Name and version of the database you are using:
MySQL 4.1.3

Code between sessionFactory.openSession() and session.close():
I have written a simple "import" tool that parses a text file and creates nets, depots, and regions.
Code:
private static void processLine( String str, Session session, Contractor cnt ) {
    String[] temp = str.split( ";" );

    String number = temp[ 0 ];
    String netName = temp[ 1 ];
    String city = temp[ 2 ];
    String street = temp[ 3 ];
    String buildingNumber = temp[ 4 ];
    String appartmentNumber = temp[ 5 ];
    String postalCode = temp[ 6 ];
    String regionName = temp[ 7 ];

    try {
        Transaction tx = session.beginTransaction();

        Net net = null;
        Region region = null;

        List regions = session.find(    "from Region r where r.name = ?",
                                        regionName,
                                        Hibernate.STRING );

        if ( !regions.isEmpty() ) {
            region = (Region) regions.get( 0 );
        } else {
            region = new Region( regionName );
            region.setContractor( cnt );
            session.save( region );
        }

        List nets = session.find(   "from Net n where n.name = ?",
                                    netName,
                                    Hibernate.STRING );
        if ( !nets.isEmpty() ) {
            net = (Net) nets.get( 0 );
        } else {
            net = new Net( netName );
            session.save( net );
        }

        Depot depot = null;
        Address address = new Address( city, postalCode, street, buildingNumber,
                        appartmentNumber );
        session.save( address );
        depot = new Depot( city );
       
        depot.setAddress( address );
        net.addDepot( depot );
       
        session.save( depot );
        session.saveOrUpdate( net );
        region.addDepot( depot );
        session.saveOrUpdate( region );
        tx.commit();
       
        // PROBLEM !!!
        //session.evict( region );
    } catch ( HibernateException e1 ) {
        e1.printStackTrace();
    }

}


There should be:
- an insert for net if there is no one of given name already
- an insert for region if there is no region of given name already
- an insert for each new depot
- an insert into region2depot to mark the "the depot is in that region" association.

My file has 249 lines. When I comment out session.evict( region ) from code I get only 105 inserts. Logs say that for some region.getDepots() collection there are no new rows to insert. With session.evict there are 249 as it should be.

The import is always done into the clean database. I also tried to do as many session.flush()es and save()s as I could. No change.

Statistics: 249 depots, 12 nets, 3 regions, 1 contractor. Not so much entities in session after all. Sounds like a bug.

WDYT?[/list]


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 05, 2004 4:16 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
sounds like a bug in your code... ;)

it seems you're trying everything , every method to get it work, just read some doc again, please, all this stuff is working

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject: please do not RTFM me
PostPosted: Mon Sep 06, 2004 2:35 am 
Regular
Regular

Joined: Wed May 05, 2004 8:01 am
Posts: 53
anthony wrote:
sounds like a bug in your code... ;)

it seems you're trying everything , every method to get it work, just read some doc again, please, all this stuff is working


I thought the forum is not meant for "buzz off" answers. Are you able to point my bug in that few liner? The model is throughly tested and a lot bigger than that (about 50 entities).

If "all this stuff is working" why doesn't region2depot inserts get executed for some new entities and for some does? Why does session.evict( region ) change that behaviour? AFAIU session.evict( object ) should not change anything in application behaviour as it's only a cache control statement.

Looks like a bug in hibernate to me.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 06, 2004 3:07 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
ok
1- are you using assigned id? if not, why are you using saveOrUpdate?
2- are you using composite id ?
3- what is in region.addDepot() ?
4- are you working with detached instances ? if not, why are you using update()?
5- Is your batch threadsafe?
6- are you sure your instance model is safe? i mean both ends of the many to many association are ok?

see you later

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject: Re: please do not RTFM me
PostPosted: Mon Sep 06, 2004 3:26 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
ouzo wrote:
I thought the forum is not meant for "buzz off" answers. Are you able to point my bug in that few liner? The model is throughly tested and a lot bigger than that (about 50 entities).

If "all this stuff is working" why doesn't region2depot inserts get executed for some new entities and for some does? Why does session.evict( region ) change that behaviour? AFAIU session.evict( object ) should not change anything in application behaviour as it's only a cache control statement.

Looks like a bug in hibernate to me.


Ouzo, you are extremely close to being banned. I won't warn again.

(1) Don't dare criticize Anthony, who helps out everyone from his own enthusiasm
(2) Don't try to blame your bugs on Hibernate
(3) Don't tell us what the forum is "meant for"
(4) Never, ever post here when you have some complicated model of 50 entities, and have not already isolated the problem by simplifying your code down to two or three entities
(5) If people RTFM you, then go off and RTFM
(6) If this is unsatisfactory to you, you can purchase a dev support contract from JBoss, and have me at your every beck and call

Now, please go away, simplify your code, and come back later after you have done much more work to resolve the problem yourself. This thread is now finished, please don't try and argue with me. Thanks.

http://www.hibernate.org/ForumMailingli ... AskForHelp


Top
 Profile  
 
 Post subject: Re: please do not RTFM me
PostPosted: Mon Sep 06, 2004 3:54 am 
Regular
Regular

Joined: Wed May 05, 2004 8:01 am
Posts: 53
gavin wrote:
ouzo wrote:
I thought the forum is not meant for "buzz off" answers. Are you able to point my bug in that few liner? The model is throughly tested and a lot bigger than that (about 50 entities).

If "all this stuff is working" why doesn't region2depot inserts get executed for some new entities and for some does? Why does session.evict( region ) change that behaviour? AFAIU session.evict( object ) should not change anything in application behaviour as it's only a cache control statement.

Looks like a bug in hibernate to me.


Ouzo, you are extremely close to being banned. I won't warn again.

(1) Don't dare criticize Anthony, who helps out everyone from his own enthusiasm
(2) Don't try to blame your bugs on Hibernate
(3) Don't tell us what the forum is "meant for"
(4) Never, ever post here when you have some complicated model of 50 entities, and have not already isolated the problem by simplifying your code down to two or three entities
(5) If people RTFM you, then go off and RTFM
(6) If this is unsatisfactory to you, you can purchase a dev support contract from JBoss, and have me at your every beck and call

Now, please go away, simplify your code, and come back later after you have done much more work to resolve the problem yourself. This thread is now finished, please don't try and argue with me. Thanks.

http://www.hibernate.org/ForumMailingli ... AskForHelp


I am sorry if I sounded rude. This was not my intention. My apologies. I am a great fan of hibernate and the purpose of my post was trying to clear things out if there really was some kind of bug in hibernate code. Please look at my original post - the case is narrowed down to 4 entities and the problematic code is a few liner really.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 06, 2004 4:55 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
OK, no problem, its forgotten.

But trust me, your case is simply not simple enough to be solveable over the forum.

Make sure you understand the full implications of evict(). Evicting a managed object does not just affect memory consumption.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 06, 2004 5:19 am 
Regular
Regular

Joined: Wed May 05, 2004 8:01 am
Posts: 53
gavin wrote:
OK, no problem, its forgotten.

But trust me, your case is simply not simple enough to be solveable over the forum.

Make sure you understand the full implications of evict(). Evicting a managed object does not just affect memory consumption.


Thank you for being so forgiving. I'll try to provide you with a completely isolated problem.

About session.evict(): I do not want to use it. The problem is without evict not every association is being inserted into database.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 06, 2004 5:27 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
the use of evict really seems to be a workaround for a problem in your code.
Try answering my previous questions and you'll find the isolated problem.

When you have the isolated snapshoot, also give us the generated mappings file (i don't like reading xdoclet) and stacktrace.

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 07, 2004 10:15 am 
Regular
Regular

Joined: Wed May 05, 2004 8:01 am
Posts: 53
anthony wrote:
the use of evict really seems to be a workaround for a problem in your code.
Try answering my previous questions and you'll find the isolated problem.

When you have the isolated snapshoot, also give us the generated mappings file (i don't like reading xdoclet) and stacktrace.


I have found a source of the problem. It is the TreeSet behaviour.:

Code:
Net net = new Net( "net" );
Depot depot1 = new Depot( net, "depot1" );
Depot depot2 = new Depot( net, "depot2" );
Set set = new TreeSet();

set.add( depot1 );
set.add( depot2 );

System.out.println( set.size() );


guess what gets printed out? 1!

The result for HashSet is 2 because HashSet invokes hashCode on object which is different event for 2 depots of the same name produce different hashCode. The object does not get inserted only if there is one with the same hashCode already in the set.

With TreeSet it is different: even though the hashCodes are calculated (debug breaks inside hashCode method) if object.compareTo( another ) gives 0 ( equal ) one of them is ommited. I wonder what is the cause of such implementation.

Just for the record if anybody gets as frustrated as I got: if you do not want to loose associations in you database and you're using TreeSets you have to make sure your compareTo method returns 0 only for the same object. This means it is a good idea to include primary key in comparison. I do not know if adding hashCode() to comparison is a good thing but does a good job for transient entities:

Code:
public int compareTo( Object object ) {
    Depot depot = (Depot) object;
    return new CompareToBuilder().append(   this.name,
                                            depot.getName() )
                                 .append(   this.getId(),
                                            depot.getId() )
                                 .append(   this.hashCode(),
                                            depot.hashCode() ).toComparison();
}


Thank you for your help.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 07, 2004 10:47 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
always remember these questions:
Quote:
1- are you using assigned id? if not, why are you using saveOrUpdate?
2- are you using composite id ?
3- what is in region.addDepot() ?
4- are you working with detached instances ? if not, why are you using update()?
5- Is your batch threadsafe?
6- are you sure your instance model is safe? i mean both ends of the many to many association are ok?

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 07, 2004 10:49 am 
Regular
Regular

Joined: Wed May 05, 2004 8:01 am
Posts: 53
anthony wrote:
always remember these questions:
Quote:
1- are you using assigned id? if not, why are you using saveOrUpdate?
2- are you using composite id ?
3- what is in region.addDepot() ?
4- are you working with detached instances ? if not, why are you using update()?
5- Is your batch threadsafe?
6- are you sure your instance model is safe? i mean both ends of the many to many association are ok?

some kind of starter set? :) Some of them were not relevant to my case (I was not using session.update() )


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 07, 2004 10:51 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
you were using saveOrUpdate which calls update() in the case of assigned id, did you know it?

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 07, 2004 11:00 am 
Regular
Regular

Joined: Wed May 05, 2004 8:01 am
Posts: 53
anthony wrote:
you were using saveOrUpdate which calls update() in the case of assigned id, did you know it?


I see.

OT: ad. 1. should I use saveOrUpdate only for assigned ids?


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