I'm a little confused by a result I am seeing in my code and am not sure if this is by JPA design, or if I have to dig a little further.
Given the following entity:
public class Provider implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
@ManyToMany
@JoinTable(name = "provider_contact", joinColumns = @JoinColumn(name = "contact_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "provider_id", referencedColumnName = "id"))
@OrderColumn
private List<Contact> contacts;
}
and the following code (occuring within a transaction):
/**
* Updates the contact for the provider
* @param providerId
* @param contactDTO
*/
@Override
public Contact addContact(final long providerId, Contact contact){
// first need to find the provider in the db
Provider p = checkNotNull( providerRepository.findOne(providerId) );
// need to save / update the contact if it already exists
contactService.saveContact(contact);
// add the contact to the provider
if( p.getContacts() == null )
p.setContacts(new ArrayList<Contact>());
p.getContacts().add(contact);
// return the contact
return contact;
}
I expect to see both the contact persisted (based on the contactService.saveContact()
) method, and the join table updated due to the fact that I've added the contact to the provider object.
However, the provider_contact join table is not being updated.
I did not think I needed a CascadeType
of any sorts to do the update to the join table. Am I mistaken? Do I need to enforce CascadeType.PERSIST
? Or is there a problem in my code in the way I add the contact to my provider?
You are only saving the Contact
not the change made to the provider. if you provider is mapped to your Contact
then you can do it this way :
@Override
public Contact addContact(final long providerId, Contact contact){
// first need to find the provider in the db
Provider p = checkNotNull( providerRepository.findOne(providerId) );
// need to save / update the contact if it already exists
// add the provider to the contact
contact.addProvider(provider)
//save the contact after adding a the provider
Contact contact = contactService.saveContact(contact);
// return the contact
return contact;
}
Or if it is not mapped you need to update the Provider
by using a transactional method from the ProviderService
:
@Override
public Contact addContact(final long providerId, Contact contact){
// first need to find the provider in the db
// need to save / update the contact if it already exists
contactService.saveContact(contact);
providerService.updateProvider(long provider, long contact);
// return the contact
return contact;
}
update provider from @ ProviderService
@Override
public Provider updateProvider(long providerId, long contact){
// Get the provider from the service
Provider p = providerService.get(providerId) ;
//get contact from contact Servoce
Contact contact = contactService.getContact(contact);
if( p.getContacts() == null )
p.setContacts(new ArrayList<Contact>());
p.getContacts().add(contact);
// update the provider
return providerRepository.save(p) ;
}
Thanks for all the suggestions. Turns out, there was a knock-on from another spot in the code (had to really trace through things to find it). Ends up, I was looking in the wrong place in the code.
Another method was accidentally overwriting the contacts
field ( List<Contact>
) to null. Hence, upon the end of the transaction, the contact that was previous added was removed.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.