The old model had a significant issue: books had a quantity field that showed how many copies existed, but when someone borrowed a book, there was no way to know which specific copy was borrowed. This created problems when returning books.
A new BookCopy model was created that represents each physical copy of a book:
- BookCopy: Each physical copy of a book
- Book: No longer has a
quantityfield, but has a relationship withBookCopy - Borrow: Now connects to
BookCopyinstead ofBook
-
Book Model:
- Removed the
quantityfield - Added
OneToManyrelationship withBookCopy - Added calculated methods:
getTotalCopies(),getAvailableCopies()
- Removed the
-
BookCopy Model:
copyId: Unique ID for each copybook: Relationship with the bookcopyNumber: Copy number (1, 2, 3, etc.)isAvailable: Whether it's available for borrowingcondition: Condition of the copy
-
Borrow Model:
- Now connects to
BookCopyinstead ofBook - The
BorrowIdusesbookCopyIdinstead ofbookId
- Now connects to
GET /api/book-copies/book/{bookId}- All copies of a bookGET /api/book-copies/book/{bookId}/available- Available copiesGET /api/book-copies/book/{bookId}/available/count- Number of available copiesPOST /api/book-copies/book/{bookId}/add/{quantity}- Add copiesPUT /api/book-copies/{copyId}- Update copyDELETE /api/book-copies/{copyId}- Delete copy
POST /api/migration/create-default-copies- Create default copiesPOST /api/migration/migrate-quantities- Migration from old model
You need to create the BOOK_COPIES table:
CREATE TABLE BOOK_COPIES (
COPY_ID BIGINT AUTO_INCREMENT PRIMARY KEY,
BOOK_ID BIGINT NOT NULL,
COPY_NUMBER INTEGER NOT NULL,
IS_AVAILABLE BOOLEAN NOT NULL DEFAULT TRUE,
CONDITION VARCHAR(50),
FOREIGN KEY (BOOK_ID) REFERENCES BOOKS(BOOK_ID)
);-- Add new column
ALTER TABLE BORROWS ADD COLUMN BOOK_COPY_ID BIGINT;
-- You'll need to migrate existing borrow data manually
-- This is complex and depends on your existing dataCall the endpoint:
POST /api/migration/create-default-copies
This will create a default copy for each book that doesn't have copies.
After migration, you can remove the QUANTITY column from the BOOKS table:
ALTER TABLE BOOKS DROP COLUMN QUANTITY;- Precise tracking: Each copy has its own ID
- Better management: You can track the condition of each copy
- Return problem solution: You know exactly which copy is being returned
- Extensibility: You can add more information for each copy
- The API for borrow/return remains the same (uses
bookId) - The logic automatically finds an available copy for borrowing
- For returns, it finds the correct copy that the user borrowed
- The BookDTO still has a
quantityfield that is calculated from the copies