I have found that fetching strategy (EAGER or LAZY) is also affecting query result.
Version :
Hibernate 3.1 final
Hibernate EntityManager 3.1 beta 5
Hibernate Annotations 3.1 beta 7
MySQL 5
JBoss 4.0.3 SP1
Background :
I have bidirectional OneToMany/ManyToOne relationship.
CustomerDAO have collections of AddressDAO and PhoneDAO. The AddressDAO and PhoneDAO
has a reference to CustomerDAO. Each of foreign key (FK) is in ADDRESS's table and
PHONE's table with both has same column name : CUSTOMER_ID.
Scenario :
Consider there is already one object of CustomerDAO in CUSTOMER table, two PhoneDAO in
PHONE table and one AddressDAO in ADDRESS table.
CUSTOMER
-------------------------------------------------------
- CUSTOMER_ID --------- CUSTOMER_NAME
-------------------------------------------------------
------ 1 ------------------------------- A ------------
PHONE
--------------------------------------------------------------------------
- PHONE_ID ------- LOCAL_NUMBER -------- CUSTOMER_ID
--------------------------------------------------------------------------
----- 1 ---------------------- 111 ----------------------- 1 ----------
----- 2 ---------------------- 222 ----------------------- 1 ----------
ADDRESS
-----------------------------------------------------------
- ADDRESS_ID -------- CITY ------- CUSTOMER_ID
-----------------------------------------------------------
------ 1 --------------- Jakarta ------------ 1 ---------
Problem :
I load CustomerDAO using entity manager...
Code:
CustomerDAO customer1 = em.find(CustomerDAO.class, "1");
Then I do this...
Code:
int addressSize = customer1.getAddresses().size();
I will get addressSize = 1 with LAZY fetch (which is correct)
and addressSize = 2 with EAGER fetch (which is wrong).
I thought (and expect) that fetching strategy will only change
fetching behaviour only, and
not affecting the query results.
I have note something interesting too, if I add one PhoneDAO to
PHONE table (total = 3 record), the addressSize will return 3 as
well (with EAGER fetch).
Is it a bug or what? Please some one give me a clue.
Here are the classes ...
Code:
@Entity
@Table(name = "CUSTOMER")
@DiscriminatorColumn(name = "SUBCLASS", length = 250)
public class CustomerDAO implements java.io.Serializable {
private String id;
private String customerName;
private java.util.List<AddressDAO> addresses = new java.util.ArrayList<AddressDAO>();
private java.util.List<PhoneDAO> phones = new java.util.ArrayList<PhoneDAO>();
@Id(generate = GeneratorType.NONE) // I'm using app generated Ids
@Column(name = "CUSTOMER_ID", nullable = false, length = 250)
public String getId(){
return id;
}
public void setId(String newValue){
this.id = newValue;
}
@Column(name = "CUSTOMER_NAME")
public String getCustomerName(){
return this.customerName;
}
public void setCustomerName(String newValue){
this.customerName = newValue;
}
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
public java.util.List<AddressDAO> getAddresses(){
return addresses;
}
public void setAddresses(java.util.List<AddressDAO> newValue){
this.addresses = newValue;
}
public void addAddressesElement(AddressDAO newValue){
this.addresses.add(newValue);
}
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
public java.util.List<PhoneDAO> getPhones(){
return phones;
}
public void setPhones(java.util.List<PhoneDAO> newValue){
this.phones = newValue;
}
public void addPhonesElement(PhoneDAO newValue){
this.phones.add(newValue);
}
}
@Entity
@Table(name = "ADDRESS")
public class AddressDAO implements java.io.Serializable {
private String id;
private String city;
private CustomerDAO customer;
@Id(generate = GeneratorType.NONE)
@Column(name = "ADDRESS_ID", nullable = false, length = 250)
public String getId(){
return id;
}
public void setId(String newValue){
this.id = newValue;
}
@Column(name = "CITY")
public String getCity(){
return this.city;
}
public void setCity(String newValue){
this.city = newValue;
}
@ManyToOne
@JoinColumn(name = "CUSTOMER_ID")
public CustomerDAO getCustomer(){
return customer;
}
public void setCustomer(CustomerDAO newValue){
this.customer = newValue;
}
}
@Entity
@Table(name = "PHONE")
public class PhoneDAO implements java.io.Serializable {
private String id;
private String number;
private CustomerDAO customer;
@Id(generate = GeneratorType.NONE)
@Column(name = "PHONE_ID", nullable = false, length = 250)
public String getId(){
return id;
}
public void setId(String newValue){
this.id = newValue;
}
@Column(name = "LOCAL_NUMBER")
public String getLocalNumber(){
return this.localNumber;
}
public void setLocalNumber(String newValue){
this.localNumber = newValue;
}
@ManyToOne
@JoinColumn(name = "CUSTOMER_ID")
public CustomerDAO getCustomer(){
return customer;
}
public void setCustomer(CustomerDAO newValue){
this.customer = newValue;
}
}