我正在构建一个Spring应用程序,该应用程序使用Stripe进行基于订阅的付款。我在创建订阅时遇到问题,我得到的确切错误是:org.hibernate.AssertionFailure: non-transient entity has a null id: com.randomprogramming.projectstrics.entity.Account
,但这没有任何意义,因为当我打开数据库(PostgreSQL)时,我可以看到该帐户有一个ID。但是,当我检查Subscription
上的Account
字段时,该字段为空。以下是应该创建Subscription
并将其保存在我的数据库中的代码:
public Subscription createSubscription(CreateSubscriptionBody createSubscriptionBody, Principal principal) throws Exception {
logger.info("Started creating a new subscription...");
// probably not necessary to check both the principal and account but just to be safe
if (principal == null) throw new Exception("Principal not defined, check if you are logged in.");
Account customerAccount = accountService.findByUsername(principal.getName());
if (customerAccount == null) throw new UsernameNotFoundException("Error when searching for user.");
logger.info("Creating the Customer and PaymentMethod...");
// Create a Customer object from the passed in Customer ID
Customer customer = Customer.retrieve(createSubscriptionBody.getCustomerId());
// Create a PaymentMethod from the passed in Payment Method ID
PaymentMethod pm = PaymentMethod.retrieve(createSubscriptionBody.getPaymentMethodId());
// Attach the Customer ID to the Payment Method
pm.attach(PaymentMethodAttachParams.builder().setCustomer(customer.getId()).build());
logger.info("Creating CustomerUpdateParams and updating Customer...");
// I don't even know what this does
CustomerUpdateParams customerUpdateParams = CustomerUpdateParams
.builder()
.setInvoiceSettings(
CustomerUpdateParams
.InvoiceSettings.builder()
.setDefaultPaymentMethod(createSubscriptionBody.getPaymentMethodId())
.build()
)
.build();
// and we update the customer with whatever the fuck we did above
customer.update(customerUpdateParams);
logger.info("Creating the Subscription params...");
// Create the subscription params
SubscriptionCreateParams subCreateParams = SubscriptionCreateParams
.builder()
.addItem(
SubscriptionCreateParams
.Item.builder()
.setPrice(PRICE_ID)
.build()
)
.setCustomer(customer.getId())
.addAllExpand(Collections.singletonList("latest_invoice.payment_intent"))
.build();
logger.info("Creating the subscription...");
// Create the subscription
// I'm pretty sure that Subscription.create is async, so be careful with this
Subscription subscription = Subscription.create(subCreateParams);
// Save the subscription that was returned into our database
StripeSubscription stripeSubscription = new StripeSubscription(subscription.getId(),
subscription.getCurrentPeriodEnd(),
subscription.getCustomer(),
// Since we're only going to be charging for one thing, we can use 0 index here
subscription.getItems().getData().get(0).getPrice().getId(), customerAccount);
save(stripeSubscription);
// Save the subscription to the account and save the account into the database
customerAccount.setSubscription(stripeSubscription);
accountService.save(customerAccount);
logger.info("Finished creating the subscription.");
return subscription;
}
在使用调试器运行该程序几次后,我注意到该错误发生在行save(stripeSubscription);
上。当使用调试器检查值时,所有内容都有一个ID,对我来说一切都很好。
这是保存方法:
public void save(StripeSubscription stripeSubscription) {
stripeSubscriptionRepository.save(stripeSubscription);
logger.info("Saved StripeSubscription in the database.");
}
这是我的StripeSubscription
实体:
@Entity(name = "stripe_subscription")
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class StripeSubscription {
@Id
private String id;
private Long currentPeriodEnd;
private String customerId;
private String priceId;
@JsonIgnore
@OneToOne(mappedBy = "subscription")
private Account account;
}
要注意的另一件事是实际上已创建了订阅,可以从我的Stripe仪表板检查该订阅。我在做什么错了?
答案 0 :(得分:0)
嗯,我尝试在StripeSubscription
中创建一个新的ID字段,并将订阅ID保存在另一个字段中,这似乎已经解决了问题。