-2

Getting null value for days calculated / added current date plus the user entered value

We are calculating a column value based on the user entered value ie Number of days entered by the User plus the current date.

private Date setdaysAttendanceApprovedWithAdditionalDays(int daysAttendanceApproved2) {

    Date currentDate = new Date();
    Calendar c = Calendar.getInstance();
    c.setTime(currentDate);

    c.add(Calendar.DATE, daysAttendanceApproved2);

    Date currentDatePlusUserInput = c.getTime();
    return currentDatePlusUserInput;
}

Desired Output

If a user enters the value of 10 then 8 May 2020 Plus 10 the Output would be 18-May-2020 in the set NewDate

Issue

the setNewdate setdaysAttendanceApprovedWithAdditionalDays is the being set to null

<h:form>
<p:panel id="panel" header="New User">

    <h:panelGrid columns="3" cellpadding="5">
        <p:outputLabel for="Additional Days" value="Additionaldays:" />
        <p:inputText id="additionaldays" value="#{saveMB.attendanceApprovalEntity.daysAttendanceApproved}">
        </p:inputText>
    </h:panelGrid>

    <p:commandButton value="Save" actionListener="#{saveMB.approveAttendance}" />
</p:panel>
</h:form>

saveMB.java

@ManagedBean(name = "saveMB")
@ViewScoped
public class saveMB implements Serializable {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(saveMB.class);

private Integer daysAttendanceApproved;

public Integer getdaysAttendanceApproved() {
    return daysAttendanceApproved;
}

public void setdaysAttendanceApproved(Integer daysAttendanceApproved) {
    this.daysAttendanceApproved = daysAttendanceApproved;
}

private Date newdate;

public Date getNewdate() {
    return newdate;
}

public void setNewdate(Date newdate) {
    this.newdate = newdate;
}

private AttendanceFlow attendanceApprovalEntity;

public AttendanceFlow getattendanceApprovalEntity() {
    return attendanceApprovalEntity;
}

public void setattendanceApprovalEntity(AttendanceFlow attendanceApprovalEntity) {
    this.attendanceApprovalEntity = attendanceApprovalEntity;
}


@PostConstruct
public void init() {

    ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
    Map<String, String> params = externalContext.getRequestParameterMap();

}

private Date setdaysAttendanceApprovedWithAdditionalDays(int daysAttendanceApproved2) {

    Date currentDate = new Date();
    Calendar c = Calendar.getInstance();
    c.setTime(currentDate);

    c.add(Calendar.DATE, daysAttendanceApproved2);

    Date currentDatePlusUserInput = c.getTime();
    return currentDatePlusUserInput;
}

public void approveAttendance(AjaxBehaviorEvent event) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    try {

        this.attendanceApprovalEntity.setNewdate(setdaysAttendanceApprovedWithAdditionalDays(this.attendanceApprovalEntity.getdaysAttendanceApproved())); 

    } catch (Exception e) {}

}
}

AttendanceFlow.java

@Entity
@Table(name = "ATTENDANCE_FLOW")
@NamedQuery(name = "AttendanceFlow.findAll", query = "SELECT h FROM AttendanceFlow h")
public class AttendanceFlow implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@SequenceGenerator(name = "ATTENDANCE_FLOW_ID_GENERATOR", sequenceName = "ATTENDANCE_FLOW_ID_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ATTENDANCE_FLOW_ID_GENERATOR")
@Column(name = "ATTENDANCE_FLOW_ID")
private Integer AttendanceFlowId;

@Column(name = "DAYS_ATTENDANCE_APPROVED")
private Integer daysAttendanceApproved;

@Column(name = "NEW_DATE")
@Temporal(TemporalType.DATE)
private Date newdate;

public Date getNewdate() {
    return newdate;
}

public void setNewdate(Date newdate) {
    this.newdate = newdate;
}    

public Integer getAttendanceFlowId() {
    return AttendanceFlowId;
}

public void setAttendanceFlowId(Integer AttendanceFlowId) {
    this.AttendanceFlowId = AttendanceFlowId;
}

public Integer getdaysAttendanceApproved() {
    return daysAttendanceApproved;
}

public void setdaysAttendanceApproved(Integer daysAttendanceApproved) {
    this.daysAttendanceApproved = daysAttendanceApproved;
}

}

While Debugging I can find the value of

 this.attendanceApprovalEntity.getdaysAttendanceApproved   

ie user entered value something like 10 , but I could not proceed afterthat

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • Does it work in a unittest? Put this logic in a service and test... not jsf related – Kukeltje May 09 '20 at 08:32
  • anveshijain: please do not use [java] tag as long as the problem is not demonstrable in a plain Java application class with `main()` method. Else you get completely unhelpful answers from ones who know nothing about JSF. – BalusC May 09 '20 at 10:29

2 Answers2

2

LocalDate::plusDays

Use LocalDate instead of outdated Date and Calendar. Check this for more details.

Do it as follows:

private LocalDate setDaysAttendanceApprovedWithAdditionalDays(int daysAttendanceApproved) {
    LocalDate date = LocalDate.now();
    return date.plusDays(daysAttendanceApproved);
}

A quick demo:

import java.time.LocalDate;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(setDaysAttendanceApprovedWithAdditionalDays(10));
    }

    static LocalDate setDaysAttendanceApprovedWithAdditionalDays(int daysAttendanceApproved) {
        LocalDate date = LocalDate.now();
        return date.plusDays(daysAttendanceApproved);
    }
}

Output:

2020-05-18

JPA and java.time

Remove @Temporal annotation from the attribute. Also, note that if you are using JPA 2.1 or earlier, you need to write a converter as shown here. If you are are using JPA 2.2 or later, you do not need any converter.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • So I tried your solution and in the Entity @Column(name = "NEW_DATE") @Temporal(TemporalType.DATE) private Date newdate; public Date getNewdate() { return newdate; } public void setNewdate(Date newdate) { this.newdate = newdate; } I had to change from Date to LocalDate – anveshijain May 08 '20 at 17:38
  • I had to change from Date to LocalDate @Column(name = "NEW_DATE") @Temporal(TemporalType.DATE) private LocalDate newdate; public LocalDate getNewdate() { return newdate; } public void setNewdate(LocalDate localDate) { this.newdate = localDate; } – anveshijain May 08 '20 at 17:38
  • But i receive this error in the entity class @Temporal should only be used on a java.util.Date or java.util. calender – anveshijain May 08 '20 at 17:38
  • @anveshijain - I've updated my answer to address this problem. – Arvind Kumar Avinash May 08 '20 at 17:46
  • I understood some part of your solution , But I did not understand how to handle the LocalDate attribute for a DATE column. – anveshijain May 08 '20 at 18:20
  • @anveshijain - Just create a converter class shown in the link and it will be automatically applied to the attributes of type `LocalDate`. Remove `@Temporal` annotation from the attribute. Feel free to comment in case of any further doubt/issue. – Arvind Kumar Avinash May 08 '20 at 18:50
-1

Use the GregorianCalendar class instead. Today's date can be obtained with date=new GregorianCalendar() and the number entered by the user can be added with date.add(Calendar.DAY_OF_MONTH,number).

Zelig63
  • 1,592
  • 1
  • 23
  • 40
  • 2
    `GregorianCalendar` in a *terrible* class, deeply flawed in design, as are the related `Calendar` & `Date` classes. These were supplanted years ago by the *java.time* classes defined in JSR 310. See [Answer by Avinash](https://stackoverflow.com/a/61684496/642706) for a modern solution. – Basil Bourque May 09 '20 at 05:23
  • I have never had any problem using this "terrible" class however... – Zelig63 May 10 '20 at 13:03