Skip to content

Java attributes and methods111

Rashmika_Harshamal edited this page Jul 20, 2026 · 1 revision

Java Attributes and Methods in the HMIS System

This GitHub Wiki page covers only Java attributes and methods, including naming conventions, access modifiers, getters, setters, validation, null safety, DTO and JPQL usage, and HMIS-style examples. It intentionally excludes detailed lessons on classes and objects, constructors, and CDI bean scopes.

Contents


4. Attributes or Fields

An attribute is declared inside a class but outside a method.

private String name;
private Date dob;
private boolean retired;

General syntax:

accessModifier dataType attributeName;

Example:

private Department department;
  • private = access modifier.
  • Department = type.
  • department = attribute name.

Attribute declaration and initialization

Declaration only:

private List<Patient> patients;

Declaration with initialization:

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

Initializing collections immediately is often safer because it reduces NullPointerException.

Default values

Instance fields receive default values automatically.

Type Default
int, long, double 0 or 0.0
boolean false
Object references null
char Unicode zero value

Local variables do not receive automatic usable values. They must be assigned before reading.

int count;
System.out.println(count); // Compilation error

5. Types of Variables

Instance variable

Each object has its own value.

private String name;

Two patients may have different names.

Static or class variable

One value belongs to the class and is shared.

private static int objectCount;

Local variable

Declared inside a method and exists only during that method call.

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

finalAmount is local.

Parameter variable

Receives a value when a method is called.

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

The second name is a parameter.


6. Java Data Types

Java data types are divided into primitive types and reference types.

Primitive types

Type Example Common use
byte 10 Very small integer
short 1000 Small integer
int 25 Counts and indexes
long 100000L IDs and large integers
float 10.5f Decimal with lower precision
double 2500.75 Financial or measured values in legacy code
char 'A' Single character
boolean true Status flag

Reference types

Reference variables point to objects.

String name;
Date createdAt;
Patient patient;
List<Bill> bills;

Primitive versus wrapper

Primitive Wrapper
int Integer
long Long
double Double
boolean Boolean
char Character

Wrapper types can be null; primitives cannot.

private boolean cancelled;   // Always true or false
private Boolean approved;    // Can be true, false, or null

HMIS DTO constructor queries should normally use matching wrapper types such as Long, Double, Integer, and Boolean when null safety is required.


7. Access Modifiers

Access modifiers decide where a class, method, constructor, or field can be used.

public

Accessible from any package.

public String getName() {
    return name;
}

Use public for methods that must be called by XHTML, controllers, services, or other packages.

private

Accessible only inside the same class.

private String name;

Fields are normally private to protect object state.

protected

Accessible:

  • Inside the same class.
  • Inside the same package.
  • Inside subclasses in other packages.
protected double total;

It is mainly useful in inheritance.

Default or package-private

When no access modifier is written, access is limited to the same package.

String internalCode;

This is called default access, package-private access, or no modifier.

Access table

Modifier Same class Same package Subclass elsewhere Any class
private Yes No No No
default Yes Yes No No
protected Yes Yes Yes No
public Yes Yes Yes Yes

Recommended HMIS rule

Use:

  • private for entity, controller, service, and DTO fields.
  • public for required getters, setters, actions, and service methods.
  • protected only when inheritance genuinely requires it.
  • Package-private for internal package helpers when appropriate.

8. Non-access Modifiers

static

Belongs to the class rather than one object.

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

final

Prevents reassignment, overriding, or inheritance depending on where it is used.

private static final long serialVersionUID = 1L;

abstract

Declares incomplete behaviour that subclasses must implement.

public abstract class AbstractReport {
    public abstract void generate();
}

synchronized

Allows controlled access by multiple threads. It should be used only when required and understood.

transient

The Java keyword transient excludes a field from standard Java serialization.

private transient String temporaryToken;

Do not confuse Java's transient keyword with JPA's @Transient annotation.

volatile

Tells the JVM that a field may be changed by different threads. It is uncommon in normal HMIS entity/controller code.


9. Methods

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

General form:

accessModifier returnType methodName(parameters) {
    // 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 { return total - discount; }

Method categories

Getter method

public String getName() {
    return name;
}

Setter method

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

Calculation method

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

Validation method

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

Action/navigation method

public String navigateToReport() {
    return "/reports/lab/investigation_report?faces-redirect=true";
}

Factory method

A factory method creates and returns an object.

public static InvestigationSummary createEmpty() {
    return new InvestigationSummary("", 0);
}

10. Method Parameters and Arguments

A parameter is declared in the method definition.

public void setDepartment(Department department)

department is a parameter.

An argument is the actual value passed to the method.

report.setDepartment(laboratoryDepartment);

laboratoryDepartment is the argument.

Multiple parameters

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

Pass-by-value

Java is always pass-by-value.

For an object, Java passes a copy of the reference value. The method can modify the referenced object's internal state, but replacing the local reference does not replace the caller's reference.

public void updatePatientName(Patient patient) {
    patient.getPerson().setName("Updated Name");
}

This can modify the same object.


11. Return Types

Returning a value

public int getCount() {
    return count;
}

Returning an object

public Department getDepartment() {
    return department;
}

Returning a collection

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

void

void means the method does not return a value.

public void clearFilters() {
    department = null;
    investigation = null;
    results = new ArrayList<>();
}

A void method can still use return; to exit early.

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

12. Getters and Setters

Getters and setters provide controlled access to private fields.

private String name;

public String getName() {
    return name;
}

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

Boolean naming

Primitive boolean getter:

public boolean isRetired() {
    return retired;
}

Wrapper Boolean getter may use:

public Boolean getApproved() {
    return approved;
}

Why JSF needs getters and setters

An XHTML expression such as:

#{investigationWiseReport.department}

normally maps to:

getDepartment()

When a user selects a department, JSF calls:

setDepartment(...)

Avoid unnecessary logic in getters

JSF may call getters many times during one request. Heavy database queries should not normally be executed directly in simple getters.

Bad:

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

Better:

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

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

15. static

A static member belongs to the class.

Static field

private static final long serialVersionUID = 1L;

Static method

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

Call it with the class name:

AmountValidator.isPositive(100.0);

Instance versus static

Instance:

patient.getName();

Static:

Person.checkAgeSex(dob, sex, title);

A static method cannot directly access a non-static field because no particular object is selected.


16. final

Final variable

Can be assigned only once.

final int maximumRows = 100;

Constant

private static final int DEFAULT_MAX_RESULTS = 100;

Constants normally use uppercase snake case.

Final method

Cannot be overridden.

public final void audit() {
}

Final class

Cannot be extended.

public final class ReportConstants {
}

A final object reference cannot point to a different object, but the object's contents may still be mutable.

final List<String> names = new ArrayList<>();
names.add("A");              // Allowed
// names = new ArrayList<>(); // Not allowed

22. Method Overloading

Overloading means methods have the same name but different parameter lists.

public void search() {
}

public void search(String text) {
}

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

The compiler selects the correct method using parameter number and types.

Changing only the return type is not enough:

// Not allowed:
public int find();
public String find();

23. Method Overriding

Overriding means a child class replaces a parent method implementation.

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

Rules:

  • Same method name.
  • Same parameter list.
  • Compatible return type.
  • Access cannot be made more restrictive.
  • Use @Override to let the compiler verify it.

Common overridden methods:

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

@Override
public boolean equals(Object object) {
    // equality logic
}

@Override
public int hashCode() {
    // hash logic
}

25. Arrays, Collections, and Generics

Array

Fixed size:

String[] names = new String[3];

List

Ordered collection that can grow.

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

Set

Stores unique elements.

Set<String> codes = new HashSet<>();

Map

Stores key-value pairs.

Map<String, Object> parameters = new HashMap<>();
parameters.put("fromDate", fromDate);

JPQL commonly uses a parameter map in HMIS.

Generics

Generics define the contained type.

List<Bill> bills;

This is safer than a raw list:

List bills;

With generics, the compiler knows list elements are Bill objects.

Common operations

results.add(result);
results.remove(result);
results.clear();
int size = results.size();
boolean empty = results.isEmpty();

26. Null Handling

null means an object reference does not point to an object.

Unsafe:

String departmentName = bill.getDepartment().getName();

If department is null, this throws NullPointerException.

Safe:

String departmentName = "";

if (bill != null
        && bill.getDepartment() != null
        && bill.getDepartment().getName() != null) {
    departmentName = bill.getDepartment().getName();
}

Early return

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

    // continue safely
}

Objects.equals

if (Objects.equals(firstId, secondId)) {
    // safe when either value is null
}

Optional

Optional may be useful in service APIs, but it is not normally used as a JPA entity field.

HMIS relationship chains

Guard every nullable relationship level.

if (record.getAdministeredBy() != null
        && record.getAdministeredBy().getPerson() != null) {
    name = record.getAdministeredBy().getPerson().getName();
}

27. Exceptions

An exception represents an error or unusual condition.

Checked exception

Must be handled or declared.

public void export() throws IOException {
}

Unchecked exception

Extends RuntimeException.

Examples:

  • NullPointerException
  • IllegalArgumentException
  • IllegalStateException

try-catch

try {
    workbook.write(outputStream);
} catch (IOException e) {
    logger.log(Level.SEVERE, "Excel export failed", e);
}

finally

Runs whether an exception occurs or not.

try {
    // work
} finally {
    // cleanup
}

Try-with-resources

Automatically closes resources.

try (Workbook workbook = new XSSFWorkbook()) {
    // create workbook
}

Do not silently hide exceptions

Bad:

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

Better:

try {
    process();
} catch (PersistenceException e) {
    logger.log(Level.SEVERE, "Report query failed", e);
    JsfUtil.addErrorMessage("Unable to generate the report.");
}

Do not expose private patient data or database details in user-facing error messages.


28. Annotations

Annotations add metadata for Java frameworks and tools.

@Entity

Marks a persistent JPA entity.

@Entity
public class Person {
}

@Id

Marks the primary key.

@Id
private Long id;

@GeneratedValue

Lets the database generate the ID.

@GeneratedValue(strategy = GenerationType.IDENTITY)

@Named

Registers a CDI bean name for JSF.

@Named
public class InvestigationWiseReport {
}

XHTML:

#{investigationWiseReport.results}

@SessionScoped

Keeps a controller across requests in one user session.

@SessionScoped

A session-scoped bean should implement Serializable.

@EJB

Injects an Enterprise JavaBean.

@EJB
private PatientInvestigationFacade patientInvestigationFacade;

@Inject

Injects a CDI-managed dependency.

@Inject
private SessionController sessionController;

@PersistenceContext

Injects an EntityManager.

@PersistenceContext(unitName = "hmisPU")
private EntityManager entityManager;

@Override

Confirms that a parent method is being overridden.

@Deprecated

Warns developers that an API should no longer be used for new code.

@Transient

Tells JPA not to store the field in the database.

@Transient
private String displayName;

@Temporal

Defines how legacy java.util.Date is stored.

@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;

29. JPA Entity Attributes in HMIS

A JPA entity represents persistent database data.

Simplified HMIS-style entity:

@Entity
public class PatientNote implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    private Patient patient;

    @Lob
    private String note;

    @ManyToOne
    private WebUser creater;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;

    private boolean retired;

    @Transient
    private String patientDisplayName;

    public PatientNote() {
    }

    // getters and setters
}

Persisted attribute

Usually stored in the database.

private String note;

Relationship attribute

Stores a link to another entity.

@ManyToOne
private Patient patient;

Calculated/non-persisted attribute

Not stored.

@Transient
private String patientDisplayName;

Field access

When JPA annotations are placed on fields, JPA uses field access and can read/write fields directly.

Entity caution

Entity fields may be used by:

  • Existing database columns.
  • JPQL.
  • XHTML expressions.
  • Reports.
  • Serialization.
  • External integrations.
  • Old production data.

Do not casually rename or remove existing entity attributes.


31. Transient and Calculated Attributes

CareCode HMIS entities contain both persisted data and calculated display data.

Example concept:

@Temporal(TemporalType.TIMESTAMP)
private Date dob;

@Transient
private String ageAsString;

public String getAgeAsString() {
    calculateAge();
    return ageAsString;
}

dob is stored, while the age string is calculated.

Important JPQL rule

JPQL queries can use mapped persistent attributes, not arbitrary calculated getter-only properties.

Wrong concept:

SELECT p.nameWithTitle FROM Person p

when nameWithTitle is calculated and not persisted.

Better:

SELECT p.title, p.name FROM Person p

Then combine them in Java or the DTO.

Java transient versus JPA @Transient

private transient String token;
  • Java serialization rule.
@Transient
private String displayText;
  • JPA persistence rule.

A field may use either or both depending on the requirement.


34. DTO Attributes and Methods

DTO means Data Transfer Object.

It carries only the data required for a use case.

public class InvestigationCountDTO {

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

    public InvestigationCountDTO(Long investigationId,
                                 String investigationName,
                                 Long patientCount) {
        this.investigationId = investigationId;
        this.investigationName = investigationName;
        this.patientCount = patientCount;
    }

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

    // getters
}

Entity versus DTO

Entity:

private Investigation investigation;

DTO navigation pattern:

private Long investigationId;
private String investigationName;

The DTO is lighter and avoids loading an entire entity graph.

Direct DTO query

String jpql =
        "SELECT new com.divudi.core.data.dto.InvestigationCountDTO("
        + "i.id, i.name, COUNT(pi.id)) "
        + "FROM PatientInvestigation pi "
        + "JOIN pi.investigation i "
        + "WHERE pi.createdAt BETWEEN :fromDate AND :toDate "
        + "GROUP BY i.id, i.name";

The HMIS developer guidelines recommend direct DTO queries instead of loading full entities and converting each entity in a loop.

Constructor safety

For existing DTOs:

  • Keep current attributes.
  • Keep current constructors.
  • Add new attributes when required.
  • Add overloaded constructors rather than breaking existing queries.

35. JPQL and Attribute Names

JPQL works with Java entity names and mapped attributes, not table-column syntax in the same way as SQL.

SELECT pi
FROM PatientInvestigation pi
WHERE pi.createdAt BETWEEN :fromDate AND :toDate

Parameter map

Map<String, Object> parameters = new HashMap<>();
parameters.put("fromDate", fromDate);
parameters.put("toDate", toDate);

Exact constructor matching

SELECT new SomeDTO(
    entity.id,
    entity.name,
    entity.total
)

must match:

public SomeDTO(Long id, String name, Double total)

Type mismatch

If an entity field is double or Double, use Double in the DTO constructor rather than an unrelated numeric type.

Nullable relationships

Unsafe JPQL relationship traversal can remove rows or cause failures.

Use explicit joins where appropriate:

LEFT JOIN b.patient patient
LEFT JOIN patient.person person

For nullable string values in DTO projections, use a safe default when supported:

COALESCE(person.name, '')

Persisted fields only

Do not use calculated getter properties in JPQL unless they are actually mapped persistent attributes.


36. equals, hashCode, and toString

These methods come from java.lang.Object.

toString

Returns a readable representation.

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

It may be used by logs, dropdowns, converters, and debugging.

Do not include sensitive patient information unnecessarily.

equals

Checks logical equality.

@Override
public boolean equals(Object object) {
    if (this == object) {
        return true;
    }

    if (!(object instanceof Investigation)) {
        return false;
    }

    Investigation other = (Investigation) object;
    return Objects.equals(id, other.id);
}

hashCode

Objects that are equal must return the same hash code.

@Override
public int hashCode() {
    return Objects.hashCode(id);
}

JPA entity caution

New unsaved entities may have null IDs. Equality based only on IDs needs careful handling.


39. Dates and Times

Legacy HMIS code commonly uses java.util.Date.

@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;

TemporalType.DATE

Date only.

@Temporal(TemporalType.DATE)
private Date billDate;

TemporalType.TIME

Time only.

TemporalType.TIMESTAMP

Date and time.

Date validation

public boolean isValidDateRange() {
    if (fromDate == null || toDate == null) {
        return false;
    }
    return !fromDate.after(toDate);
}

Avoid mutable date exposure where important

Date is mutable. Defensive copying may be used in isolated domain models, though existing project conventions must be respected.

Modern Java offers:

  • LocalDate
  • LocalTime
  • LocalDateTime
  • Instant

Do not replace legacy entity date types without checking JPA mappings, existing queries, converters, and production compatibility.


40. Naming Conventions

Classes

PascalCase:

InvestigationWiseReport
PatientInvestigationFacade
StockDTO

Methods and fields

camelCase:

fromDate
patientCount
calculateAge()
findInvestigations()

Constants

UPPER_SNAKE_CASE:

DEFAULT_MAX_RESULTS

Boolean names

retired
cancelled
approved

Getters:

isRetired()
isCancelled()
getApproved()

Collection names

Use plural names:

results
bills
investigations

Method names should describe actions

Good:

generateReport()
clearFilters()
calculateNetTotal()
findActiveInvestigations()

Weak:

doIt()
processData2()
abc()

Existing spelling mistakes

Large legacy systems may contain old misspelled attributes or methods kept for backward compatibility. Do not rename them casually. First search:

  • Java references.
  • JPQL.
  • XHTML.
  • database schema.
  • reports.
  • integrations.
  • migration scripts.

41. Common HMIS Mistakes

1. Making entity fields public

Bad:

public String name;

Better:

private String name;

with getters and setters.

2. Calling an instance method as if it were static

Wrong:

Patient.getName();

Correct:

patient.getName();

3. Creating EJBs with new

Wrong:

new PatientInvestigationFacade();

Correct:

@EJB
private PatientInvestigationFacade facade;

4. Missing Serializable on a session bean

@Named
@SessionScoped
public class ReportController implements Serializable {
}

5. Heavy queries inside getters

Load data in an action method or initialization step instead.

6. Uninitialized collections

Risky:

private List<Bill> bills;

Safer:

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

7. Using a calculated property in JPQL

Select persisted fields and calculate display text in Java.

8. DTO constructor mismatch

Query parameter count, order, and types must match the constructor.

9. Wrong wrapper type

A projected Double should not be sent to a BigDecimal constructor parameter without explicit conversion.

10. Null relationship chain

Guard each relationship or use correct joins.

11. Removing an existing DTO constructor

Add an overloaded constructor instead.

12. Returning null collections

Prefer an empty collection when it accurately represents “no results.”

13. Storing user-specific data in static fields

Static mutable data is shared across users and can cause privacy and concurrency problems.

14. Logging sensitive medical information

Logs should not unnecessarily include patient names, identifiers, diagnoses, or report values.

15. Confusing void main components

public static void main(String[] args)
  • public: JVM can access the method.
  • static: JVM calls it without creating an object.
  • void: it returns no value.
  • main: standard starting method name.
  • String[] args: command-line arguments.

A Java EE web application is normally started by the application server, not by a business class's main method.


42. Complete HMIS-style Example

The following example combines attributes, methods, access modifiers, annotations, DTOs, facades, controllers, and XHTML binding. It is a simplified learning example and not a direct replacement for an existing HMIS file.

42.1 Entity

package com.divudi.core.entity.lab;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;

@Entity
public class LabResultAudit implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private PatientInvestigation patientInvestigation;

    @ManyToOne(fetch = FetchType.LAZY)
    private WebUser creater;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;

    @Lob
    private String comments;

    private boolean retired;

    @Transient
    private String investigationName;

    public LabResultAudit() {
    }

    public Long getId() {
        return id;
    }

    public PatientInvestigation getPatientInvestigation() {
        return patientInvestigation;
    }

    public void setPatientInvestigation(
            PatientInvestigation patientInvestigation) {
        this.patientInvestigation = patientInvestigation;
    }

    public WebUser getCreater() {
        return creater;
    }

    public void setCreater(WebUser creater) {
        this.creater = creater;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public String getComments() {
        return comments;
    }

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

    public boolean isRetired() {
        return retired;
    }

    public void setRetired(boolean retired) {
        this.retired = retired;
    }

    public String getInvestigationName() {
        if (patientInvestigation == null
                || patientInvestigation.getInvestigation() == null) {
            return "";
        }
        return patientInvestigation.getInvestigation().getName();
    }
}

Theory shown

  • Private attributes.
  • Primitive boolean.
  • Object references.
  • JPA annotations.
  • No-argument constructor.
  • Getter and setter methods.
  • Validation/normalization in a setter.
  • Calculated transient getter.
  • Null safety.
  • Serializable entity.

42.2 DTO

package com.divudi.core.data.dto;

import java.util.Date;

public class LabResultAuditDTO {

    private Long auditId;
    private String investigationName;
    private Date createdAt;
    private String creatorName;
    private String comments;

    public LabResultAuditDTO(Long auditId,
                             String investigationName,
                             Date createdAt,
                             String creatorName,
                             String comments) {
        this.auditId = auditId;
        this.investigationName = investigationName;
        this.createdAt = createdAt;
        this.creatorName = creatorName;
        this.comments = comments;
    }

    public Long getAuditId() {
        return auditId;
    }

    public String getInvestigationName() {
        return investigationName;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public String getCreatorName() {
        return creatorName;
    }

    public String getComments() {
        return comments;
    }
}

Theory shown

  • Lightweight attributes.
  • Parameterized constructor.
  • Read-only style through getters.
  • No full entity graph in the DTO.

42.3 Facade

package com.divudi.core.facade;

import com.divudi.core.entity.lab.LabResultAudit;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class LabResultAuditFacade
        extends AbstractFacade<LabResultAudit> {

    @PersistenceContext(unitName = "hmisPU")
    private EntityManager entityManager;

    public LabResultAuditFacade() {
        super(LabResultAudit.class);
    }

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

Theory shown

  • Inheritance.
  • Generic type.
  • Constructor calling super.
  • Method overriding.
  • Dependency injection.
  • Stateless EJB.

42.4 Controller

package com.divudi.bean.lab;

import com.divudi.core.data.dto.LabResultAuditDTO;
import com.divudi.core.facade.LabResultAuditFacade;
import java.io.Serializable;
import java.util.*;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.persistence.TemporalType;

@Named
@SessionScoped
public class LabResultAuditController
        implements Serializable {

    private static final long serialVersionUID = 1L;

    @EJB
    private LabResultAuditFacade facade;

    private Date fromDate;
    private Date toDate;
    private List<LabResultAuditDTO> results =
            new ArrayList<>();

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

        if (!isDateRangeValid()) {
            return;
        }

        String jpql =
                "SELECT new com.divudi.core.data.dto."
                + "LabResultAuditDTO("
                + "a.id, "
                + "a.patientInvestigation.investigation.name, "
                + "a.createdAt, "
                + "COALESCE(person.name, ''), "
                + "a.comments) "
                + "FROM LabResultAudit a "
                + "LEFT JOIN a.creater creator "
                + "LEFT JOIN creator.webUserPerson person "
                + "WHERE a.retired = false "
                + "AND a.createdAt BETWEEN :fromDate AND :toDate "
                + "ORDER BY a.createdAt DESC";

        Map<String, Object> parameters = new HashMap<>();
        parameters.put("fromDate", fromDate);
        parameters.put("toDate", toDate);

        results = (List<LabResultAuditDTO>)
                facade.findLightsByJpql(
                        jpql,
                        parameters,
                        TemporalType.TIMESTAMP);
    }

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

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

    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 List<LabResultAuditDTO> getResults() {
        return results;
    }
}

Theory shown

  • CDI bean annotations.
  • Session scope and serialization.
  • EJB injection.
  • Collection initialization.
  • Public action methods.
  • Private validation method.
  • Direct DTO query.
  • Parameter map.
  • Getter/setter binding.
  • Null and date validation.

42.5 XHTML

<h:form id="auditForm">

    <p:datePicker value="#{labResultAuditController.fromDate}" />

    <p:datePicker value="#{labResultAuditController.toDate}" />

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

    <p:commandButton value="Clear"
                     action="#{labResultAuditController.clear}"
                     update="@form" />

    <p:outputPanel id="resultPanel">

        <p:dataTable value="#{labResultAuditController.results}"
                     var="row"
                     emptyMessage="No records found">

            <p:column headerText="Investigation">
                <h:outputText value="#{row.investigationName}" />
            </p:column>

            <p:column headerText="Created At">
                <h:outputText value="#{row.createdAt}" />
            </p:column>

            <p:column headerText="Created By">
                <h:outputText value="#{row.creatorName}" />
            </p:column>

            <p:column headerText="Comments">
                <h:outputText value="#{row.comments}" />
            </p:column>

        </p:dataTable>

    </p:outputPanel>

</h:form>

Clone this wiki locally