I have a simple @ManyToOne and @OneToMany relation between Profile and Link entities. Changes applied in any attribute of those entities are being save/updated thought ProfileRepository.save(profile). In these two cases everything works fine, in case a new Link is add to the Profile.links a new Link is saved to DB, the same if I change an existent link, the modified values from this Link are updated in DB.
What I was expecting to happen when I remove an existent Link form Profile list, is that the same Link would be removed from DB also, but it is not happening.
What am I missing here?
@Entity
@Table(name = "profiles")
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "user_id", unique = true)
private Long userId;
@OneToMany(mappedBy = "profile", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Link> links = new ArrayList<>();
public void addLink(Link link) {
links.add(link);
link.setProfile(this);
}
// ...
.
@Entity
@Table(name = "links")
public class Link {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotEmpty(message = "Description cannot be empty")
private String description;
@NotEmpty(message = "Link cannot be empty")
private String url;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "profile_id", nullable = false)
private Profile profile;
// ...
.
public ProfileDTO updateProfile(ProfileDTO profileDTO) {
Optional<Profile> optProfile = profileRepository.findByUserId(profileDTO.getUserId());
Profile profile = optProfile
.orElseThrow(() -> new UserNotFoundException(profileDTO.getUserId()));
List<Link> links = profileDTO.getLinks()
.stream()
.map(l -> aLink()
.withId(l.getId())
.withDescription(l.getDescription())
.withUrl(l.getUrl())
.build())
.collect(toList());
profile.addLinks(links);
profile.setDescription(profileDTO.getDescription());
return ProfileDTOBuilder.from(profileRepository.saveAndFlush(profile));
}
.
@Repository
public interface ProfileRepository extends JpaRepository<Profile, Long> {
Optional<Profile> findByUserId(Long userId);
}
UPDATE
If I run the same code using a Test class and persisting Profile
entity with TestEntityManager
, it works as expected. Links are removed from memory database.
entityManager.persist(profile);
entityManager.flush();