CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-immutables--immutables

Comprehensive Java annotation processing framework for generating immutable value objects, marshalers, repositories, and custom code generators with extensive integration support.

Pending
Overview
Eval results
Files

bean-style.mddocs/

Bean Style Support

Annotations for generating bean-style accessors and applying conservative coding conventions for enterprise environments. These annotations help integrate Immutables with frameworks that expect JavaBean conventions.

Capabilities

Bean-Style Accessors

Generate bean-style accessor methods with get and is prefixes.

/**
 * Generate bean-style accessor naming with get/is prefixes.
 * Transforms accessor methods to follow JavaBean conventions
 * for compatibility with frameworks expecting bean-style naming.
 */
@Target({ElementType.TYPE, ElementType.PACKAGE})
@Retention(RetentionPolicy.SOURCE)
@interface BeanStyle.Accessors {}

Usage Example:

import org.immutables.value.Value;
import org.immutables.value.BeanStyle;
import java.util.List;

@Value.Immutable
@BeanStyle.Accessors
public interface Person {
  String getName();      // Already bean-style
  int getAge();          // Already bean-style
  boolean isActive();    // Already bean-style
  List<String> getTags(); // Already bean-style
}

// Generated implementation has bean-style accessors
Person person = ImmutablePerson.builder()
    .name("Alice")      // Builder uses simple names
    .age(30)
    .active(true)
    .addTags("developer", "java")
    .build();

// Accessors follow bean conventions
String name = person.getName();
int age = person.getAge();
boolean active = person.isActive();
List<String> tags = person.getTags();

Conservative Bean Style

Apply conservative bean-style conventions with private implementation and constructor-based builders.

/**
 * Apply conservative bean-style conventions.
 * Combines bean-style accessors, setter-style initialization,
 * private implementation visibility, and constructor-based builders
 * for maximum enterprise framework compatibility.
 */
@Target({ElementType.TYPE, ElementType.PACKAGE})
@Retention(RetentionPolicy.SOURCE)
@interface BeanStyle.Conservative {}

Usage Example:

import org.immutables.value.Value;
import org.immutables.value.BeanStyle;
import java.util.Optional;

@Value.Immutable
@BeanStyle.Conservative
public interface Employee {
  String getName();
  String getEmail();
  String getDepartment();
  boolean isActive();
  Optional<String> getManagerId();
}

// Conservative style generates:
// - Bean-style accessors (getName(), getEmail(), etc.)
// - Setter-style builder methods (setName(), setEmail(), etc.)
// - Private implementation class
// - Constructor-based builder pattern

// Usage with conservative style
Employee employee = ImmutableEmployee.builder()
    .setName("Alice Smith")        // Setter-style builder
    .setEmail("alice@company.com")
    .setDepartment("Engineering")
    .setActive(true)
    .setManagerId("mgr123")
    .build();

// Bean-style accessors
String name = employee.getName();
String email = employee.getEmail();
boolean active = employee.isActive();

Generated Features

Bean-Style Accessor Patterns

When @BeanStyle.Accessors is applied:

// Original interface
@Value.Immutable
@BeanStyle.Accessors
public interface UserData {
  String username();     // Becomes getUsername()
  int score();          // Becomes getScore()
  boolean verified();   // Becomes isVerified()
  List<String> roles(); // Becomes getRoles()
}

// Generated implementation
public final class ImmutableUserData implements UserData {
  public String getUsername() { ... }
  public int getScore() { ... }
  public boolean isVerified() { ... }
  public List<String> getRoles() { ... }
}

Conservative Style Features

When @BeanStyle.Conservative is applied, it combines multiple style settings:

// Equivalent to:
@Value.Style(
    get = {"get*", "is*"},           // Bean-style accessors
    init = "set*",                   // Setter-style builder methods
    visibility = ImplementationVisibility.PRIVATE,  // Private implementation
    typeBuilder = "*Builder"         // Constructor-based builder
)
@Value.Immutable
public interface ConservativeType {
  // ... methods
}

Framework Integration Examples

Spring Framework Integration

@Value.Immutable
@BeanStyle.Conservative
@Component
public interface ApplicationConfig {
  @Value("${app.name}")
  String getName();
  
  @Value("${app.version}")
  String getVersion();
  
  @Value("${app.debug:false}")
  boolean isDebugEnabled();
  
  @Value("${app.features}")
  List<String> getEnabledFeatures();
}

// Spring can inject values using bean-style setters in builder
@Configuration
public class ConfigurationSetup {
  @Bean
  public ApplicationConfig appConfig(
      @Value("${app.name}") String name,
      @Value("${app.version}") String version,
      @Value("${app.debug:false}") boolean debug,
      @Value("${app.features}") List<String> features) {
    
    return ImmutableApplicationConfig.builder()
        .setName(name)
        .setVersion(version)
        .setDebugEnabled(debug)
        .setEnabledFeatures(features)
        .build();
  }
}

Jackson Bean Integration

@Value.Immutable
@BeanStyle.Accessors
@Jackson.Mapped
@JsonIgnoreProperties(ignoreUnknown = true)
public interface ApiResponse {
  @JsonProperty("response_code")
  int getResponseCode();
  
  @JsonProperty("message")
  String getMessage();
  
  @JsonProperty("success")
  boolean isSuccess();
  
  @JsonProperty("data")
  Optional<Object> getData();
}

// Jackson recognizes bean-style accessors
ObjectMapper mapper = new ObjectMapper();
String json = "{'response_code':200,'message':'OK','success':true}";
ApiResponse response = mapper.readValue(json, ApiResponse.class);

JPA/Hibernate Integration

@Value.Immutable
@BeanStyle.Conservative
@Entity
@Table(name = "users")
public interface UserEntity {
  @Id
  @Column(name = "user_id")
  String getId();
  
  @Column(name = "username", nullable = false)
  String getUsername();
  
  @Column(name = "email", nullable = false)
  String getEmail();
  
  @Column(name = "active")
  boolean isActive();
  
  @OneToMany(mappedBy = "user")
  List<Role> getRoles();
}

// Conservative style works with JPA frameworks that expect
// bean-style accessors and constructor patterns

Package-Level Configuration

Apply bean styles to entire packages via package-info.java:

// package-info.java
@BeanStyle.Conservative
package com.example.model;

import org.immutables.value.BeanStyle;

This applies conservative bean style to all immutable types in the package.

Migration from JavaBeans

Bean-style annotations help migrate from traditional mutable JavaBeans:

// Traditional JavaBean
public class LegacyUser {
  private String name;
  private int age;
  private boolean active;
  
  // Getters and setters...
  public String getName() { return name; }
  public void setName(String name) { this.name = name; }
  // ... etc
}

// Immutable replacement
@Value.Immutable
@BeanStyle.Conservative
public interface User {
  String getName();
  int getAge();
  boolean isActive();
}

// Usage maintains similar patterns
User user = ImmutableUser.builder()
    .setName("Alice")      // Similar to setName()
    .setAge(30)            // Similar to setAge()
    .setActive(true)       // Similar to setActive()
    .build();

String name = user.getName();  // Same as JavaBean

Performance Considerations

  • Bean-style accessors: No performance overhead - only naming changes
  • Conservative style: Slightly more method dispatch due to builder patterns
  • Framework compatibility: Enables efficient integration with bean-expecting frameworks
  • Code generation: Bean styles are compile-time transformations with no runtime cost

Install with Tessl CLI

npx tessl i tessl/maven-org-immutables--immutables

docs

attributes.md

bean-style.md

code-generation.md

collections.md

core-immutable.md

index.md

integrations.md

json-marshaling.md

runtime-marshaling.md

styling.md

tile.json