# Java Spring Enterprise

> >

- **Type:** Skill
- **Install:** `agentstack add skill-iambrzdev-enterprise-agent-skills-java-spring-enterprise`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [iamBrzDev](https://agentstack.voostack.com/s/iambrzdev)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [iamBrzDev](https://github.com/iamBrzDev)
- **Source:** https://github.com/iamBrzDev/enterprise-agent-skills/tree/main/skills/java-spring-enterprise

## Install

```sh
agentstack add skill-iambrzdev-enterprise-agent-skills-java-spring-enterprise
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

## When to activate

- Scaffolding a new Spring Boot enterprise project
- "How do I structure this feature?" in a Java/Spring context
- Designing a service layer, use case, or domain model
- Configuring `@Transactional` — any question about transactions, isolation, or rollback
- Setting up HikariCP connection pool tuning
- Implementing Virtual Threads (Java 21+) for I/O-heavy operations
- Adding observability: Micrometer, Prometheus, Grafana, OpenTelemetry tracing
- Refactoring a fat controller or a service with too many responsibilities
- Any mention of Hexagonal Architecture, ports/adapters, DDD, or use cases in Java

## Rules — Non-negotiable

1. **No business logic in controllers.** Controllers receive HTTP input,
   delegate to a use case or service, and return a response. Nothing else.

2. **Domain layer has zero Spring dependencies.** Entities and domain services
   must not import Spring annotations. Domain is framework-agnostic.

3. **`@Transactional` is not a default annotation.** Apply it deliberately,
   with the correct isolation level. Add `readOnly = true` for all read operations.

4. **Never expose domain entities in API responses.** Always map to DTOs or
   response records before returning from the controller.

5. **HikariCP pool size must be tuned explicitly.** The default pool size (10)
   is wrong for most enterprise workloads. Always configure based on load profile.

## Project Structure — Clean / Hexagonal Architecture

```
src/main/java/com/company/app/
├── domain/
│   ├── model/              # Entities, Value Objects, Aggregates — NO Spring here
│   ├── port/
│   │   ├── in/             # Use case interfaces (driving ports)
│   │   └── out/            # Repository + external service interfaces (driven ports)
│   └── service/            # Domain services — pure business logic
│
├── application/
│   └── usecase/            # Use case implementations — orchestrate domain + ports
│       ├── CreateOrderUseCase.java
│       └── GetOrderByIdUseCase.java
│
├── adapter/
│   ├── in/
│   │   └── web/            # Controllers, request/response DTOs, mappers
│   └── out/
│       ├── persistence/    # JPA entities, repositories (Spring Data)
│       └── external/       # HTTP clients, message producers
│
└── config/                 # Spring configuration, beans, security
```

### Dependency direction
```
adapter/in → application → domain ← application ← adapter/out
```
Domain knows nothing about adapters. Application knows nothing about HTTP or JPA.

## Use Case Pattern

Every feature is a use case. Controllers call use cases, not services directly.

```java
// domain/port/in/CreateOrderUseCase.java
public interface CreateOrderUseCase {
    OrderResponse execute(CreateOrderCommand command);
}

// application/usecase/CreateOrderUseCaseImpl.java
@Service
@RequiredArgsConstructor
public class CreateOrderUseCaseImpl implements CreateOrderUseCase {

    private final OrderRepository orderRepository;   // port/out — interface
    private final InventoryPort inventoryPort;        // port/out — interface

    @Override
    @Transactional
    public OrderResponse execute(CreateOrderCommand command) {
        // 1. Validate domain rules
        // 2. Call domain service if needed
        // 3. Persist via output port
        // 4. Return mapped response
    }
}

// adapter/in/web/OrderController.java
@RestController
@RequestMapping("/api/v1/orders")
@RequiredArgsConstructor
public class OrderController {

    private final CreateOrderUseCase createOrderUseCase;

    @PostMapping
    public ResponseEntity create(@Valid @RequestBody CreateOrderRequest request) {
        CreateOrderCommand command = OrderMapper.toCommand(request);
        return ResponseEntity.status(HttpStatus.CREATED)
            .body(createOrderUseCase.execute(command));
    }
}
```

## @Transactional — Correct Usage

```java
// ✅ Write operation — transactional with default isolation
@Transactional
public OrderResponse createOrder(CreateOrderCommand command) { ... }

// ✅ Read operation — always readOnly = true (avoids dirty checks, improves performance)
@Transactional(readOnly = true)
public OrderResponse getOrderById(Long id) { ... }

// ✅ Explicit isolation for financial operations
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void processPayment(PaymentCommand command) { ... }

// ❌ Never annotate entire class as @Transactional without understanding the blast radius
@Transactional          // BAD — every method gets a transaction, including reads
public class OrderService { ... }

// ❌ Never catch and swallow exceptions inside a @Transactional method
@Transactional
public void createOrder(CreateOrderCommand command) {
    try { ... }
    catch (Exception e) { log.error("failed"); }  // BAD — transaction won't roll back
}
```

## Virtual Threads (Java 21+)

For I/O-intensive applications, replace platform thread pools with Virtual Threads:

```java
// config/ThreadConfig.java
@Configuration
public class ThreadConfig {

    @Bean
    public TomcatProtocolHandlerCustomizer virtualThreadsProtocolHandler() {
        return protocolHandler ->
            protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
    }
}

// Or via application.yml (Spring Boot 3.2+)
// spring:
//   threads:
//     virtual:
//       enabled: true
```

**When to use Virtual Threads:**
- ✅ REST APIs with high concurrency and blocking I/O (DB calls, HTTP clients)
- ✅ Applications doing many simultaneous external service calls
- ❌ CPU-bound workloads (image processing, heavy computation) — no benefit

## HikariCP — Connection Pool Tuning

```yaml
# application.yml
spring:
  datasource:
    hikari:
      maximum-pool-size: 20          # Start here; tune based on DB capacity
      minimum-idle: 5
      connection-timeout: 3000       # 3s — fail fast, don't queue forever
      idle-timeout: 600000           # 10 min
      max-lifetime: 1800000          # 30 min — less than DB's wait_timeout
      pool-name: HikariPool-Enterprise
      # With Virtual Threads: keep pool-size conservative
      # DB connections saturate before virtual threads do
```

```java
// Always validate pool configuration on startup
@Component
@Slf4j
public class DataSourceHealthCheck {

    @EventListener(ApplicationReadyEvent.class)
    public void logPoolConfig(ApplicationReadyEvent event) {
        // Log effective pool size to verify configuration was applied
    }
}
```

## Observability — Micrometer + OpenTelemetry

```xml

    io.micrometer
    micrometer-registry-prometheus

    io.micrometer
    micrometer-tracing-bridge-otel

    io.opentelemetry
    opentelemetry-exporter-otlp

```

```yaml
# application.yml
management:
  endpoints:
    web:
      exposure:
        include: health, info, prometheus, metrics
  metrics:
    distribution:
      percentiles-histogram:
        http.server.requests: true    # Enables P50/P95/P99 latency histograms
  tracing:
    sampling:
      probability: 1.0               # 100% in dev; reduce to 0.1 in prod
```

```java
// Custom business metric example
@Service
@RequiredArgsConstructor
public class OrderMetrics {

    private final MeterRegistry meterRegistry;

    public void recordOrderCreated(String channel) {
        meterRegistry.counter("orders.created", "channel", channel).increment();
    }
}
```

## Common mistakes

- ❌ Calling repositories directly from controllers
- ✅ Controllers → Use Cases → Repositories (always through the port interface)

- ❌ `@Transactional` on a `private` method (Spring proxy won't intercept it)
- ✅ `@Transactional` only on `public` methods of Spring-managed beans

- ❌ Setting `maximum-pool-size: 100` without checking DB max connections
- ✅ Pool size = (DB max connections / number of app instances) × 0.8

- ❌ Returning `Optional` from controllers
- ✅ Map to response DTO inside the use case; throw domain exception if not found

- ❌ Placing `@Entity` JPA classes inside the `domain/model/` package
- ✅ JPA entities live in `adapter/out/persistence/`; domain model is pure Java

## Definition of Done

A feature built with this skill is complete only when:

- [ ] Business logic lives exclusively in domain services or use cases
- [ ] Controller delegates to a use case interface — not a concrete service
- [ ] All write operations have `@Transactional`; all reads have `readOnly = true`
- [ ] API response uses a DTO/record — no domain entity leaking through HTTP
- [ ] HikariCP pool size is explicitly configured (not default)
- [ ] At least one custom Micrometer metric or trace exists for the new feature
- [ ] Domain model has no Spring imports

## Reference files

Load on demand:
- `references/hexagonal-architecture-full.md` — full project scaffold with all layers
- `references/transaction-patterns.md` — saga pattern, compensation, outbox for distributed transactions
- `references/observability-grafana.md` — Grafana dashboard setup for Spring Boot metrics

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [iamBrzDev](https://github.com/iamBrzDev)
- **Source:** [iamBrzDev/enterprise-agent-skills](https://github.com/iamBrzDev/enterprise-agent-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-iambrzdev-enterprise-agent-skills-java-spring-enterprise
- Seller: https://agentstack.voostack.com/s/iambrzdev
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
