First Definition
Simply, I've 2 entity, first is User and second is Address, every user can have one or more addresses. It means, I want bidirectional OneToMany relation between User and Address.
Question
I have a user with 3 addresses (User with a list of 3 address) when I update my user and delete some of the addresses (User with list of 2 address) and after that save the user, the fk of addresses is no updated.
I expect my new user has 2 addresses after the update but the addresses weren't changed.
In Brief: Address table's fk is not updated when I update a list of it from User.
User Entity (Just address field is written)
@Entity
@Table(name = TABLE_NAME)
public class User {
public static final String TABLE_NAME = "User";
//Some Fields Like ID , name ,...
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
@JsonManagedReference
private List<Address> addresses;
public List<Address> getAddresses() {
return addresses;
}
public void setAddresses(List<Address> addresses) {
this.addresses = addresses;
}
}
Address Entity (Just User field is written)
@Entity
@Table(name = TABLE_NAME)
public class Address {
public static final String TABLE_NAME = "ADDRESS";
//Some Fields Like ID , name ,...
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
@JsonBackReference
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Service class
@Service
public class UserService
@Autowired
UserRepository repository;
public updateUserAddress() {
//Get User With Id of 1
User user = repository.findById(1L);
//Get Addresses
List<Address> addresses = user.getAddresses();
//Delete One Address From List
addresses.remove(0);
//Set New Address to User Entity
user.setAddresses(addresses);
//Save User
repository.save(user)
//It doesn't work (List of Address of user is the same and not changed)
}
Btw, I use Spring-data-jpa and Hibernate for DAO layer.
By adding removeAddress
method in User
entity, you can update the fk of the address
table and also you can keep the row:
public void removeAddress(Address address) {
address.setUser(null); // or the value you want
}
The updateUserAddress
method should be like this:
public void updateUserAddress() {
User user = repository.findById(1L);
List<Address> addresses = user.getAddresses();
Address address = addresses.get(0); //the address to be removed
user.removeAddress(address);
user.setAddresses(addresses);
repository.save(user);
}
User Entity:
@Entity
@Table(name = "users")
public class User {
// other fields
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch=FetchType.EAGER)
@JsonManagedReference
private List<Address> addresses;
// getters, setters, constructors etc.
// the remove method
public void removeAddress(Address address) {
address.setUser(null);
}
}
Address Entity:
@Entity
@Table(name = "address")
public class Address {
// other fields
@ManyToOne
@JoinColumn(name = "user_id")
@JsonBackReference
private User user;
// getters, setters, constructors etc.
}