Prosto do rzeczy, problemem jest zapisanie operatora obiektu do bazy danych MySQL. Przed zapisaniem próbuję wybrać z tej tabeli i działa, więc jest połączenie z db.
Oto mój obiekt Operator:
@Entity
public class Operator{
@Id
@GeneratedValue
private Long id;
private String username;
private String password;
private Integer active;
//Getters and setters...
}
Aby zapisać używam JPA EntityManager
jest persist
metoda.
Oto dziennik:
Hibernate: insert into Operator (active, password, username, id) values (?, ?, ?, ?)
com.mysql.jdbc.JDBC4PreparedStatement@15724a0: insert into Operator (active,password, username, id) values (0, 'pass', 'user', ** NOT SPECIFIED **)
Z mojego punktu widzenia problemem jest konfiguracja z automatyczną inkrementacją, ale nie wiem gdzie.
Wypróbowałem kilka sztuczek, które tutaj widziałem: Hibernacja nie respektuje pola klucza podstawowego MySQL auto_increment Ale nic z tego nie działało
Jeśli będą potrzebne inne pliki konfiguracyjne, dostarczę je.
DDL:
CREATE TABLE `operator` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`first_name` VARCHAR(40) NOT NULL,
`last_name` VARCHAR(40) NOT NULL,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL,
`active` INT(1) NOT NULL,
PRIMARY KEY (`id`)
)
Odpowiedzi:
Aby użyć
AUTO_INCREMENT
kolumny MySQL , powinieneś użyćIDENTITY
strategii:Co otrzymujesz korzystając
AUTO
z MySQL:Co w rzeczywistości jest równoważne
Innymi słowy, twoje mapowanie powinno działać. Ale Hibernate powinien pomijać
id
kolumnę w instrukcji wstawiania SQL, a tak nie jest. Gdzieś musi być jakieś niedopasowanie.Czy określiłeś dialekt MySQL w konfiguracji Hibernacji (prawdopodobnie
MySQL5InnoDBDialect
lub wMySQL5Dialect
zależności od używanego silnika)?Kto stworzył stół? Czy możesz pokazać odpowiedni DDL?
Kontynuacja: nie mogę odtworzyć twojego problemu. Korzystając z kodu twojej encji i twojego DDL, Hibernate generuje następujący (oczekiwany) SQL z MySQL:
Zauważ, że
id
zgodnie z oczekiwaniami w powyższej instrukcji brakuje kolumny.Podsumowując, twój kod, definicja tabeli i dialekt są poprawne i spójne, powinno działać. Jeśli tak nie jest, być może coś nie jest zsynchronizowane (wykonaj czystą kompilację, dwukrotnie sprawdź katalog kompilacji itp.) Lub coś innego jest po prostu nie tak (sprawdź dzienniki pod kątem podejrzanych treści).
Jeśli chodzi o dialekt, jedyną różnicą między
MySQL5Dialect
lubMySQL5InnoDBDialect
jest to, że później dodajeENGINE=InnoDB
do obiektów tabeli podczas generowania DDL. Użycie jednego lub drugiego nie zmienia wygenerowanego kodu SQL.źródło
@GeneratedValue(strategy=GenerationType.IDENTITY)
kiedy piszesz@GeneratedValue(strategy=GenerationType.AUTO)
i@GeneratedValue
. Dlatego bądź ostrożny i staraj się być rozwlekły.Używając MySQL, działało tylko to podejście:
Pozostałe 2 podejścia podane przez Pascala w jego odpowiedzi nie działały w moim przypadku.
źródło
JPA
zspring-boot
iMySQL
.Dla każdego, kto to czyta i używa EclipseLink dla JPA 2.0, oto dwie adnotacje, których musiałem użyć, aby JPA utrwalił dane, gdzie „MySequenceGenerator” to dowolna nazwa, jaką chcesz nadać generatorowi, „myschema” to nazwa schemat w bazie danych, który zawiera obiekt sekwencji, a „mysequence” to nazwa obiektu sekwencji w bazie danych.
W przypadku użytkowników korzystających z EclipseLink (i prawdopodobnie innych dostawców JPA) KRYTYCZNYM jest ustawienie atrybutuocationSize na wartość INCREMENT zdefiniowaną dla sekwencji w bazie danych. Jeśli tego nie zrobisz, dostaniesz ogólny błąd trwałości i stracisz dużo czasu, próbując go wyśledzić, tak jak ja. Oto strona referencyjna, która pomogła mi pokonać to wyzwanie:
http://wiki.eclipse.org/EclipseLink/Examples/JPA/PrimaryKey#Using_Sequence_Objects
Aby nadać kontekst, oto czego używamy:
Java 7 Glassfish 3.1 PostgreSQL 9.1 PrimeFaces 3.2 / JSF 2.1
Ponadto, ze względu na lenistwo, zbudowałem to w Netbeans z kreatorami do generowania jednostek z DB, kontrolerów z jednostek i JSF z jednostek, a kreatorzy (oczywiście) nie wiedzą, jak radzić sobie z kolumnami identyfikatorów opartych na sekwencjach, więc będziesz musiał ręcznie dodać te adnotacje.
źródło
źródło
Jeśli używasz MySQL z Hibernate v3, możesz go używać,
GenerationType.AUTO
ponieważ wewnętrznie będzie używałGenerationType.IDENTITY
, co jest najbardziej optymalne dla MySQL.Jednak w Hibernate v5 to się zmieniło.
GenerationType.AUTO
użyje,GenerationType.TABLE
co generuje za dużo zapytań do wstawienia.Możesz tego uniknąć, używając
GenerationType.IDENTITY
(jeśli MySQL jest jedyną bazą danych, której używasz) lub z tymi notacjami (jeśli masz wiele baz danych):źródło
Próbowałem wszystkiego, ale nadal nie byłem w stanie tego zrobić, używam mysql, jpa z hibernacją, rozwiązałem swój problem, przypisując wartość id 0 w konstruktorze Poniżej znajduje się mój kod deklaracji identyfikatora
źródło
Ponieważ podczas tworzenia bazy danych zdefiniowałeś identyfikator w typie int, musisz użyć tego samego typu danych również w klasie modelu. A ponieważ zdefiniowałeś identyfikator do automatycznego zwiększania w bazie danych, musisz wspomnieć o tym w klasie modelu, przekazując wartość „GenerationType.AUTO” do atrybutu „strategy” w adnotacji @GeneratedValue. Następnie kod wygląda jak poniżej.
źródło
tak samo jak odpowiedział Pascal, tylko jeśli z jakiegoś powodu potrzebujesz użyć .AUTO, wystarczy dodać właściwości aplikacji:
źródło
czy możesz sprawdzić, czy połączyłeś się z właściwą bazą danych. ponieważ napotkałem ten sam problem, ale w końcu odkryłem, że połączyłem się z inną bazą danych.
tożsamość obsługuje kolumny tożsamości w DB2, MySQL, MS SQL Server, Sybase i HypersonicSQL. Zwrócony identyfikator jest typu long, short lub int.
Więcej informacji: http://docs.jboss.org/hibernate/orm/3.5/reference/en/html/mapping.html#mapping-declaration-id
źródło
Jeśli używasz MariaDB, to zadziała
Aby uzyskać więcej, możesz sprawdzić https://thorben-janssen.com/hibernate-tips-use-auto-incremented-column-primary-key/
źródło