Aplikacja z modułami, moduły deklarują tabele bazodanowe

1

Aplikacja jawoska podzielona na modułu / pluginy (mowa o cięciu w przestrzeni użyteczności dla użytkownika, jeśli to nie oczywiste)
Jakiś Core/Root/Main plus rodzaj Security
Pracownicy (przykładowo) -> zależy od Core
Gospodarka samochodowa (przykładowo) -> Core, Pracownicy
BHP (przykładowo) -> Core, Pracownicy

Jak w fajnie w Javie zakodować, ze moduł zgłasza do jednej monolitycznej bazy (tzn nie myślimy mikrosewisami) swoje tabele - jego tabele mogą zależeć od bardziej podstawowych, np mieć tam klucze obce.
Oczywiście fajnie mi się to układa w JPA - ale że wypada narzekać na to środowisko ... są jakieś nowoczesne alternatywy? Osobiście jestem skłonny powtórzyć ...

Na poziomie operacyjnym używamy DBI (które skądinąd ma minimalistyczny layer kompatybilności z JPA), historycznie było macanie się się XxxxBatis, dema i testy kilku innych

Te narzędzia maja dużą siłą w operacyjnym SQL, ale małą w DDL
Deklarowanie na typach javowskich, w których przynajmniej część jest podpowiadana i kontrolowana kompilatorem, fajna rzecz.

2

Podsyłam ciekawą myśl, którą nauczyłem się u Wujka Boba.

Gdy projektuję swoje systemy nie myślę na początku o bazie. Odkładam decyzję o implementacji persystencji najpóźniej jak się da. Operuję na Plain Old Java Objects i wyrzucam zapytania persystencji do warstwy za interfejsem. Pierwszą implementacją jaką wstrzykuję jest trzymanie w pamięci operacyjnej. Jeżeli to nie spełnia wymagań zmieniam implementację na serializację na dysku twardym. Jeżeli to nie spełnia wymagań zmieniam implementację na sqlite. I dopiero na końcu, jak wymaga tego sytuacja rozważam zastosowanie zaawansowanej bazy danych SQL. Często okazuje się, że nie dochodzę do ostatniego kroku.

Myślę, że nagabywani przez bazodanowych marketingowców zapomnieliśmy trudnej sztuki projektowania swoich systemów w zależności od potrzeb.

W takim podejściu moduły JAR są de facto mikroserwisami, każdy z własną implentacją persystencji i komunikują się przez interfejsy. Mogą spokojnie siedzieć na jednej maszynie obok siebie.

Pytanie. 1. Dlaczego koniecznie jedna baza?

Pytanie. 2. Powiedz mi, bo się nie znam, czy JPA umożliwia te warstwy pośrednie implementacji persystencji czy wysyła nas od razu do pełnowymiarowej bazy danych SQL?

1
Michał Kuliński napisał(a):

Pytanie. 1. Dlaczego koniecznie jedna baza?

Pytanie. 2. Powiedz mi, bo się nie znam, czy JPA umożliwia te warstwy pośrednie implementacji persystencji czy wysyła nas od razu do pełnowymiarowej bazy danych SQL?

1 Choćby przez reguły integralności. Pocięcie bazy (w duchu mikroseriwsów - bo tak odczytuję Twoją wrzutkę) wymaga wiele wysiłku, aby na tym odbudować namiastkę tego, co mieliśmy za darmo: eventual integrity, synchronizacja. Złozonośc pieknie jedzie w górę. Brrrrr.
Samochód można przypisać tylko aktywnemu Pracownikowi, i nie można gdy utracił aktywności itd... dokument może sporządzić aktywny Operator itd
Filozofia mikroseriwsowa to overkill

  1. JPA to standard, jego wiodące implementacje to Hibernate, Eclipselink, OpenJPA i jeszce jakieś. Generalnie rzecz jest mocno skomplikowana, stany w jakich może być encja są skomplikowane. Zwykle w 99.9% trafia do bazy danych SQL (chyba są dialecty SQLLite, ale nie będe przysięgał), ale np zwłaszcza Eclipselink zabawia się innymi backendami niż bazy SQL, jak webserwisy
    Niektóre implementacje JPA sa czapką nad bazami obiektowymi (implementacje chyba nie mają 100% zgodności, bo paradygmat bazy jest radykalnie inny)

w pamięci operacyjnej. Jeżeli to nie spełnia wymagań zmieniam implementację na serializację na dysku twardym. Jeżeli to nie spełnia wymagań zmieniam implementację na sqlite. I dopiero na końcu, jak wymaga tego sytuacja rozważam zastosowanie zaawansowanej bazy danych SQL.

Pewne dane: wieloletnie, o silnych w naturze relacjach (Operator, Pracownik, Dział , Wydział), wieloletnie o skomplikowanej zależności czasowej (trzymamy dane "od stworzenia świata", choć zwykle kontakt mamy z bieżącym rokiem) z natury wskazują wprost, bez etapów prób serializacji, na bazę relayjną Samochód eksploatowany w 2022 został przyjęty w 2014, i tam mają źródła jego "kwity", obecnie jest w rękach Pracownika z 1998 roku (poprzednio tzrech innych), obecnie jest w Wydziale A, choć dawniej był w Wydziale B.
Są sytuacje, ze szkoda energii na serializację, profesjonalista z góry wie, że niecelowe (podobnie na SQLite - choć mając warstwowy system można to mieć bez rewolucji, ale po co)

2

Trochę nie rozumiem idei. Jeżeli chcesz mieć monolityczną bazę danych, to dlaczego chcesz ją tworzyć po kawałku?

0
piotrpo napisał(a):

Trochę nie rozumiem idei. Jeżeli chcesz mieć monolityczną bazę danych, to dlaczego chcesz ją tworzyć po kawałku?

Taki brzydki monolit z modułami. Moduły z zaleznościoami jednostronnymi (bez cyklicznych zaleznosci) Zapomniana wiedza starych Indian. W onecie by napisali "bankowcy są wkurzeni, nigdy nie będzie tak samo, gdy się dowiesz"

(skądinąd, jako branża za szybko zapominamy co było dobre w poprzednich modach, wielokrotnie buksujemy na mieliznach, które znali starzy żeglarze)
Dlaczego człowiek od samochodówki ma mieć głęboką wiedze o czymś, co go nie dotyczy. Dla niego Pracownik to "sztuka" - ma jakiś być wybrany, ale gdzie mu do szczegółów

1

@ZrobieDobrze: Ja to rozumiem. Nie widzę jedynie sensu takiego podejścia (nie znaczy, ze go nie ma). Jak przy każdej hierarchii (chyba o tym nawet razem pisaliśmy przy okazji REST) możesz tę hierarchię tworzyć używając dowolnego węzła drzewa jako "root".
Masz jakiś podział funkcjonalny z punktu widzenia użytkownika. Masz też strukturę architektoniczną w kodzie. Nikt ci nie narzuca, które warstwy mają być rozłożone pomiędzy moduły, a które mają być wspólne.
Dla mnie (znowu, moja perspektywa), warstwa persistent wgryzająca się w górę ma dużo wad. Podstawową jest to, że skoro baza jest wspólna, to jakieś tam zależności będą tak czy inaczej. Wolę mieć te zależności w jednym miejscu, niż przejmować się tym, że Zenek robiący moduł samochodów, zmienił coś w strukturze tabel, która bardziej pasuje do modułu pracowników. Jeżeli te moduły są robione na zasadzie pluginów, to robi się wręcz groźnie, bo skąd wiesz czy moduł A w wersji X będzie prawidłowo działać z kawałkiem bazy stworzonym przez moduł B w wersji Y?

Możliwe, że to brak otwartości umysły u mnie, ale traktuję utrwalanie danych jako coś, co następuje poza aplikacją. Dlatego staram się ucinać wiedzę o tym jak to utrwalanie jest robione, możliwie wcześnie i sprowadzać ją w części logiki biznesowej do Employee.findById(5).

1

To żeby się zbliżyć do finału, zawężona wersja pytania, zostawmy te moduły poza wątkiem.

Czy jest w javie równie dobry / lepszy sposób DEKLAROWANIA tabel, niż JPA
Czyli deklarowanie tabel, nie w SQL, XML etc
Należy przypuszczać używanie nie mniej niż 2 dialectów do serwerów baz.

@Entity 
class Cosik {
    @Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	int id;
 
 @Column(length=32, unique=true, nullable=false)
	String someField;   
}
1

Może nie w Javie, ale to jest właściwie "standard" obecnie: https://www.liquibase.org/

1

A może Ty szukasz czegoś w podobie do Ruby on Rails? ... No to proponuję Grails. https://en.wikipedia.org/wiki/Grails_(framework). ... GORM ... Tylko konieczna jest przesiadka na Groovy. Na szczęście zostajemy w JVM. (EDIT) Podobno można używać Javy. — Michał Kuliński 33 minuty temu

Do ekosystemu Grooviego mnie trzeba mnie przekonywać. Uważam za fajny jezyk, znam bebechy, integruję sobie z Javą (bardzo ciekawe i dobrze udokumentowane) ... Mastering samego języka (pisanie idiomatyczne) przyjdzie z czasem, ma fajne szybkie mozliwości. (nota bene dla javowców: moze być językiem sztywno kompilowanym)

Nie mam przekonania do produktu za to, ze jest All-in-one. Nie wiem jak będzie ze "stanięciem przed murem", jak już finałowa aplikacja będzie duża, wieloletnia.

Pod GORM jest Hibernate

piotrpo napisał(a):

Może nie w Javie, ale to jest właściwie "standard" obecnie: https://www.liquibase.org/

Że upgrejdy miedzy wersjami bazy na produkcji z Liquidbase, to oczywiste, ale ... to jest na inny etap zycia

1

@ZrobieDobrze: Jeżeli chcesz mieć deklarowanie DDL z poziomu kodu, to raczej ciężko będzie znaleźć coś skuteczniejszego niż jakaś implementacja JPA. Szczególnie, jeżeli chcesz mieć też ORM'a, to jak by nie patrzeć, podejście w którym zdefiniujesz sobie model danych na obiektach i użyjesz go zarówno do stworzenia struktury, jak i do CRUDowania tych obiektów jest wygodny.
Efekty bywają dziwne, bo podejście obiektowe i relacyjne są różne i różnie się te dane powinno układać. Jeżeli stosujesz "code first", to chyba nie znajdziesz nic lepszego. Pytanie, czy pisząc aplikację mającą bazę na wyłączność i jednocześnie udającą, że tej relacyjnej bazy nie ma warto się upierać przy SQL. Ale może akurat potrzebujesz transakcyjności, na skalowaniu ci nie zależy, więc jest jest jakieś uzasadnienie.

Inne podejście, sprawdzające się w przypadkach kiedy naprawdę potrzebujesz RDBMS, to stworzyć sobie definicję struktury za pomocą normalnego DDL'a/liquibase, dostosować to JPA do tak zrobionej struktury, albo używać np. jooq.

Jeszcze disclaimer, ja zacząłem programować przed nastaniem epoki ORM, być może z tego powodu mam lekkie uprzedzenie do tych narzędzi, w szczególności do ich "wyższych" funkcji powodujących, że programista może ignorować istnienie bazy relacyjnej.

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