Question

Imported ejb entity into tapestry project looks like this its in "generated sorces (jax-ws)"

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "money", propOrder = {
    "moneyAmount",
    "moneyCurrency",
    "moneyDate",
    "moneyFinishDate",
    "moneyIO",
    "moneyId",
    "moneyName",
    "moneyNextDate",
    "moneyNumber",
    "moneyPurpose",
    "moneyRenewal",
    "moneyTs"
})
public class Money {
    protected Double moneyAmount;
    protected String moneyCurrency;
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar moneyDate;
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar moneyFinishDate;
    protected MoneyIO moneyIO;
    protected Integer moneyId;
    protected String moneyName;
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar moneyNextDate;
    protected Integer moneyNumber;
    protected String moneyPurpose;
    protected MoneyNextTimeType moneyRenewal;
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar moneyTs;

    // Getters and Setters for above
    ...
}

all XMLGregorianCalendar is Date in ejb module

In tapestry page class:

@ejb
statefullEjbMoney

@Persist
@Property
List<Money> mylist

void onPrepareForRender() {
  mylist=statefullEjbMoney.findAll();
}

In my template I have:

 <table t:type="grid" t:source="mylist"
                   t:rowsPerPage="10" t:pagerPosition="both"
                   t:exclude="moneyId,moneyIO,moneyNextDate,moneyFinishDate,cliClientId"
                   t:reorder="moneyName,moneyPurpose,moneyAmount,moneyCurrency,moneyDate">
                [Grid here]
            </table>

The stacktrace in the glassfish log is:

Render queue error in SetupRender[Expenses:grid.columns]: Bean editor model for logic.ws.Money does not contain a property named 'moneyDate'.
org.apache.tapestry5.ioc.internal.util.TapestryException: Bean editor model for logic.ws.Money does not contain a property named 'moneyDate'. [at classpath:org/apache/tapestry5/corelib/components/Grid.tml, line 6]
    ...
Caused by: org.apache.tapestry5.ioc.util.UnknownValueException: Bean editor model for logic.ws.Money does not contain a property named 'moneyDate'.
    at org.apache.tapestry5.internal.beaneditor.BeanModelImpl.get(BeanModelImpl.java:160)
    at org.apache.tapestry5.internal.beaneditor.BeanModelImpl.reorder(BeanModelImpl.java:223)
    at org.apache.tapestry5.internal.beaneditor.BeanModelUtils.reorder(BeanModelUtils.java:107)
    at org.apache.tapestry5.internal.beaneditor.BeanModelUtils.modify(BeanModelUtils.java:51)
    at org.apache.tapestry5.corelib.components.Grid.getDataModel(Grid.java:523)
    at org.apache.tapestry5.corelib.components.GridColumns.setupRender(GridColumns.java:112)
    at org.apache.tapestry5.corelib.components.GridColumns.setupRender(GridColumns.java)
    at org.apache.tapestry5.internal.structure.ComponentPageElementImpl$SetupRenderPhase.invokeComponent(ComponentPageElementImpl.java:179)
    at org.apache.tapestry5.internal.structure.ComponentPageElementImpl$AbstractPhase.invoke(ComponentPageElementImpl.java:138)
    ... 84 more

If anyone has an idea what is wrong please share?

Était-ce utile?

La solution

The exception says the Bean Editor Model doesn't have a property called moneyDate, which I've always thought was a bit unclear.

To explain, Tapestry doesn't know what an XMLGregorianCalendar is, so when Tapestry creates the Bean Model for your grid, it helpfully ignores it.

Quick Solution

The quick way to solve this is to provide getters on your Money entity that return standard JDK Calendars, and display these properties in your grid.

So in your entity:

public class Money {
  @XmlSchemaType(name = "dateTime")
  protected XMLGregorianCalendar moneyDate;

  public Calendar getMoneyDataCalendar() {
    return moneyDate.toGregorianCalendar();
  }
  ...
}

Then use it in your grid:

<table t:type="grid" t:source="mylist" t:rowsPerPage="10" t:pagerPosition="both"
  t:exclude="moneyId,moneyIO,moneyNextDate,moneyFinishDate,cliClientId"
  t:reorder="moneyName,moneyPurpose,moneyAmount,moneyCurrency,moneyDateCalendar">

  [Grid here] Note 'moneyDate' changed to 'moneyDateCalendar' above [/Grid here]

</table>

Long Solution

If you plan to display lots of XMLGregorianCalendars then the (more involved) solution is to tell Tapestry about XMLGregorianCalendars and how to display them.

First tell Tapestry to add XMLGregorianCalendar to the Bean Model by adding this to your Module class:

@Contribute(DefaultDataTypeAnalyzer.class)
public static void contributeDefaultDataTypeAnalyzer(MappedConfiguration<Class<?>, String> config) {
  config.add(XMLGregorianCalendar.class, "xmlGregorianCalendar");
}

Now tell Tapestry how to display the new "xmlGregorianCalendar". Add to your Module class:

@Contribute(BeanBlockSource.class)
public static void contributeDisplayBlocksForGrid(Configuration<BeanBlockContribution> config) {
  config.add(new DisplayBlockContribution("xmlGregorianCalendar", "DisplayBlocks", "xmlGregorianCalendar"));
}

You now have to create a page called DisplayBlocks with a component with an id xmlGregorianCalendar:

public class DisplayBlocks {

  @Inject
  private Locale locale;

  @Property
  @Environmental
  private PropertyOutputContext context;

  private final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);

  public DateFormat getDateFormat(){
    return dateFormat;
  }

  public Date getCalendarDate() {
    XMLGregorianCalendar calendar = (XMLGregorianCalendar) context.getPropertyValue();        
    if (calendar == null)
        return null;        
    return calendar.getTime();
  }
}
<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">

  <t:block id="xmlGregorianCalendar">
    <t:output value="calendarDate" format="dateFormat"/>
  </t:block>

</t:container>

For more info look at the Tapestry source code and see how Tapestry configures itself. In particular look at:

org.apache.tapestry5.services.TapestryModule.contributeDefaultDataTypeAnalyzer()    
org.apache.tapestry5.services.TapestryModule.provideDefaultBeanBlocks()
org.apache.tapestry5.corelib.pages.PropertyDisplayBlocks

Autres conseils

There are minimal changes I have made to make it work

description is below.

Appmodule.java added following methods

public static void contributeDefaultDataTypeAnalyzer(MappedConfiguration<Class<?>, String> config) {
    config.add(XMLGregorianCalendar.class, "XMLGregorianCalendar");
}

@Contribute(BeanBlockSource.class)
public static void contributeDisplayBlocksForGrid(Configuration<BeanBlockContribution> config) {
    config.add(new DisplayBlockContribution("XMLGregorianCalendar", "DisplayBlocks", "XMLGregorianCalendar"));
}

no @Contribute on method contributeDefaultDataTypeAnalyzer

DisplayBlocks.java

public class DisplayBlocks {

    @Inject
    private Locale locale;
    @Property
    @Environmental
    private PropertyOutputContext context;
    private final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);

    public DateFormat getDateFormat() {
        return dateFormat;
    }

    public Date getCalendarDate() {
        XMLGregorianCalendar date = (XMLGregorianCalendar) context.getPropertyValue();
        Calendar calendar = date.toGregorianCalendar();
        if (calendar == null) {
            return null;
        }
        return calendar.getTime();
    }

XMLGregorianCalendar to context.getPropertyValue(); Than to Calender

DisplayBlocks.tml

<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">

    <t:block id="XMLGregorianCalendar">
        <t:output value="calendarDate" format="dateFormat"/>
    </t:block>

</t:container>

Changed block id to XMLGregorianCalendar

I got an error like this and reached this page. As it is clear from the error you should easily add a public getter for your property.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top