Domain class for the entity

In the src/main/java/com/mycompany/store/domain folder, you will find the entity domain object. Open Product.java:

@ApiModel(description = "Product sold by the Online store")
@Entity
@Table(name = "product")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Product implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotNull
@Column(name = "name", nullable = false)
private String name;

@Column(name = "description")
private String description;

@Lob
@Column(name = "image")
private byte[] image;

@Column(name = "image_content_type")
private String imageContentType;

@NotNull
@DecimalMin(value = "0")
@Column(name = "price", precision=10, scale=2, nullable = false)
private BigDecimal price;

@NotNull
@Enumerated(EnumType.STRING)
@Column(name = "jhi_size", nullable = false)
private Size size;

@ManyToOne
private ProductCategory productCategory;

// jhipster-needle-entity-add-field - JHipster will add fields
here, do not remove

... // getters

public Product name(String name) {
this.name = name;
return this;
}

... // setters

// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove

... // equals, hashcode and toString methods
}

The entity class defines the fields and relationships.

@ApiModel(description = "Product sold by the Online store")

This annotation is used by Swagger to show useful documentation when the entity is used in an endpoint:

@Entity
@Table(name = "product")

These are JPA annotations declaring the POJO as an entity and mapping it to an SQL table:

@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)

This is a Hibernate annotation, which lets us enable level 2 cache for this entity. In our case using Hazelcast:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

The id field is special and is mapped as a generated value field. Depending on the DB, this field will use a native generation technique or a sequence provided by Hibernate. Since we are using MySQL, it will use the native DB primary key generation technique:

@Column(name = "name", nullable = false)

This JPA annotation is used to map columns to fields and it can also be used to declare properties such as nullable, precision, scale, unique, and so on for the field:

@NotNull
@DecimalMin(value = "0")

These are Bean validation annotations enabling validation for the fields:

@Lob
@Column(name = "image")
private byte[] image;

@Column(name = "image_content_type")
private String imageContentType;

The image field is a Blob and it is marked by the Lob type since we are using MySQL. It also has an additional field to hold the content type information:

@Enumerated(EnumType.STRING)

The Enumerated annotation is used to map Enum fields. These are stored as simple varchar fields in the DB:

@ManyToOne
private ProductCategory productCategory;

The relationships are mapped using annotations such as @ManyToOne, @OneToMany, @OneToOne, and @ManyToMany.

Here, ProductCategory is mapped as ManyToOne; on the other side of the relationship Product is mapped as OneToMany as shown here:

@OneToMany(mappedBy = "productCategory")
@JsonIgnore
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Product> products = new HashSet<>();

As you can see, the relationship also specifies a cache for it. It tells Jackson to ignore the field while converting to JSON to avoid a circular reference since ProductCategory is already mapped in Product entity:

public Product name(String name) {
this.name = name;
return this;
}

This is a fluent setter generated by default along with the standard setter. This can be turned off by specifying the noFluentMethod for the entity in JDL. Fluent methods are handy as they let us chain setters as follows for more concise code:

new Product().name("myProduct").price(10);

The corresponding table definitions and constraints are created using Liquibase and can be found in src/main/resources/config/liquibase/changelog with the file names <timestamp>_added_entity_Product and <timestamp>_added_entity_constraints_Product.xml, which automatically get applied to the database when we reload or start the application again.