什么可以导致使用@GeneratedValue(strategy = GenerationType.IDENTITY)注释的id为null

时间:2018-01-03 02:30:18

标签: jpa

实体

属性得分

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor(onConstructor = @__({@JsonIgnoreProperties(ignoreUnknown = true)}))
@Table(name = "ATTRIBUTE_SCORE")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AttributeScore implements Serializable {

   /**
    * 
    */
   private static final long serialVersionUID = 621935018037696921L;
   public final static int ABOVE_VALUE = 80;
   public final static int AT_VALUE = 70;
   @Getter(onMethod = @__({
         @Id,
         @GeneratedValue(strategy = GenerationType.IDENTITY),
         @Column(name = "ID")
   }))
   private Long id;

   /** Attribute Score */
   @Getter(onMethod = @__({
         @ManyToOne(fetch = FetchType.EAGER),
         @JoinColumn(name = "ATTRIBUTE_ID")
   }))
   private Attribute attribute;

   /** Score */
   @Getter(onMethod = @__({
         @Column(name = "SCORE")}))
   private int score;

}

Attribute.java

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonInclude;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "ATTRIBUTES")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Attribute implements Serializable {

   /**
    * 
    */
   private static final long serialVersionUID = -8847589625501522335L;

   public static final int MAX_POINTS = 3;
   /** Attribute id */
   @Getter(onMethod = @__({
         @Id,
         @GeneratedValue(strategy = GenerationType.IDENTITY),
         @Column(name = "ID")
   }))
   private Long id;
   /** Attribute Name */
   @Getter(onMethod = @__({
         @Column(name = "NAME", length = 500)}))
   private String name;
   /** Weight */
   @Getter(onMethod = @__({
         @Column(name = "WEIGHT")}))
   private int weight;
   /** Points */
   @Getter(onMethod = @__({
         @Column(name = "DISPLAY_ORDER")}))
   private int displayOrder;
   /** Required */
   @Getter(onMethod = @__({
         @Column(name = "REQUIRED")}))
   private boolean required;

}

调用

来自@Stateless @LocalBean类的

   protected E saveInstance(E entity) {
      if (entity == null) {
         throw new NosisEJBValidationException("entity cannot be null");
      } else {
         I id = getId(entity);
         if (id == null) {
            em.persist(entity);
            logger.info(Logger.EVENT_UNSPECIFIED, "entity of type '" + entity.getClass().getSimpleName()
                  + "' with id '" + getId(entity) + "' created.");
         } else {
            entity = em.merge(entity);
            logger.info(Logger.EVENT_UNSPECIFIED,
                  "entity of type '" + entity.getClass().getSimpleName() + "' with id '" + id + "' updated.");
         }
      }
      return entity;
   }

调用上述saveInstance方法会产生以下结果:

SQL Error: 1400, SQLState: 23000
ORA-01400: cannot insert NULL into ("COMMON_USER"."ATTRIBUTE_SCORE"."ID")

问题的名字几乎说明了一切。我试图坚持ATTRIBUTE_SCORE的新实例。传入entity的{​​{1}} saveInstance id。知道为什么这不起作用。

老实说,我不知道在哪里看。

修改

事实证明正在生成错误的sql:

null

它应该是:

Hibernate: insert into common_user.ATTRIBUTE_SCORE (ATTRIBUTE_ID, SCORE) values (?, ?)

所以新问题:为什么要排除id字段?

1 个答案:

答案 0 :(得分:0)

如果对@GeneratedValue使用策略javax.persistence.GenerationType.IDENTITY,则表必须具有标识生成器。这可以完成,包括主键的AUTO_INCREMENT。

如果你没有为你的id字段设置任何值,它应该是null或默认值(或者如果你设置了那个属性,它会自动增加)。

@GeneratedValue注释只是告诉Hibernate数据库本身正在生成此值。所以AUTO_INCREMENT也应该在数据库中定义。

此链接的类似问题, Hibernate @GeneratedValue null error for primary key