1

I am working on a web application using PrimeFaces, JPA, Hibernate and JSF 2.0.

I have two entities Students and Course with an many to one relationship.

@Entity
@Table(name = "STUDENTS")
public class Students extends MainUsers implements Serializable {

    private String firstName;
    private String lastName;
    private long mobile;
    private String jobTitle;
    private int duration;
    @Temporal(TemporalType.TIMESTAMP)
    private Date startDate;
    @Temporal(TemporalType.TIMESTAMP)
    private Date endDate;

    @ManyToOne
    @JoinColumn(name = "course_id", nullable = true)
    private Course company;

    // Getters and setters.
}
@Entity
@Table(name = "COURSE")
@NamedQueries({
        @NamedQuery(name = "course.findCourseByCourseId", query = "select c from Course c where c.Id =:id"),
        @NamedQuery(name = "course.findCourseByCourseName", query = "select c from Course c where c.courseName =:courseName") })
public class Course implements Serializable {

    public static final String FIND_COURSE_BY_COURSE_ID = "course.findByCourseId";
    public static final String FIND_COURSE_COURSE_NAME = "course.findByCourseName";

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int Id;
    private String courseName;
    @OneToMany(targetEntity = Students.class, mappedBy = "course", fetch = FetchType.LAZY)
    private List<Students> students;

    // Getters and setters.

    @Override
    public int hashCode() {
        return getId();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Course) {
            Course course = (Course) obj;
            return course.getId() == Id;
        }

        return false;
    }

}

I have a registration page where it takes student's names, email, password and course. For selecting the course I have used this

<h:outputText value="Course :" />
<p:selectOneMenu value="#{courseMB.course}">
    <f:selectItem itemLabel="Select one Course" itemValue="" />
    <f:selectItems value="#{courseMB.allCourses}" var="crs"
        itemLabel="#{crs.courseName}" itemValue="#{crs.id}" />
    <f:converter converterId = "courseConverter"/>  
</p:selectOneMenu>

To create a student I have the following method in StudentMB class:

public void createStudent() {       
    String test = student.getEmail();

    if (getStudentFacade().isStudentExist(test)){
        System.out.println(test);
    } else {
        try {
            student.setActivation_key(hashKey());
            student.setRole(Role.STUDENT);
            student.setActive(0);
            getStudentFacade().createStudent(student);
            displayInfoMessageToUser("Created with success");
            SendEmail.Send(username, password, student.getEmail(), title, linkToSend());
            loadStudent();
            resetStudent();
        } catch (Exception e) {
            displayErrorMessageToUser("Opps, we could not create the user. Try again");
            e.printStackTrace();
        }
    }
}

I don't really know how to get the course into StudentMB and persist that into the database. The current methodology gives me an error

Conversion Error setting value 'courseID' for 'null Converter'.

I tried to use a converter but I am getting empty string into the argument.

@FacesConverter(value="courseConverter", forClass = com.model.Course.class)
public class CourseConverter implements Converter  {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
        CourseFacade courseFacade = new CourseFacade();
        int courseId;

        try {
            courseId = Integer.parseInt(submittedValue);
        } catch (NumberFormatException exception) {
            throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, 
                "Type the name of a Course and select it (or use the dropdown)", 
                "Type the name of a Course and select it (or use the dropdown)"));
        }

        return courseFacade.findCourse(courseId);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
        Course course = null;
        if (modelValue instanceof Course){
            course = (Course) modelValue;
            StringBuilder asString = new StringBuilder();
            asString.append(course.getId()+"-");
            asString.append(course.getCourseName());
            return asString.toString();

        }
        return "";
    }

}

How is this caused and how can I solve it?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
user1806180
  • 11
  • 2
  • 4

1 Answers1

1

You need to set the select item value to the Course itself, not to its id.

Replace

itemValue="#{crs.id}"

by

itemValue="#{crs}"

Otherwise the converter would only get the #{crs.id} as modelValue in getAsString() and thus return an empty string. This empty string is in turn submitted back to the server through getAsObject() which in turn causes the exception.

You should have thrown a ConverterException in the else part of the if (modelValue instanceof Course) so that it was immediately clear that the converter isn't suitable for the given model value.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you very much . But I am getting new error """Conversion Error setting value 'BE Process & Chemical Engineering' for 'null Converter'."""" I get this error when I select the course from the selects. – user1806180 Dec 01 '12 at 17:54
  • If you get the `null converter` error, then it basically means that no converter can be found for the `Course` class. Have you changed the `` or `@FacesConverter` after you posted the initial question? – BalusC Dec 01 '12 at 21:05
  • No, I did not change anything. All i did is just change #{crs.id } to #{crs} as you said. I have @ManagedConverter(name="courseConverterBean"), tried , but did not work. – user1806180 Dec 01 '12 at 21:36
  • *@ManagedBean(name="courseConverterBean") – user1806180 Dec 01 '12 at 21:46