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