MYSQL otomatik artırma alanına JPA ek açıklamalarıyla nasıl açıklama eklenir


106

Asıl sorun, nesne Operatörünü MySQL DB'ye kaydetmektir. Kaydetmeden önce, bu tablodan seçim yapmaya çalışıyorum ve çalışıyor, db'ye bağlantı da öyle.

Operatör nesnem:

@Entity
public class Operator{

   @Id
   @GeneratedValue
   private Long id;

   private String username;

   private String password;


   private Integer active;

   //Getters and setters...
}

Ben JPA kullanmak kaydetmek için EntityManager'ın persistyöntemi.

İşte bazı günlükler:

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

Gördüğüm gibi, sorun otomatik artışlı konfigürasyon ama nerede olduğunu anlayamıyorum.

Burada gördüğüm bazı hileler denedim: Hazırda bekletme MySQL auto_increment birincil anahtar alanına saygı göstermiyor Ama hiçbiri işe yaramadı

Gerekirse başka yapılandırma dosyaları varsa bunları sağlayacağım.

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

Hibernate'in hangi sürümünü kullanıyorsunuz?
Steven Benitez

Yanıtlar:


150

Bir MySQL AUTO_INCREMENTsütunu kullanmak için bir IDENTITYstrateji kullanmanız gerekir :

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

AUTOMySQL ile kullanırken elde edeceğiniz şey şudur :

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

Aslında eşdeğer olan

@Id @GeneratedValue
private Long id;

Başka bir deyişle, haritanızın çalışması gerekir. Ancak Hazırda Bekletme id, SQL ekleme deyimindeki sütunu çıkarmalıdır ve öyle değildir. Bir yerde bir tür uyumsuzluk olmalı.

Hazırda Bekletme yapılandırmanızda bir MySQL lehçesi belirlediniz mi (muhtemelen MySQL5InnoDBDialectveya MySQL5Dialectkullandığınız motora bağlı olarak)?

Ayrıca, masayı kim yarattı? İlgili DDL'yi gösterebilir misiniz?

Takip: Sorununuzu yeniden oluşturamıyorum. Kodunu kullanarak sizin varlık ve sizin DDL, Hazırda MySQL ile aşağıdaki (beklenen) SQL oluşturur:

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

idBeklendiği gibi , sütunun yukarıdaki ifadede bulunmadığına dikkat edin .

Özetlemek gerekirse, kodunuz, tablo tanımı ve lehçe doğru ve tutarlı, çalışmalıdır. Sizin için değilse, belki bir şeyler senkronize değildir (temiz bir yapı yapın, yapı dizinini iki kez kontrol edin, vb.) Veya başka bir şey yanlıştır (şüpheli herhangi bir şey için günlükleri kontrol edin).

Lehçeyle ilgili olarak, arasındaki tek fark MySQL5Dialectveya MySQL5InnoDBDialectdaha sonra DDL'yi ENGINE=InnoDBoluştururken tablo nesnelerine eklemeleridir . Birini veya diğerini kullanmak, oluşturulan SQL'i değiştirmez.


Pascal, bu konuda haklısın ama yapılandırma dosyalarımdaki bir şeyler doğru değil. Yeni bilgiler ve yapılandırma dosyaları koyduğuma göre belki başka önerileriniz var mı?
trivunm

9
@Pascal - JPA 2 / Hibernate 4.0.0.CR2 / JBoss AS 7. bit.ly/tdNyOJ
Joshua Davis

4
Bunun MySQL için doğru olduğunu unutmayın . İle PostgreSQL sen alamadım @GeneratedValue(strategy=GenerationType.IDENTITY)yazdığınız zaman @GeneratedValue(strategy=GenerationType.AUTO)ve @GeneratedValue. Bu yüzden dikkatli olun ve ayrıntılı olmaya çalışın.
sajjadG

not: Hibernate ve / veya MySQL / MariaDB GenerationType'ın daha yeni sürümlerinde, AUTO varsayılan olarak GenerationType.TABLE olacaktır. Bu, yükseltme sırasında senkronize olmayan dizilerle kötü sorunlara yol açabilir.
jwenting

tabloyu yeniden oluşturmayı unutmayın: spring.jpa.hibernate.ddl-auto = oluştur. Güncelleme ile çalışmayacak
Glasnhost

38

MySQL kullanarak, sadece bu yaklaşım benim için çalışıyordu:

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

Pascal'ın cevabında belirttiği diğer 2 yaklaşım benim için işe yaramadı.


Evet, sorum / cevabımda bunu hakettim. stackoverflow.com/questions/39675714/…
Yan Khonski

Teşekkürler, benim için çalışıyor, ve JPAile kullanıyorum . spring-bootMySQL
Usame Al-Banna

12

Bunu okuyan ve JPA 2.0 için EclipseLink kullanan herkes için, veriyi kalıcı hale getirmek üzere JPA almak için kullanmak zorunda olduğum iki ek açıklama burada verilmiştir; burada "MySequenceGenerator", oluşturucuya vermek istediğiniz addır, "myschema" Veritabanınızdaki sıra nesnesini içeren şema ve "sıralılık", veri tabanındaki sıra nesnesinin adıdır.

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

EclipseLink (ve muhtemelen diğer JPA sağlayıcılarını) kullananlar için, ayırmaSize özniteliğini veritabanındaki sıranız için tanımlanan ARTIŞ değeriyle eşleşecek şekilde ayarlamanız KRİTİKTİR. Bunu yapmazsanız, genel bir kalıcılık başarısızlığı yaşarsınız ve benim yaptığım gibi, onun izini sürmek için epey zaman harcarsınız. İşte bu zorluğun üstesinden gelmeme yardımcı olan referans sayfası:

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

Ayrıca bağlam sağlamak için kullandığımız şey şu:

Java 7 Glassfish 3.1 PostgreSQL 9.1 PrimeFaces 3.2 / JSF 2.1

Ayrıca, tembellik aşkına, bunu Netbeans'te DB'den Varlıklar, Varlıklardan Denetleyiciler ve Varlıklardan JSF oluşturmak için sihirbazlarla oluşturdum ve sihirbazlar (açıkçası) sıra tabanlı kimlik sütunlarıyla nasıl başa çıkacaklarını bilmiyorlar. bu ek açıklamaları manuel olarak eklemeniz gerekecek.


6

Lütfen id veri türünün String yerine Long olduğundan emin olun, eğer bu string olacaksa @GeneratedValue ek açıklaması çalışmayacak ve sql oluşturacak

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

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

olması gereken

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

6

Hibernate v3 ile Mysql kullanıyorsanız, GenerationType.AUTOdahili olarak kullanacağı için kullanmakta sorun yoktur.GenerationType.IDENTITY , ki bu MySQL için en uygun olanıdır.

Ancak Hibernate v5'te değişti. hangi ekleme için çok fazla sorgu oluşturduğunu GenerationType.AUTOkullanacaktır GenerationType.TABLE.

Bunu kullanmaktan GenerationType.IDENTITY( kullandığınız tek veritabanı MySQL ise) veya bu gösterimlerle (birden fazla veritabanınız varsa) kaçınabilirsiniz :

@GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
@GenericGenerator(name = "native", strategy = "native")

evet, Spring uygulamanızı yükseltirken, aynı zamanda Hazırda Bekletme'yi de yükselten bazı kötü regresyon hatalarının zor nedeni.
jwenting

1

Her şeyi denedim ama yine de yapamadım, mysql, jpa'yı hazırda bekletme ile kullanıyorum, kurucuda id 0 değerini atayarak sorunumu çözdüm Aşağıdaki id bildirim kodum

@Id
@Column(name="id",updatable=false,nullable=false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

1

Veritabanı oluştururken int tipinde id tanımladığınız için, model sınıfında da aynı veri tipini kullanmanız gerekir. Ve veritabanında otomatik artış için kimliği tanımladığınız için, 'GenerationType.AUTO' değerini @GeneratedValue ek açıklaması içindeki 'strateji' özniteliğine geçirerek model sınıfında belirtmeniz gerekir. Ardından kod aşağıdaki gibi olur.

@Entity
public class Operator{

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

  private String username;

  private String password;

  private Integer active;

  //Getters and setters...
}

1

pascal yanıtıyla aynı, sadece .AUTO kullanmanız gerekiyorsa, herhangi bir nedenle yalnızca uygulama özelliklerinize eklemeniz gerekir:

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto = update


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.