최대 절전 모드에서 org.hibernate.AnnotationException이 발생 함 : 엔티티에 지정된 식별자가 없습니다 : com..domain.idea.MAE_MFEView


207

이 예외가 발생하는 이유는 무엇입니까?

package com.domain.idea;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.AccessType;

/**
 * object model for the view [InvestmentReturn].[vMAE_MFE]
 */
@Entity
@Table(name="vMAE_MFE", schema="InvestmentReturn")
@AccessType("field")
public class MAE_MFEView
{
    /**
     * trade property is a SuggestdTradeRecommendation object
     */
    @OneToOne(fetch = FetchType.LAZY , cascade = { CascadeType.PERSIST })
    @JoinColumn(name = "suggestedTradeRecommendationID")
    private SuggestedTradeRecommendation trade;

    /**
     * Most Adeverse Excursion value
     */
    private int MAE;

    public int getMAE()
    {
        return MAE;
    }

    /**
     * Most Favorable Excursion value
     */
    private int MFE;

    public int getMFE()
    {
        return MFE;
    }

    /**
     * @return trade property
     * see #trade
     */
    public SuggestedTradeRecommendation getTrade()
    {
        return trade;
    }
}

업데이트 : 코드를 다음과 같이 변경했습니다.

package com.domain.idea;

import javax.persistence.CascadeType;
import javax.persistence.FetchType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.AccessType;

/**
 * object model for the view [InvestmentReturn].[vMAE_MFE]
 */
@Entity
@Table(name="vMAE_MFE", schema="InvestmentReturn")
@AccessType("field")
public class MAE_MFEView
{
    /**
     * trade property is a SuggestdTradeRecommendation object
     */
    @Id
    @OneToOne(fetch = FetchType.LAZY , cascade = { CascadeType.PERSIST })
    @JoinColumn(name = "suggestedTradeRecommendationID")
    private SuggestedTradeRecommendation trade;

    /**
     * Most Adeverse Excursion value
     */
    private int MAE;

    public int getMAE()
    {
        return MAE;
    }

    /**
     * Most Favorable Excursion value
     */
    private int MFE;

    public int getMFE()
    {
        return MFE;
    }

    /**
     * @return trade property
     * see #trade
     */
    public SuggestedTradeRecommendation getTrade()
    {
        return trade;
    }
}

그러나 지금이 예외가 발생합니다.

Caused by: org.hibernate.MappingException: Could not determine type for: com.domain.idea.SuggestedTradeRecommendation, at table: vMAE_MFE, for columns: [org.hibernate.mapping.Column(trade)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:292)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:276)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:216)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1135)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1320)
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
    ... 145 more

btw는 질문과 관련이 없으며 다소 긴 스택 추적입니다. 반복되는 호출이 있습니다. 거기에 모든 것이 정확합니까?
Bozho

왜 스택 추적이 항상 긴지 잘 모르겠습니다. 영향을받는 많은 백그라운드 서비스가 실행되고 있다고 생각합니다.
Ramy

ID가 정적이 아니거나 클래스의 일부 속성이 아닌 경우주의하십시오. 그것은 나와 함께 일어났다 :)
Gean Felipe

답변:


433

로 표시된 필드가 누락되었습니다 @Id. 각각 @Entity@Id-데이터베이스의 기본 키입니다.

엔터티를 별도의 테이블에 유지하지 않고 다른 엔터티의 일부로 유지하려는 경우 @Embeddable대신 대신 사용할 수 있습니다 @Entity.

단순히 데이터 전송 객체가 최대 절전 모드 엔터티의 일부 데이터를 보유하도록하려면 아무 주석도 사용하지 마십시오. 단순한 포조로 두십시오.

업데이트 : SQL 뷰와 관련하여 Hibernate 문서는 다음과 같이 작성합니다.

최대 절전 모드 매핑의 뷰와 기본 테이블에는 차이가 없습니다. 이것은 데이터베이스 수준에서 투명합니다.


2
@Id 필드가 있어야합니까? 내 견해로는 엄밀히 말하면 ID가 없습니다.
Ramy

"보기"는 무슨 뜻입니까? 최대 절전 모드에는 "보기"가 없습니다. 모델 만 있습니다.
Bozho

1
글쎄,보기에 일부 ID를 할당하십시오. 그것 없이는 갈 수 없습니다. 각 행 (객체)은 고유하게 식별되어야합니다.
Bozho

@Id 추가 후 새로운 예외가 발생합니다
Ramy

3
감사합니다! 이것은 성가신 NullPointerFromHellException을 수정했습니다!
malix

172

나를 javax.persistence.Id위해 대신 사용해야합니다 org.springframework.data.annotation.Id. 이 문제가 발생한 사람은 올바른 Id수업 을 가져 왔는지 확인할 수 있습니다 .


2
당신은 내 하루를 저장 : ')
Amitrajit Bose

비슷한 문제가있었습니다.
AngelThread

59

이 오류는 @Id에 대해 Javax.persistance.Id 와 다른 라이브러리를 가져올 때 발생할 수 있습니다 . 이 경우에도주의를 기울여야 할 수도 있습니다.

내 경우에는

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Table;

import org.springframework.data.annotation.Id;

@Entity
public class Status {

    @Id
    @GeneratedValue
    private int id;

이와 같은 코드를 변경하면 작동합니다.

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Table;

import javax.persistence.Id;

@Entity
public class Status {

    @Id
    @GeneratedValue
    private int id;

1
귀중한 조언. org.springframework.data.annotation.Id plz
Christian Meyer

13

아래 코드는 NullPointerException을 해결할 수 있습니다.

@Id
@GeneratedValue
@Column(name = "STOCK_ID", unique = true, nullable = false)
public Integer getStockId() {
    return this.stockId;
}
public void setStockId(Integer stockId) {
    this.stockId = stockId;
}

을 추가 @Id하면 위에 선언 된 메소드와 같이 더 선언 할 수 있습니다.


becoz ur @Id 값이 널 포인터 예외가있는 곳을 지정 및 업데이트하지 않았습니다 ...
Shivendra Prakash Shukla

2

나는 미친 소리를 알고 있지만 제거하는 것을 잊어 버렸기 때문에 그러한 오류가 발생했습니다.

private static final long serialVersionUID = 1L;

내가 테이블을 엔터티로 변환하면 Eclipse JPA 도구가 자동으로 생성합니다.

문제를 해결 한 위의 줄을 제거


1

PK 엔터티에 @EmbeddableId를 사용하면 문제가 해결되었습니다.

@Entity
@Table(name="SAMPLE")
 public class SampleEntity implements Serializable{
   private static final long serialVersionUID = 1L;

   @EmbeddedId
   SampleEntityPK id;

 }

1

모델 클래스 잘못된 가져 오기에 따라이 문제가 있다고 생각합니다.

    import org.springframework.data.annotation.Id;

일반적으로 다음과 같아야합니다.

    import javax.persistence.Id;

1

TL; DR

@Id엔티티 속성 이 누락 되었으므로 Hibernate가 해당 예외를 발생시킵니다.

엔터티 식별자

모든 JPA 엔터티에는 Id주석으로 표시된 식별자 속성이 있어야합니다 .

식별자에는 두 가지 유형이 있습니다.

  • 할당
  • 자동 생성

할당 된 식별자

할당 된 식별자는 다음과 같습니다.

@Id
private Long id;

공지 사항 우리가 래퍼 (예를 들어, 사용하고 있는지 Long, Integer) 대신 기본 유형을 (예를 들어, long, int). 래퍼 형식을 사용하여 있기 때문에,이 경우 확인하여 최대 절전 모드를 사용하여 더 나은 선택 id입니다 null여부, Hibernate는 더 나은, 그것은 연관된 테이블 행이 (엔티티가 일시적인지 확인 (이 연관된 테이블 행이 없음) 또는 분리 할 수 있습니다 그러나 현재 지속성 컨텍스트에 의해 관리되지는 않습니다).

persist를 호출하기 전에 애플리케이션이 지정된 ID를 수동으로 설정해야합니다.

Post post = new Post();
post.setId(1L);

entityManager.persist(post);

자동 생성 식별자

자동 생성 식별자에는 다음 @GeneratedValue외에 주석이 필요 합니다 @Id.

@Id
@GeneratedValue
private int id;

이 기사 에서 설명했듯이 Hibernate가 엔티티 식별자를 자동 생성하는 데 사용할 수있는 3 가지 전략이 있습니다.

  • IDENTITY
  • SEQUENCE
  • TABLE

IDENTITY전략은 기본 데이터베이스가 순서를 지원하는 경우 피할 수있다 (예를 들어, 오라클, PostgreSQL을, 10.3 이후 MariaDB 2012 년 이후 SQL 서버). 시퀀스를 지원하지 않는 유일한 주요 데이터베이스는 MySQL입니다.

문제 IDENTITY는이 전략에서 자동 최대 절전 배치 삽입을 사용할 수 없다는 것입니다. 이 주제에 대한 자세한 내용은 이 기사를 확인 하십시오 .

SEQUENCE당신이 MySQL을 사용하지 않는 전략은 최선의 선택입니다. 를 들어 SEQUENCE전략, 당신은 또한 사용할 pooled최적화 같은 지속성 컨텍스트에서 여러 엔티티를 지속 할 때 데이터베이스 왕복의 수를 줄일 수 있습니다.

TABLE생성기 때문에 끔찍한 선택 이 확장되지 않습니다 . 이식성 을 위해이 기사 에서 설명하는 것처럼 SEQUENCE기본적으로 사용 하는 것이 좋으며 IDENTITYMySQL 전용으로 전환하는 것이 좋습니다 .


첫 번째 예는을 가져서는 안됩니다 @GeneratedValue.
Josef Cech

0

이 오류는 잘못된 Id 클래스를 가져 오기 때문에 발생했습니다. org.springframework.data.annotation.Id를 javax.persistence.Id로 변경 한 후 애플리케이션 실행

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