【问题标题】:JPA primary key value is always 0JPA 主键值始终为 0
【发布时间】:2011-06-07 01:07:54
【问题描述】:

我有一个帖子类,它有点工作,但有一个问题:主键没有增加。

@Entity
@Table(name="posts")
public class Post extends GenericModel{

    @Id
    @Column(name="post_id")
    public int id;

    @Column(name="post_situation")
    public String situation;

    @Column(name="post_date")
    public Date date;

    @Column(name="post_userid")
    public int userid;

    @OneToMany(mappedBy="post", cascade=CascadeType.ALL)
    public List<Block> blocks;

    public Post addBlock(String content, int position){
        Block b = new Block(this, content, position);
        b.save();

        this.blocks.add(b);

        this.save();
        return this;
    }

    public Post(String situation, Date date){
        this.situation = situation;
        this.date = date;
        this.userid = 2;
    }

}

当我第一次在空桌子上调用它时,它工作正常,但第二次,我得到PersistenceException occured : org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update post_id 列始终为 0。知道如何解决这个问题吗?我有 @Id 注释。

这就是我在控制器中的方式:

    Post p = new Post("Midden in het middenoosten.", new Date()).save();

任何想法是什么导致了这个问题?

【问题讨论】:

    标签: java jpa primary-key playframework


    【解决方案1】:

    您似乎希望自动生成主键值。如果是这种情况,除了@Id 注释之外,您还需要将@GeneratedValue 注释添加到id 属性。因此,您的代码应该是:

    @Id
    @Column(name="post_id")
    @GeneratedValue
    public int id;
    

    There are several strategies 可用于生成 Id。您必须阅读这些内容才能决定是否要选择基于 TABLESEQUENCE 或基于 IDENTITY 的策略(这取决于您的数据库支持的内容)。如果您明确选择策略,将使用定义策略,而不是默认的 AUTO 策略。明确的战略决策,在代码中传达为:

    @Id
    @Column(name="post_id")
    @GeneratedValue(strategy=SEQUENCE, generator="POST_SEQ")
    public int id;
    

    如果没有生成值,Java 中整数的默认值,即 0 将被持久化为 post_id 列。由于主键约束,您不能拥有具有相同键的第二行,从而导致描述的失败。

    【讨论】:

    • 当它在查询中保持打开状态时,mysql 不应该能够自己生成主键吗?有没有办法让 JPA 在保存对象时忽略它,只将它用于读取?
    • 我没有阅读您更新的答案。我试过没有@GeneratedValue 参数,现在它告诉我java.sql.SQLException: Field 'post_id' doesn't have a default value
    • 是的,我的 SQL 也可以做到这一点。您需要在创建表时指定该列。
    • 您指的是 AUTO_INCREMENT 列吗?如果是这样,您需要选择 IDENTITY 策略。
    • @Sled,不客气。我想指出,AUTO 策略通常会导致选择 TABLE 策略,因此您最好指定您需要的策略。
    【解决方案2】:

    有几种策略可用于生成 id:

    1. GenerationType.AUTO
    2. GenerationType.SEQUENCE
    3. GenerationType.IDENTITY
    4. GenerationType.TABLE

    如果您希望自动生成主键值,请使用GenerationType.AUTO,它适用于 MySQL。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-15
      • 2014-07-10
      相关资源
      最近更新 更多