2010-11-04 2 views
75

Direkt auf den Punkt, Problem ist das Objekt Operator in MySQL DB speichern. Vor dem Speichern, versuche ich aus dieser Tabelle zu wählen und es funktioniert, so ist die Verbindung zu db.Wie Annotation MYSQL Autoincrement-Feld mit JPA-Anmerkungen

Hier ist mein Operator Objekt:

@Entity 
public class Operator{ 

    @Id 
    @GeneratedValue 
    private Long id; 

    private String username; 

    private String password; 


    private Integer active; 

    //Getters and setters... 
} 

speichern Ich benutze JPA EntityManager ‚s persist Methode. Hier

ist einige log:

Hibernate: insert into Operator (active, password, username, id) values (?, ?, ?, ?) 
[email protected]: insert into Operator (active,password, username, id) values (0, 'pass', 'user', ** NOT SPECIFIED **) 

So wie ich es sehe, Problem ist Konfiguration mit Autoinkrement aber ich kann nicht herausfinden, wo.

einige Tricks habe ich versucht, hier gesehen habe: Hibernate not respecting MySQL auto_increment primary key field Aber nichts von dem,

arbeitete benötigt

Wenn andere Konfigurationsdateien ich ihnen bieten.

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`) 
) 
+0

Welche Version von Hibernate verwenden Sie? –

+0

Hibernate 3.2.4 – trivunm

Antwort

110

eine MySQL AUTO_INCREMENT Spalte zu verwenden, sollen Sie eine IDENTITY Strategie verwenden:

@Id @GeneratedValue(strategy=GenerationType.IDENTITY) 
private Long id; 

das ist, was Sie bekommen würde, wenn AUTO mit MySQL:

@Id @GeneratedValue(strategy=GenerationType.AUTO) 
private Long id; 

Das entspricht tatsächlich

@Id @GeneratedValue 
private Long id; 

Mit anderen Worten, Ihr Mapping sollte funktionieren. Aber Hibernate sollte die id Spalte in der SQL-Anweisung insert auslassen, und es ist nicht. Es muss irgendwo eine Art von Missverhältnis geben.

Haben Sie in Ihrer Hibernate-Konfiguration einen MySQL-Dialekt angegeben (wahrscheinlich MySQL5InnoDBDialect oder MySQL5Dialect, je nachdem, welche Engine Sie verwenden)?

Auch wer hat den Tisch erstellt? Können Sie die entsprechende DDL anzeigen?

Follow-up: Ich kann Ihr Problem nicht reproduzieren. Mit dem Code von Ihre Einheit und Ihre DDL generiert Hibernate die folgende (erwartet) SQL mit MySQL:

insert 
into 
    Operator 
    (active, password, username) 
values 
    (?, ?, ?) 

Beachten Sie, dass die id Spalte aus der obigen Aussage fehlt, wie erwartet.

Zusammengefasst, Ihr Code, die Tabellendefinition und der Dialekt sind korrekt und kohärent, es sollte funktionieren. Wenn es nicht für Sie ist, ist vielleicht etwas nicht synchron (machen Sie einen sauberen Build, überprüfen Sie das Build-Verzeichnis, etc.) oder etwas anderes ist nur falsch (überprüfen Sie die Protokolle auf etwas Verdächtiges).

Bezüglich des Dialekts, das nur Unterschied zwischen MySQL5Dialect oder MySQL5InnoDBDialect ist, dass der spätere ENGINE=InnoDB den Tabellenobjekte hinzufügt, wenn die DDL erzeugen. Die Verwendung des einen oder anderen ändert das generierte SQL nicht.

+0

Pascal, Sie haben Recht, aber etwas in meinen Konfigurationsdateien ist einfach nicht richtig. Irgendwelche anderen Vorschläge vielleicht, nachdem ich neue Informationen und Konfigurationsdateien eingefügt habe? – trivunm

+9

@Pascal - Ich habe herausgefunden, dass @GeneratedValue (strategie = GenerationType.IDENTITY) benötigt wird, damit AUTO_INCREMENT ordnungsgemäß funktioniert, wenn JPA 2/Hibernate 4.0.0.CR2/JBoss AS 7 verwendet wird. Http://bit.ly/ tdNyOJ –

+4

Beachten Sie, dass dies für ** MySQL ** gilt. Mit ** PostgreSQL ** erhalten Sie '@GeneratedValue (strategie = GenerationType.IDENTITY)' nicht, wenn Sie '@GeneratedValue (strategie = GenerationType.AUTO)' und '@ GeneratedValue' schreiben. Sei also vorsichtig und versuche, ausführlich zu sein. – sajjadG

11

Für jeden, der EclipseLink für JPA 2.0 verwendet, sind hier die zwei Anmerkungen, die ich verwenden musste, um JPA zu erhalten persistent Daten, wo "MySequenceGenerator" ist welcher Name Sie den Generator geben möchten, "myschema" ist der Name des Schemas in Ihrer Datenbank, das das Sequenzobjekt enthält, und "mysequence" ist der Name des Sequenzobjekts in der Datenbank.

@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="MySequenceGenerator") 
@SequenceGenerator(allocationSize=1, schema="myschema", name="MySequenceGenerator", sequenceName = "mysequence") 

Für diejenigen, Eclipse mit (und möglicherweise anderem PPV-Anbieter), ist es wichtig, dass Sie die allocationSize Attribut der Inkrementwert für Ihre Sequenz in der Datenbank definiert entsprechen. Wenn Sie dies nicht tun, erhalten Sie einen generischen Persistenzfehler und verschwenden viel Zeit mit dem Versuch, es aufzuspüren, so wie ich es getan habe. Hier ist die Referenzseite, die ich diese Herausforderung zu überwinden half:

http://wiki.eclipse.org/EclipseLink/Examples/JPA/PrimaryKey#Using_Sequence_Objects

Auch, um Kontext zu geben, hier ist das, was wir verwenden:

Java 7 Glassfish 3.1 PostgreSQL 9.1 PrimeFaces 3.2/JSF 2.1

Auch um der Faulheit Willen, baute ich dies in Netbeans mit den Assistenten für die Generierung von Entities von DB, Controller von Entities und JSF von Entities, und die Assistenten (offensichtlich) nicht wissen, wie man damit umgeht Sequen ce-basierte ID-Spalten müssen Sie diese Annotationen manuell hinzufügen.

19

MySQL verwenden, nur dieser Ansatz für mich gearbeitet:

@Id @GeneratedValue(strategy=GenerationType.IDENTITY) 
private Long id; 

Die anderen 2 Ansätze erklärt Pascal in seiner Antwort nicht für mich arbeiteten.

+0

Ja, das habe ich in meiner Frage/Antwort beschrieben. http: // Stapelüberlauf.com/questions/39675714/Schema-Validierung-Fehlende-Tabelle-Hibernate-Sequenzen/39675802 # 39675802 –

3

Bitte stellen Sie sicher, dass id-Datentyp Lange statt String ist, wenn das Zeichenfolge wird dann @GeneratedValue Annotation wird nicht funktionieren und die SQL-Erzeugungs für

@Id @GeneratedValue(strategy=GenerationType.IDENTITY) 
private String id; 

create table VMS_AUDIT_RECORDS (id **varchar(255)** not null auto_increment primary key (id)) 

dass muss sein

create table VMS_AUDIT_RECORDS (id **bigint** not null auto_increment primary key (id))