How to create a new Entity Type
This guide outlines the process of creating a new entity type in FFQMS by extending the base entity system. In this case, we will see and example of Manufacturer
entity class, which defines attributes and relationships that will be persisted in the database. This is similar to creating entity types in TypeScript, but tailored for Java, Hibernate, and JPA.
Manufacturer Entity Class
The Manufacturer
class extends the base entity class and defines the structure for manufacturer-related data, including relationships with other entities like ManufacturerDoc
, ManufacturerCategory
, and Address
.
Key Annotations:
@Entity
: Marks the class as a JPA entity, which means it will be mapped to a database table.@Getter
,@Setter
: Lombok annotations to automatically generate getter and setter methods for all fields.@AllArgsConstructor
and@NoArgsConstructor
: Generate constructors with and without arguments.@SQLDelete
and@Where
: Soft delete functionality, ensuring theManufacturer
is not deleted from the database but marked as deleted.@Id
and@GeneratedValue
: Mark the primary key and define auto-increment behavior.@OneToMany
,@OneToOne
, and@ManyToMany
: Define relationships with other entities.
Example: Manufacturer Class
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@SQLDelete(sql = "UPDATE manufacturer SET is_deleted = true WHERE id = ?", check = ResultCheckStyle.COUNT)
@Where(clause = "is_deleted is null or is_deleted <> true")
public class Manufacturer extends Base {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String type;
private Boolean accreditedByAgency;
private VendorType vendorType;
private String agencyName;
private String licenseNumber;
private Double totalScore;
@Column(name = "is_raw_materials_procured", columnDefinition = "tinyint(1) default 0")
private Boolean isRawMaterialsProcured = false;
private String externalManufacturerId;
// One-to-Many relationship with ManufacturerDoc
@OneToMany(mappedBy = "manufacturer", cascade = CascadeType.ALL, orphanRemoval = true)
@ToString.Exclude
private Set<ManufacturerDoc> manufacturerDocs = new HashSet<>();
// One-to-Many relationship with ManufacturerCategory
@OneToMany(mappedBy = "manufacturer", cascade = CascadeType.ALL, orphanRemoval = true)
@ToString.Exclude
private Set<ManufacturerCategory> manufacturerCategories = new HashSet<>();
// One-to-One relationship with Address
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "address_id", referencedColumnName = "id")
private Address address;
private Boolean licenseStatus;
@JsonIgnore
@OneToMany(mappedBy = "manufacturer", cascade = CascadeType.ALL, orphanRemoval = true)
@ToString.Exclude
private Set<User> users = new HashSet<>();
// Many-to-Many relationships with other manufacturers (source/target mappings)
@ManyToMany(cascade = CascadeType.DETACH)
@JoinTable(name = "Manufacturer_source_mapping",
joinColumns = {@JoinColumn(name = "source_manufacturer_id")},
inverseJoinColumns = {@JoinColumn(name = "target_manufacturer_id")}
)
private Set<Manufacturer> targetManufacturers;
@ManyToMany(cascade = CascadeType.DETACH)
@JoinTable(name = "material_manufacturer_mapping",
joinColumns = {@JoinColumn(name = "target_manufacturer_id")},
inverseJoinColumns = {@JoinColumn(name = "source_manufacturer_id")}
)
private Set<Manufacturer> sourceManufacturers;
private ManufacturerType manufacturerType;
// One-to-Many relationship with ManufacturerCategoryAttributes
@OneToMany(mappedBy = "manufacturer", cascade = CascadeType.ALL, orphanRemoval = true)
@OrderBy(value = "id DESC")
@ToString.Exclude
private Set<ManufacturerCategoryAttributes> manufacturerAttributes = new HashSet<>();
// One-to-Many relationship with ManufacturerProperty
@OneToMany(mappedBy = "manufacturer", cascade = CascadeType.ALL, orphanRemoval = true)
@ToString.Exclude
@OrderBy(value = "id desc")
private Set<ManufacturerProperty> manufacturerProperties = new HashSet<>();
public Manufacturer(Long id) {
this.id = id;
}
}
Key Features
Soft Delete: The entity uses
@SQLDelete
and@Where
annotations to handle soft deletion. Instead of removing records, the entity is marked as deleted by updating theis_deleted
flag.Relationships: This entity has multiple relationships:
One-to-Many
withManufacturerDoc
,ManufacturerCategory
,ManufacturerCategoryAttributes
, andManufacturerProperty
.One-to-One
withAddress
.Many-to-Many
with otherManufacturer
entities for source and target mappings.
Custom Fields: Attributes like
name
,type
,vendorType
,totalScore
, andlicenseStatus
represent the core business data for a manufacturer. Some fields, likeisRawMaterialsProcured
, have default values specified in the column definition.
Best Practices
Entity Definition: Keep business logic separate from persistence logic. The entity class should define attributes but not handle database operations directly.
Relationships: Carefully define relationships with cascading behavior (
CascadeType.ALL
) andorphanRemoval
to automatically manage related entities when performing operations on theManufacturer
entity.Data Integrity: Use
@JoinColumn
,@OrderBy
, and@Column
annotations to enforce data integrity and control how data is stored and retrieved.
Conclusion
The entity class uses JPA annotations to map the entity to a database table, including fields, relationships, and soft delete logic, making it a flexible and scalable part of a larger system.
Last updated