2011-10-19 26 views
0

我曾經初始化一個實體對象的某些屬性,它具有預定義的值,只要它在jsf託管bean的@PostConstruct方法中實例化(或者甚至是託管bean的構造函數)。當將託管bean移出項目到Seam時,我不能再保留這個功能(也想知道如何在沒有託管bean的情況下在JSF 2.2中)。從核心JSF遷移到Seam時移植託管bean的功能

實體類:

@Entity 
@Name("task") // this line in Seam version 
public class Task implements Serializable { 

    private Integer id; 
    private String subject; 
    private Date creationDate; 
    private Date completionDate; 
    private Category category; 
    private User user; 

    public Task() { 
    } 

    public Task(Date creationDate) { 
     this.creationDate = creationDate; 
     this.user = user; 
    } 

    // getters & setters, etc. 
} 

Managed Bean的

public class TaskBean extends BaseBean { 

    // Super class provides the logged in user object and a default category object 

    private Task task = new Task(java.util.Calendar.getInstance().getTime(), this.user); 

    @PostConstruct 
    public void initTaskBean() { 
     if (certainConditionMet) 
      task.setCategory(defaultCategory); 
    } 

    // Other managed bean business... 
} 

JSF頁面的JSF

<h:form> 
<h:panelGrid columns="2"> 
    Date: <h:outputText value="#{taskBean.task.creationDate}"> 
      <f:convertDateTime pattern="dd/MM/yyyy" /> 
      </h:outputText> 
    User: <h:outputText value="#{taskBean.task.user.name}" /> 
    Subject: <h:inputText value="#{taskBean.task.subject}" id="subjectField" /> 
    Category: <h:selectOneMenu value="#{taskBean.task.category}" id="catMenu"> 
       <f:selectItems value="#{taskBean.categories}" /> 
       </h:selectOneMenu> 
    // remaining stuff 
</h:panelGrid> 
</h:form> 

無狀態會話Bean Seam的版本中還假設了JSF的責任管理的bean

@Name("taskAction") 
@Stateless 
public class TaskAction implements TaskActionLocal { 

    @PersistenceContext 
    private EntityManager em; 

    @In private FacesMessages facesMessages; 
    @In User user; 
    @In Category defaultCategory 
    @Logger private Log log; 

    @In 
    // private Task task = new Task(java.util.Calendar.getInstance().getTime(), user) 
    // the above didn't work so 
    private Task task; 

    @PostConstruct 
    public void baslarken() { 
     System.out.println("TaskAction PostConstructed"); 
     task = new task(java.util.Calendar.getInstance().getTime(), user); 
     if (certainConditionMet) 
       task.setCategory(defaultCategory); 

     // the above won't work either. Date and User always blank on the ui form 
    } 

    // other business methods, etc 
} 

形式的縫版本:

<h:form id="todo" styleClass="edit"> 
    <rich:panel> 
     <f:facet name="header">Task To Do</f:facet> 

     <s:decorate id="dateField" template="layout/edit.xhtml"> 
      <ui:define name="label">Date:</ui:define> 
      <h:outputText value="#{task.creationDate}"/> 
     </s:decorate> 

     <s:decorate id="userField" template="layout/edit.xhtml"> 
      <ui:define name="label">User:</ui:define> 
      <h:outputText value="#{task.user.name}"/> 
     </s:decorate> 

     <s:decorate id="subjectField" template="layout/edit.xhtml"> 
      <ui:define name="label">Başlık</ui:define> 
      <h:inputText id="subject" required="true" value="#{task.subject}" > 
      <a4j:support event="onblur" reRender="subjectField" bypassupdates="true" ajaxSingle="true" /> 
      </h:inputText> 
     </s:decorate> 

     <!-- other components, etc --> 
    </rich:panel> 
</h:form> 

我需要就如何使任務對象的意見保存日期並登錄用戶數據(最好是默認類別),在實例化時預先填充。

回答

1

首先我很抱歉,但我找不到評論鏈接這個答覆?? (所以版主可以隨意移動這篇文章;))

擴展entityhome類作爲會話bean應該是可以的yes。但如果它是正確的我不確定。我更可能創建一個新的會話bean,更精確地爲我的目的服務。

用於工廠調用。您將以與其他任何名稱相同的方式從jsf頁面調用此方法。即值= 「#{createNewTask.id}」。或者你可以注入另一個班級。看一下縫文檔。它寫得很好。

+0

謝謝,馬丁。我在項目中使用了一種服務外觀模式,其中每個與數據庫的直接通信都使用會話bean作爲服務外觀完成,並且它們由Seam(managed-bean)組件調用 - 儘管Seam明智地說這種模式可能不是非常合適,因爲它可以消除對JSF託管bean的需求。因此,我將尋找一種更適合Seam的更合適的設計模式,並使我能夠保持大型項目的代碼清潔。 – Skyhan

1

您有幾種可能性來初始化實體。您可以爲實體擴展EntityHome類。這是編輯器處理實體的默認實現。如果您使用seam-gen創建您的應用程序,也可以使用它。

這將是這個樣子:

@Name("queryHome") 
@Scope(ScopeType.CONVERSATION) 
public class QueryHome extends EntityHome<Query> { 
    /* 
    * (non-Javadoc) 
    * @see org.jboss.seam.framework.Home#createInstance() 
    */ 
    @Override 
    public Query createInstance() { 
     Query query = super.createInstance(); 
     query.setUser(loggedUser); 
     query.setCreationDate(new Date()); 
     query.setLastExecutionDate(new Date()); 
     return query; 
    } 
} 

而且你將調用queryHome.getInstance()。 如果entityHome中的id屬性被設置,它將嘗試從數據庫中加載具有該id的實體,如果沒有id,它將調用createInstance()。 這是我通常使用它的方式。

您還可以在接縫管理bean中創建工廠註釋的方法。在那裏你可以做任何你喜歡的事情。

@Name("CreationFactory") 
@Scope(ScopeType.STATELESS) 
pulic class CreationFactory { 

    @Factory("createNewTask") 
    public Task createTask() { 
     Task task = new Task(); 
     task.sometext = "sometext"; 
     return task; 
    } 
} 

我通常不直接訪問或創建一個bean,但我使用管理器組件,如entityhome做到這一點。您可以使用工廠簡化訪問,但在Seam文檔中對此進行了解釋。

Martin馬丁

+0

馬丁,感謝您的建議,第一種方法工作得很好 - 儘管我不確定在EJB場景中,將EntityHome擴展爲會話bean會起作用(是嗎?)第二種方法,您可以給我一個想法如何調用createTask方法? – Skyhan