Hibernae leniwe pobieranie w Many to Many?

0

Witajcie,

Mam taką asocjajce ManyToMany:

@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE, region="clases.question")
@Table(name = "QUESTIONS")
@SequenceGenerator(name="PK",sequenceName="GEN_QUESTIONS_ID",allocationSize=1)
public class Question implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="PK")
@Column(name = "ID")     
private int id;

@Version                                                                   
@Column(name = "VERSION")
private int version;

@Column(name = "DESCRIPTION")
private String description;

@Column(name = "ACTIVE")
boolean active;

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="QUESTIONS_AREAS", 
           joinColumns={@JoinColumn(name="QUESTIONS_ID")},
           inverseJoinColumns={@JoinColumn(name="AREAs_ID")})
private Set<Area> areas = new HashSet<Area>(0);code>

Przy próbie wyciągnięcia HashSeta wywal mi błąd:

` failed to lazily initialize a collection of role: clases.Question.areas, could not initialize proxy - no Session`

Oczywiście jak zmienię pobieranie obiektów na: fetch = FetchType.EAGER to wszystko działa.
Ale niebardzo rozumem dlaczego nie chce działać domyśnie na lazily? Nie powinien załadowąć sobie kolekci przy próbie jej wywołania?

```java
System.out.println(q.getAreas().toString());
2

Ech, słabo mi. Potem sie ludzie dziwią że im sie coś ładuje 5 minut a do bazy leci tysiac zapytań bo geniusz zrobił "lazy". Jeśli faktycznie często wyciągasz tylko obiekty Question i nie korzystasz z tych Area (w co wątpię...) to zostaw lazy ale w DAO zrób dwie osobne metody. Jedna która wyciąga tak jak masz teraz i tej uzywaj tam gdzie nie potrzebujesz Area, a druga metoda niech robi fetch join na tym polu (wczyta sobie te Area od razu, jednym zapytaniem) i jej używaj tam gdzie potrzebujesz Area.

Za zostawienie lazy i liczenie na to że "dociagnie sobie jak będzie potrzebne" to powinni łamać kołem i rwać pasy ze skóry...

A czemu ci to nie działa? Bo na szczęście jak zamykasz transakcję to sesja jest ubijana i tam gdzie próbujesz się odwołać do tych swoich Area sesja nie jest już otwarta i nie można sobie nic dociągnąć.

0

Ok, w Hibernate dopiero raczkuje, a w podręcznikach zalecają stosować wszędzie lazy. Jak widać znów praktyka wygrywa z teorią. Dzięki i informacje.

0

No stosowanie wszędzie eager też dobre nie jest bo wyciągasz sobie z bazy mały obiekt a przy okazji wyrywasz pół bazy powiązań ;) Po prostu trzeba myśleć o tym co i dlaczego robisz. Lepiej mieć kilka metod w dao, które wyciągają obiekt + jakieś konkretne powiązania niż zdawać sie na ślepy los ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1