(Hibernate, mysql) 原因:java.sql.SQLException: Field 'id' doesn't have a default value

Posted

技术标签:

【中文标题】(Hibernate, mysql) 原因:java.sql.SQLException: Field \'id\' doesn\'t have a default value【英文标题】:(Hibernate, mysql) Caused by: java.sql.SQLException: Field 'id' doesn't have a default value(Hibernate, mysql) 原因:java.sql.SQLException: Field 'id' doesn't have a default value 【发布时间】:2017-11-24 02:44:46 【问题描述】:

我有一个在 H2 数据库上运行的应用程序,而 Hibernate 是 ORM 工具。目前,我正在将此应用程序更改为使用 mysql 数据库而不是 H2 数据库,在执行此操作时,我在保存 flagjp 实体时遇到了这个问题。

这是导致此问题的 FlagJP 实体。

@Entity
public class FlagJP extends BaseModelJP 

    @Id
    @GeneratedValue(generator = "IdOrGenerated")
    @GenericGenerator(name = "IdOrGenerated", strategy = "com.jp.menu.api.model.JPSequenceGenerator")
    private Long flagId;

    private String flagKey;

    @OneToMany(mappedBy="flag", cascade = CascadeType.ALL)
    private List<FlagLangJP> flagLangs = new ArrayList<>();

    @ManyToOne
    private FlagCategoryJP flagCategory;

这里是 FlagJP 的相关实体

第二个实体

@Entity
public class FlagLangJP extends BaseModelJP 

    @Id
    @GeneratedValue(generator = "IdOrGenerated")
    @GenericGenerator(name = "IdOrGenerated", strategy = "com.jp.menu.api.model.JPSequenceGenerator")
    private Long id;

    private String languageCode;

    private String flagName;

    private String flagDescription;

    @ManyToOne
    private FlagJP flag;

第三实体

@Entity
public class FlagCategoryJP extends BaseModelJP 

    @Id
    @GeneratedValue(generator = "IdOrGenerated")
    @GenericGenerator(name = "IdOrGenerated", strategy = "com.jp.menu.api.model.JPSequenceGenerator")
    private Long flagCategoryId;

    private String flagCategoryName;

    @OneToMany(mappedBy = "flagCategory")
    private List<FlagJP> flags;

在研究这个问题时,我发现这是由于在休眠生成 DDL 时,FlagJP 表架构没有在数据库中设置自动增量。

这是FlagJP的DDL

如果我尝试通过执行 sql 查询手动设置自动增量,那么 mysql 会抛出此错误。

Operation failed: There was an error while applying the SQL script to the database.
ERROR 1833: Cannot change column 'flagId': used in a foreign key constraint 'FK_sk95esyf1n0gt1qqmlmdmq0uw' of table 'butterfly_emenu.flaglangbpa'
SQL Statement:

我的问题是,使用 H2 数据库时不会发生此问题。当数据库是mysql时如何使用hibernate解决这个问题。

提前感谢您的任何建议

更新:

这是我正在使用的序列生成器的代码

public class JPSequenceGenerator extends IdentityGenerator 

    private static final Logger logger = LoggerFactory.getLogger(JPSequenceGenerator.class);

    @Override
    public Serializable generate(SessionImplementor session, Object object) throws HibernateException 
        Serializable id = session.getEntityPersister(null, object).getClassMetadata().getIdentifier(object, session);

        if (id == null) 
            id = super.generate(session, object);

        



        return id;
    


【问题讨论】:

当序列生成 id null 或未正确存储在表中时,会出现此问题。 【参考方案1】:

在 mysql 中使用 auto_increment 字段 ID 尝试以下代码

  @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long flagId;

如果您无法为 flagId 添加 auto_increment 则删除 foreignKey FK_sk95esyf1n0gt1qqmlmdmq0uw 然后添加 auto_increment 并再次添加外键

【讨论】:

谢谢你的回答,我做了你建议的改变,但问题仍然存在。关于您对删除 FK 并对表格进行更改的评论,我不喜欢这种方法。我希望基于休眠实体生成 DDL,它应该可以在不手动更改数据库的情况下工作。在这种情况下如何让休眠工作 @KItis 通过在 Entity 类中指定这个 @GeneratedValue(strategy = GenerationType.AUTO) 并通过 hibernate 生成 DDL。它会给出同样的错误吗?你试过了吗

以上是关于(Hibernate, mysql) 原因:java.sql.SQLException: Field 'id' doesn't have a default value的主要内容,如果未能解决你的问题,请参考以下文章

hibernate课程 初探单表映射3-3 对象类型

JPA事务不生效原因

hibernate中的schema

为啥这个 Hibernate MySQL 连接是只读的?

Java EE 之 Hibernate异常解决:org.hibernate.exception.SQLGrammarException: could not execute statement(示例代

Hibernate入门