java - JSF SelectOneMenu 获取实体

标签 java jsf entity javabeans converters

我正在尝试从 JSF SelectOneMenu 组件获取 Customer 实体:我拥有的类如下:

客户实体

@Entity
@Table(name="CUSTOMERS")
@NamedQuery(name="Customer.findAll", query="SELECT c FROM Customer c")
public class Customer implements Serializable {

    @Id
    @GeneratedValue
    @Column(name="CUSTOMER_ID")
    private Long customerId;

    @Column(name="FIRST_NAME")
    private String firstName;

    @Column(name="LAST_NAME")
    private String lastName;

    private String email;

    public Long getCustomerId() {  
        return customerId;
    }

    public void setCustomerId(Long customerId) {
        this.customerId = customerId;
    }

    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 getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        Long localCustomerId = customerId;
        String localFirstName = firstName;
        String localLastName = lastName;
        String localEmail = email;
        if (localCustomerId == null) {
            localCustomerId = 0L;
        }
        if (localEmail == null) {
            localEmail = "";
        }
        if (localFirstName == null) {
            localFirstName = "";
        }
        if (localLastName == null) {
            localLastName = "";
        }

        String toString = "customerId = " + localCustomerId + "\n";
        toString += "firstName = " + localFirstName + "\n";
        toString += "lastName = " + localLastName + "\n";
        toString += "email = " + localEmail;

        return toString;
    }

}

客户 Controller

 @ManagedBean
    @RequestScoped
    public class CustomerController implements Serializable {
    private static final long serialVersionUID = 1L;

    @Resource(name = "jdbc/__CustomerDBPool")
    private DataSource dataSource;

    @PersistenceUnit(unitName = "customerPersistenceUnit")
    private EntityManagerFactory emf;

    @Resource
    private UserTransaction userTransaction;

    @ManagedProperty(value = "#{customer}")
    private Customer customer;


    public DataSource getDataSource() {
        return dataSource;
    }

    public EntityManagerFactory getEmf() {
        return emf;
    }

    public void saveCustomer() {
        EntityManager entityManager = emf.createEntityManager();
        try {
            userTransaction.begin();
            entityManager.persist(customer);
            userTransaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void setEmf(EntityManagerFactory emf) {
        this.emf = emf;
    }

    public List<Customer> getCustomerList() {

        List<Customer> list = null;
        EntityManager em = emf.createEntityManager();
        try {
            Query q = em.createNamedQuery("Customer.findAll");
            int m = q.getResultList().size();

            list = (List<Customer>)  q.getResultList();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    public Customer getCustomerById(Long id) {
        EntityManager entityManager = emf.createEntityManager();
        Query q = entityManager.createQuery("Select c FROM Customer c WHERE c.id = :id");
        q.setParameter("id", id);
        Customer c = (Customer) q.getResultList().get(q.getFirstResult());
        return c;
    }

    public String getCustomerDetails() {
        if (customer == null)
            return "NULL";
        else
            return customer.toString();
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
        //System.out.println(customer);
    }
    }

客户转换器

@ManagedBean
@RequestScoped
@FacesConverter(value = "CustomerConverter")
    public class CustomerConverter implements Converter, Serializable {

        @ManagedProperty(value = "#{cController}")
        private CustomerController cc;

        @Override
        public Object getAsObject(FacesContext context, UIComponent component,
                String value) {

            Long pk = Long.parseLong(value);
            Customer c = null;
            List<Customer> list = (List<Customer>) cc.getCustomerList();
            for (Customer k : list) {
                if (k.getCustomerId().equals(pk))
                        c = k;
            }

            return c;
        }

        @Override
        public String getAsString(FacesContext context, UIComponent component,
                Object value) {
            Long id = (Long) value;
            return id.toString();
        }

        public CustomerController getCc() {
            return cc;
        }

        public void setCc(CustomerController cc) {
            this.cc = cc;
        }
    }

最后是 .xhtml 文件

<h:head>
    <title>Save Customer</title>
</h:head>

<h:body>
    <h:panelGrid columns="1">

        <h:form>
            <h:messages id="messages"></h:messages>
            <p/>
            <h:selectOneMenu id="select1" value="#{customerController.customer}" converter="CustomerConverter">

                <f:selectItems 
                    value="#{customerController.customerList}" var="c"
                    itemLabel="#{c.customerId} #{c.firstName} #{c.lastName}"
                    itemValue="#{c.customerId}"/>
            </h:selectOneMenu>
            <p/>
            <h:commandButton value="Output" update="output2"></h:commandButton>

            <p/>
            <h:outputText id="output2" value="#{customerController.customerDetails}"/>
        </h:form>

    </h:panelGrid>
</h:body>
</html>

基本上,我在使用 CustomerConverter bean 实例化 CustomerController bean 时似乎遇到了麻烦。你知道我做错了什么吗?

最佳答案

这里,

@ManagedBean
@RequestScoped
@FacesConverter(value = "CustomerConverter")
public class CustomerConverter implements Converter, Serializable {

您已注册该类的 2 个不同的托管实例:一个为 @ManagedBean,另一个为 @FacesConverter

每当您在 EL 上下文中的任何位置使用 #{customerConverter} 时,都会返回来自 @ManagedBean 的请求范围托管 Bean 实例,其中 @ManagedProperty 已正确注入(inject)。

每当您在 View 中的任何位置使用 converter="CustomerConverter" 时,都会返回来自 @FacesConverter 的面孔转换器实例,其中根本不支持依赖注入(inject)。

这是不对的。这很令人困惑。只需摆脱 @FacesConverter 并改为使用

converter="#{customerConverter}"
<小时/>

与具体问题无关:在 JSF 托管 bean 中混合业务服务和 JPA 逻辑是一种非常糟糕的做法。为此,您应该使用功能齐全的 EJB。您可以在以下相关问题中找到具体示例:

关于java - JSF SelectOneMenu 获取实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16614329/

相关文章:

html - selectOneListBox 大小为 1 显示为下拉菜单

java - 在 Wildfly 中连接到 h2 数据库时出现问题

java - 在 Objectify 中计算实体的排名

Java 持久实体最佳实践

java - ObjectClass.class 变量在哪里定义/初始化?

javascript - 将具有位操作的Java代码从Java转换为JavaScript代码

带有 JSF 和 Primefaces 的 CSS - styleClass 不改变字体大小

swift - 结点并 swift 加入 Realm

java - Android 应用程序无法在 Eclipse 中的设备上启动

java - 使用什么技术来构建一个非常基本的酒店预订类型的网络应用程序?