有 Person 和 Address 实体,它们之间存在 ManyToMany 关系
但是当使用spring data jpa存储库保存时,由于某种原因,在persons_addresses表中所有关系字符串都保存了两次
问题是,为什么会发生这种情况,我做错了什么?
@Entity
@Table(name = "persons")
@Data
@NoArgsConstructor
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String fullName;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "persons_addresses",
joinColumns = @JoinColumn(name = "person_id"),
inverseJoinColumns = @JoinColumn(name = "address_id"))
private List<Address> addresses;
}
@Entity
@Table(name = "addresses")
@Data
@NoArgsConstructor
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "address")
private String addressName;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "persons_addresses",
joinColumns = @JoinColumn(name = "address_id"),
inverseJoinColumns = @JoinColumn(name = "person_id"))
private List<Person> persons;
}
// 在事务中使用
@Transactional
public PersonDto create(PersonDto newPerson) {
Person person = new Person();
person.setFullName(newPerson.getFullName());
person.setAddresses(new ArrayList<>());
newPerson.getAddresses().forEach(a -> {
Address address = addressRepository.findByAddressName(a);
if (address == null) {
address = new Address();
address.setAddressName(a);
address.setPersons(new ArrayList<>());
}
address.getPersons().add(person);
addressRepository.save(address);
person.getAddresses().add(address);
});
return new PersonDto(personRepository.save(person));
}
@JoinTable
只需要在关联的一端指定。在将管理它的那个。在您的情况下,在 Person 中执行此操作是有意义的。现在,由于
@JoinTable
那里和那里,关联表中的条目在保存时Person
和保存时都被保存Address
。像这样正确:mappedBy
表示另一端(即 Person)是所有者并管理关联(即在保存时创建记录等)。为了简化关联的工作并保持内存中对象的一致性,通常会创建一个方法: