Всем привет! Пытаюсь сделать базу данных пользователей и столкнулся с проблемой сохранения списка телефонов.
Мой код:
Entity:
@Entity
@Table(name = "users")
@Setter
@Getter
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 40, name = "name")
private String name;
@Column(length = 40, name = "last_name")
private String lastname;
@Column(unique = true, length = 250, nullable = false)
private String username;
@Column(nullable = false, length = 250)
private String password;
@Column(nullable = false, length = 250)
private String email;
@OneToMany(cascade = CascadeType.ALL)
private List<Telephone> telephones = new ArrayList<>();
private String position;
@ElementCollection
@LazyCollection(LazyCollectionOption.FALSE)
private Set<Role> roles;
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Builder
@ToString
public class Telephone {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String number;
@Override
public String toString() {
return number;
}
@ToString.Exclude
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
DTO
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Setter
public class UserRegistrationDTO {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long user_id;
@Size(min = 3, max = 50)
@Pattern(regexp = "([A-Za-z])*", message = "The firstname contains invalid characters")
private String name;
@Size(min = 3, max = 50)
@Pattern(regexp = "([A-Za-z])*", message = "The lastname contains invalid characters")
private String lastname;
@Pattern(regexp = "\\w*", message = "The username contains invalid characters")
private String username;
@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$", message = "The password short or contain invalid characters")
private String password;
@Pattern(regexp = "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$", message = "The email field does not contain a valid email address")
private String email;
private List<Telephone> telephones;
@Size(min = 3, max = 50)
@Pattern(regexp = "([A-Za-z])*", message = "The position contains invalid characters")
private String position;
Mapper
@Mapper(componentModel = "spring")
@Component
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
UserRegistrationDTO userToDto(User user);
User dtoToUser(UserRegistrationDTO registrationDTO);
}
Service
@Service
public class UserService implements UserDetailsService {
@Autowired
private final UserRepository userRepository;
UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
private final Logger log = Logger.getLogger(UserService.class.getName());
public boolean save(UserRegistrationDTO userRegistrationDTO) {
User user = UserMapper.INSTANCE.dtoToUser(userRegistrationDTO);
user.setRoles(Set.of(Role.ADMIN));
user.setPassword(passwordEncoder().encode(userRegistrationDTO.getPassword()));
userRepository.save(user);
log.log(Level.INFO, "User saved " + userRegistrationDTO.getUsername());
return true;
}
Controller
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/registration")
public String registration(Model model) {
model.addAttribute("newUser", new UserRegistrationDTO());
return "registration";
}
@PostMapping("/registration")
public String registration(@ModelAttribute("newUser") @Valid UserRegistrationDTO userRegistrationDTO,
BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
return "registration";
} else {
boolean isRegistered = userService.save(userRegistrationDTO);
if (isRegistered) {
return "redirect:/user/authorization";
} else {
model.addAttribute("message", "User with this username is already exist");
return "registration";
}
}
}
<b>html</b>
<code lang="html">
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Registration</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<style>
html, body{width:100%; height:100%; margin:0}
.mb-3 {
margin-left: auto;
margin-right: auto;
width: 25%;
}
form{padding:50px}
</style>
</head>
<body>
<div th:replace="~{_header}"></div>
<form th:action="@{/user/registration}" th:object="${newUser}" th:method="POST">
<div style="text-align: center;"><p>Enter your registration details:</p></div>
<div class="mb-3">
<label for="FirstName" class="form-label">First Name</label>
<input type="text" class="form-control" th:field="*{name}" id="FirstName">
<p th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></p>
</div>
<div class="mb-3">
<label for="LastName" class="form-label">Last Name</label>
<input type="text" class="form-control" th:field="*{lastname}" id="LastName">
<p th:if="${#fields.hasErrors('lastname')}" th:errors="*{lastname}"></p>
</div>
<div class="mb-3">
<label for="UserName" class="form-label">Username</label>
<input type="text" class="form-control" th:field="*{username}" id="UserName">
<p th:if="${#fields.hasErrors('username')}" th:errors="*{username}"></p>
</div>
<div class="mb-3">
<label for="Email" class="form-label">Email</label>
<input type="text" class="form-control" th:field="*{email}" id="Email">
<p th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></p>
</div>
<div class="mb-3">
<label for="Password" class="form-label">Password</label>
<input type="text" class="form-control" th:field="*{password}" id="Password">
<p th:if="${#fields.hasErrors('password')}" th:errors="*{password}"></p>
</div>
<div class="mb-3">
<label for="Telephones" class="form-label">Telephone</label>
<input type="text" class="form-control" th:field="*{telephones}" id="Telephones">
<p th:if="${#fields.hasErrors('telephones')}" th:errors="*{telephones}"></p>
</div>
<div class="mb-3">
<label for="Position" class="form-label">Position</label>
<input type="text" class="form-control" th:field="*{position}" id="Position">
<p th:if="${#fields.hasErrors('position')}" th:errors="*{position}"></p>
</div>
<div style="text-align:center"><button class="btn btn-secondary">Registration</button></div>
</form>
</code>