혼란 : JPA 및 최대 절전 모드의 @NotNull 대 @Column (nullable = false)


242
  1. 그들이의 필드 / getter에 나타날 때 @Entity, 그들 사이의 차이점은 무엇입니까? (나는 최대 절전 모드를 통해 엔티티를 유지합니다 ).

  2. 각각의 프레임 워크 및 / 또는 사양은 무엇입니까?

  3. @NotNull안에 javax.validation.constraints있습니다. 에서 javax.validation.constraints.NotNull의 javadoc가 말한다

    주석이 달린 요소는 null이 아니어야합니다.

    그러나 데이터베이스의 요소 표현에 대해서는 이야기하지 않으므로 nullable=false열에 제약 조건 을 추가하는 이유는 무엇입니까?

답변:


328

@NotNullA는 JSR 303 콩 검증 주석은. 데이터베이스 제약 조건 자체와는 아무런 관련이 없습니다. 그러나 Hibernate는 JSR 303의 참조 구현이므로 이러한 제약 조건을 지능적으로 선택하여 데이터베이스 제약 조건으로 변환하므로 하나의 가격으로 두 가지를 얻을 수 있습니다. @Column(nullable = false)열이 널이 아닌 것으로 선언하는 JPA 방식입니다. 즉, 전자는 유효성 검사를위한 것이고 후자는 데이터베이스 스키마 세부 사항을 나타내는 것입니다. 유효성 검사 주석에 대한 Hibernate의 도움을 받고 있습니다.


2
감사! 따라서 JPA 지속성이 Hibernate 구현 (예 : EJB3으로 변경)에 묶이지 않게하려면 필드와 열 모두에서 null을 금지하기 위해 두 주석을 모두 사용해야합니까?
rapt

3
모르겠어요 JPA 제공자가 JSR 303 어노테이션을 인식해야한다는 스펙은 없지만 다른 제공자가이를 인식하지는 않습니다. 나는 여부를 말할 수 없습니다.
Ryan Stewart

7
JPA 제공자는 JSR303 구현을 제공 할 필요는 없지만 제 3 자 JSR303 구현과 통합 할 수있는 기능을 제공하는 데 필요한 스펙에 따라 다릅니다. 따라서 Hibernate는 JSR303을 제공하지만 어떤 이유로 든 JSR303을 제공하지 않기로 결정하고 다른 사람과 함께 가지거나 openJPA와 같은 JPA 구현을 사용하고 다른 사람을 사용하여 JSR303을 제공 할 수 있습니다. 또한 Hibernate의 JPA 구현은 EJB3입니다. '내 JPA 지속성이 Hibernate 구현에 묶이지 않기를 원한다면 (즉 EJB3로 변경) JPA는 EJB3 사양의 일부이다.
Shahzeb

5
@Shahzeb : JSR 303 검증을 누가 지원 / 제공하는지에 대한 질문은 없습니다. 그것은 어떤에 대한 ORM (들)와 같은 JSR 303 주석 인식이다 @NotNull, @Size, @Min, @Max, 등, 데이터베이스 제약에 그 번역.
Ryan Stewart

1
예. 그러나 내 의견은 OP가 귀하가 알지 못하는 후속 의견에서 요구 한 내용과 관련하여 유효합니다.
Shahzeb

18

최신 버전의 최대 절전 모드 JPA 제공자는 @NotNull기본적으로 DDL 과 같은 Bean 유효성 검증 제한 조건 (JSR 303)을 적용합니다 ( hibernate.validator.apply_to_ddl property기본값은 true). 그러나 다른 JPA 제공 업체가이를 수행하거나 수행 할 수 있다는 보장은 없습니다.

@NotNullJVM에서 Java Bean을 유효성 검증 할 때 Bean 특성이 널 (NULL)이 아닌 값으로 설정되도록 Bean 유효성 검증 어노테이션을 사용해야합니다 (데이터베이스 제한 조건과는 관련이 없지만 대부분의 경우 해당 특성과 일치해야 함).

또한 JPA 어노테이션을 사용하여 @Column(nullable = false)원하는 데이터베이스 제한 조건으로 테이블 컬럼을 작성하기위한 올바른 DDL을 생성하기위한 jpa 제공자 힌트를 제공해야합니다. Bean 유효성 검증 제한 조건을 기본적으로 DDL에 적용하는 Hibernate와 같은 JPA 제공자를 사용할 수 있거나 사용하려는 경우이를 생략 할 수 있습니다.


10

흥미롭게도 모든 출처는 @Column (nullable = false)이 DDL 생성에만 사용된다고 강조합니다.

그러나 @NotNull 주석이없고 hibernate.check_nullability 옵션이 true로 설정된 경우에도 Hibernate는 유지할 엔티티의 유효성을 검사합니다.

nullable = false 속성에 값이없는 경우 데이터베이스 계층에서 이러한 제한이 구현되지 않은 경우에도 "널 (NULL)이 아닌 특성이 널 또는 임시 값을 참조 함"이라는 PropertyValueException이 발생합니다.

hibernate.check_nullability 옵션에 대한 자세한 정보는 http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#configurations-mapping에서 확인할 수 있습니다 .


7

JPA @Column주석

주석 의 nullable속성 @Column에는 두 가지 목적이 있습니다.

  • 스키마 생성 도구에서 사용됩니다.
  • 지속성 컨텍스트를 플러시하는 동안 최대 절전 모드에서 사용됩니다.

스키마 생성 도구

HBM2DDL 스키마 생성 도구 는 명령문을 생성 할 때 @Column(nullable = false)엔티티 속성을 NOT NULL연관된 테이블 열의 제한 조건으로 변환합니다 CREATE TABLE.

Hibernate User Guide 에서 설명했듯이 데이터베이스 스키마 생성을 위해 HBM2DDL 메커니즘에 의존하는 대신 Flyway 와 같은 도구를 사용하는 것이 좋습니다 .

지속성 컨텍스트 플러시

지속성 컨텍스트를 플러시 할 때 Hibernate ORM은 또한 @Column(nullable = false)엔티티 속성을 사용 합니다 :

new Nullability( session ).checkNullability( values, persister, true );

유효성 검사가 실패하면 Hibernate PropertyValueException는를 던지고 INSERT 또는 UPDATE 문이 불필요하게 실행되는 것을 방지합니다.

if ( !nullability[i] && value == null ) {
    //check basic level one nullablilty
    throw new PropertyValueException(
            "not-null property references a null or transient value",
            persister.getEntityName(),
            persister.getPropertyNames()[i]
        );    
}

최대 절전 모드 플러시 메커니즘의 작동 방식에 대한 자세한 내용은 이 문서를 확인 하십시오 .

빈 검증 @NotNull주석

@NotNull주석이 최대 절전 모드 ORM 가장 인기있는 JPA 구현 한 것처럼, 콩 검증에 의해 정의되고, 가장 인기있는 콩 검증 구현은이다 최대 절전 모드 검사기 프레임 워크.

Hibernate ORM과 함께 Hibernate Validator를 사용할 때, Hibernate Validator는 ConstraintViolation엔티티를 확인할 때 를 던질 것이다 .


왜 플라이 웨이가 스키마를 생성하는 것보다 낫다고 말합니까?
Andronicus

1
좋은 관찰입니다. 참조 링크로 답변을 업데이트했습니다.
Vlad Mihalcea

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