简体   繁体   中英

JPA @ManyToMany does not seem to update join table with no CascadeType

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM