Hibernate problem z primary key

Hibernate problem z primary key
Taruun
  • Rejestracja:ponad 16 lat
  • Ostatnio:prawie 12 lat
0

Witam,
mam pewien problem z kluczami prywatnymi. A mianowicie mam takie trzy klasy.

Kopiuj
@Entity
@Table (name = "Kategorie")
public class Kategoria {
	
	@Id @Column (name = "Id_kategorii") @GeneratedValue (strategy = GenerationType.AUTO) 
	private int idKategoria;
	@Column (name = "Kategoria", unique = true)
	String nazwa;
	
	
	public int getIdKategoria() {
		return idKategoria;
	}
	public void setIdKategoria(int idKategoria) {
		this.idKategoria = idKategoria;
	}
	public String getNazwa() {
		return nazwa;
	}
	public void setNazwa(String nazwa) {
		this.nazwa = nazwa;
	}

}
Kopiuj
@Entity
@Table (name="Rodzaj_produktu")
public class Rodzaj {
	
	@Id @Column (name = "Id_rodzaju") @GeneratedValue (strategy = GenerationType.AUTO)
	private int idRodzaj;
	
	@Column (name="Nazwa")
	private String nazwa;
	
	public int getIdRodzaj() {
		return idRodzaj;
	}
	public void setIdRodzaj(int idRodzaj) {
		this.idRodzaj = idRodzaj;
	}
	public String getNazwa() {
		return nazwa;
	}
	public void setNazwa(String nazwa) {
		this.nazwa = nazwa;
	}
}
Kopiuj
@Entity
@Table (name = "Producenci")
public class Producent {
	
	@Id @Column (name = "Id_producenta") @GeneratedValue (strategy = GenerationType.AUTO) 
	private int idProducent;

	@Column (name = "Producent", unique = true)
	String nazwa;
	
	public int getIdProducent() {
		return idProducent;
	}
	public void setIdProducent(int idProducent) {
		this.idProducent = idProducent;
	}
	public String getNazwa() {
		return nazwa;
	}
	public void setNazwa(String nazwa) {
		this.nazwa = nazwa;
	}
	
	

}

i dane do tabelek przez nie stworzone wprowadzam pomocą takiego okna http://www.fotosik.pl/pokaz_obrazek/pelny/3b54d5384bffc88f.html

i problem jest taki, że jak dodaje rodzaj potem producenta a następnie kategorię to id w tabelkach jest takie:
id w rodzaj =1
id w producent = 2
id w kategoria = 3

a wszędzie powinno być równe 1 bo to przecież pierwsze wpisy do tabeli. Mam nadzieję, że dobrze wyjaśniłem problem. Proszę o rady i sugestie.

Dodam, że baza danych to postgre.

edytowany 1x, ostatnio: Taruun
0

Wyglada na to ze GenerationStrategy.AUTO dla bazy ktorej uzywasz korzysta ze wspolnej seqkencji (ewentualnie, stowrzyl sobie wlasna tabelke albo cos). Masz gdzies tam jakas nowa nieznana ci tabelke?

Taruun
  • Rejestracja:ponad 16 lat
  • Ostatnio:prawie 12 lat
0

Jest jedna z której na razie nie korzystam nazywa się asortyment. I ona jest mi znana ale na razie pusta.

edytowany 1x, ostatnio: Taruun
Taruun
  • Rejestracja:ponad 16 lat
  • Ostatnio:prawie 12 lat
0

Widzę, że nikt nie ogarnia tematu :-(

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Przeciez dostałeś odpowiedź. Skoro sie tak dzieje to znaczy ze strategia generacji kluczy tak śmiesznie działa, widocznie ma tam jedna sekwencje i tyle. Zmień strategię na inną na przykład na GenerationType.IDENTITY


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
MO
  • Rejestracja:ponad 18 lat
  • Ostatnio:około 13 godzin
0

wybierając sekwencje do generowania kluczy możesz zdefiniować nazwę sekwencji - widocznie nie konfigurując tego dalej wykorzystana jest tylko jedna sekwencja

P1
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 12 lat
  • Postów:150
0

Mam pytanko odnośnie powyższego tematu. Czytałem gdzieś (ale nie jestem tego pewien bo to był jakiś post) że mechanizm @GeneratedValue(strategy=SEQUENCE, generator="name_1") opiera się na mechanizmie (właściwości) wbudowanym w bazę danych a nie jest elementem serwera JEE. Czy to prawda?
Jeżeli tak to w bazie danych (np. MySQL) powinna być jakaś komenda uruchamiająca ten mechanizm (rodzaj Constraint??). Czy w takim razie, jeżeli wszystko powyższe jest prawdą, to czy gdy taki mechanizm zostanie raz uruchomiony dla danej tabeli przez serwer JEE podczas używania klasy encji JPA na tym serwerze (z taką adnotacją generowania PK) to czy jest on (ten mechanizm) potem aktywny dla innych aplikacji (nie JPA z JEE) które modyfikowałby tą tabelę dodając rekordy?
Innymi słowy czy różne aplikacje wspólnie zachowają ciągłość i spójność numerowania nowo tworzonych rekordów dla tej tabeli?

0

Niektore bazy nie maja sekwencji (sqlserver?), niektore nie maja kolumn identity (oracle), jeszcze inne nie maja czegos innego. Sam server Jaca EE nic nie 'wlacza', on tylko jest jakby furtka na polaczenia do bazy - co robi aplikacja to jej sprawa. Jedyna z tego co sie orientuje prawdziwie przenosna strategia jest 'table', czyli orm zrobi sobie tabelke z paroma kolumnami, w ktorej rekordy beda symulowac sekwencje. Generowanie klucza polega na select z wiersza dla danej tabelki. Np. tak wyglada taka tabelka (powiedzmy ze ma nazwe SEQ):
TABLE_NAME|CURRENT_VALUE|
tabela_1 | 10 |
tabela_2 | 17 |
tabela_4 | 190 |
Teraz, jak wstawiasz cos do tabela_1, to provider robi:
select current_value from seq where table_name = 'tabela_1'
zapisuje sobie gdzies te 10, alokuje ilestam (mozna ustawic), dajmy na to 10, i zaraz wola:
update seq set current_value = 20 where table_name = 'tabela_1'
i ma w puli 10 id do rozporzadzenia. Taka alokacja moze byc co 1 id, ale i co 1000, jak sie ustawi. Ogolnie im mniej zapytac tym lepiej, ale czasami sie nie da.

P1
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 12 lat
  • Postów:150
0

Dzięki za info.
Dobrze że poruszyłeś temat strategii TABLE bo właśnie nad tym siedziałem i nie wszystko kumałem. Nie rozumiem sensu samej alokacji ani tej jednostki alokacji: atrybut "allocationSize" przy definiowaniu adnotacji @TableGenerator.
Rozumiem sytuację w której gdy dodaję jeden obiekt encji to z tabeli SEQ sczytywana jest wartość nowego PK dla tej encji i wpisywana do pola PK encji a w tabeli SEQ powiększana jest wartość pola "tabela_1" o +1. Czyli kolejne rekordy będą miały numery PK: 1, 2, 3, 4 .... .
A jak ustawisz alokację na 10 to chodzi o to że kolejne rekordy dodawane przez persistowane encje JPA beda miały numery 1, 11, 21, 31.. ? A przerwy w numeracji są do mojego wykorzystania poza mechanizmem JPA?

I jeszcze pytanko o samo działanie tego mechanizmu z tabelą. Jeżeli stworzę dwie encje JPA (i persistuję) dla klasy encji oznaczonej @GeneratedValue(strategy=TABLE) za pomocą konstruktora bez podawania numerów PK, to rozumiem, że dopóki nie zostaną one flushowane to żadne numery PK z tabeli SEQ nie zostaną im przypisane? Będą miały domyślne wartości np. 0. Dopiero flushowanie otworzy transakcje w bazie i spowoduje przypisanie im numerów z SEQ? Czyli to jaki numer będzie miał dany obiekt encji będzie zależało od kolejności jako który ten obiekt był Persistowany w kodzie ?

1

Alokacja sluzy do cachowania, jak napisalem. Przykladowo, mamy allocationSize = 1, wtedy aplikacja musi za kazdym razem gdy zapisuje encje danego typu robic select z tej bazy, pozniej update - ale po co? Mozna zrobic taki select radziej, np. co 100, zapisac do kolumny value n+100 i trzymac te 100 w puli. Zapisywane encje dostaja kolejne numerki, i gdy pula sie wyczerpie, robi sie kolejny select i update +100. Z tego wynika, ze jest 100 razy mniej selectow i updatow, co przy aplikacji zapisujacej i kasujacej bardzo duzo encji moze miec znaczny wplyw na szybkosc aplikacji.

Co do tego kiedy id jest dostepne: pewnosc jest tylko, ze po tym, gdy nastapi flush lub commit transakcji (np. dla IDENTITY, poniewaz to robi juz sama baza danych). Zaleznie od uzywanej strategii, moze to nastapic wczesniej, ale nie powinienes sie na tym opierac, bo to moze byc nieprzenosne. Tutaj pare cytatow:

JPA 2.0 specs:
These database operations may occur directly after the persist, merge, or remove operations have been invoked or they may occur directly after a flush operation has occurred (which may be at the end of the transaction). Generated primary key values are available in the PostPersist method.

Pro JPA2:
Once the identifier value is obtained, the provider will insert it into the newly persisted entity; however, depending on the way it is generated, it might not actually be present in the object until the entity has been inserted in the database. In other words, the application cannot rely on being able to access the identifier until after either a flush has occurred or the transaction has completed.

Pro JPA2:
Another difference, hinted at earlier, between using IDENTITY and other id generation strategies is that the identifier will not be accessible until after the insert has occurred. Although no guarantee is made about the accessibility of the identifier before the transaction has completed, it is at least
possible for other types of generation to eagerly allocate the identifier.

Ostatni fragment mowi ze jest to mozliwe, ale tak byc nie musi - wiec uwazaj.

Jeszcze jedna rzecz: alokacja z duza wartoscia moze powodowac duze dziury. Np. startujemy aplikacje, pobieramy ostatnia wartosc (0), dodajemy 1000, zapisujemy 1000, po czym stopujemy aplikacje, uruchamiamy znowu, pobieramy ostatnia wartosc - 1000! Nie jest to jednakze problem w wiekszosci przypadkow, najlepiej zapomnij o tych kluczach ze istnieja, a juz na pewno nie zajmuj sie tym czy sa dziury czy nie.

P1
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 12 lat
  • Postów:150
0

Wielkie dzięki. Zajarzyłem.
Mam ściągniętą specyfikacje do JPA 2 (486 str.) ale w rozdziale o TableGenerator Annotation jest tylko tabelka z opisanymi powierzchownie atrybutami ustawień np:
"allocationSize - (Optional) The amount to increment by when allocating numbers from the generator."
I jak tu z tego wykumać o co chodzi i jak to działa?
Powinni to jakoś opisać.
No ale temat z głowy. Dzięki.

0

Tak specyfikacje sa z reguly dosc suche i nie tlumacza slowa po slowie. Tutaj kluczem jest 'alokacja' - provider bierze sobie (alokuje) X id; to inkrementowanie to wartosc o jaka jest robiony ten update.
Zgadza sie, nie zawsze jest to wszystko jasne, ale nie wiem czy nie jest to gdzies indziej opisane. Poza tym, po to sa inne pozycje (np. wspomniana Pro JPA2 - naprawde warta polecenia) zeby tlumaczyly, co specyfikacja chce powiedziec ;d

P1
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 12 lat
  • Postów:150
0

Sprawdzę to Pro JPA2 bo pierwsze słyszę.
Dzięki.
Właściwie to aby dowiedzieć sie jak coś działa w tym JPA to trzeba pisać małe programiki testowe i sprawdzać. Jak przeczytałem sobie dokumentację o Optimistic i Pessimistic Lock to nie wiedziałem jak to realnie działa (czyli reakcja bazy na np. konkretną metodę lokującą np. "find(prams, LockType)"). Dopiero jak przewaliłem te Locki na kilkunastu przykładach to jakiś obraz zaczął się wyłaniać.

P1
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 12 lat
  • Postów:150
0

Coś jeszcze mi przyszło do głowy w temacie TableGenerator.
Select i update wartości w tabeli z numerami PK (SEQ) musi być chyba dokonywany przez JPA Providera w krótkiej, osobnej, natychmiast committowanej transakcji, nie mającej nic wspólnego z transakcją główną zachodzącą dla tworzonych i persistowanych obiektów encji JPA. Inaczej pomiędzy Selectem i Updatem jakiś inny wątek mógłby próbować wykonać swoje pobranie numeru PK i update (też przez tego JPA Providera) i namieszać w numeracji. Musi tu być wprowadzona jakaś izolacja w działaniu JPA Providera.

0

Pro JPA2:
■ TIP The provider might allocate identifiers within the same transaction as the entity being persisted or in a
separate transaction. It is not specified (...)

Tak naprawde to to jest niewazne dla ciebie, po prostu uzywaj i ufaj ze dziala. Zaloze sie ze kazdy provider robi inaczej.

P1
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad 12 lat
  • Postów:150
0

No tak, nie ma co za bardzo grzebać w bebechach ....

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)