尝试通过Spring Data JPA在具有复合键(Long& Date)的表中保存行。复合键的长部分是@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
@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> {
}
有关此问题的任何想法?谢谢!
答案 0 :(得分:4)
看起来您正在将ID值设置为半准备状态(Date
正在设置但long
字段要由持久性提供程序初始化,对吧?这意味着,{{1当pk
实例交给null
时,实际上是非CashBatchPaymentHistoryDto
。如果是这样,这将导致repository.save(…)
被触发,可以想象会导致异常因为它不会期望生成ID。
一般来说,如果您手动维护id值(甚至只是部分值),则必须明确确定实体的is-new-state(因为这将有效地决定是否调用EntityManager.merge(…)
或JPA案例中的persist(…)
。默认情况下,这可以通过查看id字段并将merge(…)
值解释为新的非null
而不是新的来实现。
在您目前的情况下,有两种选择:
null
带注释的字段,并在第一次调用@Version
之前保持未初始化状态。save(…)
及其Persistable
方法检查您的对象状态,以正确判断它是否是新的(在您的情况下可能通过检查isNew()
是pk.cashBatchID
)。