Rozwi�zanie (wyczytane w necie):
Zakoduj to w Dao. W DAO od pozycji (PodDokDao) dokumentu w metodzie
zapisuj�cej (save(PozDokEntity e)) doda� wyliczanie warto�ci.
W�tpliwo�ci
- Wydaje mi si� �e to rozwi�zanie nie za�atwia problemu, w innym DAO
s�u��cym do operowania na spisie towar�w kto� pobiera encj� PozDokEntity
w celu odczytania czego� z niej i sprawdzenia jaki� warunk�w, nast�pnie
pomy�kowo ustawia pole Cena i ... JPA wysy�a update do bazy poprawiaj�c
tylko cenďż˝, bo ta encja jest skojarzona z konteksem i wszystkie zmiany
na niej sďż˝ persystowane.
- Jest jeszcze gorzej kiedy ktoďż˝ dostaje PozDokEntity nie z zapytania
JPAQLowego tylko z mapowania w swojej innej entity, przypadkiem coďż˝
zmienia ... ani wyj�tku ani dobrego wyliczenia
- Czy w tym przypadku nie przyda� by si� kod dzia�aj�cy analogicznie do
trigera bazy danych "zawsze przed zapisem niewa�ne sk�d pochodzi zmiana,
wykonaj obliczenia"?
- Da si� to jako� zrobi� w JPA? Dodam �e wyliczanie pozycji w tym
przyk�adzie jest banalne, na prawd� wymaga u�ycia kilku wstrzykiwanych
serwis�w i dosy� skomplikowanych operacji. Wi�c odpada:
- zapi�cie si� na settery w entity i wyliczanie tam nie zadzia�a bo
do entity nie wsztrzykn� serwis�w
- zapi�cie si� na metody cyklu �ycia ma t� sam� wad�
Pozdro
Kolszew
Ja bym proponowa� raczej w warstwie us�ug (*Service)
> W�tpliwo�ci
ano sďż˝...
> - Czy w tym przypadku nie przyda� by si� kod dzia�aj�cy analogicznie do
> trigera bazy danych
pewnie i by si� przyda�, ale m�odzie� nie lubi pisa� wyzwalaczy, a poza
tym...
> - Da siďż˝ to jakoďż˝ zrobiďż˝ w JPA?
nie.
Na upartego mo�na to wymusi� wi�zami integralno�ci typu CHECK (zn�w nie
przez JPA, tylko bazodanowo).
Na bardzo upartego, mo�e uda�oby si� co� wydzierga� tworz�c walidator
hibernate.
--
pozdrawiam
Mateusz
http://na-jawie.blogspot.com
http://sites.google.com/site/pudelekeclipseplugin/
Tak wysoko?
Zatem do PozDokDao musia�by mie� dost�p tylko PozDokService?
I Wszyscy inni nie otrzymali by nigdy "�ywej" Entity tylko od��czon�
albo DTO?
A co z Entity pozyskanďż˝ z mapowaďż˝ w innych entity? Przecieďż˝ tam jakby
"wycieka" mo�liwo�� zmodyfikowania PozDokEntity bez udzia�u DAO czy Serwisu.
Kolszew
zale�y jak zmapujesz, ale decyduj�c si� na denormalizacj� musisz si�
liczyďż˝ z dyscyplinďż˝.
Mo�esz j� wspomaga� za�lepkami, z kt�rych nape�niejsz� jest wyzwalacz,
ale to i tak nie uchroni Ci� w pe�ni przed mo�liwo�ci� rozjechania si�
danych.
> - Da si� to jako� zrobi� w JPA? Dodam �e wyliczanie pozycji w tym
> przyk�adzie jest banalne, na prawd� wymaga u�ycia kilku wstrzykiwanych
> serwis�w i dosy� skomplikowanych operacji. Wi�c odpada:
> - zapi�cie si� na settery w entity i wyliczanie tam nie zadzia�a bo
> do entity nie wsztrzykn� serwis�w
> - zapi�cie si� na metody cyklu �ycia ma t� sam� wad�
Nie rozumiem w koncu, jest banalne czy nie to wyliczenie? wymaga
dodatkowych serwisow czy nie? bo jedno Twoje zdanie jest sprzeczne z drugim
:)
Ja sugerowalbym:
- wywolanie wyliczenia w seterze zaleznego propertasa
- PreInsert/PreUpdate
powyzsze sposoby wymagaja dodatkowej kolumny w bazie danych, ktora jest
wyliczana, czyli psujemy postac normalna bazy danych, danych wyliczanych
nie powinno sie nadmiarowo umieszczac, wiec moim ostatecznym rozwiazaniem,
jest zasugerowanie uzycia "formu�y" hibernatowej...
Pozdrawiam
Brzezi
wymaga, trzeba tam policzy� jeszcze du�o innych warto�ci na podstawie
danych z innych serwis�w i cz�ciowo przy u�yciu innych, poda�em tylko
warto�� = ilo�� * cena dla przyk�adu, bardziej chodzi mi o to gdzie (w
kt�rym miejscu) w architekturze DB-(HIB/JPA)-DAO-EJB_SERVICE umieszcza�
logik� kt�ra musi zosta� wykonana zawsze przy modyfikacji (insert,
update) pozycji dokumentu.
"W wie�ciach z netu" og�lnie przewija si� "put buisness logic in
service layer" i ok ale jak rozwi�za� problem "wyciekaj�cych" "�ywych"
encji ??? Przecie� je�li kto� ma baz� zmapowan� to mo�e dobra� si� do
encji PozDok na kilka sposob�w, JPAQLem, zwyk�ym find() z em'a, mo�e j�
te� pobra� z innej encji kt�r� w�a�nie opracowuje pozImpExp.getPozDok()
dzi�ki mapowaniu relacji. I za ka�dym razem zmiany dokonane w niej s�
zatwierdzane do bazy bez udzia�u serwisu ani dao! Jak rozwi�za� problem
�e DAO w zasadzie ma "szkodliwe" metody skoro update() z dao zapisuje do
bazy i nie dba o to aby dane by�y sp�jne ... to po co taka warstwa,
wystarczyďż˝ by em.persit() czy session.save().
My�l� �e to raczej ja czego� nie qumam a te technologie s� dosy� dobrze
zdefiniowane i to ja b��dz� a nie �e nie ma dobrego rozwi�zania dla tak
prostej i oczywistej rzeczy.
Pozdro
Kolszew
>> Nie rozumiem w koncu, jest banalne czy nie to wyliczenie? wymaga
>> dodatkowych serwisow czy nie? bo jedno Twoje zdanie jest sprzeczne z drugim
>
> wymaga, trzeba tam policzy� jeszcze du�o innych warto�ci na podstawie
> danych z innych serwis�w i cz�ciowo przy u�yciu innych, poda�em tylko
> warto�� = ilo�� * cena dla przyk�adu, bardziej chodzi mi o to gdzie (w
> kt�rym miejscu) w architekturze DB-(HIB/JPA)-DAO-EJB_SERVICE umieszcza�
> logik� kt�ra musi zosta� wykonana zawsze przy modyfikacji (insert,
> update) pozycji dokumentu.
> "W wie�ciach z netu" og�lnie przewija si� "put buisness logic in
> service layer" i ok ale jak rozwi�za� problem "wyciekaj�cych" "�ywych"
> encji ??? Przecie� je�li kto� ma baz� zmapowan� to mo�e dobra� si� do
> encji PozDok na kilka sposob�w, JPAQLem, zwyk�ym find() z em'a, mo�e j�
> te� pobra� z innej encji kt�r� w�a�nie opracowuje pozImpExp.getPozDok()
> dzi�ki mapowaniu relacji. I za ka�dym razem zmiany dokonane w niej s�
> zatwierdzane do bazy bez udzia�u serwisu ani dao! Jak rozwi�za� problem
> �e DAO w zasadzie ma "szkodliwe" metody skoro update() z dao zapisuje do
> bazy i nie dba o to aby dane by�y sp�jne ... to po co taka warstwa,
> wystarczyďż˝ by em.persit() czy session.save().
> My�l� �e to raczej ja czego� nie qumam a te technologie s� dosy� dobrze
> zdefiniowane i to ja b��dz� a nie �e nie ma dobrego rozwi�zania dla tak
> prostej i oczywistej rzeczy.
>
> Pozdro
> Kolszew
Ok, skoro to skomplikowana operacja, wiec umieszczanie metod cyklu zycia w
encji, nie jest dobre, ale dlaczegoby nie uzyc:
http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/listeners.html
?
mozesz stworzyc narzedziowy serwis, ktory bedzie nasluchiwal na zdarzenia,
bez problemu wlozysz do niego inne serwisy do logiki bizesowej, wszystko
bedzie odseparowane na poprawnym poziomie...
Pozdrawiam
Brzezi
Pomys� jest ok, z tym �e entityListeners to zwyk�e klasy a nie beany
wi�c nie stworz� serwisu i nic do niego nie wstrzykn�.
Mo�na bawi� si� przez JNDI, ten temat �wiczy� ju� Jacek Laskowski:
http://www.jaceklaskowski.pl/wiki/Dost%C4%99p_do_EntityManager_w_metodach_zwrotnych_encji_w_JPA
Tak czy inaczej rozwi�zania tego typu wygl�daj� jak sztuczki, a ja
szukam naturalnego dla technologii (EJB, JPA) rozwi�zania tak
podstawowego wydaje mi sie problemu.
Kolszew
Co to znaczy wycieka?
1. Jeżeli encja jest pobrana w serwisie bez udziału transakcji (lub
transakcja readonly) to nie będzie automatycznie zapisana do bazy przy
końcu sesji (piszę o encji połączonej z sesją)
2. Jak jest wyłączone kaskadowanie przy zapisie to zmiany nie zostaną
zapisane przy okazji zapisu encji która referuje do PozDokEntity.
3. W serwisie robisz metodę (transactional, rw) która ma możliwość
zapisu PozDokEntity i w niej umieszczasz potrzebną logikę. Żadna inna
metoda serwisowa nie zapisuje PozDokEntity, jak musi to zrobić to
deleguje wywołanie do tej pierwszej metody.
Może to nieco zagmatwane, ale ja nie widzę problemu. Potrzebna jest
tylko przemyślana warstwa serwisowa i brak bezpośredniego dostępu
akcji webowych do DAO/entity manager-a.
Pozdrawiam,
Marcin
> Kolszew
Po pierwsze czy musisz te dane trzymać w bazie ?
Może lepiej przenieść te informacje do innej klasy i jak ktoś będzie
ich potrzebował to warstwa service mu je przeliczy ? Czyli warstwa
biznesowa zwraca encję owiniętą klasą z przeliczonymi wartościami? I
tych przeliczonych wartości nie trzymasz już w bazie.
Jeśli to z jakiś przyczyn nie jest możliwe to tak czy siak
skomplikowana logika na pewno nie powinna znależć się w warstwie
DAO.
To warstwa biznesowa powinna wykrywać zmiany tych pól i odpowiednio
je aktualizować. Wtedy wszystkie operacje które dotyczą tych
wartości powinny przechodzić przez warstwę service. Co do Twoich obaw
że ktoś zmieni te wartości poza warstwą service to równie dobrze ktoś
sobie zrobi update bezpośrednio na bazie i już masz niespójne dane.
Jedynie triggery w bazie rozwiązałyby ten problem ale to zdecydowanie
zły pomysł
--
Mist
Witam
To może i moje 3 grosze.
Świat EJB/JPA od dawna promuje Anemic Domain Model - nasze klasy mają
albo stan albo zachowanie. Standardowa architektura to: zachowanie w
service, DAO (które tak na prawde nie jest technology agnostic), dane
w encjach. Mógłbym tu wylewać swoje żale na ten temat przez pół
godziny ale sumując: nie widzę aktualnie możliwości budowanie rich
domain model applications w oparciu o pure EJB/JPA.
W twoim przypadku głownym problemem jest trudność z injectowaniem
czegoś do entity. Fajnym rozwiązaniem byłoby użycie coś w stylu
@Cofnigurable ze Springa, jeśli nie chcesz się pod spodem mieć
aspectJ to może coś takiego: http://blog.krecan.net/2009/01/24/spring-managed-hibernate-interceptor-in-jpa/.
Oba rozwiązania wykorzystują Spring, ale może byłaby możliwość troche
stunowania tego do EJB: czytac odpowiednie annotacje w klasie
entity,na ich podstawie wyciagac z JNDI obiekty i ustawiac je do
entity.
Innym rozwiązaniem jakie przyszło mi do głowy to czy nie można wywalic
settera do cena i ilość i zamiast tego stworzyć metody: updateCena(),
updateIIlosc() które oprócz faktycznej wartości do upatowania jako
argumenty wezmą obiekty klas (jeszcze lepiej tylko interfejsy)
odpowiedzialne za wyliczanie wartości pozycji. Bardzo nie wygodne, ale
jak mówiłem bez DI ciężko to zrobić ładniej. W tym przypadku
przynajmniej masz pewność że nikt ci nie zmodyfikuje wartości pozycji
bez twojej wiedzy.
pzdr miluch
Dzi�ki, doszed�em do podobnych wniosk�w, zapinanie regu� biznesu na fakt
zmiany atrybut�w w warstwie persystencji to z�y pomys�, trzeba napisa�
serwis do takiej zmiany o tam umie�ci� ta logik� - jak opisa�e�.
Mnie zmyli�y moje przyzwyczajenia -> baza danych i triggery ...
Przy migracji z 'c/s' do 'multier' jak nale�y przenie�� kod z trigger�w
do serwera app? - Nie nale�y go przenosi�!!! Napisa� na nowo logik� w
serwisach.
Dzi�kuj� wszystkim za pomoc
Krzysiek
a to nie jest przeniesienie tej�e?
Nie jest, triggerowa logika ma charakter reakcji na zmian� zawarto�ci
tabeli, zmian� warto�ci kolumny, kto� robi dowolne inserty, updaty,
delety a Ty piszesz reakcje na te zdarzenia, na zmiany konkretnych
kolumn. Przy orm'ach i ejb wyglada to inaczej, nie patrzysz od strony
danych tylko od strony funkcji udost�pnianych klientom, programujesz te
funkcje w celu spe�nienia kontraktu dzia�aj�c na grafie powi�zanych
encji a nie na jednej tabeli.
Krzysiek