Hi,
I've got two entities: Osoba (Whole) and Konto (Part) in OneToMany
association. Each contains id and name attributes. I decided to test
inner and left fetch joins.
I created 2 Osoba's, but only one got 2 Konto's.
When I run
SELECT o FROM Osoba o
it returns 2 entities which is fine. However, when I run
SELECT o FROM Osoba o JOIN FETCH o.konta
it returns 1 entity which is still fine but the number of Konta
entities is...4 (!).
When I changed the type of Osoba.konta (plural of konto in Polish)
from List<Konto> to Set<Konto> the above query returned 2 which was
what I had first expected.
Could anyone explain it to me? I seem to be missing some SQL classes
on how joins are supposed to work so any pointers to documentation
would be fine too.
Here the entities go (with Set<Konto>):
package pl.jaceklaskowski.jpa;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
@Entity
@NamedQueries({
@NamedQuery(name = "Osoba.poImieniu", query = "SELECT o FROM Osoba
o WHERE o.imie = :imie"),
@NamedQuery(name = "Osoba.wszystkieOsoby", query = "SELECT o FROM Osoba o"),
@NamedQuery(name = "Osoba.wszystkieOsoby.JOIN_FETCH", query =
"SELECT o FROM Osoba o JOIN FETCH o.konta"),
@NamedQuery(name = "Osoba.wszystkieOsoby.LEFT_JOIN_FETCH", query =
"SELECT o FROM Osoba o LEFT JOIN FETCH o.konta")
})
public class Osoba implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String imie;
private Set<Konto> konta = new HashSet<Konto>();
protected Osoba() {
}
public Osoba(String imie) {
this.imie = imie;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@OneToMany(cascade=CascadeType.PERSIST)
public Set<Konto> getKonta() {
return konta;
}
public void setKonta(Set<Konto> konta) {
this.konta = konta;
}
public void addKonto(Konto konto) {
getKonta().add(konto);
}
public String getImie() {
return imie;
}
public void setImie(String imie) {
this.imie = imie;
}
@Override
public String toString() {
return "Osoba[id=" + getId() + "]";
}
}
package pl.jaceklaskowski.jpa;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Konto implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String numer;
protected Konto() {
}
public Konto(String numer) {
this.numer = numer;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNumer() {
return numer;
}
public void setNumer(String numer) {
this.numer = numer;
}
@Override
public String toString() {
return "Konto[id=" + getId() + "]";
}
}
Jacek
--
Jacek Laskowski
http://www.JacekLaskowski.pl