[hibernate, JPA]Fetch LAZY inefficace sur association bi-directionnelle
Bonjour,
Je travaille depuis 2 mois seulement avec hibernate et je rencontre un problème au niveau du rapatriement des données de collections liées à une entité. Je m'explique :
J'ai deux entitées A et B liées par une association bi-directionnelle de type one-to-many (many-to-one) dont voici le code :
Entity A :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| @Entity
@Table(name = "AS")
//@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class A {
private long id;
private String property;
/**
* collection of Bs.
*/
private Set<B> bs;
/**
* Constructor.
*/
public A() {
bs = new HashSet<B>();
}
/**
* Gets the id.
*
* @return id
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
public long getId() {
return id;
}
/**
* Sets the id.
*
* @param id
* candidate id
*/
public void setId(long id) {
this.id = id;
}
@Column(name = "property")
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
/**
* Gets the B set.
*
* @return B set
*/
@OneToMany(mappedBy = "a", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
public Set<B> getBs() {
return this.bs;
}
/**
* Sets the B set.
*
* @param bs
*/
public void setBs(final Set<B> bs) {
for (B b : bs) {
b.setA(this);
}
this.bs = bs;
}
} |
Entity B :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| @Entity
@Table(name = "BS")
public class Context {
/**
* Id.
*/
private long id;
/**
* A.
*/
private A a;
/**
* Default Constructor.
*/
Context() {
}
/**
* Gets the id.
*
* @return id
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
public long getId() {
return id;
}
/**
* Sets the id.
*
* @param id
*
*/
public void setId(long id) {
this.id = id;
}
/**
* Gets a.
*
* @return a
*/
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "FKAId", nullable = false)
public A getA() {
return a;
}
/**
* Sets a.
*
* @param a
*/
public void setA(A a) {
this.a = a;
}
} |
L'idée c'est que je ne veux pas remplir le set de B dans A à chaque fois que je fais une requête sur A comme ci-dessous :
Code:
1 2 3
| A a = adao.findById(1L, false);
assertNotNull(a);
assertEquals("property1", a.getProperty()); |
Seulement, lorsque je fais cela, les logs m'indiquent que deux requêtes sont lancées :
Code:
1 2
| Hibernate: select A0_.ID as A1_8_0_, candidate0_.property as property8_0_ from AS A0_ where A0_.ID=?
Hibernate: select B0_.FKAId as FKA5_1_, B0_.ID as BID1_, B0_.ID as BID10_0_, B0_.FKAId as FKA5_10_0_ from BS B0_ where B0_.FKAId=? |
ou le ? = 1L
Moi ce que je voudrais, c'est qu'il ne fasse le deuxième select que si je le demande (que je fais explicitement un A.getBs()). Je pensais que cela pouvait être grâce aux fetch = FetchType.LAZY placés au niveau des @oneToMany (il semble d'ailleurs que ceux placés dans les @manyToOne fonctionnent eux...)
Il y aurait-il quelque chose que j'aurais loupé ??
en attendant une réponse de votre part, bonne journée !