name: dto-implementation description: > DTO implementation guidelines for the HMIS project. Use when creating or modifying DTOs, writing JPQL constructor queries, implementing DTO-based reports, converting entity code to DTO patterns, or troubleshooting DTO query issues. Covers constructor rules, facade methods, null relationship handling, and navigation patterns. user-invocable: true
DTO Implementation Guidelines
Critical Rules
- NEVER modify existing constructors - only add new ones
- Use direct DTO queries - avoid entity-to-DTO conversion loops
-
JPQL PERSISTED FIELDS ONLY: NEVER use derived properties like
nameWithTitle,age,displayNamein JPQL
Direct DTO Query Pattern
// CORRECT - Direct DTO query from database
String jpql = "SELECT new com.divudi.core.data.dto.StockDTO("
+ "s.id, s.itemBatch.item.name, s.itemBatch.item.code, "
+ "s.itemBatch.retailsaleRate, s.stock, "
+ "s.itemBatch.dateOfExpire, s.itemBatch.batchNo) "
+ "FROM Stock s WHERE ...";
// MUST use findLightsByJpql() with cast
List<StockDTO> dtos = (List<StockDTO>) facade.findLightsByJpql(jpql, params, TemporalType.TIMESTAMP);
// WRONG - Never do entity-to-DTO loops
List<Stock> stocks = stockFacade.findByJpql(sql, params);
List<StockDTO> dtos = new ArrayList<>();
for (Stock stock : stocks) { dtos.add(new StockDTO(stock.getField1(), ...)); }
Navigation Pattern: Use IDs, Not Entities
// CORRECT - IDs and names for navigation
public class OpdSaleSummaryDTO {
private Long categoryId; // For navigation
private String categoryName; // For display
private Long itemId; // For navigation
private String itemName; // For display
private Double total;
}
Null Relationship Handling
Accessing properties through nullable relationships causes silent query failures (0 results, no exception):
// WRONG - Fails silently if cancelledBill is null
"b.cancelledBill.createdAt"
// CORRECT - Use LEFT JOIN
"FROM Bill b LEFT JOIN b.cancelledBill cb "
// Then use cb.createdAt with COALESCE
Constructor Rules
- Always use wrapper types (
Boolean,Integer,Long) for null safety - Parameter count and order must match JPQL SELECT exactly
- Keep existing constructors intact; add new ones
Common Non-Persisted Properties (Cannot Use in JPQL)
| Entity | Non-Persisted | Use Instead |
|---|---|---|
| Person | nameWithTitle | name (or title, name separately) |
| Person | age | dob (calculate in Java) |
| Item | displayName | name |
For complete reference, read developer_docs/dto/implementation-guidelines.md.
chat Comments (0)
Sign in to join the discussion and leave a comment.
Skill Details
GitHub Stars
203
GitHub Forks
126
Created
Mar 2026
Last Updated
3 months ago
development
development architecture patterns
Related Skills
Build your own?
Join 12,000+ developers contributing to the Claude ecosystem.
No comments yet. Be the first to share your thoughts!