0

Hi I want to save data form jsp file to derby database using jpa.But cannot save the data to the database. In productorder page: Where I need save value

public class ProductOrder implements Serializable {
    @ManyToOne
    @JoinColumn(name = "customerId")
    private Customer customer;

    //getter 
    //setter
}

In EJB file:

public class OrderEJB {

    @PersistenceContext(unitName = "com.mycompany_Ebusiness_war_1.0-SNAPSHOTPU")
    private EntityManager entityManager;

    public ProductOrder placeOrder(ProductOrder productOrder) {
        entityManager.persist(productOrder);
        return productOrder;
    }
}

In jsp(xhtml file) file:

<h:form>
    <h:selectOneMenu value="#{orderController.customer}" >
        <f:selectItems value="#{orderController.customerList}" var="c" itemLabel="#{c.name}" itemValue="#{c.id}" />
    </h:selectOneMenu>
    <h:commandButton value="Place a Order" action="#{orderController.placeOrder}"/>
</h:form>

My converter file:

public class CustomerConverter implements Converter{ 

    private transient EntityManager em; 

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) { 
        return em.find(Customer.class, new Integer(value));
    }

    @Override
    public String getAsString(FacesContext fc, UIComponent uic, Object o) { 
        return ((Customer) o).getId().toString(); 
    }

}
Al-un
  • 3,102
  • 2
  • 21
  • 40
Gokul Basnet
  • 78
  • 1
  • 11
  • Any exception? error? You'll need the `referencedColumnName` attribute for the `customer` relationship btw. I guess your Customer is an Entity. You'll need a converter in your `` – Al-un Sep 22 '17 at 19:29
  • I tried to use controller but shows error like this: java.lang.Long cannot be cast to model.Customer My converter file: public class CustomerConverter implements Converter{ private transient EntityManager em; public Object getAsObject(FacesContext context, UIComponent component, String value) { return em.find(Customer.class, new Integer(value)); } public String getAsString(FacesContext fc, UIComponent uic, Object o) { return ((Customer) o).getId().toString(); } } – Gokul Basnet Sep 23 '17 at 10:05
  • My converter file: – Gokul Basnet Sep 23 '17 at 10:06
  • Can you update your post? It's hard to read your converter – Al-un Sep 24 '17 at 15:15
  • Please check I have updated.Thanks in advance. – Gokul Basnet Sep 26 '17 at 14:32

1 Answers1

0

Code errors

Your code contains some errors/missing point:

  1. missing optional referencedColumnName: as stated in comment, the JoinColumn annotation is missing an attribute. The attribute is optional but I like to make sure what is referenced:

    public class ProductOrder implements Serializable {
        @ManyToOne
        // replace "id" with the appropriate column name
        @JoinColumn(name = "customerId", referencedColumnName = "id")
        private Customer customer;
    
        //getter 
        //setter
    }
    

    the referencedColumnName is the FOREIGN KEY parallel. The above annotation is reflecting the constraint:

    FOREIGN KEY (customerId) REFERENCES customer_table(id)
    
  2. You're using JSF, not JSP. Please refer to this question for more information.

  3. Your selectOneMenu is incorrect:

    <h:form>
        <h:selectOneMenu value="#{orderController.customer}" converter="customerConverter">
            <f:selectItems value="#{orderController.customerList}" var="c"
                           itemLabel="#{c.name}" itemValue="#{c}" />
        </h:selectOneMenu>
        <h:commandButton value="Place a Order" action="#{orderController.placeOrder}"/>
    </h:form>
    
  4. You're converting the wrong value: your converter class converts customerId <-> customer object whereas in your selectOneMenu, you want to convert customer name <-> customer object

  5. Your converter class may be missing the @FacesConverter annotation

Solving

You'll need to solve each point one by one:

  1. Converter: Choose what you want to display in your form, if you want to display the customer name, then your converter should look like:

    @FacesConverter
    @RequestScoped
    public class CustomerConverter implements Converter{ 
    
        // you would normally inject your EJB here. Please refer to BalusC's 
        // answer for more information
        // private transient EntityManager em;
        @EJB
        private CustomerService customerService;
    
        @Override
        public Object getAsObject(FacesContext context, UIComponent component, String value) {
            return customerService.findByName(value);
        }
    
        @Override
        public String getAsString(FacesContext fc, UIComponent uic, Object o) { 
            return ((Customer) o).getName();
        }
    
    }
    

    in your customer service:

    @Stateless
    public class CustomerServiceImpl implements CustomerService{
    
        @Override
        public Customer findByName(String name){
            // assuming you have a name query to fetch by name,
            // otherwise use em.createQuery(...)
            TypedQuery<Customer> query = em.createNamedQuery("Customer.findByName", Customer.class);
            query.setParameter("name", name);
            return query.getSingleResult();
        }
    }
    
  2. when your converter is ready, adjust your h:selectOneMenu and f:selectItems accordingly

Al-un
  • 3,102
  • 2
  • 21
  • 40
  • it shows what?? Please be clearer when you state your issues – Al-un Sep 27 '17 at 00:57
  • I got this error when I submit the form java.lang.String cannot be cast to model.Customer – Gokul Basnet Sep 27 '17 at 00:57
  • Have you added the `converter` attribute in your `h:selectOneMenu`? – Al-un Sep 27 '17 at 00:58
  • [The error states that your converter has an issue](https://stackoverflow.com/a/23303504/4906586). Maybe your converter class has an issue. Can you check that way? – Al-un Sep 27 '17 at 01:07