Search code examples
javaspringspring-bootjpaone-to-many

Spring JPA Add Additional Entries To Child Table


This feels like something where there will already be answers to this, but I've looked through all manner of posts and am still struggling.

I'm learning how to use JPA with Spring Boot, and am specifically working to understand One To Many relationships. The issue at hand is I have a Customer Entity, and the Customer might have multiple email addresses associated with them, so we can contact multiple people at the customer. This gives me these models:

@AllArgsConstructor
@NoArgsConstructor
@Data
@ToString
@Entity
@Table(name = "customer")
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String customerName;
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @LazyCollection(LazyCollectionOption.FALSE)
    @JoinColumn(name = "email_address_id")
    private List<EMailAddress> emailAddress = new ArrayList<>();
    private int brandId;
    private boolean shipmentReport;
    private boolean salesReport;
    
}

I then have the EMailAddress Model:

@AllArgsConstructor
@NoArgsConstructor
@Data
@ToString
@Entity
@Table(name = "e_mail_address")
public class EMailAddress {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String emailAddress;

}

And this is my CustomerRepository:

public interface CustomerRepository extends JpaRepository<Customer, Integer> {
}

Now, I can add a customer, and have an email address associated with that customer:

    List<EMailAddress> eMailAddresses = new ArrayList<>();
    EMailAddress eMailAddress = new EMailAddress();
    eMailAddress.setEmailAddress("someemail@gmail.com");

    eMailAddresses.add(eMailAddress);

    Customer customer = new Customer();
    customer.setCustomerName("Company A");
    customer.setBrandId(1);
    customer.setSalesReport(false);
    customer.setShipmentReport(true);
    customer.setEmailAddress(eMailAddresses);

    repo.save(customer);

And that happily gets added to the DB.

The question is, if I want to add another email address to that customer, how would I do it? I've tried retrieving the customer using getOne from the repository, then getting the current EMail Addresses and adding to that, but if I then try to save that customer, I get a Multiple representations of the same entity error.

I thought maybe I needed to add an EMail address repository, then add new entries via that (assuming I could get the email_address_id), but I've drawn a blank on that too.

Appreciate any guidance.


This is how I've attempted to add new emails so far:

    Customer tempCustomer = repo.getOne(1);

    List<EMailAddress> curentEmails = tempCustomer.getEmailAddress();

    eMailAddress.setEmailAddress("anotheremail@gmail.com");
    curentEmails.add(eMailAddress);
    eMailAddress.setEmailAddress("athirdemail@yahoo.co.uk");
    curentEmails.add(eMailAddress);

    tempCustomer.setEmailAddress(curentEmails);
    repo.save(tempCustomer);

Solution

  • To add new EmailAddress entity to your Customer entity you can simply call findById, or other find spring-data method and then create a new EmailAddress instance to append on that EmailAddress Collection on Customer entity. It would be nice if you post here some stacktrace exception, with that we can help a lot more!

    // will retrieve your customer entity
    Customer customer = customerRepository.getOne(10)
    
    // get email collection and add new EmailAddress instance
    customer.getEmailAddresses().add(new EmailAddress(10,"email@teste.com")
    
    // save and flush email data on table
    customerRepository.saveAndFlush(customer);