I am working on a Spring Boot app using Jpa and postgresql. It is a booking app that will notify the parties for coming bookings.
I will have 3 user types: Admin, Customer and Employee. enter image description here
I add @OneToOne relation beween User and Customer(Admin and Employee) to have shared PK(Customer PK is FK(User))
@Entity
@Table(name = "userTbl", uniqueConstraints = {@UniqueConstraint(columnNames = "emailAddress")})
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long IID;
@NotEmpty
private String firstName;
@NotEmpty
private String lastName;
....
@OneToOne(mappedBy = "user")
@JsonBackReference
private Admin admin;
@OneToOne()
@JsonBackReference
private Customer customer;
@OneToOne(mappedBy = "user")
@JsonBackReference
private Employee employee;
@Entity
@Table(name = "customer")
public class Customer{
@Id
@Column(name = "USER_ID")
private Long IID;
@OneToOne()
@MapsId
private User user;
private String paymentID;
private String invoice;
same entity classes for admin and employee
When I try to register a new User, I got ‘attempted to assign id from null one-to-one property [com.application.model.Customer.user]. error.
@Service
public class RegisterAuthenticationService {
private final AuthenticationManager authenticationManager;
private final UserRepository userRepository;
private final CustomerRepository customerRepository;
private final PasswordEncoder passwordEncoder;
private final JWTService jwtService;
public RegisterAuthenticationService(AuthenticationManager authenticationManager,
UserRepository userRepository,
CustomerRepository customerRepository,
PasswordEncoder passwordEncoder,
JWTService jwtService) {
this.authenticationManager = authenticationManager;
this.userRepository = userRepository;
this.customerRepository = customerRepository;
this.passwordEncoder = passwordEncoder;
this.jwtService = jwtService;
}
@Transactional
public ResponseEntity<?> registerNewCustomer(UserRegisterRequest registerRequest) {
if (userRepository.existsByEmailAddress(registerRequest.getEmail())) {
return ResponseEntity.badRequest().body("Email used");
}
String type = registerRequest.getType();
if (type == null
|| !(type.toUpperCase(Locale.ROOT).equals("ADMIN")
|| type.toUpperCase(Locale.ROOT).equals("CUSTOMER")
|| type.toUpperCase(Locale.ROOT).equals("EMPLOYEE"))) {
throw new RuntimeException("Invalid role");
}
// TODO: add more sanity check (email, password etc...)
User user = new User(null, registerRequest.getFirstName(),
registerRequest.getLastName(),
registerRequest.getEmail(),
registerRequest.getPhoneNumber(),
UserStatus.PENDING,
UserType.valueOf(registerRequest.getType()),
registerRequest.getGeographicAddress(),
new Date().toString(),
null,
passwordEncoder.encode(registerRequest.getPassword()));
userRepository.save(user);
// is it saved, need to be updated refresh
Long iid = userRepository.getUserByEmailAddress(registerRequest.getEmail()).getIID();
switch (registerRequest.getType().toUpperCase(Locale.ROOT)) {
case "CUSTOMER" -> {
Customer userCustomer = new Customer(iid);
customerRepository.save(userCustomer);
}
case "EMPLOYEE" -> {
// save to employeee
}
default -> {
// save to admin
}
}
return ResponseEntity.ok("User registered successfully");
}
}
Also I have a ManyToMany between Employee and Service and @ManyToOne in Booking (with Customer and employee)
@Entity
@Table(name = "booking")
public class Booking {
@Id
@GeneratedValue
private Long IID;
@ManyToOne
@JoinColumn(name = "customer_id")
private Customer customer;
@ManyToOne
@JoinColumn(name = "employee_id")
private Employee employee;
@ManyToOne
@JoinColumn(name = "service_id")
private Service service;
One idea is to have just one table User, add ‘type’ (customer, admin or employee) and userCharacteristics object to it. This userCharacteristics object will contain the specific properties for an user type. But with this in mind, how to define the relationship in Booking (with customer and employee) and between Employee<->Service?
Sum:
How to design User entities so that I can have 3 types of user, have a relationship between them and relationships of user entities with other entities (like Booking with customer and employee)?
2
Answers
It is because the User in Customer is null
it’s because the customer id is null. you have to make it generate automatically for the customer too.