与在Spring中创建Stripe订阅有关的问题

huangapple 未分类评论43阅读模式
英文:

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..

huangapple
  • 本文由 发表于 2020年7月25日 20:00:13
  • 转载请务必保留本文链接:https://java.coder-hub.com/63088069.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定