JDBI bindBean fails to find named parameters

2.2k Views Asked by At

I am attempting to update an Employee row in my Employee table using JDBI. However, the bindBean method doesn't appear to like my bean. I have included getters and setters. The bean has a public default constructor. The property names of the object are an exact match for the database column names. So the LastName String for instance, corresponds to a LastName database column. Exact match. What am I doing wrong here? Am I misconstruing how bindBean works? I also tried this same code with a prefix in front of the :parameters, still no dice.

EDIT: After a little more research, I believe the issue is coming from the fact that my column names and properties start with capital letters. Annotating my getters and setters with @ColumnName and the appropriate uppercase column names does not appear to be helping though.

SOLVED: Easy solution to this problem is to rename the named parameters in the query itself to match a lowercase version of the property names. i.e if the property is called Name, change the parameter in the query to :name and the problem is resolved without touching your beans or your database columns.

Dao Method:

    @Override
public void updateEmployee(Employee empl){
    try(Handle handle = daoFactory.getDataSourceController().open()){
        handle.createUpdate("UPDATE Employees SET LastName = :LastName, FirstName = :FirstName, EmailAddress = :EmailAddress, OnVacation = :OnVacation, Active = :Active, EscalationLevel = :EscalationLevel," +
                " ScheduleExempt = :ScheduleExempt, GroupID = :GroupID, ScheduleID = :ScheduleID, SecurityGID = :SecurityGID, JobTitle = :JobTitle, Blurb = :Blurb WHERE IDX = :IDX")
                .bindBean(empl)
                .execute();
        handle.commit();
    }
    catch(Exception e){
        if(verbose){ e.printStackTrace(); }
        logger.logError("Web-EmployeeDaoService-E04", "Error updating single user in DB.");
    }
}

And my bean:

package app.pojos.Employee;

import java.io.Serializable;
import java.sql.Timestamp;

public class Employee implements Serializable {
    private int IDX;
    private String LastName;
    private String FirstName;
    private String EmailAddress;
    private boolean OnVacation;
    private boolean Active;
    private int EscalationLevel;
    private boolean ScheduleExempt;
    private int GroupID;
    private int ScheduleID;
    private int SecurityGID;
    private String JobTitle;
    private String Blurb;
    private Timestamp LastSeen;
    private String ProfilePic;

    //Default constructor
    public Employee(){}

    //Data mapped getters and setters
    public int getIDX(){ return IDX; }
    public void setIDX(int IDX){ this.IDX = IDX; }

    public String getFirstName(){ return FirstName; }
    public void setFirstName(String firstName){ this.FirstName = firstName; }

    public String getLastName(){ return LastName; }
    public void setLastName(String lastName){ this.LastName = lastName; }

    public String getProfilePic(){ return ProfilePic; }
    public void setProfilePic(String ProfilePic){ this.ProfilePic = ProfilePic; }

    public String getEmailAddress(){ return EmailAddress; }
    public void setEmailAddress(String emailAddress){ this.EmailAddress = emailAddress; }

    public int getGroupID(){ return GroupID; }
    public void setGroupID(int GroupID){ this.GroupID = GroupID; }

    public boolean getScheduleExempt(){ return ScheduleExempt; }
    public void setScheduleExempt(boolean ScheduleExempt){ this.ScheduleExempt = ScheduleExempt; }

    public boolean getOnVacation(){ return OnVacation; }
    public void setOnVacation(boolean OnVacation){ this.OnVacation = OnVacation; }

    public boolean getActive(){ return Active; }
    public void setActive(boolean Active){ this.Active = Active; }

    public int getEscalationLevel(){ return EscalationLevel; }
    public void setEscalationLevel(int EscalationLevel){ this.EscalationLevel = EscalationLevel; }

    public int getScheduleID(){ return ScheduleID; }
    public void setScheduleID(int ScheduleID){ this.ScheduleID = ScheduleID; }

    public int getSecurityGID(){ return SecurityGID; }
    public void setSecurityGID(int SecurityGID){ this.SecurityGID = SecurityGID; }

    public String getJobTitle(){ return JobTitle; }
    public void setJobTitle(String JobTitle){ this.JobTitle = JobTitle; }

    public String getBlurb(){ return Blurb; }
    public void setBlurb(String Blurb){ this.Blurb = Blurb; }

    public Timestamp getLastSeen() { return LastSeen; }
    public void setLastSeen(Timestamp LastSeen) { this.LastSeen = LastSeen; }

    //Extra helper functions
    public String getFullName(){ return this.FirstName + " " + this.LastName; }
}
1

There are 1 best solutions below

0
On BEST ANSWER

SOLVED: Easy solution to this problem is to rename the named parameters in the query itself to match a lowercase version of the property names. i.e if the property is called Name, change the parameter in the query to :name and the problem is resolved without touching your beans or your database columns.

See this response for clarity. If you're like me and made the mistake of going against best practice naming conventions and capitalized all of your bean properties, this is an easy solution. You only need to change how you reference the properties in your create/update/insert queries and nothing else.