-->
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.  [ 2 posts ] 
Author Message
 Post subject: Why does join fetching give the wrong result?
PostPosted: Wed Feb 28, 2007 4:59 am 
Newbie

Joined: Wed Feb 14, 2007 5:38 am
Posts: 6
Consider the following code


Code:
@Entity
public class Client {
    @Id 
    @GeneratedValue
    private int id;
    private String name;
    @OneToMany (cascade={CascadeType.PERSIST})
    @JoinColumn (name="clientid")
    @org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.JOIN)
     private Collection<CreditCard> creditCards;

    public Client() {
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getId() {
        return id;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
   public Collection<CreditCard> getCreditCards() {
      return creditCards;
   }
   public void setCreditCards(Collection<CreditCard> creditCards) {
      this.creditCards = creditCards;
   }
}


Code:
@Entity
public class CreditCard {
    @Id 
    @GeneratedValue
    private int id;
    private String cardnumber;

    public CreditCard() {
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getId() {
        return id;
    }
    public void setCardnumber(String cardnumber) {
        this.cardnumber = cardnumber;
    }
    public String getCardnumber() {
        return cardnumber;
    }

}


Code:
public class Application3 {
   private static SessionFactory sessionFactory;

   static {
      sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
   }

   public static void main(String[] args) {
      Session session = null;
      Transaction tx = null;
      Product product = null;
      int clientid=0;


      try {
         session = sessionFactory.openSession();
         tx = session.beginTransaction();

         Client client = new Client();
         client.setName("John Doe");
         Client client2 = new Client();
         client2.setName("Frank Brown");
         Client client3 = new Client();
         client3.setName("Mary Jones");
         Client client4 = new Client();
         client4.setName("Sue Johnson");
         CreditCard cc1 = new CreditCard();
         cc1.setCardnumber("1234 5678 2345 3456");
         CreditCard cc2 = new CreditCard();
         cc2.setCardnumber("9876 5432 7654 8765");
         CreditCard cc3 = new CreditCard();
         cc3.setCardnumber("4376 9765 4529 0001");
         CreditCard cc4 = new CreditCard();
         cc4.setCardnumber("8745 5564 3821 9930");
         CreditCard cc5 = new CreditCard();
         cc5.setCardnumber("3256 1865 3927 3345");
         CreditCard cc6 = new CreditCard();
         cc6.setCardnumber("3286 8346 9153 0011");
         CreditCard cc7 = new CreditCard();
         cc7.setCardnumber("2231 4453 7221 8333");
         CreditCard cc8 = new CreditCard();
         cc8.setCardnumber("5552 3338 4571 9992");
         Collection<CreditCard> list = new ArrayList<CreditCard>();
         list.add(cc1);
         list.add(cc2);
         Collection<CreditCard> list2 = new ArrayList<CreditCard>();
         list2.add(cc3);
         list2.add(cc4);   
         Collection<CreditCard> list3 = new ArrayList<CreditCard>();      
         list3.add(cc5);
         list3.add(cc6);
         Collection<CreditCard> list4 = new ArrayList<CreditCard>();
         list4.add(cc7);
         list4.add(cc8);
         client.setCreditCards(list);
         client2.setCreditCards(list2);
         client3.setCreditCards(list3);
         client4.setCreditCards(list4);
         session.persist(client);
         session.persist(client2);
         session.persist(client3);
         session.persist(client4);

         tx.commit();

      } catch (HibernateException e) {
         tx.rollback();
         e.printStackTrace();
      } finally {
         if (session != null)
            session.close();
      }

      try {
         session = sessionFactory.openSession();
         tx = session.beginTransaction();


         Criteria citeria = session.createCriteria(Client.class);
            Collection<Client> clientlist = citeria.list();
//         Collection<Client> clientlist = session.createQuery("from Client c left join fetch c.creditCards").list();
         Iterator<Client> clientiterator = clientlist.iterator();
         while (clientiterator.hasNext()){
            Client theClient = clientiterator.next();
            System.out.println("Client name= " + theClient.getName());
            Collection<CreditCard> list2 = theClient.getCreditCards();
            Iterator<CreditCard> iterator = list2.iterator();
            while (iterator.hasNext()){
               CreditCard theCard = iterator.next();
               System.out.println("CreditCard  number= " + theCard.getCardnumber());
            }
         }

         tx.commit();

      } catch (HibernateException e) {
         tx.rollback();
         e.printStackTrace();
      } finally {
         if (session != null)
            session.close();
      }
   }

}


I used join fetching on the creditcard collection in the client object:

[code]
@org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.JOIN)
private Collection<CreditCard> creditCards;

[code]

When I run the program, I get the following result:

Hibernate: /* criteria query */ select this_.id as id1_1_, this_.name as name1_1_, creditcard2_.clientid as clientid3_, creditcard2_.id as id3_, creditcard2_.id as id2_0_, creditcard2_.cardnumber as cardnumber2_0_ from Client this_ left outer join CreditCard creditcard2_ on this_.id=creditcard2_.clientid
Client name= John Doe
CreditCard number= 1234 5678 2345 3456
CreditCard number= 9876 5432 7654 8765
Client name= John Doe
CreditCard number= 1234 5678 2345 3456
CreditCard number= 9876 5432 7654 8765
Client name= Frank Brown
CreditCard number= 4376 9765 4529 0001
CreditCard number= 8745 5564 3821 9930
Client name= Frank Brown
CreditCard number= 4376 9765 4529 0001
CreditCard number= 8745 5564 3821 9930
Client name= Mary Jones
CreditCard number= 3256 1865 3927 3345
CreditCard number= 3286 8346 9153 0011
Client name= Mary Jones
CreditCard number= 3256 1865 3927 3345
CreditCard number= 3286 8346 9153 0011
Client name= Sue Johnson
CreditCard number= 2231 4453 7221 8333
CreditCard number= 5552 3338 4571 9992
Client name= Sue Johnson
CreditCard number= 2231 4453 7221 8333
CreditCard number= 5552 3338 4571 9992

Hibernate gets all data in 1 query as I expected with join fetching, but why
do I get all Client objects twice?

When I change the criteria to HQL with

[/code]
Collection<Client> clientlist = session.createQuery("from Client c left join fetch c.creditCards").list();
[code]

I get the same result, all Client objects are shown twice.

Any ideas?

Rene


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 28, 2007 5:53 am 
Newbie

Joined: Thu Apr 13, 2006 9:03 pm
Posts: 3
if you add:
Code:
setResultTransformer(new DistinctRootEntityResultTransformer())


such that you have

Code:
Collection<Client> clientlist = citeria.setResultTransformer(new DistinctRootEntityResultTransformer()).list();

or

Code:
Collection<Client> clientlist = session.createQuery("from Client c left join fetch c.creditCards").setResultTransformer(new DistinctRootEntityResultTransformer()).list();


it should eliminate the duplicates.


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