Agent skill

dto-implementation

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.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/dto-implementation

SKILL.md

DTO Implementation Guidelines

Critical Rules

  1. NEVER modify existing constructors - only add new ones
  2. Use direct DTO queries - avoid entity-to-DTO conversion loops
  3. JPQL PERSISTED FIELDS ONLY: NEVER use derived properties like nameWithTitle, age, displayName in JPQL

Direct DTO Query Pattern

java
// 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);
java
// 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

java
// 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):

java
// 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.

Expand your agent's capabilities with these related and highly-rated skills.

Didn't find tool you were looking for?

Be as detailed as possible for better results