I am working on an spring boot application which deals with distribution management. There are 3 types of user who will interact with the system - admin, distributor and retailer.
- There can be only one administrator of a company.
- There can be only one distributor in a city of a particular company.
- Retailer can be linked with with distributors of different companies of a specific city.
Now, for this stuff. I have created 5 classes - User, Role, Administrator, Distributor, and Retailer. Can please anyone suggest me that how should I approach this problem with respect to designing the required classes. I tried initially but still I am thinking that this classes structure is complex in itself. Is there something which I am missing out or is there any design pattern which can make things quite more understable ??
@Entity
@Table(name = "tbl_User")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long userId;
@NotNull(message = "first Name cannot be null")
@Column(name = "first_Name")
private String firstName;
@NotNull(message = "last Name cannot be null")
@Column(name = "last_Name")
private String lastName;
@ManyToOne()
@JoinColumn(name = "role_Id")
private Role role;
@NotNull
@Size(min = 10, max = 10, message = "Contact must be of 10 characters")
@Column(name = "contact")
private String contact;
@NotNull
@Email(message = "Email should be valid")
@Column(name = "email", unique = true)
private String email;
@NotNull
@Size(min = 10, max = 255,
message = "Local address must be between 10 and 255 characters")
@Column(name = "local_Address")
private String localAddress;
@ManyToOne()
@JoinColumn(name = "city_Id")
private City city;
@NotNull
@Column(name = "user_Name")
private String userName;
@NotNull
@Column(name = "password")
private String password;
@Column(name = "registered_On")
private LocalDateTime registeredOn;
@Column(name = "updated_On")
private LocalDateTime updatedOn;
@Column(name = "approved_By")
private Long approvedBy;
@NotNull
@Size(min = 1, max = 1,
message = "Approval status must be of 1 character.")
@Column(name = "approval_Status")
private String approvalStatus;
@NotNull
@Column(name = "active_Status")
private boolean activeStatus;
@Transient
private Company company;
}
@Entity
@Table(name = "tbl_Administrator")
public class Admin {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int adminId;
@OneToOne()
@JoinColumn(name = "user_Id")
private User user;
@OneToOne()
@JoinColumn(name = "company_Id")
private Company company;
}
@Entity
@Table(name = "tbl_Distributor")
public class Distributor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long distributorId;
@OneToOne()
@JoinColumn(name = "user_Id")
private User user;
@ManyToOne()
@JoinColumn(name = "company_Id")
private Company company;
}
@Entity
@Table(name = "tbl_Retailer")
public class Retailer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long retailerId;
@OneToOne()
@JoinColumn(name = "user_Id")
private User user;
}
CodePudding user response:
I would go with a @MappedSuperclass
instead of making User
and entity itself. Basically, Admin
, Distributor
and Retailer
would extend this mapped superclass. A separate table for each is created but no table is created for the superclass (User
) itself.
@MappedSuperclass
public class User {
// Your properties
}
@Entity
@Table(name = "tbl_Administrator")
public class Admin extends User {
@OneToOne()
@JoinColumn(name = "company_Id")
private Company company;
}
@Entity
@Table(name = "tbl_Distributor")
public class Distributor extends User {
@ManyToOne()
@JoinColumn(name = "company_Id")
private Company company;
}
@Entity
@Table(name = "tbl_Retailer")
public class Retailer extends User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long retailerId;
}
You have other possibilities (read more at https://medium.com/analytics-vidhya/jpa-hibernate-entity-inheritance-1f6aa7ea2eea), such as the following:
- Single table for all entities
- Separate tables for superclass and subclass. The properties defined in the superclass are not included in the tables of the subclass.
- Table per class, which is similar to the Mapped Superclass with the difference that the Superclass also has a corresponding table.
Still, I would go with the Mapped Superclass one as described.