11package com .codesungrape .hmcts .bookapi .entity ;
22
3- import jakarta .persistence .*;
4- import java .util .UUID ;
5- import lombok .*;
3+ import jakarta .persistence .Column ;
4+ import jakarta .persistence .Entity ;
5+ import jakarta .persistence .GeneratedValue ;
6+ import jakarta .persistence .GenerationType ;
7+ import jakarta .persistence .Id ;
8+ import jakarta .persistence .PrePersist ;
9+ import jakarta .persistence .PreUpdate ;
10+ import jakarta .persistence .Table ;
611import java .time .Instant ;
12+ import java .util .UUID ;
13+ import lombok .AccessLevel ;
14+ import lombok .AllArgsConstructor ;
15+ import lombok .Builder ;
16+ import lombok .Getter ;
17+ import lombok .NoArgsConstructor ;
18+ import lombok .Setter ;
719
820/**
9- * JPA Entity representing the Book table in PostgreSQL.
10- * This holds the persisted state of the resource.
11- * HMCTS Rule Check: IDs must be opaque strings. Using UUID for distributed ID generation.
12- * @Entity: Marks the class as a JPA entity - tells hibernate to map Java classes to database tables.
13- * @Table: Defines which database table this entity maps to. HMCTS Naming: Lowercase, singular table name is common practice.
14- * Lombok annotations:
15- * @Getter: Automatically generates getters for all fields.
16- * @Setter: Automatically generates setters.
17- * @AllArgsConstructor: Generates a no-argument constructor (required by JPA).
18- * JPA needs to instantiate the entity using reflection. 'PROTECTED' prevents misuse.
19- * @Builder: Adds a builder pattern for clean object creation.
20- * You can do Book.builder().title("A").author("B").build();
21+ * Represents the Book table in PostgreSQL as a JPA entity.
22+ * Stores the persisted state of a Book resource.
23+ * HMCTS Rule: IDs must be opaque; using UUID for distributed ID generation.
24+ *
25+ * @Entity: Marks the class as a JPA entity for Hibernate table mapping.
26+ * @Table: Specifies the database table; HMCTS: lowercase, singular table name.
27+ * Lombok Annotations:
28+ * @Getter: Generates getters for all fields.
29+ * @Setter: Generates setters for all fields.
30+ * @NoArgsConstructor: Protected no-arg constructor for JPA instantiation.
31+ * @AllArgsConstructor: Constructor with all fields for test convenience.
32+ * @Builder: Adds builder pattern for easy object creation.
33+ * Example: Book.builder()
34+ * .title("A")
35+ * .author("B")
36+ * .build();
2137 */
2238@ Entity
2339@ Table (name = "book" )
2844@ Builder // For convenience in creating instances
2945public class Book {
3046
31- @ Id // Primary key of the table
32- @ GeneratedValue (strategy = GenerationType .UUID )
33- @ Column (name = "id" , nullable = false ) // maps the field to a database column named 'id' + 'nullable =false' database column cannot be NULL.
34- private UUID id ;
35-
36- @ Column (name = "title" , nullable = false )
37- private String title ;
38-
39- @ Column (name = "synopsis" , nullable = false , columnDefinition = "TEXT" )
40- private String synopsis ;
47+ @ Id // Primary key of the table
48+ @ GeneratedValue (strategy = GenerationType .UUID )
49+ @ Column (name = "id" , nullable = false )
50+ private UUID id ;
4151
42- @ Column (name = "author " , nullable = false )
43- private String author ;
52+ @ Column (name = "title " , nullable = false )
53+ private String title ;
4454
45- // Soft delete - makes DELETE operations idempotent (safe to repeat)
46- // Soft delete - using @Builder.Default to ensure the builder
47- // respects this initialization if the field is not set explicitly.
48- @ Column (name = "deleted" , nullable = false )
49- @ Builder .Default
50- private boolean deleted = false ;
55+ @ Column (name = "synopsis" , nullable = false , columnDefinition = "TEXT" )
56+ private String synopsis ;
5157
52- // `createdAt` is null upon object creation.
53- // It will be set by the `onCreate()` method right before persistence.
54- @ Column (name = "created_at" , nullable = false , updatable = false )
55- private Instant createdAt ;
58+ @ Column (name = "author" , nullable = false )
59+ private String author ;
5660
57- @ Column (name = "modified_at" )
58- private java .time .Instant modifiedAt ;
61+ // Soft delete - makes DELETE operations idempotent (safe to repeat)
62+ // Using @Builder.Default to ensure the builder respects this initialization
63+ // if the field is not set explicitly.
64+ @ Column (name = "deleted" , nullable = false )
65+ @ Builder .Default
66+ private boolean deleted = false ;
5967
60- // --- JPA lifecycle callbacks ---
61- @ PrePersist
62- protected void onCreate () {
63- this .createdAt = java .time .Instant .now ();
64- }
68+ // `createdAt` is null upon object creation.
69+ // It will be set by the `onCreate()` method right before persistence.
70+ @ Column (name = "created_at" , nullable = false , updatable = false )
71+ private Instant createdAt ;
6572
66- // --- Business Logic Helper ---
67- // HMCTS mandates business logic in services, but a setter hook is acceptable.
68- // Lifecycle callback - special method runs automatically before Hibernate updates a record in the database.
69- @ PreUpdate
70- protected void onUpdate () {
73+ @ Column (name = "modified_at" )
74+ private Instant modifiedAt ;
7175
72- this .modifiedAt = java .time .Instant .now ();
73- }
76+ // --- JPA lifecycle callbacks ---
77+ /**
78+ * Sets createdAt before persisting a new Book record.
79+ */
80+ @ PrePersist
81+ protected void onCreate () {
82+ this .createdAt = Instant .now ();
83+ }
7484
85+ // --- Business Logic Helper ---
86+ // HMCTS requires business logic to live in services; setter hooks are allowed.
87+ // Lifecycle callback: runs automatically before Hibernate updates a database record.
7588
76- }
89+ /**
90+ * Updates modifiedAt before updating an existing Book record.
91+ */
92+ @ PreUpdate
93+ protected void onUpdate () {
94+ this .modifiedAt = Instant .now ();
95+ }
96+ }
0 commit comments