Skip to content

Java attributes and methods

Rashmika_Harshamal edited this page Jul 20, 2026 · 27 revisions

Java Attributes and Methods in the HMIS System

Java attributes and methods are essential parts of HMIS development.

Attributes store information such as:

  • Patient name
  • Patient code
  • Bill total
  • Created date
  • Department
  • Investigation
  • Report status
  • Retired status

Methods are used to:

  • Read attribute values
  • Change attribute values
  • Validate data
  • Calculate totals
  • Process reports
  • Search database records
  • Clear filters
  • Format information for display

A simple HMIS-style example is:

private String patientCode;
private double total;
private boolean retired;

public String getPatientCode() {
    return patientCode;
}

public void setPatientCode(String patientCode) {
    this.patientCode = patientCode;
}

public double calculateNetTotal(double discount) {
    return total - discount;
}

In this example:

  • patientCode, total, and retired are attributes.
  • getPatientCode(), setPatientCode(), and calculateNetTotal() are methods.

1. Java Attributes

An attribute stores data inside a Java component.

Attributes are also called:

  • Fields
  • Member variables
  • Instance variables
  • Properties, especially when accessed through getters and setters

General syntax:

accessModifier dataType attributeName;

Example:

private String patientName;

Explanation:

  • private is the access modifier.
  • String is the data type.
  • patientName is the attribute name.

HMIS-style attributes:

private Long id;
private String patientCode;
private Date createdAt;
private Department department;
private Investigation investigation;
private boolean retired;
private List<PatientInvestigation> results;

Attribute Declaration

An attribute can be declared without an initial value.

private String patientName;

It can also be declared with an initial value.

private boolean retired = false;

A collection should often be initialized immediately.

private List<PatientInvestigation> results = new ArrayList<>();

This is safer than:

private List<PatientInvestigation> results;

because using an uninitialized list may cause a NullPointerException.

For example:

results.clear();

will fail when results is null.


Attribute Data Types

Attributes may use primitive types or reference types.

Primitive attributes

private int patientCount;
private long recordCount;
private double total;
private boolean retired;
private char categoryCode;

Primitive types cannot contain null.

Reference attributes

private String patientName;
private Date createdAt;
private Department department;
private Investigation investigation;
private List<Bill> bills;

Reference attributes can contain null.


Primitive and Wrapper Attributes

Java provides wrapper classes for primitive types.

Primitive Wrapper
int Integer
long Long
double Double
boolean Boolean
char Character
float Float
short Short
byte Byte

Example:

private boolean retired;
private Boolean approved;

retired can contain:

true
false

approved can contain:

true
false
null

Use primitive types when a value must always exist.

Use wrapper types when the value may be unknown or nullable.

For database query projections and DTO attributes, wrapper types are often safer.

private Long patientCount;
private Double totalAmount;
private Boolean approved;

Default Attribute Values

Java automatically gives default values to attributes.

Attribute type Default value
int 0
long 0L
double 0.0
boolean false
char Unicode zero
Object reference null

Example:

private int count;
private boolean retired;
private String name;

Initial values are approximately:

count = 0
retired = false
name = null

Although Java provides defaults, important attributes should still be initialized clearly when appropriate.

private List<Bill> bills = new ArrayList<>();
private boolean retired = false;

Instance Attributes

An instance attribute stores information specific to one Java component instance.

private String patientName;
private Department department;
private Date fromDate;

Each instance has its own values.

For example, different report controllers may contain different selected dates and departments for different users.

User-specific values should normally be instance attributes.

Correct:

private Patient selectedPatient;

Dangerous:

private static Patient selectedPatient;

A static attribute may be shared across users and can create privacy, concurrency, and data-leak problems.


Static Attributes

A static attribute belongs to the Java type itself and is shared.

private static int reportCount;

A common valid static attribute is a constant.

private static final int DEFAULT_PAGE_SIZE = 50;

Another common attribute is:

private static final long serialVersionUID = 1L;

Avoid using static mutable attributes for:

  • Selected patients
  • Logged-in users
  • Report results
  • Date filters
  • Department selections
  • Patient medical data
  • Bill details

Incorrect:

private static List<Patient> selectedPatients;

Safer:

private List<Patient> selectedPatients = new ArrayList<>();

Final Attributes

A final attribute can be assigned only once.

private final int maximumResults = 100;

Constants usually use static final.

private static final int MAXIMUM_RESULTS = 100;

Naming convention for constants:

UPPER_SNAKE_CASE

Examples:

private static final int DEFAULT_PAGE_SIZE = 50;
private static final String REPORT_TITLE = "Investigation Report";
private static final double TAX_RATE = 0.15;

A final reference cannot be assigned to a different object.

private final List<String> codes = new ArrayList<>();

This is allowed:

codes.add("FBC");

This is not allowed:

codes = new ArrayList<>();

Private Attributes

Attributes should normally be declared private.

private String patientCode;
private Date createdAt;
private Department department;

Benefits:

  • Protects internal data
  • Prevents uncontrolled changes
  • Supports validation through setters
  • Reduces coupling
  • Supports encapsulation
  • Makes maintenance safer

Avoid:

public String patientCode;

Prefer:

private String patientCode;

public String getPatientCode() {
    return patientCode;
}

public void setPatientCode(String patientCode) {
    this.patientCode = patientCode;
}

Protected Attributes

A protected attribute can be accessed:

  • Inside the same Java type
  • Inside the same package
  • Inside child types
protected Long id;

Protected attributes should be used carefully.

In most HMIS code, keeping attributes private and exposing protected or public methods is safer.

Prefer:

private EntityManager entityManager;

protected EntityManager getEntityManager() {
    return entityManager;
}

rather than directly exposing the attribute.


Public Attributes

A public attribute can be accessed from anywhere.

public String name;

Public mutable attributes are generally not recommended.

Problems include:

  • No validation
  • No control over changes
  • Difficult debugging
  • Strong coupling
  • Inconsistent values

Prefer private attributes with getters and setters.


Default-Access Attributes

When no access modifier is written, Java uses package-private access.

String internalCode;

This attribute can be accessed only from the same package.

Package-private access may be useful for internal helper components, but attributes should still normally be private unless package access is intentionally required.


Attribute Naming Conventions

Java attributes use camelCase.

Correct:

private String patientName;
private Date createdAt;
private double netTotal;
private Department collectingCentre;
private List<BillItem> billItems;

Incorrect:

private String PatientName;
private Date created_at;
private double Net_Total;
private Department collectingcentre;

Rules for attribute names

Attribute names should:

  • Begin with a lowercase letter
  • Use camelCase
  • Clearly describe the stored value
  • Avoid unexplained abbreviations
  • Avoid meaningless names
  • Use nouns or noun phrases
  • Use plural names for collections
  • Use positive and clear names for Boolean values

Good:

private Date fromDate;
private Date toDate;
private Department laboratory;
private Investigation investigation;
private List<PatientInvestigation> results;
private boolean retired;

Weak:

private Date d1;
private Date d2;
private Department dep;
private Investigation inv;
private List data;
private boolean flag;

Collection Attribute Naming

Collections should normally use plural names.

Correct:

private List<Bill> bills;
private List<Patient> patients;
private List<Investigation> investigations;
private Set<String> codes;
private Map<String, Object> parameters;

Incorrect:

private List<Bill> bill;
private List<Patient> patient;

The name should communicate that multiple values are stored.


Boolean Attribute Naming

Boolean attribute names should clearly describe a true or false state.

Good:

private boolean retired;
private boolean cancelled;
private boolean active;
private boolean approved;
private boolean printed;
private boolean editable;

Avoid unclear names:

private boolean flag;
private boolean status;
private boolean value;
private boolean check;

Boolean names should allow readable conditions.

if (bill.isCancelled()) {
}
if (report.isEditable()) {
}

Avoid double-negative names.

Confusing:

private boolean notInactive;

Better:

private boolean active;

Date Attribute Naming

Date attributes should clearly describe what the date represents.

Good:

private Date createdAt;
private Date lastEditedAt;
private Date retiredAt;
private Date fromDate;
private Date toDate;
private Date dateOfBirth;
private Date appointmentDate;

Avoid:

private Date date1;
private Date date2;
private Date time;

Use At for timestamps:

createdAt
updatedAt
retiredAt

Use Date when only a date concept is represented:

billDate
appointmentDate
dateOfBirth

Entity Relationship Attributes

HMIS attributes often refer to other entities.

@ManyToOne
private Department department;

@ManyToOne
private Institution institution;

@ManyToOne
private Investigation investigation;

@ManyToOne
private Patient patient;

Relationship attribute names should represent the related object.

Correct:

private Department department;

Avoid:

private Long departmentId;

inside a normal JPA relationship when an entity relationship is required.

A DTO may use an ID:

private Long departmentId;
private String departmentName;

because DTOs are lightweight data carriers.


Persisted Attributes

A persisted attribute is stored in the database.

private String comments;
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
@ManyToOne
private Department department;

Persisted attributes may be used by:

  • JPA
  • Database columns
  • JPQL queries
  • Reports
  • Services
  • XHTML pages
  • Existing integrations

Do not rename or remove existing persisted attributes without checking all usages.

Search for:

  • Java getter and setter calls
  • JPQL attribute references
  • XHTML expressions
  • Database migration scripts
  • DTO projections
  • Reports
  • API integrations

Transient Attributes

A transient JPA attribute is not stored in the database.

@Transient
private String displayName;

It can be used for:

  • Calculated values
  • Temporary display values
  • UI-only data
  • Export-only data

Example:

@Transient
private String ageAsString;

Getter:

public String getAgeAsString() {
    return ageAsString;
}

A calculated attribute may also be returned directly by a method without storing it.

public String getDisplayName() {
    return title + " " + name;
}

JPQL generally cannot query calculated getter-only properties unless they are mapped persistent attributes.


Sensitive Attributes

HMIS contains sensitive healthcare and personal information.

Examples include:

private String patientName;
private String nationalIdentityCardNumber;
private String mobileNumber;
private String address;
private String diagnosis;
private String investigationResult;
private String prescriptionDetails;

Sensitive attributes require careful handling.

Important rules

Do not:

  • Declare them as public
  • Store them in static fields
  • Print them unnecessarily
  • Add them to error messages
  • Include them in toString() without a clear need
  • Log full patient details
  • Expose them through unrelated getters
  • Return them in DTOs that do not require them
  • Store passwords as plain text
  • Include secrets in source code

Bad:

@Override
public String toString() {
    return patientName
            + " "
            + nationalIdentityCardNumber
            + " "
            + diagnosis;
}

Safer:

@Override
public String toString() {
    return patientCode;
}

Logging should avoid unnecessary patient data.

Bad:

logger.info(
        "Patient " + patientName
        + " diagnosis is " + diagnosis
);

Better:

logger.info(
        "Patient record processing completed. Record ID: "
        + patientId
);

Even IDs should only be logged when operationally necessary.


2. Methods

A method is a named block of Java code that performs an operation.

General syntax:

accessModifier returnType methodName(parameters) {
    // method body
}

Example:

public double calculateNetTotal(
        double total,
        double discount) {

    return total - discount;
}

Method components:

Component Example
Access modifier public
Return type double
Method name calculateNetTotal
Parameters double total, double discount
Method body Calculation code
Return statement return total - discount;

Method Naming Conventions

Java methods use camelCase.

Correct:

getPatientName()
setPatientName()
calculateNetTotal()
generateReport()
clearFilters()
findActiveBills()
validateDateRange()

Incorrect:

GetPatientName()
set_patient_name()
Calculate_net_total()
GENERATEREPORT()

Method names should normally begin with a verb.

Examples:

calculateTotal()
findPatient()
loadResults()
saveBill()
deleteRecord()
validateInput()
clearSelection()
formatPatientName()

Avoid meaningless method names:

doIt()
run1()
process2()
abc()
testMethod()

Getter Methods

A getter returns an attribute value.

private String patientCode;

public String getPatientCode() {
    return patientCode;
}

For an object attribute:

private Department department;

public Department getDepartment() {
    return department;
}

For a collection:

private List<PatientInvestigation> results =
        new ArrayList<>();

public List<PatientInvestigation> getResults() {
    return results;
}

Getter naming format:

get + AttributeName

Examples:

getName()
getCreatedAt()
getDepartment()
getInvestigation()
getResults()

Boolean Getter Methods

For a primitive Boolean attribute, the getter usually begins with is.

private boolean retired;

public boolean isRetired() {
    return retired;
}

Examples:

isCancelled()
isActive()
isApproved()
isPrinted()
isEditable()

For a Boolean wrapper attribute, get may be used.

private Boolean approved;

public Boolean getApproved() {
    return approved;
}

Follow the existing HMIS naming convention when editing established code.


Setter Methods

A setter changes an attribute value.

private String patientCode;

public void setPatientCode(String patientCode) {
    this.patientCode = patientCode;
}

Setter naming format:

set + AttributeName

Examples:

setName()
setCreatedAt()
setDepartment()
setInvestigation()
setRetired()

Setters normally return void.


The this Keyword in Setters

The this keyword refers to the current instance attribute.

public void setName(String name) {
    this.name = name;
}

Explanation:

this.name = attribute
name      = method parameter

Without this, both names may refer to the parameter.

Incorrect:

public void setName(String name) {
    name = name;
}

This does not update the attribute.

Correct:

public void setName(String name) {
    this.name = name;
}

Validation in Setter Methods

A setter may validate or normalize input.

public void setDiscount(double discount) {
    if (discount < 0) {
        throw new IllegalArgumentException(
                "Discount cannot be negative"
        );
    }

    this.discount = discount;
}

String normalization:

public void setComments(String comments) {
    this.comments =
            comments == null
                    ? null
                    : comments.trim();
}

However, be careful when modifying existing entity setters.

Existing HMIS workflows may expect raw values or framework behaviour. Major business validation is often better placed in a service or processing method.


Read-Only Attributes

An attribute can be exposed through a getter without a public setter.

private double total;
private double discount;

public double getNetTotal() {
    return total - discount;
}

netTotal is calculated and cannot be changed directly.

Another example:

public boolean isDateRangeValid() {
    return fromDate != null
            && toDate != null
            && !fromDate.after(toDate);
}

This approach protects calculated information.


Calculated Getter Methods

A calculated getter returns a value based on other attributes.

public double getBalance() {
    return netTotal - paidAmount;
}

Example:

public String getDisplayName() {
    String safeTitle =
            title == null ? "" : title;

    String safeName =
            name == null ? "" : name;

    return (safeTitle + " " + safeName).trim();
}

Calculated getters should normally be lightweight.

Avoid database queries inside simple getters because UI frameworks may call getters repeatedly.


Heavy Logic in Getters

Avoid:

public List<Bill> getBills() {
    return billFacade.findAll();
}

The getter may be executed multiple times while rendering one page.

Better:

public void process() {
    bills = billFacade.findAll();
}

public List<Bill> getBills() {
    return bills;
}

Getters should usually:

  • Return an attribute
  • Perform a small calculation
  • Format a simple value
  • Avoid changing object state
  • Avoid running expensive database operations

Methods with Parameters

Methods can accept one or more parameters.

public void setDepartment(Department department) {
    this.department = department;
}

Multiple parameters:

public double calculateNetTotal(
        double total,
        double discount) {

    return total - discount;
}

HMIS-style report method:

public List<Bill> findBills(
        Date fromDate,
        Date toDate,
        Department department) {

    // Query processing
}

Parameter names should clearly describe the values.

Good:

Date fromDate
Date toDate
Department department
Investigation investigation

Weak:

Date d1
Date d2
Department dep
Investigation inv

Parameters and Arguments

A parameter is declared in the method.

public void setDepartment(Department department)

department is the parameter.

An argument is the actual value passed during the method call.

setDepartment(selectedLaboratory);

selectedLaboratory is the argument.


Return Types

A method return type defines what value is sent back.

String

public String getPatientCode() {
    return patientCode;
}

Integer

public int getResultCount() {
    return results.size();
}

Long

public Long getPatientId() {
    return patientId;
}

Double

public double calculateTotal() {
    return quantity * unitPrice;
}

Boolean

public boolean isDateRangeValid() {
    return !fromDate.after(toDate);
}

Object

public Department getDepartment() {
    return department;
}

Collection

public List<Bill> getBills() {
    return bills;
}

Void Methods

void means that a method does not return a value.

public void clearFilters() {
    fromDate = null;
    toDate = null;
    department = null;
    investigation = null;
}

Another example:

public void process() {
    results.clear();
    loadResults();
}

A void method may exit early.

public void process() {
    if (fromDate == null || toDate == null) {
        return;
    }

    loadResults();
}

Public Methods

Public methods can be called from other Java components.

public void process() {
}

Common public HMIS methods include:

getResults()
setDepartment()
process()
clear()
save()
delete()
generateReport()
exportToExcel()

Only expose methods publicly when external callers require them.

Internal helper methods should normally be private.


Private Methods

Private methods can only be called from within the same Java component.

private boolean isDateRangeValid() {
    return fromDate != null
            && toDate != null
            && !fromDate.after(toDate);
}

Another example:

private Map<String, Object> createParameters() {
    Map<String, Object> parameters =
            new HashMap<>();

    parameters.put("fromDate", fromDate);
    parameters.put("toDate", toDate);

    return parameters;
}

Benefits of private helper methods:

  • Reduce duplication
  • Improve readability
  • Separate validation
  • Hide internal implementation
  • Make public APIs smaller

Protected Methods

Protected methods are commonly used with inheritance.

@Override
protected EntityManager getEntityManager() {
    return entityManager;
}

The method is available to:

  • The same component
  • The same package
  • Child components

Static Methods

A static method belongs to the type rather than an instance.

public static boolean isPositive(double amount) {
    return amount > 0;
}

Call it with the type name:

AmountValidator.isPositive(100.0);

Static methods are suitable for:

  • Pure utility calculations
  • Formatting helpers
  • Validation that does not require instance attributes
  • Factory helpers
  • Constants-related operations

Avoid static methods that depend on:

  • Current user
  • Selected patient
  • Session-specific values
  • Mutable shared state
  • Injected database dependencies

Final Methods

A final method cannot be overridden.

public final void writeAuditEntry() {
}

Use final methods only when preventing overriding is intentional and necessary.

Too many final methods may reduce extensibility and testability.


Method Overloading

Method overloading means using the same method name with different parameter lists.

public void search() {
}

public void search(String text) {
}

public void search(
        Date fromDate,
        Date toDate) {
}

The following differences allow overloading:

  • Different number of parameters
  • Different parameter types
  • Different parameter order

Changing only the return type is not enough.

Invalid:

public int find();
public String find();

Method Overriding

Method overriding occurs when inherited behaviour is replaced.

@Override
protected EntityManager getEntityManager() {
    return entityManager;
}

Rules:

  • Same method name
  • Same parameter list
  • Compatible return type
  • Access cannot be more restrictive
  • Use @Override

Another common example:

@Override
public String toString() {
    return name;
}

Validation Methods

Validation methods check whether data is acceptable.

private boolean isDateRangeValid() {
    if (fromDate == null || toDate == null) {
        return false;
    }

    return !fromDate.after(toDate);
}

Amount validation:

private boolean isAmountValid(double amount) {
    return amount >= 0;
}

Required filter validation:

private boolean areRequiredFiltersSelected() {
    return department != null
            && investigation != null;
}

Boolean validation methods should normally use names such as:

isValid()
hasResults()
canEdit()
isDateRangeValid()
areRequiredFieldsAvailable()

Processing Methods

A processing method performs an application action.

public void process() {
    results.clear();

    if (!isDateRangeValid()) {
        JsfUtil.addErrorMessage(
                "Please select a valid date range."
        );
        return;
    }

    results = loadResults();
}

Processing methods should normally:

  1. Clear old data when appropriate.
  2. Validate input.
  3. Build query parameters.
  4. Call the service or facade.
  5. Store returned results.
  6. Display safe user messages.
  7. Handle exceptions appropriately.

Clear Methods

A clear method resets attributes.

public void clear() {
    fromDate = null;
    toDate = null;
    department = null;
    investigation = null;
    results.clear();
}

Use clear method names such as:

clear()
clearFilters()
resetForm()
resetSelection()

Be careful not to remove data that should remain in the current workflow.


Find Methods

Methods that retrieve records should use meaningful names.

Examples:

findPatientById()
findActiveBills()
findInvestigations()
findResultsByDateRange()
findByJpql()

Example:

public List<PatientInvestigation>
        findResultsByDateRange(
                Date fromDate,
                Date toDate) {

    // Query
}

The method name should communicate:

  • What is returned
  • Which condition is used
  • Whether only active or non-retired records are returned

Calculate Methods

Calculation methods should begin with a clear verb.

public double calculateNetTotal() {
    return total - discount;
}
public double calculateBalance() {
    return netTotal - paidAmount;
}
public int calculatePatientCount() {
    return results == null
            ? 0
            : results.size();
}

Calculations should be predictable and ideally avoid changing unrelated attributes.


Format Methods

Format methods prepare values for display.

public String formatPatientName() {
    if (patient == null
            || patient.getPerson() == null) {
        return "";
    }

    String name =
            patient.getPerson().getName();

    return name == null ? "" : name.trim();
}

Examples:

formatPatientName()
formatBillNumber()
formatDateRange()
formatAmount()

Formatting methods must not expose sensitive values unnecessarily.


Null-Safe Methods

HMIS entity relationships may contain null values.

Unsafe:

public String getDepartmentName() {
    return department.getName();
}

Safe:

public String getDepartmentName() {
    if (department == null
            || department.getName() == null) {
        return "";
    }

    return department.getName();
}

Long relationship chain:

public String getPatientName() {
    if (patientInvestigation == null
            || patientInvestigation.getPatient() == null
            || patientInvestigation
                    .getPatient()
                    .getPerson() == null
            || patientInvestigation
                    .getPatient()
                    .getPerson()
                    .getName() == null) {

        return "";
    }

    return patientInvestigation
            .getPatient()
            .getPerson()
            .getName();
}

Returning Collections Safely

Avoid returning null when an empty collection correctly represents no results.

Risky:

public List<Bill> getBills() {
    return null;
}

Better:

private List<Bill> bills = new ArrayList<>();

public List<Bill> getBills() {
    return bills;
}

If necessary:

public List<Bill> getBills() {
    if (bills == null) {
        bills = new ArrayList<>();
    }

    return bills;
}

Method Exception Handling

Methods that may fail should handle exceptions responsibly.

Bad:

public void process() {
    try {
        loadResults();
    } catch (Exception e) {
    }
}

This hides the problem.

Better:

public void process() {
    try {
        results = loadResults();
    } catch (PersistenceException e) {
        logger.log(
                Level.SEVERE,
                "Unable to load report results",
                e
        );

        JsfUtil.addErrorMessage(
                "Unable to generate the report."
        );
    }
}

User-facing messages should not include:

  • SQL statements
  • Passwords
  • Database server names
  • Stack traces
  • Patient diagnoses
  • Investigation results
  • Full personal details

Getter and Setter Usage in XHTML

An XHTML value expression may use a Java attribute through its getter and setter.

<p:inputText
    value="#{reportController.comments}" />

This maps to:

public String getComments() {
    return comments;
}

public void setComments(String comments) {
    this.comments = comments;
}

Output:

<h:outputText
    value="#{reportController.department.name}" />

This may call:

getDepartment()
getName()

Action method:

<p:commandButton
    value="Process"
    action="#{reportController.process}" />

This calls:

public void process() {
}

DTO Attributes

DTO attributes should contain only the information needed by a report or page.

private Long investigationId;
private String investigationName;
private Long patientCount;

Avoid placing complete entity graphs in DTOs when IDs and names are enough.

Heavy:

private Investigation investigation;
private Patient patient;
private Department department;

Lighter:

private Long investigationId;
private String investigationName;
private Long patientId;
private String patientCode;
private Long departmentId;
private String departmentName;

Only include sensitive patient attributes when the use case requires them and the user is authorized to view them.


DTO Getter Methods

DTOs normally provide getters.

public Long getInvestigationId() {
    return investigationId;
}

public String getInvestigationName() {
    return investigationName;
}

public Long getPatientCount() {
    return patientCount;
}

A DTO can also provide lightweight calculated methods.

public boolean hasPatients() {
    return patientCount != null
            && patientCount > 0;
}

Avoid placing complex database operations inside DTO methods.


Attributes Used in JPQL

JPQL uses mapped entity attribute names.

Example:

String jpql =
        "SELECT pi "
        + "FROM PatientInvestigation pi "
        + "WHERE pi.retired = false "
        + "AND pi.createdAt BETWEEN "
        + ":fromDate AND :toDate";

Attributes referenced are:

retired
createdAt

If an entity attribute is renamed, existing queries may fail.

Do not rename an attribute before checking all JPQL queries.


Query Parameter Attributes

A query parameter map stores parameter names and values.

Map<String, Object> parameters =
        new HashMap<>();

parameters.put("fromDate", fromDate);
parameters.put("toDate", toDate);
parameters.put("department", department);

The names must match the JPQL placeholders.

JPQL:

"WHERE pi.createdAt BETWEEN "
+ ":fromDate AND :toDate "
+ "AND pi.department = :department"

Java:

parameters.put("fromDate", fromDate);
parameters.put("toDate", toDate);
parameters.put("department", department);

Mismatch example:

parameters.put("startDate", fromDate);

This will not match :fromDate.


Method and Attribute Consistency

Attribute names, getter names, and setter names should match.

Attribute:

private Department laboratory;

Getter:

public Department getLaboratory() {
    return laboratory;
}

Setter:

public void setLaboratory(
        Department laboratory) {

    this.laboratory = laboratory;
}

Incorrect getter:

public Department getLab() {
    return laboratory;
}

This may be intentional, but it creates inconsistency and can confuse XHTML binding.


Avoiding Side Effects in Getters

A getter should not unexpectedly change data.

Bad:

public List<Bill> getBills() {
    bills.clear();
    bills = billFacade.findAll();
    return bills;
}

Better:

public List<Bill> getBills() {
    return bills;
}

public void loadBills() {
    bills = billFacade.findAll();
}

A caller expects a getter to return a value, not to reset or reload unrelated state.


Sensitive Data in Getter Methods

A getter makes an attribute available to callers and potentially to UI pages.

Before adding a getter for a sensitive attribute, consider:

  • Does the page need this information?
  • Is the current user authorized?
  • Could the value appear in logs or exports?
  • Is masking required?
  • Is the complete value necessary?

Example masked method:

public String getMaskedNic() {
    if (nationalIdentityCardNumber == null
            || nationalIdentityCardNumber.length() < 4) {
        return "";
    }

    int visibleStart =
            nationalIdentityCardNumber.length() - 4;

    return "****"
            + nationalIdentityCardNumber.substring(
                    visibleStart
            );
}

Do not use masking as a replacement for access control. It is only an additional display protection.


Sensitive Data in Setter Methods

Setters for sensitive values should validate and normalize input carefully.

Example:

public void setMobileNumber(String mobileNumber) {
    if (mobileNumber == null) {
        this.mobileNumber = null;
        return;
    }

    this.mobileNumber =
            mobileNumber.trim();
}

Passwords should not be stored directly through a normal plain-text setter.

Bad:

public void setPassword(String password) {
    this.password = password;
}

Password handling should use the project's approved secure hashing and authentication process.


Method Length

Methods should focus on one clear responsibility.

A very long method may contain:

  • Validation
  • Query building
  • Database access
  • Formatting
  • Export logic
  • Error handling
  • UI messages

Separate these into helper methods where appropriate.

Example:

public void process() {
    clearPreviousResults();

    if (!validateFilters()) {
        return;
    }

    Map<String, Object> parameters =
            createQueryParameters();

    results = loadResults(parameters);
}

Helper methods:

private void clearPreviousResults() {
    results.clear();
}

private boolean validateFilters() {
    return isDateRangeValid();
}

private Map<String, Object>
        createQueryParameters() {

    Map<String, Object> parameters =
            new HashMap<>();

    parameters.put("fromDate", fromDate);
    parameters.put("toDate", toDate);

    return parameters;
}

Method Comments

Method names should make the purpose understandable.

Good:

private boolean isDateRangeValid()

This may not need a comment.

A comment is useful when explaining:

  • Business rules
  • Non-obvious calculations
  • Legacy compatibility
  • Special query behaviour
  • Security requirements

Avoid comments that only repeat the code.

Weak:

// Set name
this.name = name;

Useful:

// Preserve the existing misspelled property name because
// several legacy XHTML pages and JPQL queries still use it.

Method Documentation

Public methods with important behaviour may use Javadoc.

/**
 * Loads non-retired patient investigations created
 * within the selected date range.
 *
 * @return list of matching patient investigations;
 *         never {@code null}
 */
public List<PatientInvestigation> loadResults() {
    // implementation
}

Useful Javadoc tags:

@param
@return
@throws
@deprecated

Do not place sensitive operational information in public documentation.


Deprecated Methods

An old method may be marked as deprecated.

@Deprecated
public void processOldReport() {
}

A replacement should be documented.

/**
 * @deprecated Use {@link #process()} instead.
 */
@Deprecated
public void processOldReport() {
    process();
}

Do not delete deprecated methods immediately if existing code still uses them.


Common Attribute Mistakes

Public mutable attributes

Avoid:

public String patientName;

Static user-specific attributes

Avoid:

private static Patient selectedPatient;

Unclear names

Avoid:

private String x;
private Date d;
private boolean flag;

Singular collection names

Avoid:

private List<Bill> bill;

Uninitialized collections

Avoid:

private List<Bill> bills;

when the code immediately calls clear() or add().

Storing derived data unnecessarily

Avoid storing values that can be safely calculated.

private double total;
private double discount;
private double netTotal;

If netTotal must always equal total - discount, consider:

public double getNetTotal() {
    return total - discount;
}

unless persistence or audit requirements require storing it.


Common Method Mistakes

Database query inside a getter

public List<Bill> getBills() {
    return billFacade.findAll();
}

Empty exception catch

try {
    process();
} catch (Exception e) {
}

Misleading method name

public void getReport() {
    results.clear();
    deleteOldRecords();
}

A method beginning with get should normally return data rather than delete or modify unrelated records.

Too many responsibilities

public void processAndSaveAndExportAndEmail() {
}

Separate the operations.

Returning null collections

public List<Bill> getBills() {
    return null;
}

Exposing sensitive information

public String getFullPatientDetailsForLog() {
    return patientName + diagnosis + address;
}

Recommended Attribute Example

private Date fromDate;
private Date toDate;

private Institution institution;
private Department laboratory;
private Investigation investigation;

private List<PatientInvestigation> results =
        new ArrayList<>();

private boolean includeRetired;

Why these names are good:

  • They use camelCase.
  • They clearly describe the values.
  • The collection uses a plural name.
  • The Boolean name expresses a condition.
  • Entity relationship attributes use entity names.
  • Date range values use fromDate and toDate.

Recommended Method Example

public void process() {
    results.clear();

    if (!isDateRangeValid()) {
        JsfUtil.addErrorMessage(
                "Please select a valid date range."
        );
        return;
    }

    Map<String, Object> parameters =
            createQueryParameters();

    results =
            patientInvestigationFacade
                    .findByJpql(
                            createQuery(),
                            parameters
                    );
}

private boolean isDateRangeValid() {
    return fromDate != null
            && toDate != null
            && !fromDate.after(toDate);
}

private Map<String, Object>
        createQueryParameters() {

    Map<String, Object> parameters =
            new HashMap<>();

    parameters.put("fromDate", fromDate);
    parameters.put("toDate", toDate);

    if (laboratory != null) {
        parameters.put(
                "laboratory",
                laboratory
        );
    }

    if (investigation != null) {
        parameters.put(
                "investigation",
                investigation
        );
    }

    return parameters;
}

private String createQuery() {
    String jpql =
            "SELECT pi "
            + "FROM PatientInvestigation pi "
            + "WHERE pi.retired = false "
            + "AND pi.createdAt BETWEEN "
            + ":fromDate AND :toDate";

    if (laboratory != null) {
        jpql +=
                " AND pi.department = :laboratory";
    }

    if (investigation != null) {
        jpql +=
                " AND pi.investigation = "
                + ":investigation";
    }

    return jpql;
}

This example demonstrates:

  • Private attributes
  • Public processing method
  • Private helper methods
  • Clear method naming
  • Date validation
  • Null checking
  • Query parameter consistency
  • Collection clearing
  • Safe user-facing errors

Complete Attributes and Methods Example

public class InvestigationReportData {

    private Date fromDate;
    private Date toDate;

    private Department laboratory;
    private Investigation investigation;

    private List<PatientInvestigation> results =
            new ArrayList<>();

    private boolean includeRetired;

    public Date getFromDate() {
        return fromDate;
    }

    public void setFromDate(Date fromDate) {
        this.fromDate = fromDate;
    }

    public Date getToDate() {
        return toDate;
    }

    public void setToDate(Date toDate) {
        this.toDate = toDate;
    }

    public Department getLaboratory() {
        return laboratory;
    }

    public void setLaboratory(
            Department laboratory) {

        this.laboratory = laboratory;
    }

    public Investigation getInvestigation() {
        return investigation;
    }

    public void setInvestigation(
            Investigation investigation) {

        this.investigation = investigation;
    }

    public List<PatientInvestigation>
            getResults() {

        return results;
    }

    public boolean isIncludeRetired() {
        return includeRetired;
    }

    public void setIncludeRetired(
            boolean includeRetired) {

        this.includeRetired =
                includeRetired;
    }

    public int getResultCount() {
        return results == null
                ? 0
                : results.size();
    }

    public boolean hasResults() {
        return results != null
                && !results.isEmpty();
    }

    public void clearFilters() {
        fromDate = null;
        toDate = null;
        laboratory = null;
        investigation = null;
        includeRetired = false;
        results.clear();
    }

    public boolean isDateRangeValid() {
        return fromDate != null
                && toDate != null
                && !fromDate.after(toDate);
    }

    public void addResult(
            PatientInvestigation result) {

        if (result == null) {
            return;
        }

        results.add(result);
    }
}

Summary

Java attributes store state.

Examples:

private String patientCode;
private Date createdAt;
private Department department;
private boolean retired;
private List<Bill> bills;

Java methods perform actions or return information.

Examples:

getPatientCode()
setPatientCode()
calculateNetTotal()
validateDateRange()
process()
clearFilters()
findActiveBills()

The most important rules are:

  1. Keep attributes private.
  2. Use camelCase names.
  3. Use clear and meaningful names.
  4. Use plural names for collections.
  5. Use clear Boolean names.
  6. Initialize collections when appropriate.
  7. Avoid static attributes for user-specific information.
  8. Use getters and setters consistently.
  9. Keep getters lightweight.
  10. Use private helper methods for internal logic.
  11. Validate null values and input.
  12. Do not expose sensitive patient information unnecessarily.
  13. Do not include sensitive values in logs or toString().
  14. Keep method names action-oriented.
  15. Ensure JPQL parameter names match Java parameter-map names.
  16. Check all usages before renaming persisted attributes.
  17. Return empty collections instead of null when appropriate.
  18. Keep methods focused on one responsibility.

Clone this wiki locally