替换所有执行 PUT 的子项 (OneToMany),Spring,Java 8
Replacing all Children (OneToMany) doing PUT, Spring, Java 8
我有关系ManyToOne......
User
entity/class
@Entity
@Table(name = "users")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JsonManagedReference
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
private Set<Phone> phones;
@PrePersist
public void prePersist() {
this.created = new Date();
this.lastLogin = new Date();
}
public User() {
this.phones = new HashSet<>();
}
public Set<Phone> getPhones() {
return phones;
}
public void setPhones(Set<Phone> phones) {
this.phones = phones;
}
//Getters and Setters
}
Phone
entity/class
@Entity
@Table(name = "phones")
public class Phone implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long number;
@JsonBackReference
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
//Getters and Setters
}
当从我的控制器调用 PUT 时
@Operation(summary = "edit User", security = @SecurityRequirement(name = "bearerAuth"))
@PutMapping("/{id}")
public ResponseEntity<?> edit(@RequestHeader(value="Authorization") String token,
@Valid @RequestBody User user, BindingResult result, @PathVariable Long id) {
//Some Code
Optional<User> optionalStoredUser = userService.findById(id);
if (!optionalStoredUser.isPresent()) {
return ResponseEntity.notFound().build();
}
User editedUser = optionalStoredUser.get();
editedUser.setName(user.getName());
editedUser.setEmail(user.getEmail());
editedUser.setPassword(user.getPassword());
editedUser.setPhones(user.getPhones());
editedUser.setModified(new Date());
editedUser.setIsactive(user.isIsactive());
editedUser.setToken(token);
try {
User savedUser = userService.save(editedUser);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
} catch (Exception exp) {
throw new DefaultException(exp.getLocalizedMessage());
}
}
在我的 Phone 存储库界面中,我有:
public interface PhoneDao extends CrudRepository<Phone, Long> {
List<Phone> deleteByUser_id(Long id);
List<Phone> findByUser_id(Long id);
}
如您所见,我调用我的服务,我有:
@Autowired
private UserDao userDao;
@Autowired
private PhoneDao phoneDao;
我需要清除所有未在新 Phone 中列出的旧 Phone(已存储)。
@Override
@Transactional
public User save(User user) {
if (user.getId() != null) {
// phoneDao.deleteByUser_id(user.getId());
List<Phone> listOldPhones = phoneDao.findByUser_id(user.getId());
Set<Phone> listNewPhones = user.getPhones();
if (listNewPhones != null && listOldPhones != null) {
Set<Long> listOldIds = listOldPhones.stream().map(p -> p.getId()).collect(Collectors.toSet());
Set<Long> listNewIds = listNewPhones.stream().map(p -> p.getId()).collect(Collectors.toSet());
listOldIds.stream().filter(id -> !listNewIds.contains(id)).forEach(id -> phoneDao.deleteById(id));
}
}
return userDao.save(user);
}
根据其父级 (User
) 命名接口方法的正确方式是什么?
如何高效地做同样的事情(只删除丢弃的phone,保留确认的phone并创建插入的phone)?
谢谢
将存储库更改为 findByUser_Id
将 Id 更改为大写!
public interface PhoneDao extends CrudRepository<Phone, Long> {
List<Phone> deleteByUser_Id(Long id);
List<Phone> findByUser_Id(Long id);
}
如果需要,在 User
class 中将 CascadeType.ALL
更改为 CascadeType.MERGE
。
@JsonManagedReference
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY, mappedBy = "user")
private Set<Phone> phones;
我有关系ManyToOne......
User
entity/class
@Entity
@Table(name = "users")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JsonManagedReference
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
private Set<Phone> phones;
@PrePersist
public void prePersist() {
this.created = new Date();
this.lastLogin = new Date();
}
public User() {
this.phones = new HashSet<>();
}
public Set<Phone> getPhones() {
return phones;
}
public void setPhones(Set<Phone> phones) {
this.phones = phones;
}
//Getters and Setters
}
Phone
entity/class
@Entity
@Table(name = "phones")
public class Phone implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long number;
@JsonBackReference
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
//Getters and Setters
}
当从我的控制器调用 PUT 时
@Operation(summary = "edit User", security = @SecurityRequirement(name = "bearerAuth"))
@PutMapping("/{id}")
public ResponseEntity<?> edit(@RequestHeader(value="Authorization") String token,
@Valid @RequestBody User user, BindingResult result, @PathVariable Long id) {
//Some Code
Optional<User> optionalStoredUser = userService.findById(id);
if (!optionalStoredUser.isPresent()) {
return ResponseEntity.notFound().build();
}
User editedUser = optionalStoredUser.get();
editedUser.setName(user.getName());
editedUser.setEmail(user.getEmail());
editedUser.setPassword(user.getPassword());
editedUser.setPhones(user.getPhones());
editedUser.setModified(new Date());
editedUser.setIsactive(user.isIsactive());
editedUser.setToken(token);
try {
User savedUser = userService.save(editedUser);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
} catch (Exception exp) {
throw new DefaultException(exp.getLocalizedMessage());
}
}
在我的 Phone 存储库界面中,我有:
public interface PhoneDao extends CrudRepository<Phone, Long> {
List<Phone> deleteByUser_id(Long id);
List<Phone> findByUser_id(Long id);
}
如您所见,我调用我的服务,我有:
@Autowired
private UserDao userDao;
@Autowired
private PhoneDao phoneDao;
我需要清除所有未在新 Phone 中列出的旧 Phone(已存储)。
@Override
@Transactional
public User save(User user) {
if (user.getId() != null) {
// phoneDao.deleteByUser_id(user.getId());
List<Phone> listOldPhones = phoneDao.findByUser_id(user.getId());
Set<Phone> listNewPhones = user.getPhones();
if (listNewPhones != null && listOldPhones != null) {
Set<Long> listOldIds = listOldPhones.stream().map(p -> p.getId()).collect(Collectors.toSet());
Set<Long> listNewIds = listNewPhones.stream().map(p -> p.getId()).collect(Collectors.toSet());
listOldIds.stream().filter(id -> !listNewIds.contains(id)).forEach(id -> phoneDao.deleteById(id));
}
}
return userDao.save(user);
}
根据其父级 (User
) 命名接口方法的正确方式是什么?
如何高效地做同样的事情(只删除丢弃的phone,保留确认的phone并创建插入的phone)?
谢谢
将存储库更改为 findByUser_Id
将 Id 更改为大写!
public interface PhoneDao extends CrudRepository<Phone, Long> {
List<Phone> deleteByUser_Id(Long id);
List<Phone> findByUser_Id(Long id);
}
如果需要,在 User
class 中将 CascadeType.ALL
更改为 CascadeType.MERGE
。
@JsonManagedReference
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY, mappedBy = "user")
private Set<Phone> phones;