gpt4 book ai didi

jpa - NULL ID 通过 @GeneratedValue 在复合键上使用 @EmbeddedId 生成

转载 作者:行者123 更新时间:2023-12-04 20:07:16 24 4
gpt4 key购买 nike

尝试通过 Spring Data JPA 在具有复合键(长和日期)的表中保存一行。组合键的 Long 部分是@GeneratedValue。但是在进行基本的 save() 调用时出现以下错误:

org.hibernate.id.IdentifierGenerationException: null id generated for:class com.bts.billing.domain.CashBatchPaymentHistoryDto

日期是在 save() 之前手动设置的,我已经验证了数据库中存在的音序器并且可以访问。

实体
@Entity
@Table(name = "CASH_BATCH_PMT_H")
public class CashBatchPaymentHistoryDto implements Serializable {
private static final long serialVersionUID = 1L;

@EmbeddedId
private CashBatchPaymentHistoryPK pk;

private Date cashBatchProcDt;
@Column(name = "C_CBP_STS", nullable = false)
private String cashBatchStatus;
@Column(name = "C_CBP_TYP", nullable = false)
private String cashBatchType;

//Removed Getters & Setters To Save Space
}

@Embeddable 类
@Embeddable    
@SequenceGenerator(name = "CBPMT", sequenceName = "CBPMT", allocationSize = 1)
public class CashBatchPaymentHistoryPK implements Serializable {
private static final long serialVersionUID = 1L;

@Column(name = "N_CBP_OID", nullable=false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CBPMT")
private Long cashBatchID;
@Column(name = "D_CBP_PROC", nullable=false)
private Date cashBatchProcDt;

public CashBatchPaymentHistoryPK() {}

public CashBatchPaymentHistoryPK(long cashBatchID, Date cashBatchProcDt) {
this.cashBatchID = cashBatchID;
this.cashBatchProcDt = cashBatchProcDt;
}

//Removed Getters & Setters For Space

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (cashBatchID ^ (cashBatchID >>> 32));
result = prime * result + (int) (cashBatchProcDt.hashCode() ^ (cashBatchProcDt.hashCode() >>> 32));
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
CashBatchPaymentHistoryPK other = (CashBatchPaymentHistoryPK) obj;
if (cashBatchID != other.cashBatchID) {
return false;
}
if (cashBatchProcDt != other.cashBatchProcDt) {
return false;
}
return true;
}
}

存储库类
public interface CashBatchPaymentHistoryRepository extends CrudRepository<CashBatchPaymentHistoryDto, CashBatchPaymentHistoryPK> {
}

对这个问题有什么想法吗?谢谢!

最佳答案

看起来您将 ID 值设置为半准备状态(设置了 Datelong 字段将由持久性提供程序初始化,对吗?这意味着,pk 实际上是非 nullCashBatchPaymentHistoryDto 实例被交给 repository.save(…) 。如果是这样,这将导致 EntityManager.merge(…) 被触发,这可以想象会导致异常,因为它不会期望必须生成 ID。

一般来说,如果您手动维护 id 值(即使只是部分的),您必须明确确定实体的 is-new-state(因为这将有效地决定是否调用 persist(…)merge(…) JPA 案例)。默认情况下,这是通过查看 id 字段并解释 null 来实现的。值(value)为新的,非 null因为不是新的。

在您目前的情况下,有两种选择:

  • 使用 @Version注释字段并在第一次调用 save(…) 之前保持未初始化.
  • 实现 Persistable和它的 isNew()检查对象状态以正确确定它是否是新对象的方法(在您的情况下可能通过检查( pk.cashBatchIDnull )。
  • 关于jpa - NULL ID 通过 @GeneratedValue 在复合键上使用 @EmbeddedId 生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24088776/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com