使用带有 @GeneratedValue 生成的 PrimaryKey 的 jdbctemplate 插入行

Posted

技术标签:

【中文标题】使用带有 @GeneratedValue 生成的 PrimaryKey 的 jdbctemplate 插入行【英文标题】:Insert row using jdbctemplate with PrimaryKey generated by @GeneratedValue 【发布时间】:2019-08-12 16:28:17 【问题描述】:

我在 Spring Boot 应用程序的 Oracle 表中插入一行。主键需要使用注释生成。我有一个代表表格的实体模型:

@Entity
@Table(name="PURCH_TENDR")
public class LhlPurchTendrModel implements Serializable 

    @Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
    @Column(name="PURCH_TENDR_ID")
    private String purchTendrId;

    @Column(name="CREATED_BY_NM")
    private String createdByNm;

    @Column(name="CREATED_DT")
    private Timestamp createdDt;

    @Column(name="UPDATED_BY_NM")
    private String updatedByNm;

    @Column(name="UPDATED_DT")
    private Timestamp updatedDt;

    @Column(name="MODIFY_BY_NM")
    private String modifyByNm;

    @Column(name="MODIFY_DT")
    private Timestamp modifyDt;

    @Column(name="CARRIER_TENDER_ID")
    private long CarrierTenderId;

    @Column(name="EVENT_GMT_TM")
    private Timestamp EventGmtTm;

    @Column(name="PURCH_COST_ID")
    private int PurchCostId;

    @Column(name="LAT")
    private float Lat;

    @Column(name="LON")
    private float Lon;

    @Column(name="CITY_NM")
    private String cityNm;

    @Column(name="STATE_CD")
    private String stateCd;

    @Column(name="CARER_EDI_NBR")
    private String carerEdiNbr;

    @Column(name="EVENT_STAT_CD")
    private String eventStatCd;

    @Column(name="ETN_TM")
    private Timestamp EtnTm;

    @Column(name="PCKUP_NBR")
    private String PickupNbr;

    @Column(name="VIN")
    private String Vin;

    @Column(name="EQUIP_NBR")
    private String EquipNbr;

    @Column(name="EQUIP_PREFIX")
    private String EquipPrefix;

这些成员变量也有 getter 和 setter。 我使用一个 Repository 类来实现一个 jdbctemplate 来插入行。 当我使用这种插入变体时,我收到列类型无效的错误:

public boolean insertPurchaseInfo(LhlPurchTendrModel lhlPurchTendrModel) throws SQLException 
        boolean success= false;
        String ds = lhlJdbcTemplate.getDataSource().getConnection().getSchema();
        LOGGER.info("Schema and Insert Purchase Info ", ds);
        String insertSequenceNbrSQLStatement = "INSERT INTO purch_tendr(created_by_nm, created_dt, modify_by_nm, modify_dt, carrier_tender_id, purch_cost_id, event_stat_cd, equip_nbr, equip_prefix) " +
                "VALUES (?, SYSDATE, ?, SYSDATE, ?, ?, ?, ?, ?)";
        try
            int rowsInserted = lhlJdbcTemplate.update(
                    insertSequenceNbrSQLStatement,                
                    new Object[] lhlPurchTendrModel);

            if(rowsInserted > 0)
                success = true;
            
        

当我尝试使用此代码插入时,我收到错误“无法将 NULL 插入表 Purch_Tendr 列 Purch_Tendr_Id。

public boolean insertPurchaseInfo(LhlPurchTendrModel lhlPurchTendrModel) throws SQLException 
        boolean success= false;
        String ds = lhlJdbcTemplate.getDataSource().getConnection().getSchema();
        LOGGER.info("Schema and Insert Purchase Info ", ds);
        String insertSequenceNbrSQLStatement = "INSERT INTO purch_tendr(created_by_nm, created_dt, modify_by_nm, modify_dt, carrier_tender_id, purch_cost_id, event_stat_cd, equip_nbr, equip_prefix) " +
                "VALUES (?, SYSDATE, ?, SYSDATE, ?, ?, ?, ?, ?)";
        try
            int rowsInserted = lhlJdbcTemplate.update(
                    insertSequenceNbrSQLStatement,                
                      new Object[]lhlPurchTendrModel.getCreatedByNm(), lhlPurchTendrModel.getModifyByNm(), lhlPurchTendrModel.getCarrierTenderId(), lhlPurchTendrModel.getPurchCostId(),
                                lhlPurchTendrModel.getEventGmtTm(), lhlPurchTendrModel.getEquipNbr(), lhlPurchTendrModel.getEquipPrefix());
            if(rowsInserted > 0)
                success = true;
            
        

我不确定如何将 @Entity 类与 JdbcTemplate 一起使用。如何指示 JdbcTemplate 生成主键值?

【问题讨论】:

【参考方案1】:

您不能因为@Entity 和您使用的所有注释(例如@GeneratedValue@GenericGenerator 等)都来自JPA,而幕后JdbcTemplate 仅基于JDBC,它对JPA 一无所知。

如果你想使用 JPA 来管理你的数据,你需要看的是选择一个 JPA 实现(例如 Hibernate 是一个流行的),并通过 JPA 接口研究如何使用它而不是看JdbcTemplate

一旦您掌握了使用 JPA 管理数据的基本概念,您可能会考虑查看 Spring Data,它是构建在纯 JPA 之上的更高级工具,可以帮助实现存储库/DAO 类型的管理和查询数据。

【讨论】:

谢谢!该死。这将意味着改变很多东西。有没有其他方法可以使用 jdbc 生成 UUID 值? 你能简单地在Java中使用UUID.randomUUID().toString()先获取一个UUID,然后像使用JBDCTemplate的简单JDCB插入语句一样插入一条新记录吗? 生成的值和JPA生成的值有什么区别? 不确定 ID 生成 Hibernate UUID 的详细信息,但如果您只想获取随机 ID,UUID.randomUUID() 也是一个安全的选择

以上是关于使用带有 @GeneratedValue 生成的 PrimaryKey 的 jdbctemplate 插入行的主要内容,如果未能解决你的问题,请参考以下文章

JOOQ 生成 pojo 缺少 GeneratedValue 注释

JPA 自动建表- @Id,@GeneratedValue 与 @GenericGenerator 设置主键生成策略

JPA / Hibernate中@GeneratedValue中的字段生成器有啥用?

JPA SequenceGenerator 和 GeneratedValue:名称/生成器属性仅每个类唯一?

休眠并在 CockroachDB 中使用 @GeneratedValue 会导致 SQLGrammarException

Springboot集成Mybatis ID生成策略注解 @GeneratedValue