Home > database >  Cascade Persist with Spring JPA
Cascade Persist with Spring JPA

Time:09-02

I have two tables professional and address that will be linked in a associative entity (professional_address).

And I have the following example (summed up) code:

Address address1 = new Address();
Address address2 = new Address();
Address address3 = new Address();

Professional professional = new Professional();
List<Address> addressList = new ArrayList<>();

address1.setStreet("A");
address2.setStreet("B");
address3.setStreet("C");


addressList.add(address1);
addressList.add(address2);
addressList.add(address3);

professional.setAddresses(addressList);

professionalRepository.save(professional);

What I've expected from code execution, was something like this:

The same professional, with 3 different addresses

But, what I'm getting is this:

The same address id 3 times

My entities:

Professional

package example_package;

import lombok.*;

import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@Builder
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Table(name = "professional")
public class Professional extends Auditable implements Serializable {

    @Column(name = "first_name", nullable = false)
    private String firstName;

    @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinTable(name = "professional_address",
            joinColumns = @JoinColumn(name = "professional_id"),
            inverseJoinColumns = @JoinColumn(name = "address_id")
    )
    private List<Address> addresses = new ArrayList<>();
}

Address

package example_package;

import lombok.*;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;

@Builder
@Entity
@NoArgsConstructor
@Data
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Table(name = "address")
public class Address extends Auditable implements Serializable {

    @Column(name = "street")
    private String street;

}

What am I doing wrong and how do I solve it?

CodePudding user response:

AFAIK, when mapping many-to-many association we should include a Collection in both classes: as stated in Hibernate's docs, every many-to-many association has two sides, the owning side and the non-owning, or inverse, side.

Since your Professional is the owning side, your Address should look like:

@Builder
@Entity
@NoArgsConstructor
@Data
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Table(name = "address")
public class Address extends Auditable implements Serializable {

    @Column(name = "street")
    private String street;

    @ManyToMany(mappedBy = "addresses", fetch = FetchType.LAZY)
    private List<Professional> professionals = new ArrayList<>();
}
  • Related