-->
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.  [ 9 posts ] 
Author Message
 Post subject: Duplicate results despite using CollectionId annotation
PostPosted: Sun Sep 26, 2010 6:23 am 
Newbie

Joined: Sun Sep 26, 2010 5:23 am
Posts: 7
Hi,

I have a simple model where a Parent has a unidirectional ManyToMany relation with a Child and the child has a unidirectional OneToMany relation with a Toy. The ManyToMany relation is (obviously) via a join table, which has a surrogate PK that is used for the CollectionID, and the OneToMany relation is via a foreign key in the table of the many side of that relation.

In my example data I have 1 parent who has 1 child, who has two toys.

An em.find with the ID of the parent however returns a parent with -2- (identical) children instead of 1.

I don't understand why this is happening. Via the CollectionId annotation, Hibernate should know that there is only 1 record in the join table between the Parent and Child, so that the Parent only has one Child.

I tried with both Hibernate 3.3.1 (JBoss AS 5.1) and 3.5.5 (JBoss AS 6m5).

These are my entities:
Code:
@Entity
public class Parent {

   private Long id;
   private String name;
   private List<Child> children;

   @Id
   @GeneratedValue(strategy = IDENTITY)
   public Long getId() {
      return id;
   }

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

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
   
   @ManyToMany(fetch = FetchType.EAGER)
   @JoinTable (
      name = "parent_child",
      joinColumns = @JoinColumn(name = "parent_id"),
      inverseJoinColumns = @JoinColumn(name = "child_id")
   )
   @CollectionId(
      columns = @Column(name = "id"),
      type = @Type(type = "string"),
      generator = "identity"
   )
   public List<Child> getChildren() {
      return children;
   }

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

}


Code:
@Entity
public class Child {

   private Long id;
   private String name;
   private List<Toy> toys;

   @Id
   @GeneratedValue(strategy = IDENTITY)
   public Long getId() {
      return id;
   }

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

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
   
   @OneToMany(fetch = FetchType.EAGER)
   @JoinColumn(name = "child_id")
   public List<Toy> getToys() {
      return toys;
   }

   public void setToys(List<Toy> toys) {
      this.toys = toys;
   }   
}


Code:
@Entity
public class Toy {

   private Long id;
   private String name;

   @Id
   @GeneratedValue(strategy = IDENTITY)
   public Long getId() {
      return id;
   }

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

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
   
}


The SQL query that Hibernate generates:

Code:
select
        parent0_.id as id0_2_,
        parent0_.name as name0_2_,
        children1_.parent_id as parent1_4_,
        child2_.id as child2_4_,
        children1_.id as id4_,
        child2_.id as id2_0_,
        child2_.name as name2_0_,
        toys3_.child_id as child3_5_,
        toys3_.id as id5_,
        toys3_.id as id1_1_,
        toys3_.name as name1_1_
    from
        Parent parent0_
    left outer join
        parent_child children1_
            on parent0_.id=children1_.parent_id
    left outer join
        Child child2_
            on children1_.child_id=child2_.id
    left outer join
        Toy toys3_
            on child2_.id=toys3_.child_id
    where
        parent0_.id=?


When I run this query manually on my DB (PostgreSQL 8.4) it returns two rows, one for each different toy. I expect Hibernate to read the object graph from these two rows and give me back 1 parent, with 1 child with 2 toys.

If any additional information is needed I'll be happy to provide it.


Top
 Profile  
 
 Post subject: Re: Duplicate results despite using CollectionId annotation
PostPosted: Tue Sep 28, 2010 5:23 pm 
Newbie

Joined: Sun Sep 26, 2010 5:23 am
Posts: 7
Anyone? Should I create a JIRA issue for this?


Top
 Profile  
 
 Post subject: Re: Duplicate results despite using CollectionId annotation
PostPosted: Wed Sep 29, 2010 3:07 pm 
Newbie

Joined: Sun Sep 26, 2010 5:23 am
Posts: 7
Just wondering, do the Hibernate developers still read this forum? This is the *official* forum, isn't it?


Top
 Profile  
 
 Post subject: Re: Duplicate results despite using CollectionId annotation
PostPosted: Sun Oct 03, 2010 1:16 pm 
Newbie

Joined: Sun Sep 26, 2010 5:23 am
Posts: 7
I seems there are still a lot of people asking questions here, but not really a lot of answers are posted.

For a popular product such as Hibernate and this being -the- official forum this is a little sad...


Top
 Profile  
 
 Post subject: Re: Duplicate results despite using CollectionId annotation
PostPosted: Mon Oct 04, 2010 5:18 am 
Beginner
Beginner

Joined: Fri Nov 14, 2008 7:34 pm
Posts: 24
tried with Hibernate 3.3.2.GA, Hibernate EntityManager 3.4.0.GA, Hibernate Annotations 3.4.0.GA

all is ok, found 1 parent with 1 child and 2 toys

the only thing I had to change to work :

@CollectionId(
columns = @Column(name = "id"),
type = @Type(type = "long"),
generator = "sequence"
)


Top
 Profile  
 
 Post subject: Re: Duplicate results despite using CollectionId annotation
PostPosted: Sat Oct 16, 2010 7:30 am 
Newbie

Joined: Sun Sep 26, 2010 5:23 am
Posts: 7
maint175 wrote:
tried with Hibernate 3.3.2.GA, Hibernate EntityManager 3.4.0.GA, Hibernate Annotations 3.4.0.GA

all is ok, found 1 parent with 1 child and 2 toys

the only thing I had to change to work :

@CollectionId(
columns = @Column(name = "id"),
type = @Type(type = "long"),
generator = "sequence"
)


Thanks a lot for the reply. Yes, I did change the type to long. Actually, I started with long and changed it to string to see it it maybe helped.

The main difference is thus in "sequence" vs "identity". I'm a little confused now. I thought that with identity Hibernate let's the DB generate an ID in case of persisting, while with sequence Hibernate takes a value from a given sequence and persists that.

In this case we're not persisting anything but just reading. How can the generator make any difference here?

Additionally, don't you have to name the sequence you're using somewhere? Sorry if I misunderstand something here.


Top
 Profile  
 
 Post subject: Re: Duplicate results despite using CollectionId annotation
PostPosted: Mon Oct 18, 2010 4:37 am 
Beginner
Beginner

Joined: Fri Nov 14, 2008 7:34 pm
Posts: 24
hi

with mysql, you can use "identity"

@GenericGenerator(name = "gg1", strategy = "increment")
@CollectionId(
columns = @Column(name = "id"),
type = @Type(type = "long"),
generator = "gg1"
)



you have mentioned postgresql, so I tested it with the database to use "sequence" generator ( defalt sequence "hibernate_sequence" )
To define another sequence, define it in entity class as

@SequenceGenerator(name="my_seq_hello", sequenceName="my_seq_hello")

and refer like
@CollectionId(
columns = @Column(name = "id"),
type = @Type(type = "long"),
generator = "my_seq_hello"
)


Top
 Profile  
 
 Post subject: Re: Duplicate results despite using CollectionId annotation
PostPosted: Mon Oct 18, 2010 4:22 pm 
Newbie

Joined: Sun Sep 26, 2010 5:23 am
Posts: 7
maint175 wrote:
hi

with mysql, you can use "identity"


Thanks again. Do you mean that if you use generator="identity" (as in my original example), then on MySQL you don't get the duplicate results?

That would be rather strange really. With identity when -inserting- Hibernate has to read back the ID that the database generated. Maybe with PG Hibernate does something clever and doesn't actually do a select query but uses the DB "session" to read back the generated ID. In PG there's a sequence behind an "identity" column (a column of type Serial or BigSerial) and theoretically Hibernate could discover which one that is.

Maybe that is the difference between PG and MySQL?

BUT...

In my example we were only reading, not writing. So the question is still, why would the generator matter when only reading?


Top
 Profile  
 
 Post subject: Re: Duplicate results despite using CollectionId annotation
PostPosted: Tue Jun 04, 2013 9:30 pm 
Newbie

Joined: Tue Apr 09, 2013 4:38 am
Posts: 1
This is because 2 IDs are getting generated
First ID genenration is because of using:
@CollectionId(
columns = @Column(name = "id"),
type = @Type(type = "string"),
generator = "identity"
)
public List<Child> getChildren() {

Second ID generation is because of using:
@Id
@GeneratedValue(strategy = IDENTITY)
public Long getId() {
return id;
}

Try removing one and check..


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