Jon
Jon

Reputation: 833

Struts2 select tag save and recall issue

I am getting confused trying to use the struts2 tag. I have followed several examples and they all seem to have the same usage pattern, but this doesn't work for me (below is all of the code that is relevant).

Basically, the struts2 select drop down allows me to display the initial list and save the value, but does not get displayed correctly when I bring the page up to edit the object. Once the page is displayed, all select values display the default instead of the expected value. If I modify the select value and save the page again, it will correctly save the value. Somewhere, the tag is not properly setting the SELECTED value of the option list. I am able to view the correct change being persisted to the database, so I know the action is correctly receiving the object.

I believe the problem lies somewhere within the <s:select list="lifeInsuranceStatuses" name="domainObject.lifeInsuranceCoverages[%{#status.index}].lifeInsuranceStatus.oid" listKey="oid" listValue="status" theme="simple" /> line of the JSP, but I may be wrong. It seems like all of the pieces of this page work except for setting the proper value of the drop down when the object is recalled.

Where I expect this

public class MemberAction
    extends AbstractAction<Member>
{
    private static final long serialVersionUID = 1L;
    private Service<LifeInsuranceStatus> lifeInsuranceStatusService;

    // Code removed for brevity...

    public List<LifeInsuranceStatus> getLifeInsuranceStatuses()
    {
        return lifeInsuranceStatusService.getObjects().getResponse();
    }

    public Service<LifeInsuranceStatus> getLifeInsuranceStatusService()
    {
        return lifeInsuranceStatusService;
    }

    public void setLifeInsuranceStatusService(Service<LifeInsuranceStatus> lifeInsuranceStatusService)
    {
        this.lifeInsuranceStatusService = lifeInsuranceStatusService;
    }
}

My JSP page looks like the following:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>

<s:form action="saveMember" method="post">
<table border="1">
    <tr>
        <td>
            <s:text name="domainObject.lifeInsuranceCoveragesn.lifeInsuranceStatus.status" />
        </td>
    </tr>
    <s:div id="LifeInsuranceCoverages" theme="simple">
        <s:iterator value="domainObject.lifeInsuranceCoverages" status="status">
            <tr class="lifeInsuranceCoverageRow<s:property value="%{#status.index}" />">
                <td>
                    <s:select list="lifeInsuranceStatuses" name="domainObject.lifeInsuranceCoverages[%{#status.index}].lifeInsuranceStatus.oid" listKey="oid" listValue="status" theme="simple" />
                </td>
            </tr>
        </s:iterator>
    </s:div>

    <tr id="addLifeInsuranceCoverageRow">
        <td>
            <a href="#" onClick="return LifeInsuranceCoverages.addRow()">Add Life Insurance Coverage...</a>
        </td>
    </tr>
</table>

<s:submit key="submit" />
</s:form>

And my model looks like:

public class Member
    extends Person
{
    private static final long serialVersionUID = 1L;

    private List<LifeInsuranceCoverage> lifeInsuranceCoverages;

    public List<LifeInsuranceCoverage> getLifeInsuranceCoverages()
    {
        if (lifeInsuranceCoverages == null)
        {
            lifeInsuranceCoverages = new ArrayList<LifeInsuranceCoverage>();
        }

        return lifeInsuranceCoverages;
    }

    public LifeInsuranceCoverage getActiveLifeInsuranceCoverage()
    {
        if (lifeInsuranceCoverages == null || lifeInsuranceCoverages.size() < 1)
        {
            return null;
        }
        else
        {
            return lifeInsuranceCoverages.get(lifeInsuranceCoverages.size() - 1);
        }
    }

    public void setLifeInsuranceCoverages(List<LifeInsuranceCoverage> lifeInsuranceCoverages)
    {
        this.lifeInsuranceCoverages = lifeInsuranceCoverages;

        for (LifeInsuranceCoverage lifeInsuranceCoverage : this.lifeInsuranceCoverages)
        {
            lifeInsuranceCoverage.setMember(this);
        }
    }

    public void addLifeInsuranceCoverage(LifeInsuranceCoverage lifeInsuranceCoverage)
    {
        lifeInsuranceCoverage.setMember(this);
        getLifeInsuranceCoverages().add(lifeInsuranceCoverage);
    }

    public void removeLifeInsuranceCoverage(LifeInsuranceCoverage lifeInsuranceCoverage)
    {
        getLifeInsuranceCoverages().remove(lifeInsuranceCoverage);
        lifeInsuranceCoverage.setMember(null);
    }
}

... and ...

public class LifeInsuranceCoverage
    extends AbstractDomainObject
{
    private static final long serialVersionUID = 1L;
    private Member member;
    private LifeInsuranceStatus lifeInsuranceStatus;

    public LifeInsuranceStatus getLifeInsuranceStatus()
    {
        return lifeInsuranceStatus;
    }

    public void setLifeInsuranceStatus(LifeInsuranceStatus lifeInsuranceStatus)
    {
        this.lifeInsuranceStatus = lifeInsuranceStatus;
    } 

    public Member getMember()
    {
        return member;
    }

    public void setMember(Member member)
    {
        this.member = member;
    }
}

... and ...

public class LifeInsuranceStatus
    extends AbstractDomainObject
{
    private static final long serialVersionUID = 1L;
    private String status;

    public String getStatus()
    {
        return status;
    }

    public void setStatus(String status)
    {
        this.status = status;
    }
}

... and also ...

public abstract class AbstractDomainObject
    implements DomainObject
{
    private static final long serialVersionUID = 1L;
    private Long oid;

    public Long getOid()
    {
        return oid;
    }

    public void setOid(Long oid)
    {
        this.oid = oid;
    }
}

Upvotes: 1

Views: 1922

Answers (1)

Jon
Jon

Reputation: 833

I was able to figure out this issue after some trial and error. The solution I found doesn't make sense to me but it works regardless.

In order to fix this, I had to do two things. First, I added a toString() method in the LifeInsuranceStatus class that returned just the status value. Then I removed the listKey portion of the struts2 tag. Once I did these two things together, the value I stored in the database was recalled properly and saved properly.

I would love to know why this worked this way. Anyone have better knowledge of struts2 tags or why another drop down that used an enum worked perfectly fine without removing the listKey portion of the tag...

Upvotes: 0

Related Questions