英文:
Issues with create a Stripe Subscription in Spring
问题
我正在构建一个使用Stripe进行订阅支付的Spring应用程序。在创建订阅时遇到了问题,我收到的确切错误信息是:org.hibernate.AssertionFailure: non-transient entity has a null id: com.randomprogramming.projectstrics.entity.Account
,但这似乎没有什么道理,因为当我打开我的数据库(使用的是PostgreSQL)时,我可以看到Account有一个ID。但是当我检查Account上的Subscription字段时,它是空的。以下是应该创建Subscription并将其保存在我的数据库中的代码部分:
public Subscription createSubscription(CreateSubscriptionBody createSubscriptionBody, Principal principal) throws Exception {
// ...(代码内容省略)...
// 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);
// ...(代码内容省略)...
return subscription;
}
运行程序几次并使用调试器进行检查后,我注意到错误发生在save(stripeSubscription);
这一行。在调试器中检查值时,所有内容都有一个ID,并且在我看来一切都正常。
以下是save
方法:
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仪表板中查看。我做错了什么?
英文:
I am building a Spring app which uses Stripe for subscription based payments. I am having issues when creating a Subscription, the exact error that I am getting is: org.hibernate.AssertionFailure: non-transient entity has a null id: com.randomprogramming.projectstrics.entity.Account
, but that doesn't really make sense since when I open my database(which is PostgreSQL), I can see that the Account has an ID. But when I check the Subscription
field on my Account
, it's empty. Here is the code which is supposed to create a Subscription
and save it in my database:
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;
}
Upon running the program a few times with my debugger, I noticed that the error happens on the line save(stripeSubscription);
. When checking the values with the debugger, everything has an Id, and everything looks fine to me..
Here's the save method:
public void save(StripeSubscription stripeSubscription) {
stripeSubscriptionRepository.save(stripeSubscription);
logger.info("Saved StripeSubscription in the database.");
}
Here's my StripeSubscription
Entity:
@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;
}
Another thing to note is that the subscription actually gets created, which I can check from my Stripe dashboard.. What am I doing wrong?
答案1
得分: 0
嗯,我尝试在StripeSubscription
中创建一个新的Id字段,并将订阅ID保存在另一个字段中,这似乎解决了问题...
英文:
Hmm, I tried creating a new Id field in StripeSubscription
and saving the Subscription id in another field, and that seems to have fixed the problem..
专注分享java语言的经验与见解,让所有开发者获益!
评论