jimgardener
jimgardener

Reputation: 637

storing currently selected payment info in Customer class

I need to store a customer's currently selected payment info ,so that this info can be used in processing a purchase.Customer can have many credit cards.So I modelled it as a OneToMany relation.I am doubtful about storing the currently selected payment info as a different field(as shown below).Having a field of Set<Payment> and Payment side by side ,looks not quite right.

Is there a better way to do this?May be use some flag to mark that this is the currently selected card info

@Entity
class Customer{
...
@OneToMany( cascade=CascadeType.ALL,orphanRemoval=true)
Set<Payment> payments;

Payment currentlySelectedPayment;//?

}

@Entity
@Table(uniqueConstraints=@UniqueConstraint(columnNames={"cardType","cardNumber"}))
public class Payment{
...
   String cardType;
   String cardNumber;
   String nameOnCard;
   ...
   Date dateOfExpiry;//day,month,year of expiry

}

I implemented the business logic as

void addNewCard(...){
  Payment payment = get_from_db_or_create_new_payment(...);
  if(!customer.getPayments().contains(payment) ){
      customer.getPayments().add(payment);
  }
 ...
}

void setCurrentlySelectedPaymentForCustomer(Long paymentId,..){
    Payment payment = getPaymentFromDB(paymentId);
    if(!customer.getCurrentlySelectedPayment().equals(payment)){
        customer.setCurrentlySelectedPayment(payment);
    }
...
}

Upvotes: 0

Views: 166

Answers (1)

Alfredo Osorio
Alfredo Osorio

Reputation: 11475

I don't see any problem with the design. You need to add the payment to the payments set. After that you need to assign the selected payment to the Customer.

If you are using a set you don't need to use:

if(!customer.getPayments().contains(payment) ){

because a Set doesn't permit to add duplicated elements.

Also I don't see a reason to do this:

if(!customer.getCurrentlySelectedPayment().equals(payment)){

You could just set it and don't need to evaluate if the currentlySelectedPayment is not equal.

I have came across with similar situations where you need to first add the elements to the parent and then assign one of those elements to one of the parent's attributes. The way I've solved it is the way you did instead of having a flag (true/false attribute) in the childs.

I think the way you are doing it is the right way to do. I think a flag like for example in this case an attribute named selectedPayment in Payment is not an appropriate attribute for the object. Why? Because first is an attribute of the Customer and not the Payment itself. Second when you want to change the selectedPayment you would need to obtain the selectedPayment from the child object, delete the flag and assign the flag to the new child, many steps that could have been avoided if you just create the attribute in the parent.

Upvotes: 2

Related Questions