JPA 주석으로 MYSQL 자동 증가 필드에 주석을다는 방법


106

요점은 문제는 객체 연산자를 MySQL DB에 저장하는 것입니다. 저장하기 전에이 테이블에서 선택하려고 시도하면 작동하므로 db에 연결됩니다.

내 연산자 개체는 다음과 같습니다.

@Entity
public class Operator{

   @Id
   @GeneratedValue
   private Long id;

   private String username;

   private String password;


   private Integer active;

   //Getters and setters...
}

저장하기 위해 JPA EntityManagerpersist방법을 사용합니다.

다음은 몇 가지 로그입니다.

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

내가 보는 방식, 문제는 자동 증분 구성이지만 어디에 있는지 알 수 없습니다.

여기에서 본 몇 가지 트릭을 시도했습니다. Hibernate가 MySQL auto_increment 기본 키 필드를 존중하지 않지만 그 중 아무것도 작동하지 않았습니다.

다른 구성 파일이 필요한 경우 제공합니다.

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를 사용하고 있습니까?
Steven Benitez

답변:


150

MySQL AUTO_INCREMENT열을 사용하려면 IDENTITY전략 을 사용해야합니다 .

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

AUTOMySQL과 함께 사용할 때 얻을 수있는 것은 다음 과 같습니다.

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

실제로는

@Id @GeneratedValue
private Long id;

즉, 매핑이 작동해야합니다. 그러나 Hibernate는 idSQL insert 문에서 열을 생략해야하며 그렇지 않습니다. 어딘가에 일종의 불일치가 있어야합니다.

Hibernate 구성에서 MySQL 언어를 지정 했습니까 (아마도 MySQL5InnoDBDialect또는 MySQL5Dialect사용중인 엔진에 따라 다름)?

또한 누가 테이블을 만들었습니까? 해당 DDL을 보여줄 수 있습니까?

후속 조치 : 문제를 재현 할 수 없습니다. 의 코드를 사용 하여 개체와 당신의 DDL을, Hibernate는 MySQL은 다음과 같은 (예상) SQL을 생성합니다 :

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

id예상대로 위의 명령문 에는 열이 없습니다.

요약하면, 코드, 테이블 정의 및 방언이 정확하고 일관 적이므로 작동해야합니다. 그렇지 않다면 무언가 동기화되지 않았거나 (깨끗한 빌드를 수행하고, 빌드 디렉토리를 다시 확인하는 등) 다른 것이 잘못되었을 수 있습니다 (의심스러운 것이 있는지 로그를 확인하십시오).

방언과 관련하여 or 의 유일한 차이점 은 DDL을 생성 할 때 나중에 테이블 개체에 추가된다는 것 입니다. 둘 중 하나를 사용해도 생성 된 SQL은 변경되지 않습니다.MySQL5DialectMySQL5InnoDBDialectENGINE=InnoDB


Pascal, 당신은 그것에 대해 옳지 만 내 구성 파일의 내용이 옳지 않습니다. 새로운 정보와 구성 파일을 넣었으므로 다른 제안이 있습니까?
trivunm 2010

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

4
MySQL의 경우에도 마찬가지입니다 . 으로 PostgreSQL을 당신은하지 않습니다 @GeneratedValue(strategy=GenerationType.IDENTITY)당신이 쓸 때 @GeneratedValue(strategy=GenerationType.AUTO)@GeneratedValue. 따라서 조심하고 장황하게 만드십시오.
sajjadG 2013

참고 : 최신 버전의 Hibernate 및 / 또는 MySQL / MariaDB GenerationType.AUTO는 기본적으로 GenerationType.TABLE로 설정됩니다. 업그레이드 할 때 동기화되지 않은 시퀀스로 인해 불쾌한 문제가 발생할 수 있습니다.
jwenting

테이블을 다시 만드는 것을 잊지 마세요 : spring.jpa.hibernate.ddl-auto = create. 업데이트로 작동하지 않습니다
Glasnhost

38

MySQL을 사용하면이 접근 방식 만 저에게 효과적이었습니다.

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

Pascal이 그의 답변에서 언급 한 다른 두 가지 접근 방식은 저에게 효과적이지 않았습니다.


네, 내 질문 / 답변에서 이것을 참조했습니다. stackoverflow.com/questions/39675714/...
얀 Khonski에게

고마워, 그것은 나를 위해 일하고, 나는 및 JPA함께 사용 spring-boot하고 MySQL있습니다.
Osama Al-Banna

12

JPA 2.0 용 EclipseLink를 사용하는이 글을 읽는 모든 사람을 위해 JPA가 데이터를 유지하기 위해 사용해야하는 두 가지 주석이 있습니다. 여기서 "MySequenceGenerator"는 생성자에 부여하려는 이름이고 "myschema"는 시퀀스 개체를 포함하는 데이터베이스의 스키마이고 "mysequence"는 데이터베이스에있는 시퀀스 개체의 이름입니다.

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

EclipseLink (및 기타 JPA 공급자)를 사용하는 경우 데이터베이스에서 시퀀스에 대해 정의 된 INCREMENT 값과 일치하도록 assignmentSize 속성을 설정하는 것이 중요합니다. 그렇지 않으면 일반적인 지속성 실패가 발생하고 저처럼 추적하는 데 많은 시간을 낭비하게됩니다. 이 문제를 극복하는 데 도움이 된 참조 페이지는 다음과 같습니다.

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

또한 컨텍스트를 제공하기 위해 다음을 사용합니다.

자바 7 Glassfish 3.1 PostgreSQL 9.1 PrimeFaces 3.2 / JSF 2.1

또한 게으름을 위해 DB에서 엔터티, 엔터티에서 컨트롤러 및 엔터티에서 JSF를 생성하는 마법사를 사용하여 Netbeans에 이것을 구축했으며 마법사는 (분명히) 시퀀스 기반 ID 열을 처리하는 방법을 모릅니다. 이러한 주석을 수동으로 추가해야합니다.


6

id 데이터 유형이 String 대신 Long인지 확인하십시오. 이것이 문자열이면 @GeneratedValue 주석이 작동하지 않고 SQL 생성

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

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

그게 필요합니다

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

6

Hibernate v3와 함께 Mysql을 사용하는 경우 GenerationType.AUTO내부적 GenerationType.IDENTITY으로 MySQL에 가장 적합한를 사용 하므로 사용 해도됩니다 .

그러나 Hibernate v5에서는 변경되었습니다. GenerationType.AUTO사용 GenerationType.TABLE삽입에 대한 많은 질의를 생성한다.

사용 GenerationType.IDENTITY(MySQL이 유일한 데이터베이스 인 경우) 또는 다음 표기법 (여러 데이터베이스가있는 경우) 을 사용하지 않도록 할 수 있습니다 .

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

예, 내부적으로 Hibernate도 업그레이드하는 Spring 애플리케이션을 업그레이드 할 때 불쾌한 회귀 오류가 발생하는 까다로운 원인입니다.
jwenting

1

나는 모든 것을 시도했지만 여전히 그렇게 할 수 없었습니다 .mysql, jpa를 최대 절전 모드로 사용하고 있습니다. 생성자에 id 0 값을 할당하여 문제를 해결했습니다. 다음은 내 ID 선언 코드입니다.

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

1

데이터베이스 생성시 int 유형으로 id를 정의 했으므로 모델 클래스에서도 동일한 데이터 유형을 사용해야합니다. 그리고 데이터베이스에서 자동 증분을 위해 id를 정의 했으므로 @GeneratedValue 주석의 'strategy'속성에 'GenerationType.AUTO'값을 전달하여 모델 클래스에서이를 언급해야합니다. 그러면 코드는 다음과 같습니다.

@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

어떤 이유로 .AUTO를 사용해야 할 경우 응용 프로그램 속성을 추가하면됩니다.

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


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.