Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » scout » BeanArrayHolder and FormData
BeanArrayHolder and FormData [message #821837] Thu, 15 March 2012 17:57 Go to next message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 117
Registered: November 2010
Senior Member
I am trying to use a BeanArrayHolder with formData:

Here a first example that works:

  @Override
  public AnswerBean[] loadAll() throws ProcessingException {
    BeanArrayHolder<AnswerBean> beansArray = new BeanArrayHolder<AnswerBean>(AnswerBean.class);

    SQL.selectInto(" select question_id, name, answer_id " +
        " from answers " +
        " into  :QuestionNr, :YourName, :AnswerNr", beansArray);

    return beansArray.getBeans(null);
  }


with the Bean (defined in shared):
public class AnswerBean implements Serializable {
  private static final long serialVersionUID = 1L;
  private Long m_answerNr;
  private Long m_questionNr;
  private String m_yourName;

  public Long getAnswerNr() {
    return m_answerNr;
  }

  public void setAnswerNr(Long answerNr) {
    m_answerNr = answerNr;
  }

  public Long getQuestionNr() {
    return m_questionNr;
  }

  public void setQuestionNr(Long questionNr) {
    m_questionNr = questionNr;
  }

  public String getYourName() {
    return m_yourName;
  }

  public void setYourName(String yourName) {
    m_yourName = yourName;
  }
}


This works fine.

Now instead of this bean, I want to use the formData of the AnswerForm:

  @Override
  public AnswerFormData[] loadAll() throws ProcessingException {
    BeanArrayHolder<AnswerFormData> formDataArray = new BeanArrayHolder<AnswerFormData>(AnswerFormData.class);

    SQL.selectInto(" select question_id, name, answer_id " +
        " from answers " +
        " into  :QuestionNr, :YourName, :AnswerNr", formDataArray);

    return formDataArray.getBeans(null);
  }


This do not work, because the getters getQuestionNr() and getYourName() return a QuestionNr class (extending AbstractValueFieldData<Integer>) and a YourName class (extending AbstractValueFieldData<String>). These getters are just convenience getter for getFieldByClass(..).

The jdbc processor do not seems to recognize the formData and handle this like a normal Bean.

Quote:
ProcessingException[ProcessingStatus[ERROR code=0 invoking org.eclipselabs.mcqs.shared.services.process.IAnswerProcessService:loadAll / SQL with binds:
SELECT QUESTION_ID,
NAME,
ANSWER_ID
FROM ANSWERS
INTO :QuestionNr,
:YourName,
:AnswerNr
OUT :QuestionNr => ? [QuestionNr]
OUT :YourName => ? [YourName]
OUT :AnswerNr => ? [Long] / property QuestionNr java.lang.IllegalArgumentException: converting 1 from Long to AnswerFormData$QuestionNr failed with code 3 (no to-mapping)]]
at org.eclipse.scout.rt.server.services.common.jdbc.internal.exec.AbstractBeanPropertyOutput.finishBatch(AbstractBeanPropertyOutput.java:107)
at org.eclipse.scout.rt.server.services.common.jdbc.internal.exec.BeanArrayHolderOutput.finishBatch(BeanArrayHolderOutput.java:67)
at org.eclipse.scout.rt.server.services.common.jdbc.internal.exec.StatementProcessor.finishOutputBatch(StatementProcessor.java:550)
at org.eclipse.scout.rt.server.services.common.jdbc.internal.exec.StatementProcessor.processSelectInto(StatementProcessor.java:278)
at org.eclipse.scout.rt.server.services.common.jdbc.AbstractSqlService.selectInto(AbstractSqlService.java:717)
at org.eclipse.scout.rt.server.services.common.jdbc.SQL.selectInto(SQL.java:117)
at org.eclipselabs.mcqs.server.services.process.AnswerProcessService.loadAll(AnswerProcessService.java:103)
... and more
Caused by: java.lang.IllegalArgumentException: converting 1 from Long to AnswerFormData$QuestionNr failed with code 3 (no to-mapping)
at org.eclipse.scout.commons.TypeCastUtility.createException(TypeCastUtility.java:217)
at org.eclipse.scout.commons.TypeCastUtility.castBasicValueImpl(TypeCastUtility.java:286)
at org.eclipse.scout.commons.TypeCastUtility.castValueImpl(TypeCastUtility.java:145)
at org.eclipse.scout.commons.TypeCastUtility.castValue(TypeCastUtility.java:64)
at org.eclipse.scout.rt.server.services.common.jdbc.internal.exec.AbstractBeanPropertyOutput.finishBatch(AbstractBeanPropertyOutput.java:102)
... 61 more


Is there a FormDataArrayHolder ??? or something similar to achieve this ?

Is it reasonable to change scout in order to offer support for formData in the BeanArrayHolder or to create a FormDataArrayHolder ? (If you think this is a good idea, I could try to submit a patch).

Re: BeanArrayHolder and FormData [message #824050 is a reply to message #821837] Mon, 19 March 2012 03:35 Go to previous messageGo to next message
Ivan Motsch is currently offline Ivan Motsch
Messages: 100
Registered: March 2010
Senior Member
The javadoc of ISqlService describes all possibilities of binding.

For output batch filling, use :{name} instead of :name
Re: BeanArrayHolder and FormData [message #824136 is a reply to message #824050] Mon, 19 March 2012 05:53 Go to previous messageGo to next message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 655
Registered: October 2011
Senior Member
Ivan Motsch wrote on Mon, 19 March 2012 08:35
For output batch filling, use :{name} instead of :name


From what I can read in the Javadoc:
Quote:
Output Binds
* Output (SELECT INTO) binds are treated as follows
:name is filled by the column value. If there are multiple rows it is filled by an array containing all values of the corresponding column.
:tableHolder.column is a batch INTO bind. For every row in the select, one tableHolder row is created and filled up.

* Output (Stored Procedure Out Parameters) binds are treated as follows
:[OUT]name is filled by the single out parameter value
Note that :{name} is not a legal INTO bind.


The question is: how is it possible to get a tableHolder that contains formdatas.
Re: BeanArrayHolder and FormData [message #824165 is a reply to message #824136] Mon, 19 March 2012 06:41 Go to previous messageGo to next message
Ivan Motsch is currently offline Ivan Motsch
Messages: 100
Registered: March 2010
Senior Member
When using batch output i would write the query as follows:

@Override
public AnswerBean[] loadAll() throws ProcessingException {
BeanArrayHolder<AnswerBean> beansArray = new BeanArrayHolder<AnswerBean>(AnswerBean.class);

SQL.selectInto(" select question_id, name, answer_id " +
" from answers " +
" into :{QuestionNr}, :{YourName}, :{AnswerNr}", beansArray);

return beansArray.getBeans(null);
}
Re: BeanArrayHolder and FormData [message #824169 is a reply to message #824165] Mon, 19 March 2012 06:45 Go to previous messageGo to next message
Ivan Motsch is currently offline Ivan Motsch
Messages: 100
Registered: March 2010
Senior Member
Some "best practice" note:
1) To be more precise with binds i would qualify the bean array holder
2) java bean names always start with lowercase characters, use the java bean name, even though the sql binding might be lenient.
3) sql tables could be aliased
4) when getting all beans, beansArrayHolder.getBeans(); would do since the argument is an ellipsis.

This leads to the following:

@Override
  public AnswerBean[] loadAll() throws ProcessingException {
    BeanArrayHolder<AnswerBean> beansArrayHolder= new BeanArrayHolder<AnswerBean>(AnswerBean.class);

    SQL.selectInto(" select a.question_id, a.name, a.answer_id " +
        " from answers a" +
        " into  :{h.questionNr}, :{h.yourName}, :{h.answerNr}", 
        new NVPair("h",beansArrayHolder));

    return beansArrayHolder.getBeans();
  }

[Updated on: Mon, 19 March 2012 06:46]

Report message to a moderator

Re: BeanArrayHolder and FormData [message #824186 is a reply to message #824169] Mon, 19 March 2012 07:12 Go to previous messageGo to next message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 655
Registered: October 2011
Senior Member
According to the best practices (thanks for that), the first example should be written:
    BeanArrayHolder<AnswerBean> beanArrayHolder2 = new BeanArrayHolder<AnswerBean>(AnswerBean.class);
    SQL.selectInto(" select question_id, name, answer_id " +
        " from answers " +
        " into  :{list.questionNr}, :{list.yourName}, :{list.answerNr}", new NVPair("list", beanArrayHolder2));



It works fine with Java Beans (POJO)

For my tests, I tried several methods:
    //Plain Select
    Object[][] plainSelectResult = SQL.select(" select question_id, name, answer_id from answers ");
    System.err.println("plainSelectResult.size: " + plainSelectResult.length); // -> 3 rows.

    //BeanArrayHolder -> lenient [SOULD NOT BE USED]
    BeanArrayHolder<AnswerBean> beanArrayHolder1 = new BeanArrayHolder<AnswerBean>(AnswerBean.class);
    SQL.selectInto(" select question_id, name, answer_id " +
        " from answers " +
        " into  :questionNr, :yourName, :answerNr", beanArrayHolder1);
    System.err.println("beanArrayHolder1.size: " + beanArrayHolder1.getBeanCount()); // -> 3 beans.

    //BeanArrayHolder -> explicit binds
    BeanArrayHolder<AnswerBean> beanArrayHolder2 = new BeanArrayHolder<AnswerBean>(AnswerBean.class);
    SQL.selectInto(" select question_id, name, answer_id " +
        " from answers " +
        " into  :{list.questionNr}, :{list.yourName}, :{list.answerNr}", new NVPair("list", beanArrayHolder2));
    System.err.println("beanArrayHolder2.size: " + beanArrayHolder2.getBeanCount()); // -> 3 beans.

    //BeanArrayHolder using a formData -> still do not work because of Type Cast Exception (same as in the first message of the forum post).
    BeanArrayHolder<AnswerFormData> formDataArrayHolder = new BeanArrayHolder<AnswerFormData>(AnswerFormData.class);
    SQL.selectInto(" select question_id, name, answer_id " +
        " from answers " +
        " into  :{list.questionNr.value}, :{list.yourName.value}, :{list.answerNr.value}", new NVPair("list", formDataArrayHolder));
    System.err.println("formDataArrayHolder.size: " + formDataArrayHolder.getBeanCount()); // Exception before this line.



I still see the described exceptions because of QuestionNr being an AbstractValueFieldData<Integer>.

On the formData, there is no setQuestionNr(Integer). At the end of the batch, the AbstractBeanPropertyOutput should invoke formData.getQuestionNr().setValue(Integer)

I also tried:
    BeanArrayHolder<AnswerFormData> formDataArrayHolder = new BeanArrayHolder<AnswerFormData>(AnswerFormData.class);
    SQL.selectInto(" select question_id, name, answer_id " +
        " from answers " +
        " into  :{list.questionNr.value}, :{list.yourName.value}, :{list.answerNr.value}", new NVPair("list", formDataArrayHolder));


This also do not work.
Re: BeanArrayHolder and FormData [message #824214 is a reply to message #824186] Mon, 19 March 2012 07:57 Go to previous messageGo to next message
Ivan Motsch is currently offline Ivan Motsch
Messages: 100
Registered: March 2010
Senior Member
You are right, this case is not working as expected.
Let me check the test statement in the scout james server test.
It might be that this case is not yet part of the set.
Re: BeanArrayHolder and FormData [message #824248 is a reply to message #824214] Mon, 19 March 2012 08:39 Go to previous messageGo to next message
Ivan Motsch is currently offline Ivan Motsch
Messages: 100
Registered: March 2010
Senior Member
Can you please open a bugzilla ticket so we can fix that issue.
Please try to find a patch proposal if you can, else of course
i will take care of.
Re: BeanArrayHolder and FormData [message #824261 is a reply to message #824248] Mon, 19 March 2012 09:04 Go to previous message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 117
Registered: November 2010
Senior Member
Thanks for your inputs.

I opened the bug: Bugzilla 374646

Previous Topic:Sequence Shortcuts
Next Topic:Customizable JDialog in Scout
Goto Forum:
  


Current Time: Fri Aug 01 22:39:44 EDT 2014

Powered by FUDForum. Page generated in 0.01804 seconds