Persistence problems
andreea Jun 7, 2010 8:02 PMI'm pretty much new to all things Seam, so please have mercy and help me with this one.
I'm using JBoss Seam 2.2 and JBoss Application Server 5.1.0.
This is the scenario:
I've got TestCases and TestSteps. One TestCase has multiple TestSteps.
I have a table that displays the steps and actions like addStep
and deleteStep
.
I use rich:inplaceInput to edit existing steps. This works perfectly.
Adding or deleting a step however does not. When adding, I create an empty
step which is displayed in the table and the user can then edit it.
I can't explain how it persists changes to existing steps, but doesn't cooperate when list TestCaseHome.testSteps changes in size.
Entity TestStep:
@Entity @Table(name = "teststeps") public class TestStep implements java.io.Serializable { private static final long serialVersionUID = 6534546556882292702L; private long id; private TestCase testCase; private String test; private String expectedResult; private long ordering; [...] @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "tc_id") public TestCase getTestCase() { return this.testCase; } public void setTestCase(TestCase testCase) { this.testCase = testCase; } [...] }
Entity TestCase:
Entity CoreTestObject isn't really relevant, TestCase just inherits it's id from it.
@Entity @Table(name = "testcases") @PrimaryKeyJoinColumn(name="id") public class TestCase extends CoreTestObject implements java.io.Serializable{ [...] private Set<TestStep> testSteps = new HashSet<TestStep>(0); public TestCase(Set<TestStep> testSteps, ...) { [...] this.testSteps = testSteps; } [...] @OneToMany(fetch = FetchType.LAZY, mappedBy = "testCase") @OrderBy("test") public Set<TestStep> getTestSteps() { return this.testSteps; } public void setTestSteps(Set<TestStep> testSteps) { this.testSteps = testSteps; } }
TestCaseHome:
@Name("testCaseHome") @Scope(ScopeType.CONVERSATION) public class TestCaseHome extends EntityHome<TestCase> { @DataModel private List<TestStep> testSteps; [...] /*@param step The Step after which the new Step is to be inserted*/ public void addStep(TestStep step){ testSteps = new ArrayList<TestStep>(this.getInstance().getTestSteps()); long id, ordering; [...] // here I find the id and ordering of step testSteps.add(new TestStep(id+1, this.getInstance(), "", "", ordering+1)); this.getInstance().setTestSteps(new HashSet<TestStep>(testSteps)); } /*@param step The Step to be deleted*/ public void deleteStep(TestStep step){ int index = testSteps.indexOf(step); testSteps.remove(index); this.getInstance().setTestSteps(new HashSet<TestStep>(testSteps)); } }
EntityHome:
public class EntityHome<E> extends Home<EntityManager, E> { @Transactional public String update() { joinTransaction(); getEntityManager().flush(); updatedMessage(); raiseAfterTransactionSuccessEvent(); return "updated"; } @Transactional public String persist() { getEntityManager().persist( getInstance() ); getEntityManager().flush(); assignId( PersistenceProvider.instance().getId( getInstance(), getEntityManager() ) ); createdMessage(); raiseAfterTransactionSuccessEvent(); return "persisted"; } [...] }
View:
<rich:dataTable value="#{testCaseHome.testSteps}" var="_testStep" id="testStepsTable" rowKeyVar="row" autoresize="true"> <rich:column sortBy="#{_testStep.ordering}" sortOrder="ASCENDING" style=" width : 20px;"> <f:facet name="header">Order</f:facet> <rich:inplaceInput layout="block" value="#{_testStep.ordering}" selectOnEdit="true" editEvent="onclick"> <a:support event="onviewactivated" ajaxSingle="true" reRender="testStepsTable" /> </rich:inplaceInput> </rich:column> <rich:column sortBy="#{_testStep.expectedResult}" [...] </rich:column> <rich:column sortBy="#{_testStep.test}"> [...] </rich:column> <rich:column style=" width : 80px;"> <f:facet name="header"> Action </f:facet> <a:commandLink ajaxSingle="true" id="deletelink" reRender="testStepsTable" action="#{testCaseHome.deleteStep(_testStep)}"> <h:graphicImage value="/img/delete.gif" /> <f:param name="testCaseId" value="#{testCaseHome.instance.id}" /> <f:param name="testStepFrom" value="TestCase" /> </a:commandLink> <a:commandLink ajaxSingle="true" id="addlink" reRender="testStepsTable" action="#{testCaseHome.addStep(_testStep)}"> <h:graphicImage value="/img/plus_icon.gif" style=" width : 16px; height : 16px;"/> <f:param name="testCaseId" value="#{testCaseHome.instance.id}" /> <f:param name="testStepFrom" value="TestCase" /> <s:conversationId /> <!-- <<<<I thought that might help but it didn't--> </a:commandLink> </rich:column> </rich:dataTable> [...] <div class="actionButtons"> <h:commandButton id="save" value="Save" action="#{testCaseHome.persist}" disabled="#{!testCaseHome.wired}" rendered="#{!testCaseHome.managed}" /> <h:commandButton id="update" value="Save" action="#{testCaseHome.update}" rendered="#{testCaseHome.managed}" /> [...] </div>
I had to cut a lot from the code, I hope I didn't leave anything relevant out.
I also hope this is the right place for this question, excuse me if not (noob here).
I would very much appreciate your help since I'm trying to fix this for weeks.
Thank you!