0

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;
    }

}

カスタマーコントローラー

 @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 をインスタンス化するのに問題があるようです。私が間違っていることはありますか?

4

2 に答える 2

1

ここ、

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

クラスの 2 つの異なるマネージド インスタンスを登録しました。1 つは as@ManagedBeanで、もう 1 つは as@FacesConverterです。

EL コンテキストの任意の場所で使用する#{customerConverter}と、リクエスト スコープのマネージド Bean インスタンス@ManagedBeanが返され、@ManagedProperty適切に注入されます。

ビューのどこでも使用すると、依存関係の挿入がまったくサポートされていないconverter="CustomerConverter"面コンバーターのインスタンスが返されます。@FacesConverter

これは正しくないです。これは紛らわしいです。単に取り除き@FacesConverter、代わりに使用する

converter="#{customerConverter}"

具体的な問題とは関係ありません。JSF マネージド Bean でビジネス サービスと JPA ロジックを混在させることは、非常に貧弱な方法です。これには完全な EJB を使用する必要があります。次の関連する質問で具体的な例を見つけることができます。

于 2013-05-19T02:12:42.390 に答える
1

@ManagedBeanand を使うの@FacesConverterは非常に悪いことだと思います。マネージド Bean は、ビューの処理を担当する必要があります。コンバーターは、値を変換するためのものです。
コードのもう 1 つの悪い設計ポイントは、マネージド Bean から直接 DB にアクセスしていることです。これも非常に悪いことです。データ アクセス用に別のレイヤー (DAO レイヤー) を定義する必要があります。顧客アクセス用に
を定義したとします。次に、DAO を介してマネージド Bean とコンバーターのテーブルに CustomerDAO簡単にアクセスできます。CUSTOMERS

于 2013-05-17T20:33:12.303 に答える