Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

JPA, DAO i spójność Entity

13 views
Skip to first unread message

Kolszew

unread,
Nov 24, 2009, 5:22:48 AM11/24/09
to
Problem:
"Jak zrobi� aby warto�� pozycji dokumentu zawsze r�wna�a si� cena*ilo��?"

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

Matt Z

unread,
Nov 24, 2009, 6:00:00 AM11/24/09
to
Kolszew pisze:

> 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.

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/

Kolszew

unread,
Nov 24, 2009, 6:07:28 AM11/24/09
to
Matt Z pisze:

> Kolszew pisze:
>> 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.
>
> Ja bym proponowa� raczej w warstwie us�ug (*Service)


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

Matt Z

unread,
Nov 24, 2009, 9:27:28 AM11/24/09
to
Kolszew pisze:

> A co z Entity pozyskanďż˝ z mapowaďż˝ w innych entity? Przecieďż˝ tam jakby
> "wycieka" mo�liwo�� zmodyfikowania PozDokEntity bez udzia�u DAO czy
> Serwisu.

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.

Brzezi

unread,
Nov 24, 2009, 9:33:07 AM11/24/09
to
wto, 24 lis 2009 o 11:22 GMT, Kolszew napisaďż˝(a):

> - 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

Kolszew

unread,
Nov 24, 2009, 10:03:42 AM11/24/09
to
> 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

Brzezi

unread,
Nov 24, 2009, 11:18:48 AM11/24/09
to
wto, 24 lis 2009 o 16:03 GMT, Kolszew napisaďż˝(a):

>> 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

Kolszew

unread,
Nov 25, 2009, 2:37:35 AM11/25/09
to
> 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...

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

Marcin Kuthan

unread,
Nov 25, 2009, 3:37:23 AM11/25/09
to
On 24 Lis, 12:07, Kolszew <WYTNIJTOkrzysiekWYTNIJTO...@stream.com.pl>
wrote:

> Matt Z pisze:
>
> > Kolszew pisze:
> >> 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.
>
> > Ja bym proponował raczej w warstwie usług (*Service)
>
> 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.
>

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

MiSt

unread,
Nov 25, 2009, 3:48:29 AM11/25/09
to
On 25 Lis, 08:37, Kolszew <WYTNIJTOkrzysiekWYTNIJTO...@stream.com.pl>
wrote:
(...)
> 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.
>

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

miluch

unread,
Nov 26, 2009, 4:23:26 AM11/26/09
to

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

Kolszew

unread,
Nov 30, 2009, 8:05:23 AM11/30/09
to
> 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.

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


Matt Z

unread,
Nov 30, 2009, 1:50:44 PM11/30/09
to
Kolszew pisze:

> 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.

a to nie jest przeniesienie tej�e?

Kolszew

unread,
Dec 1, 2009, 2:20:23 AM12/1/09
to
> Kolszew pisze:
>> 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.
>
> 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

0 new messages