-
1. Re: Seam newbie question - default db field values
gonorrhea Apr 27, 2009 10:01 PM (in response to dzakharov.dmitri.zakharov.gmail.com)Depending on whether your form is causing setter/getter methods to be fired on an entity class directly or on an action backing bean (i.e. SFSB or JavaBean), the code would look something similar to this (this example is assuming the former scenario):
@In EntityManager entityManager; private EquipmentRepair equipmentRepairCost; public void submit() { //setter methods from form input text fields, etc. have already been called on entity class by now... equipmentRepairCost.setDate(new Date()); entityManager.persist(equipmentRepairCost); entityManager.flush(); //assuming you are using Hibernate MANUAL flush mode set in @Begin }
The entity needs to be persisted by invoking the persist() method b/c it is in transient state. The default flush mode in JPA is AUTO, so if you're not using Hibernate manual flush, you can delete the last line in the submit() method above and the persistence context will be automatically flushed/synchronized with the db when the tx commits successfully at the end of the method. We are assuming you're using SFSB and CMT (tx is required by default).
-
2. Re: Seam newbie question - default db field values
gonorrhea Apr 27, 2009 10:17 PM (in response to dzakharov.dmitri.zakharov.gmail.com)Here is a very good example from SIA book. Note that the call to the add() method passes the tip entity as a param. In the add() method you would call the add'l setters for that entity instance, like my code above.
<h:form id="golfTip"> <rich:simpleTogglePanel switchType="client" opened="false"> <f:facet name="header">Do you have golf wisdom to share?</f:facet> <div class="prop"> <h:outputLabel styleClass="name" for="author">Author <span class="required">*</span></h:outputLabel> <span class="value"> <h:inputText id="author" value="#{tip.author}" required="true" style="width: 150px;"/> </span> <span class="error"> <h:graphicImage value="/img/error.gif" rendered="#{not empty facesMessages.getCurrentMessagesForControl('author')}" styleClass="errors"/> <h:message for="author" styleClass="errors"/> </span> </div> <div class="prop"> <h:outputLabel styleClass="name" for="category">Category <span class="required">*</span></h:outputLabel> <span class="value"> <h:selectOneMenu id="category" value="#{tip.category}" required="true" style="width: 153px;"> <f:selectItem itemValue="" itemLabel="-- Select --"/> <f:selectItem itemValue="The Swing"/> <f:selectItem itemValue="Putting"/> <f:selectItem itemValue="Attitude"/> </h:selectOneMenu> </span> <span class="error"> <h:graphicImage value="/img/error.gif" rendered="#{not empty facesMessages.getCurrentMessagesForControl('category')}" styleClass="errors"/> <h:message for="category" styleClass="errors"/> </span> </div> <div class="prop"> <h:outputLabel styleClass="name" for="content">Content <span class="required">*</span></h:outputLabel> <span class="value"> <h:inputTextarea id="content" value="#{tip.content}" cols="20" rows="4" style="width: 200px;" required="true"/> </span> <span class="error"> <h:graphicImage value="/img/error.gif" rendered="#{not empty facesMessages.getCurrentMessagesForControl('content')}" styleClass="errors"/> <h:message for="content" styleClass="errors"/> </span> </div> <div style="clear: both;"> <span class="required">*</span> required fields </div> <div class="actionButtons"> <h:commandButton action="#{tipAction.add(tip)}" value="Submit Tip"/> </div> </rich:simpleTogglePanel> </h:form>
tipAction:
@Name("tipAction") public class TipAction { @Logger private Log log; @In private EntityManager entityManager; @In private FacesMessages facesMessages; @DataModel(scope = ScopeType.PAGE) private List<GolfTip> tips; @DataModelSelection @Out(required = false) private GolfTip activeTip; @Factory("tips") public void retrieveAllTips() { log.info("Factory for tips called. Retrieving all golf tips..."); tips = (List<GolfTip>) entityManager.createQuery("select t from GolfTip t").getResultList(); } public void add(GolfTip tip) { log.info("tipAction.add(GolfTip) action called"); if (tip.getContent().trim().length() == 0) { FacesMessages.instance().add("Please provide a tip from which we may all learn."); return; } log.info("Adding new golf tip..."); entityManager.persist(tip); activeTip = tip; facesMessages.add("Thanks for the tip, #{activeTip.author}!"); retrieveAllTips(); // required to reset form (because the submitted GolfTip is still populated) // another option is to outject a null value to the context variable tip Contexts.removeFromAllContexts("tip"); } public void delete() { log.info("tipAction.delete() action called"); log.info("Removing golf tip..."); activeTip = entityManager.find(GolfTip.class, activeTip.getId()); entityManager.remove(activeTip); facesMessages.add("The selected golf tip, contributed by #{activeTip.author}, has been deleted."); retrieveAllTips(); } }
-
3. Re: Seam newbie question - default db field values
dzakharov.dmitri.zakharov.gmail.com Apr 27, 2009 11:29 PM (in response to dzakharov.dmitri.zakharov.gmail.com)Thanks for the leads Arbi.
Here's what I found in my project... I generated it as EAR project. And here's what seam-gen generated for me. The action of my
Save
button in ClaimEdit.xhtml looks like this:<div class="actionButtons"> <h:commandButton id="save" value="Save" action="#{claimHome.persist}" disabled="#{!claimHome.wired}" rendered="#{!claimHome.managed}"/> ...
As far as I understand the action method persist() of the claimHome is called. ClaimHome class contains the following code:
@Name("claimHome") public class ClaimHome extends EntityHome<Claim> { @In(create = true) ClaimStatusHome claimStatusHome; @In(create = true) ExporterHome exporterHome; @In(create = true) TransmissionHome transmissionHome; public void setClaimClaimId(Integer id) { setId(id); } public Integer getClaimClaimId() { return (Integer) getId(); } @Override protected Claim createInstance() { Claim claim = new Claim(); return claim; } public void wire() { getInstance(); ClaimStatus claimStatus = claimStatusHome.getDefinedInstance(); if (claimStatus != null) { getInstance().setClaimStatus(claimStatus); } Exporter exporter = exporterHome.getDefinedInstance(); if (exporter != null) { getInstance().setExporter(exporter); } Transmission transmission = transmissionHome.getDefinedInstance(); if (transmission != null) { getInstance().setTransmission(transmission); } } public boolean isWired() { if (getInstance().getClaimStatus() == null) return false; if (getInstance().getExporter() == null) return false; return true; } public Claim getDefinedInstance() { return isIdDefined() ? getInstance() : null; } public List<Reject> getRejects() { return getInstance() == null ? null : new ArrayList<Reject>( getInstance().getRejects()); } }
I double checked the API docs and found that persist() method comes from the class EntityHome which ClaimHome extends. So my guess is that I should add another method to ClaimHome class, something likepublic void add() { // ... set constants and current date here persist(); }
I'll try it out and let you know.
Thank you.
-
4. Re: Seam newbie question - default db field values
dzakharov.dmitri.zakharov.gmail.com Apr 27, 2009 11:54 PM (in response to dzakharov.dmitri.zakharov.gmail.com)Arbi, thanks alot for the tips again.
Here's the method that I added to ClaimHome class that does the trick:
... @Override public String persist() { Claim c = getInstance(); c.setCreateDate(new Date()); c.setCreateApplication("credits"); //TODO: set with the current application user //c.setCreateUser(""); return super.persist(); } ...