Spring boot 违反了获取JPA错误完整性约束(FK_XXXXX)-未找到父密钥
我有两张桌子Spring boot 违反了获取JPA错误完整性约束(FK_XXXXX)-未找到父密钥,spring-boot,hibernate,spring-data-jpa,oracle12c,Spring Boot,Hibernate,Spring Data Jpa,Oracle12c,我有两张桌子 CREATE TABLE stripe_product ( id NUMBER NOT NULL PRIMARY KEY, product_id VARCHAR2(256) NOT NULL, name VARCHAR2(256) NOT NULL, description VARCHAR2(256), active NUMBER(1,0), deleted NUMBER(1,0), created_at TIMESTAMP,
CREATE TABLE stripe_product (
id NUMBER NOT NULL PRIMARY KEY,
product_id VARCHAR2(256) NOT NULL,
name VARCHAR2(256) NOT NULL,
description VARCHAR2(256),
active NUMBER(1,0),
deleted NUMBER(1,0),
created_at TIMESTAMP,
created_by NUMBER,
updated_at TIMESTAMP,
updated_by NUMBER,
deleted_at TIMESTAMP,
CONSTRAINT UC_stripe_product_id_product_id UNIQUE (id, product_id),
CONSTRAINT UC_stripe_product_product_id UNIQUE (product_id)
);
及
我使用以下类映射了这些表
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "stripe_product")
public class StripeProduct {
@Id
@SequenceGenerator(name = "stripe_product_seq", sequenceName = "stripe_product_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "stripe_product_seq")
private Long id;
@Column(name = "product_id", unique = true)
private String productId;
@Column(nullable = false)
private String name;
private String description;
private Boolean active;
private Boolean deleted;
@Embedded
private Audit audit = new Audit();
@Column(name = "deleted_at")
private Instant deletedAt;
public StripeProduct() {
}
public StripeProduct(Product product) {
this.productId = product.getId();
this.name = product.getName();
this.description = product.getDescription();
this.active = product.getActive();
this.deleted = product.getDeleted();
}
// getters and setter
}
另一个
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "stripe_price")
public class StripePrice {
@Id
@SequenceGenerator(name = "stripe_price_seq", sequenceName = "stripe_price_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "stripe_price_seq")
private Long id;
@Column(name = "price_id", unique = true)
private String priceId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "stripe_product_product_id")
private StripeProduct stripeProduct;
private Boolean active;
private Boolean deleted;
private String currency;
....
@Embedded
private Audit audit = new Audit();
@Column(name = "deleted_at")
private Instant deletedAt;
public StripePrice() {
}
public StripePrice(Price price, StripeProduct stripeProduct) {
Assert.notNull(price, "price cannot be null");
this.priceId = price.getId();
this.stripeProduct = stripeProduct;
this.active = price.getActive();
this.currency = price.getCurrency();
this.billingScheme = price.getBillingScheme();
this.unitAmount = price.getUnitAmount();
this.type = price.getType();
Recurring recurring = price.getRecurring();
if (recurring != null) {
this.recurringAggregateUsage = recurring.getAggregateUsage();
this.recurringInterval = recurring.getInterval();
this.recurringIntervalCount = recurring.getIntervalCount();
this.recurringUsageType = recurring.getUsageType();
}
this.deleted = price.getDeleted();
}
// getters and setters
}
在数据库中,我有以下记录
现在,如果我使用下面的sql直接在数据库中插入记录,它就可以工作了
insert into stripe_price (active, created_by, created_at, updated_by, updated_at, billing_scheme,
currency, deleted, deleted_at, price_id, recurring_aggregate_usage, recurring_interval,
recurring_interval_count, recurring_usage_type, stripe_product_product_id, type, unit_amount, id)
values (1, 0, SYSDATE, 0, SYSDATE, 'Billing scheme', 'usd', 0, null, 'adsad', 'hjgjh', 'sfsad', 1,
'asdsad', 'prod_Io2qV0NPORZhnX', 'adsad', 100, 33);
insert into stripe_price (active, created_by, created_at, updated_by, updated_at, billing_scheme,
currency, deleted, deleted_at, price_id, recurring_aggregate_usage, recurring_interval,
recurring_interval_count, recurring_usage_type, stripe_product_product_id, type, unit_amount, id)
values (1, 0, SYSDATE, 0, SYSDATE, 'Billing scheme', 'usd', 0, null, 'price_id-2', 'hjgjh', 'sfsad',
1, 'asdsadxzcxzc', 'prod_Io2qV0NPORZhnX', 'asd1234', 100, 34)
但是现在使用JPA我得到了错误
Caused by: java.sql.BatchUpdateException: ORA-02291: integrity constraint (BUILDADMIN.FK_STRIPE_PRICE_STRIPE_PRODUCT_PRODUCT_ID) violated - parent key not found
这是我的密码
List<Price> prices = priceCollection.getData();
if (!CollectionUtils.isEmpty(prices)) {
prices.forEach(price -> {
String productId = price.getProduct();
StripeProduct managedStripeProduct = stripeProductRepository.findByProductId(productId).orElse(null);
if (managedStripeProduct != null) {
StripePrice newStripePrice = new StripePrice(price, managedStripeProduct);
StripePrice managedStripePrice = stripePriceRepository.save(newStripePrice);
}
});
}
正如您所注意到的,当hibernate生成SQL时,没有条带产品id。我认为这就是它产生错误的原因
虽然我将其设置为StripePrice,但无法找到我下注错误的原因。谁能解释一下我做错了什么?我怎样才能解决这个问题
谢谢,我已经解决了这个问题。事实上,问题是我有不同的名称列。在
stripe\u product
表中,列名为product\u id
。而在stripe\u price
表中,列名为stripe\u product\u id
。因此,我必须在映射中使用以下内容
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "stripe_product_product_id", referencedColumnName = "product_id", nullable = false)
private StripeProduct stripeProduct;
因此基本上referencedColumnName=“product\u id”
缺失,这就是为什么JPA无法从stripe\u product
表中找到product\u id
值的原因。希望它对其他人也有用
Hibernate: select stripe_price_seq.nextval from dual
Hibernate: insert into stripe_price (active, created_by, created_at, updated_by, updated_at, billing_scheme, currency, deleted, deleted_at, price_id, recurring_aggregate_usage, recurring_interval, recurring_interval_count, recurring_usage_type, stripe_product_product_id, type, unit_amount, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
binding parameter [1] as [BIT] - [true]
binding parameter [2] as [BIGINT] - [0]
binding parameter [3] as [TIMESTAMP] - [2021-01-25T23:18:11.104Z]
binding parameter [4] as [BIGINT] - [0]
binding parameter [5] as [TIMESTAMP] - [2021-01-25T23:18:11.104Z]
binding parameter [6] as [VARCHAR] - [per_unit]
binding parameter [7] as [VARCHAR] - [usd]
binding parameter [8] as [BIT] - [null]
binding parameter [9] as [TIMESTAMP] - [null]
binding parameter [10] as [VARCHAR] - [price_1ICQl8JOji9YLkEKmju4jUmu]
binding parameter [11] as [VARCHAR] - [null]
binding parameter [12] as [VARCHAR] - [month]
binding parameter [13] as [BIGINT] - [1]
binding parameter [14] as [VARCHAR] - [licensed]
binding parameter [15] as [BIGINT] - [30]
binding parameter [16] as [VARCHAR] - [recurring]
binding parameter [17] as [BIGINT] - [100000]
binding parameter [18] as [BIGINT] - [80]
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "stripe_product_product_id", referencedColumnName = "product_id", nullable = false)
private StripeProduct stripeProduct;