[ORM-y, Hibernate] Jak jest z tymi kolekcjami?

0

Piszę mój pierwszy projekt, w którym używam Hibernate i JPA. I tak sobie piszę i rozmyślam o nim i tak mnie naszło, czy ja coś źle robię, czy ORM jest taki cwany.

Mianowicie mam w klasie zbiór:

// adnotacje
private Set<Person> persons = new HashSet<Person>();

Dodaje do zbiory nowo utworzone osoby:

firm.getPersons().add(person1);
person1.setFirm(firm);

i zapisuję:
session.save(firm);

I teraz zastanawia mnie kwestia, czy HashSet nie będzie miał jakiś problemów z tym, ze Person zacznie zwracać innego hasha za pomocą hashCode(). Najpierw zwracał hasha wygenerowanego na podstawie pol i ID, które było nullem. Po zapisaniu do bazy ID zmieniło wartość na jakąś liczbę, więc hashCode() zwraca inną wartość.

Mógłby mi ktoś powiedzieć, czy to coś może spieprzyć? Jak sobie z tym radzić?

0

Nie będzie problemu. Hibernate obuduje HashSet własną implementacją - PersistentBagCOŚTAM, która potrafi w podmienić odpowiedni obiekt.

0

Polecam przeczytac ksiazke Java Persistance with Hibernate, a przynajmniej fragment o tym dokladnie problemie. Zaleca sie tam aby equals i hashCode nie polegaly na wartosciach id, a jedynie na "biznesowej rownosci" (business equality, nie wiem jak to przetlumaczyc). Np, masz klase osoba, to jej metoda equals powinna porownywac np pesel (teoretycznie unikalny), lub imie nazwisko i adres (niby tez unikalne, ale zawsze matka i zona moga miec to samo imie i razem mieszkac, wiec jeszcze mozna date urodzic dorzucic).
PersistentBagCOSTAM nie ma nic wspolnego z problemem i pytaniem autora watku, drogi Koziolku. To jest jedynie implementacja seta ktora moze byc lazy. Poza tym w tym przypadku nie PersistenBadCOSTAM a PersistentSet, ktory wewnetrznie uzywa HashSeta:
https://www.hibernate.org/hib_docs/v3/api/org/hibernate/collection/PersistentSet.html
Bag to jest dla cos pomiedzy setem a lista, gdzie moga byc duplikaty (jak w liscie, nie w secie) ale nie interesuje nas kolejnosc wstawiania (jak w secie, ale nie jak w liscie ktra ma indeky).

0

@fafel, ale porównywanie wartości pól innych niż ID jest obarczone tym samym problemem. Zmienię wartość któregoś pola i znowu hashCode() jest inny.
Co do equals to ja używam standardowej implementacji, czyli equals działającego jak == dlatego, że aplikacja jest desktopowa z wbudowaną bazą danych. Używam jednej sesji, więc gdzieś czytałem, że mam zagwarantowane, że nie będzie duplikatów tege samego bytu (tak się chyba tłumaczy Entity).

0

Ten problem nie jest problemem hibernate tylko tego w jaki sposob uzywasz kolekcji. To jest fragment dokumentacji klasy Set:
Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set. A special case of this prohibition is that it is not permissible for a set to contain itself as an element.
Prostymi slowy, zle uzywasz seta - po wstawieniu do niego elementu nie powienienes zmieniac elementow tak, ze moze sie zmienic hashCode lub metoda equals bedzie inaczej dzialac.
W tym wypadku mysle ze powinienes uzyc wspomnianej bag lub listy.

0

Hmmm... Dzięki za oświecenie. Dobrze, że zapytałem, bo nie chciałbym się męczyć z powstałymi z niewiedzy błędami. Wszędzie w tutkach używają tylko Set i Set, że aż sam się zagalopowałem. Dzieki fafel xD

0

natknąłem się przypadkiem

"There is, arguably, one more advantage that indexed collections have over sets for many-to-many associations or collections of values. Because of the structure of a Set, Hibernate does not UPDATE a row when an element is "changed". Changes to a Set always work via INSERT and DELETE of individual rows. Once again, this consideration does not apply to one-to-many associations. "

http://docs.jboss.org/hibernate/stable/core/reference/en/html/performance.html

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