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

@Version, problem z optimistic locking w EJB3.0

53 views
Skip to first unread message

Gabcia85

unread,
Mar 20, 2007, 4:38:37 AM3/20/07
to
CZesc,

chcialam sobie zalozyc na tranzakcji sprawdzanie versji encji w
aplikacji i mam problem:
mam na kazdym entity beanie versje:
private long version;

@Version
public long getVersion() {..}
no i seta

problem w tym ze pobieajac przy logowaniu obiekt person (wczytuje
obiekt, cos porobie w nim i a pozniej em.merge();)
zamiast inkrementowac mi od 0 w gore co jeden; wrzuca mi losowo jakies
warstosci, 2,13,28,32 itd.
po odpaleniu kilku podstron w aplikacji losowo po jakims czasie wywala
mi komunikat:
"No row with the given identifier exists: "

Dla informacji dodam ze uzywama manager entity manager w seamie.
@PersistenceContext(unitName="userDatabase")
private EntityManage em;

mozliwe ze mam zle skonfigurowany em, ale nie wiem jaki pieron:P

a to moj persistence.xml
<persistence>
<persistence-unit name="userDatabase">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/myAppDatasource</jta-data-source>
<properties>
<property name="dialect">org.hibernate.dialect.MySQLDialect</
property>
<!-- <property name="hibernate.show_sql" value="true"/> -->
<!-- <property name="hibernate.hbm2ddl.auto" value="create"/> --
>
</properties>
</persistence-unit>
</persistence>

Regards Gabcia!

Jacek Laskowski

unread,
Mar 20, 2007, 5:23:31 AM3/20/07
to
Gabcia85 wrote:
> CZesc,
>
> chcialam sobie zalozyc na tranzakcji sprawdzanie versji encji w
> aplikacji i mam problem:

tj. chciałabyś wykorzystać zalecane optymistyczne blokowanie?

> mam na kazdym entity beanie versje:
> private long version;
>
> @Version
> public long getVersion() {..}
> no i seta
>
> problem w tym ze pobieajac przy logowaniu obiekt person (wczytuje
> obiekt, cos porobie w nim i a pozniej em.merge();)

To mi się nie podoba. Możesz podać serię operacji jakie wykonujesz na
EM? Najbardziej uderzające jest wykorzystanie em.merge(). Po co?

> zamiast inkrementowac mi od 0 w gore co jeden; wrzuca mi losowo jakies
> warstosci, 2,13,28,32 itd.

A gdzie napisano, że kolejne wartości muszą być faktycznie kolejne w
sensie liczb zmiennoprzecinkowych (ciekawe czy w ogóle takie pojęcie
istnieje dla nich)?

Pole @Version jest wyłącznie dla dostawcy JPA, więc obojętnie jakie tam
są wartości nie powinny być częścią aplikacji, a jedynie mechanizmem do
utrwalania zmian i zapewnienia, że nie będzie nadpisywania ich.

> po odpaleniu kilku podstron w aplikacji losowo po jakims czasie wywala
> mi komunikat:
> "No row with the given identifier exists: "

To za mało. Nie musi to oznaczać, że są problemy z @Version. Zresztą -
usuń @Version i potestuj. Założę się, że będą te same "kwiatki".

> Dla informacji dodam ze uzywama manager entity manager w seamie.

Ooohooo, tu może być problem podczas integracji możliwości Seama z JPA.
Na razie odsuńmy to na bok, tj. korzystaj z niego, ale jeśli pomysły z
samym JPA nam się wyczerpią dopiero do niego podejdziemy.

> @PersistenceContext(unitName="userDatabase")
> private EntityManage em;
>
> mozliwe ze mam zle skonfigurowany em, ale nie wiem jaki pieron:P

Albo źle z niego korzystasz. Coś mi się zdaje, że nie zapisujesz zmian w
odpowiednim momencie, jeśli w ogóle.

> a to moj persistence.xml
> <persistence>
> <persistence-unit name="userDatabase">
> <provider>org.hibernate.ejb.HibernatePersistence</provider>
> <jta-data-source>java:/myAppDatasource</jta-data-source>
> <properties>
> <property name="dialect">org.hibernate.dialect.MySQLDialect</
> property>
> <!-- <property name="hibernate.show_sql" value="true"/> -->
> <!-- <property name="hibernate.hbm2ddl.auto" value="create"/> --
> </properties>
> </persistence-unit>
> </persistence>

Wydaje się być w porządku. Możesz opcjonalnie włączyć zapisywanie
zapytań SQL, aby prześledzić co się dzieje "pod spodem".

Jacek

--
Jacek Laskowski
http://www.JacekLaskowski.pl

Gabcia85

unread,
Mar 20, 2007, 5:48:33 AM3/20/07
to

> tj. chciałabyś wykorzystać zalecane optymistyczne blokowanie?

Tak

> > mam na kazdym entity beanie versje:
> > private long version;
>
> > @Version
> > public long getVersion() {..}
> > no i seta
>
> > problem w tym ze pobieajac przy logowaniu obiekt person (wczytuje
> > obiekt, cos porobie w nim i a pozniej em.merge();)
>
> To mi się nie podoba.

Co ci sie nie podoba dokladniej?

>Możesz podać serię operacji jakie wykonujesz na
> EM? Najbardziej uderzające jest wykorzystanie em.merge(). Po co?

Dlatego zeby zsynchronizowac sie z bazą danych tzn. robie jakies
zmiany na obiekcie i merge mi powininen zapisac zmiany, co nie?

W sesji mam obiekt person i metoda wyglada np. tak, wchodze na kolejna
podstrone :
try {
person = em.merge(person); //chce zeby obiekt byl zarzadzany
przez em. dla kolekcji lazy
em.refresh(person); //odswiezam stan z bazy czy cos
sie nie zmienilo
tutaj cos robie na niej, nie uzywajac em. jakies zmiany pol itp.
i na koniec em.merge(person); //na koniec robie update do bazy
nowych rzeczy..
}
podobna kombinacja jest w prawie kazdej metodzie, czy taka kombinacja
jest bledna?

> > zamiast inkrementowac mi od 0 w gore co jeden; wrzuca mi losowo jakies
> > warstosci, 2,13,28,32 itd.
>
> A gdzie napisano, że kolejne wartości muszą być faktycznie kolejne w
> sensie liczb zmiennoprzecinkowych (ciekawe czy w ogóle takie pojęcie
> istnieje dla nich)?

rozmawialam z kolega co w hibernate to kiedys uzywal to mowile ze
zwykle przy kolejnym update rekordu dodawana jest nowa wartosc w
kolumnie version, wieksza o 1 od poprzedniej.

>
> Pole @Version jest wyłącznie dla dostawcy JPA, więc obojętnie jakie tam
> są wartości nie powinny być częścią aplikacji, a jedynie mechanizmem do
> utrwalania zmian i zapewnienia, że nie będzie nadpisywania ich.
>
> > po odpaleniu kilku podstron w aplikacji losowo po jakims czasie wywala
> > mi komunikat:
> > "No row with the given identifier exists: "
>
> To za mało. Nie musi to oznaczać, że są problemy z @Version. Zresztą -
> usuń @Version i potestuj. Założę się, że będą te same "kwiatki".

Bez uzycia adnotacji @Version kolumna ma wciaz wartosc 0 i nic nie
robi, co jest oczywiste. Bledow tez nie ma

>
> > Dla informacji dodam ze uzywama manager entity manager w seamie.
>
> Ooohooo, tu może być problem podczas integracji możliwości Seama z JPA.
> Na razie odsuńmy to na bok, tj. korzystaj z niego, ale jeśli pomysły z
> samym JPA nam się wyczerpią dopiero do niego podejdziemy.
>

Przeczytalam road map seama i napisane jest ze w wersji 1.2.1 GA ma
byc:
Bug JBSEAM-942 UNRESOLVED Optimistic locking an seam
persistence context replication
Czyzby versionowanie nie dzialalo w seamie?
tutaj masz link do tego:
http://jira.jboss.com/jira/browse/JBSEAM?report=com.atlassian.jira.plugin.system.project:roadmap-panel


> > @PersistenceContext(unitName="userDatabase")
> > private EntityManage em;
>
> > mozliwe ze mam zle skonfigurowany em, ale nie wiem jaki pieron:P
>
> Albo źle z niego korzystasz. Coś mi się zdaje, że nie zapisujesz zmian w
> odpowiednim momencie, jeśli w ogóle.

To w takim razie jak powinnam uzywac obiektu zeby poprawnie oblsugiwac
wersjonowanie? Mozesz jakis przyklad prosty podac?

Jacek Laskowski

unread,
Mar 20, 2007, 7:10:16 AM3/20/07
to
Gabcia85 wrote:

> Co ci sie nie podoba dokladniej?

Wykorzystanie merge(), który robi co innego niż sądzisz.

> Dlatego zeby zsynchronizowac sie z bazą danych tzn. robie jakies
> zmiany na obiekcie i merge mi powininen zapisac zmiany, co nie?

Właśnie, że nie. Jedyną sytuacja, w której następuje zapisanie zmian do
bazy danych to, albo podczas zatwierdzenia transakcji (commit), albo
podczas flush(). Pozostałe operacje są "lokalne".

Wszystko zatem zależy od ustawienia transakcji na EM albo PC. Z tego, co
pamiętam masz ustawione tak, że PC jest TRANSACTION oraz FlushMode
ustawione jest na AUTO na EM.

> try {
> person = em.merge(person); //chce zeby obiekt byl zarzadzany
> przez em. dla kolekcji lazy

To jest w porządku, ale skłaniałbym się jednak ku rozszeżonemu PC.

> em.refresh(person); //odswiezam stan z bazy czy cos
> sie nie zmienilo

...i nadpisujesz wszystkie zmiany jakie dokonałaś do tej pory, a które
nie były w bazie.

> tutaj cos robie na niej, nie uzywajac em. jakies zmiany pol itp.

Ok.

> i na koniec em.merge(person); //na koniec robie update do bazy
> nowych rzeczy..

Tego nie rozumiem (!) Dlaczego nie robisz flush(), albo po prostu
wymuszasz zapisanie zmian przy zakończeniu transakcji? Flush może zostać
zignorowany i jego działanie ujawni się dopiero podczas commit.

> }
> podobna kombinacja jest w prawie kazdej metodzie, czy taka kombinacja
> jest bledna?

Komentarze powyżej.

> rozmawialam z kolega co w hibernate to kiedys uzywal to mowile ze
> zwykle przy kolejnym update rekordu dodawana jest nowa wartosc w
> kolumnie version, wieksza o 1 od poprzedniej.

Zatem tak było w Hibernate. Możliwe, że w Hibernate JPA tego nie ma?!
Dodatkowo, do czego potrzebna byłaby Ci ta informacja? Chyba nie
zamierzałaś oprzeć na niej działania aplikacji?!

> Przeczytalam road map seama i napisane jest ze w wersji 1.2.1 GA ma
> byc:
> Bug JBSEAM-942 UNRESOLVED Optimistic locking an seam
> persistence context replication
> Czyzby versionowanie nie dzialalo w seamie?
> tutaj masz link do tego:
> http://jira.jboss.com/jira/browse/JBSEAM?report=com.atlassian.jira.plugin.system.project:roadmap-panel

Dzięki za namiary!

> To w takim razie jak powinnam uzywac obiektu zeby poprawnie oblsugiwac
> wersjonowanie? Mozesz jakis przyklad prosty podac?

Tak! Przykład byłby pomocny. Posiedzę nad nim, ale nie mogę teraz - może
wieczorem, chociaż też tego nie widzę biorąc pod uwagę wieczorne
spotkanie Warszawa JUG. Tak, czy owak przykład będzie, ale trochę później.

Gabcia85

unread,
Mar 20, 2007, 7:47:00 AM3/20/07
to
> Wykorzystanie merge(), który robi co innego niż sądzisz.
>
> > Dlatego zeby zsynchronizowac sie z bazą danych tzn. robie jakies
> > zmiany na obiekcie i merge mi powininen zapisac zmiany, co nie?
>
> Właśnie, że nie. Jedyną sytuacja, w której następuje zapisanie zmian do
> bazy danych to, albo podczas zatwierdzenia transakcji (commit), albo
> podczas flush(). Pozostałe operacje są "lokalne".

ooo a ja myslalam ze commit wykorzystuje sie w non-manager entity
manager.
W sumie to ja dop. raczkuje w ejb, jak pewno zauwazyles po moich
postach.

>
> Wszystko zatem zależy od ustawienia transakcji na EM albo PC. Z tego, co
> pamiętam masz ustawione tak, że PC jest TRANSACTION oraz FlushMode
> ustawione jest na AUTO na EM.

Zgadza sie!

>
> > try {
> > person = em.merge(person); //chce zeby obiekt byl zarzadzany
> > przez em. dla kolekcji lazy
>
> To jest w porządku, ale skłaniałbym się jednak ku rozszeżonemu PC.
>
> > em.refresh(person); //odswiezam stan z bazy czy cos
> > sie nie zmienilo
>
> ...i nadpisujesz wszystkie zmiany jakie dokonałaś do tej pory, a które
> nie były w bazie.

Dlaczego nadpisuje zmiany ktore nie byly w bazie. Nie rozumiem, z tego
co mi sie wydaje to refresh wlasnie robi na odwrot, sprawdza czy w
bazie sa jakies zmiany w stosunku do obiektu w sesji i jesli sa to do
obiektu w aplikacji wczytuje mi te zmiany, a merge na odrwot. Myle
sie?

> > i na koniec em.merge(person); //na koniec robie update do bazy
> > nowych rzeczy..

>


> > To w takim razie jak powinnam uzywac obiektu zeby poprawnie oblsugiwac
> > wersjonowanie? Mozesz jakis przyklad prosty podac?
>
> Tak! Przykład byłby pomocny. Posiedzę nad nim, ale nie mogę teraz - może
> wieczorem, chociaż też tego nie widzę biorąc pod uwagę wieczorne
> spotkanie Warszawa JUG. Tak, czy owak przykład będzie, ale trochę później.
>

wiesz co, bardzo by mi pomogło jak bys zorganizowal nieco czasu, i
zaprezentowal przyklad taki od A-Z.
Majac persistence.xml, zadeklarowanie mojego entity manager i jakis
prosty entity bean z wykorzystaniem wersjonowania.
No i jakies 2 metody. Jedna wczytuje encje, przekazuje do sesji, a
druga zapisuje z sprawdzeniem stanu w bazie na poczatku, jakas zmiana
prosta na polu i zapisanie do bazy zmian.
Bylo by mi to bardzo przydatne, a i moze do Twojego notatnika
projektanta bylo by to bardzo przydatne albo do wiki, dla ludzi klasy
"newbie" jak ja:)
A jak by to byl przyklad z wykorzystaniem Seam'a to bylo by miodzio:P
<marzenia>

A tak na marginesie, kiedys pisalam na forum Seam'a jak zadeklraowac
EntityManager w Seamie to Gavin King odpisam mi inaczej niz
@PersistenceContext(...)
@In(create=true)
ktory wstrzykuje go, lecz nie wiem ktore rozwiazanie jest
lepsze...moja wiedza jest na ten temat zbyt slaba zeby porownac obie
metody.
Pozdrawiam Cie Jacku i czekam z niecierpliwością na przykladzik.
Gabcia

Jacek Laskowski

unread,
Mar 20, 2007, 8:02:47 PM3/20/07
to
Gabcia85 wrote:

> ooo a ja myslalam ze commit wykorzystuje sie w non-manager entity
> manager.
> W sumie to ja dop. raczkuje w ejb, jak pewno zauwazyles po moich
> postach.

Czekaj tutaj to razem raczkujemy stąd takie rozbieżności. Wydaje mi się,
że masz rację z transakcjami w trybie zarządzanym. Nie ty decydujesz o
transakcjach tylko kontener.

Za dużo bawiłem się JPA w trybie poza kontenerem (ang. outside the
container) i teraz mi się wszystko myli. Muszę zestawić sobie środowisko
do testów z kontenerem EJB 3.0.

>>> em.refresh(person); //odswiezam stan z bazy czy cos
>>> sie nie zmienilo
>> ...i nadpisujesz wszystkie zmiany jakie dokonałaś do tej pory, a które
>> nie były w bazie.
> Dlaczego nadpisuje zmiany ktore nie byly w bazie. Nie rozumiem, z tego
> co mi sie wydaje to refresh wlasnie robi na odwrot, sprawdza czy w
> bazie sa jakies zmiany w stosunku do obiektu w sesji i jesli sa to do
> obiektu w aplikacji wczytuje mi te zmiany, a merge na odrwot. Myle
> sie?

Dokładnie jak piszesz. A co ze zmianami w encji, które nie trafiły
jeszcze do bazy podczas wywołania refresh()? Jak dla mnie to są zamazywane.

> wiesz co, bardzo by mi pomogło jak bys zorganizowal nieco czasu, i
> zaprezentowal przyklad taki od A-Z.

Sam odczuwam brak takiego przykładu. W nadchodzący piątek prezentuję
Apache Geronimo i Java EE 5 na Software Development GigaCon 2007, więc
może udałoby się zestawić taki przykład na wykład (ale mi się zarymowało
;-))

> Majac persistence.xml, zadeklarowanie mojego entity manager i jakis
> prosty entity bean z wykorzystaniem wersjonowania.
> No i jakies 2 metody. Jedna wczytuje encje, przekazuje do sesji, a
> druga zapisuje z sprawdzeniem stanu w bazie na poczatku, jakas zmiana
> prosta na polu i zapisanie do bazy zmian.
> Bylo by mi to bardzo przydatne, a i moze do Twojego notatnika
> projektanta bylo by to bardzo przydatne albo do wiki, dla ludzi klasy
> "newbie" jak ja:)

Przyjmuję wyzwanie! Od jutra zabieram się do pracy.

> A jak by to byl przyklad z wykorzystaniem Seam'a to bylo by miodzio:P

Też mi się podoba. Ech, już nie mogę doczekać się, kiedy zobaczę to
działające.

> A tak na marginesie, kiedys pisalam na forum Seam'a jak zadeklraowac
> EntityManager w Seamie to Gavin King odpisam mi inaczej niz
> @PersistenceContext(...)
> @In(create=true)
> ktory wstrzykuje go, lecz nie wiem ktore rozwiazanie jest
> lepsze...moja wiedza jest na ten temat zbyt slaba zeby porownac obie
> metody.

Tutaj poczekałbym na odpowiedź od kogoś od Seama. Nie czuję się na
siłach podejmować dysputy na ten temat. Może znajdą się chętni?!
Poczekajmy na szerkana. On wymiata w Seamie.

Gabcia85

unread,
Mar 21, 2007, 5:57:46 AM3/21/07
to

>
> Dokładnie jak piszesz. A co ze zmianami w encji, które nie trafiły
> jeszcze do bazy podczas wywołania refresh()? Jak dla mnie to są zamazywane.

Jesli uwzglednie w kazdej metodzie takie zachowanie jak przedstawilam
tzn:
odswiez stan z bazy
zrob cos na encji,
zapisz stan.
To nie dopuszczalne jest zebym miala cos w encji i pozniej to
utracila.

>
> Przyjmuję wyzwanie! Od jutra zabieram się do pracy.
>

Czekam z niecierpliwością!


sherkan

unread,
Mar 21, 2007, 6:15:22 AM3/21/07
to
Heloł:P

No ciekawy jest ten post, wiec postanowilem pobuszować nieco po forum
seam'a!
Jak to chlopaki z seam'a maja zasade co jest dobre chcą zrobić jeszcze
lepsze!
Ostatnio mialem niezłą zabawe z AJAX'em bo chłopcy postanowili
zamieszać nieco i pozmieniali konfiguracje ajax'a
dla najnowszej wersji seam'a 1.2.0 i cala aplikacja mi sie rozpadła:/

Moze zachęce kogoś do uzywania Seam'a bo to niezly bajer...ostatnio
chlopaki zaczeły pracować nad integracją ze Springiem i
juz maja jakies calkiem niezle efekty z tego co slyszalem.
Kombinują też nad swoim schedulerem dla Seam'a.

Tak na marginesie Jacek, czy jest gdzies jakas e-wersja, lub movie z
waszych spotkan w Warszawie?
Kurcze chetnie bym do was sie przylaczyl i posluchal wykładów. Moze
pomyślicie nad tym (o ile nie istnieje już),
zeby np. udostepniac na Twojej stronie wersji elektronicznych
wykladow, bądź nagrywać spotkania i udostepniać na stronie.
Mysle ze takie nagranie w formie divxa chetnie by ludzie ogladali, co
uczestnicza tutaj na forum javy.
co ty na to? taka java-videoteka byla by niezłym kompedium wiedzy:P
Ja jestem za!

Wiec w seamie Em wstrzykuje się poprzez adnotacje @In(create=true), co
powoduje ze em staje się "seam managed persistence",
ktory ma nieco inne parametry niz uzyty przez @PersictenceContex
adnotacje.
Jaka z tego zaleta? em staje sie "conversation-scope entity manager"
dla Seama.

Moze Tobie tez Jacku przydadzą się te linki z informacjami do
tutorialka, ktory chetnie zobaczę!:)


Generalnie zasada w Seamie jest taka:
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=85357
To jest niezle!
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=70997

W najnowszym seam docu to jest rozdzial 8.2

Tutaj masz ciekawy referat o Seam Manager Persistece Context
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=88460


http://www.jboss.com/index.html?module=bb&op=viewtopic&t=98971
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=100627
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=104400
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=89319

Takie ciekawostki odnosnie EM:
1.
Posts: gavin...@jboss.com
If you have an extended persistence context, and a conversation, you
don't need to use merge.
2.
) A Seam persistence context is most like a container-managed extended
persistence context.
But whereas the container-managed context is tied to an SFSB instance,
and hence there can be multiple contexts per conversation,
the Seam persistence context has exactly one per conversation.

Wiec wg. mnie morał taki że dla Seam'a lepiej uzywać: Seam Managed
Persistence, a w pozostalych przypadkach PersistenceContext

sherkan

unread,
Mar 21, 2007, 7:18:46 AM3/21/07
to
Kolejny raz off topic, sorki:P

Postanowilem stworzyc nowy topic z tymi nagraniami spotkan JUG, jak
chcesz to mnie tam zbluzgaj Jacku, ale ciekaw jestem co ludzie
powiedzia na ten pomysl.
A noz tak moze Cie zmobilizujemy do robienia nagran dla całej rzeszy
Java developerow from Poland:P hehe

Jacek Laskowski

unread,
Mar 21, 2007, 1:47:38 PM3/21/07
to
sherkan wrote:

Taaa, jak Cię nie było, to był dopiero spokój! :P

Gabcia85

unread,
Mar 27, 2007, 7:26:54 AM3/27/07
to
> > Majac persistence.xml, zadeklarowanie mojego entity manager i jakis
> > prosty entity bean z wykorzystaniem wersjonowania.
> > No i jakies 2 metody. Jedna wczytuje encje, przekazuje do sesji, a
> > druga zapisuje z sprawdzeniem stanu w bazie na poczatku, jakas zmiana
> > prosta na polu i zapisanie do bazy zmian.
> > Bylo by mi to bardzo przydatne, a i moze do Twojego notatnika
> > projektanta bylo by to bardzo przydatne albo do wiki, dla ludzi klasy
> > "newbie" jak ja:)
>
> Przyjmuję wyzwanie! Od jutra zabieram się do pracy.

I jak Jacku, udało ci się coś osiągnąć?

Jacek Laskowski

unread,
Mar 27, 2007, 1:00:16 PM3/27/07
to
Gabcia85 wrote:

> I jak Jacku, udało ci się coś osiągnąć?

Nic. Wątek jest jednak wciąż na mojej liście do obsłużenia.

Jacek Laskowski

unread,
Apr 2, 2007, 5:20:27 AM4/2/07
to
Jacek Laskowski wrote:

> Przyjmuję wyzwanie! Od jutra zabieram się do pracy.

Trwało to znacznie dłużej niż przypuszczałem, ale w końcu jest -
Optymistyczne blokowanie w JPA - adnotacja @Version i zbiór doświadczeń
z dostawcami JPA. Zajrzyj do Notatnika (adres niżej).

Komentarze mile widziane!

p.s. Zadanie schodzi z listy TODO. Zostało jeszcze
5398...5399...5400...5401...zadań do wykonania i wciąż przybywa ;-)

0 new messages