0

I'm very to to jsf and Primefaces. My problem is, if I do not comment currentLunch = new Lunch(...)in *IndexBean.java` out, I'll get the error message which I've append below.

Without this line of code, the code will run.

Why I do that?

I want to add a new lunch instance in case of a 'save' click. That's why the 'add'-form has an empty instance of a lunch object. Is this way okay?

I checked the following Stackoverflow posts but I think, their solution would not solve my problem

Error log

1100: JSF1073: java.lang.IllegalArgumentException caught during processing of RENDER_RESPONSE 6 : UIComponent-ClientId=, Message=Cannot format given Object as a Date

Code

Index.htmlx

<h:form id="newLunch">
        <h:panelGrid columns="2" style="width: 300px;">
            <h:outputLabel for="initiator" value="Initiator" />
            <p:inputText id="initiator" value="#{indexBean.currentLunch.initiator}"/>

            <h:outputLabel for="date" value="Date" />
            <p:calendar id="date" minHour="11" maxHour="13" stepMinute="15" value="#{indexBean.currentLunch.date}"/>

            <p:commandButton value="save" action="#{indexBean.onSaveLunch}" update=":lunches" />
        </h:panelGrid>
</h:form>

IndexBean.java

@ManagedBean
@SessionScoped
public class IndexBean
{
private List<Lunch> lunches;
private Lunch currentLunch;
public List<Lunch> getLunches() ...
public void setLunches(List<Lunch> lunches) ...
public Lunch getCurrentLunch() ...
public void setCurrentLunch(Lunch currentLunch) ...

public IndexBean()
{
    // Set attributes to a value whichs should work (as you can see one line below)
    currentLunch = new Lunch("Tobi", "Starbucks", new DateTime(2014, 5, 30, 12, 0, 0 ,0));

    // This works without any problems.
    lunches = new ArrayList<Lunch>();
    lunches.add(new Lunch("Tobi", "Starbucks", new DateTime(2014, 5, 30, 12, 0, 0 ,0)));
}

public void onSaveLunch() ...

}

Lunch.java

public class Lunch
{
    private String initiator;
    private String location;
    private DateTime date;

    public Lunch(String initiator, String location, DateTime date)
    {
        this.initiator = initiator != null ? initiator : "";
        this.location = location != null ? location : "";
        this.date = date != null ? date : DateTime.now();
    }

    // default getter / setter


    public String getFormattedDate()
    {
        if(date == null) return "";
        DateTimeFormatter fmt = DateTimeFormat.forPattern("hh:MM (dd.MM.yyyy)");
        return date.toString(fmt);
    }
}
Community
  • 1
  • 1
Tobonaut
  • 2,245
  • 2
  • 26
  • 39

1 Answers1

1

This problem arise when you're not using java.util.Date. Check that the respective field in Lunch class has java.util.Date type and not java.sql.Date or another type.

Looks like you're using DateTime for Joda API. To solve this issue and not modify your current design, you may want to have a custom getter/setter for date field in your view. Just add this code to IndexBean:

public class IndexBean {
    //current code...
    public Date getDate() {
        if (currentLunch.getDate() != null) {
            return currentLunch.getDate().toDate();
        }
        return null;
    }
    public void setDate(Date date) {
        return currentLunch.setDate(new DateTime(date));
    }
}

And change the view to:

<!-- Note the expression language in value attribute -->
<p:calendar id="date" minHour="11" maxHour="13" stepMinute="15"
    value="#{indexBean.date}"/>

Not related to your current problem, but maybe @SessionScoped is a wider scope than you will need, probably the bean should be @ViewScoped.

Also, it is better to have any business logic associated to the bean initialization in a @PostConstruct annotated method:

public class IndexBean {
    public IntexBean() {
    }
    @PostConstruct
    public void init() {
        // Set attributes to a value whichs should work (as you can see one line below)
        currentLunch = new Lunch("Tobi", "Starbucks", new DateTime(2014, 5, 30, 12, 0, 0 ,0));
        // This works without any problems.
        lunches = new ArrayList<Lunch>();
        lunches.add(new Lunch("Tobi", "Starbucks", new DateTime(2014, 5, 30, 12, 0, 0 ,0)));
    }
    //rest of code...
}
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • Big thanks Luiggi. It's late in Germany and I'll test it tomorrow. In case of success, I'll mark your post as 'the answer'. – Tobonaut May 23 '14 at 19:56
  • 1
    I would suggest steering away from adding logic into your getters/setters, mostly due to potential null pointers on currentLaunch. If you really want to use DateTime on view your view Layer you could add a f:converter and generate a jsf converter than does the logic conversion from Date to DateTime. see: http://stackoverflow.com/questions/11641001/convert-jsf-calendar-date-into-jodatime-in-converter where they suggest using just util.Date for View, and DateTime in Business. :) – VeenarM May 24 '14 at 00:03
  • @VeenarM if OP already has lot of classes using Joda Time instead of `java.util.Date` then switching may not be an option. If not, then BalusC's suggestion would be great. – Luiggi Mendoza May 24 '14 at 00:07
  • Agreed, in which case creating a converter may be a better option - I would suggest that than putting the conversion in 'all' of your getters/setters yes? – VeenarM May 24 '14 at 02:29
  • Thanks to rest for also supporting a newbie! – Tobonaut May 24 '14 at 17:36