niedziela, 10 stycznia 2010

Hibernate NamingStrategy

Na jednym z ostatnich spotkań WJUGa pożaliłem się odrobinie osobie siedzącej po mojej prawej stronie na Hibernate. Były to żale bardziej estetyczne niż funkcjonalne a dotyczyły nazw generowanych przez to właśnie narzędzie ORM. Nie podobały mi się ani nazwy tabel ani kolumn ani kluczy obcych jakie nadaje Hibernate podczas tworzenia schematu bazy danych. Osoba słuchająca moich marudzeń powiedziała krótko i fachowo: "Obczaj naming strategy". Obczaiłem.

Domyślnie Hibernate tworzy nazwę tabeli taką samą jak nazwa klasy - encji, natomiast nazwę kolumny taką samą jak nazwa pola. Nazwy kluczy obcych generowane są w sposób nieokreślony: np. 'FK2F894B2DC512614D'.

Ja chciałbym, aby nazwy kolumn i tabel utrzymane były w konwencji z podkreśleniem (czyli np. user_data, default_color), nazwy tabel występowały w liczbie mnogiej, a nazwy kluczy obcych były jakkolwiek zrozumiałe (np. FK_EMP_COM dla klucza łączącego tabelę EMPLOYEES z COMPANIES).

Pierwsze spojrzenie na interfejs NamingStrategy pozbawiło mnie złudzeń. O czytelnych nazwach kluczy obcych mogę sobie pomarzyć. Wybrana strategia stosowana jest tylko do nazw kolumn i tabel. Dobre i to.

Szybki przegląd implementacji:

DefaultNamingStrategy
EJB3NamingStratefy
DefaultComponentSafeNamingStratefy
ImprovedNamingStrategy

wykazał, że trzy pierwsze odpadają w przedbiegach. Konwencja wielbłądzia zachowana. Z klasy UserData.java tworzy się tabela UserData.

Cała nadzieja w ImprovedNamingStrategy. Konwertuje ona nazwy na konwencję z podkreśleniem... i tyle. O liczbie mnogiej mogę póki co pomarzyć. Nie tylko z resztą ja więc chyba skończy się na napisaniu swojej implementacji.

Nazwy kluczy obcych pozostają nie ruszone. Nawet nie nagryzione. Jeżeli wiesz, jak można je zmienić, daj koniecznie znać.

3 komentarze:

a pisze...

To jeszcze byłoby fajnie, jakby aliasy w zapytaniach, które generuje Hibernate były odrobinę mniej od czapy - może tu też jest jakieś fachowe 'obczaj to i tamto' ? :)

Tomasz Nurkiewicz pisze...

Zadziwiające, jaki ten świat mały ;-). Ale cieszę się, że mogłem pomóc :-).

Co do kluczy obcych i aliasów w zapytaniach SQL: kodu Hibernate nie czyta się może niczym powieści Dostojewskiego, ale pewnie nie trudno namierzyć kod odpowiedzialny za te oba grzechy przeciwko czytelności. Niemniej jednak ja już swoje 'obczaiłem', wasza kolej :-).

Tomasz Nurkiewicz pisze...

OK, nie wytrzymałem, otworzyłem projekt z Hibernate 3.4.0.GA na pokładzie i sprawdziłem "przy okazji" ;-).

Nazwy kluczy obcych: org.hibernate.mapping.Table # createForeignKey

a aliasy kolumn (w SELECT): org.hibernate.persister.entity.AbstractEntityPersister # generateSnapshotSelectString

Implementacja nie nastraja optymizmem (swoją drogą wolałbym nie wiedzieć przez jak długi stos przechodzą moje encje w JPA...) a już na pewno nie jest rozszerzalna...