Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Info: Velocity Expressions using many calls to $dataSource can cause error

    Hi Isomorphic,

    I have the following use case: Three boolean fields, exactly one must be set to true. Fields are defined as follows:
    Code:
    <field name="field1" length="1" type="boolean" sqlStorageStrategy="singleChar" sqlTrueValue="J" sqlFalseValue="N" required="true">...</field>
    Each field has this (definitely too complicated) validator:
    Code:
    <validators>
    	<validator type="serverCustom" errorMessage="Set exactly one field of 1/2/3!">
    			<serverCondition><![CDATA[
    	(
    			 (("$!record.field1" == "" && $dataSource.fetchById($record.ID).field1) || ("$!record.field1" != "" && "$!record.field1" == "true"))
    		&&
    			!(("$!record.field2" == "" && $dataSource.fetchById($record.ID).field2) || ("$!record.field2" != "" && "$!record.field2" == "true"))
    		&&
    			!(("$!record.field3" == "" && $dataSource.fetchById($record.ID).field3) || ("$!record.field3" != "" && "$!record.field3" == "true"))
    	) ||
    		(
    			!(("$!record.field1" == "" && $dataSource.fetchById($record.ID).field1) || ("$!record.field1" != "" && "$!record.field1" == "true"))
    		&&
    			 (("$!record.field2" == "" && $dataSource.fetchById($record.ID).field2) || ("$!record.field2" != "" && "$!record.field2" == "true"))
    		&&
    			!(("$!record.field3" == "" && $dataSource.fetchById($record.ID).field3) || ("$!record.field3" != "" && "$!record.field3" == "true"))
    	) ||
    		(
    			!(("$!record.field1" == "" && $dataSource.fetchById($record.ID).field1) || ("$!record.field1" != "" && "$!record.field1" == "true"))
    		&&
    			!(("$!record.field2" == "" && $dataSource.fetchById($record.ID).field2) || ("$!record.field2" != "" && "$!record.field2" == "true"))
    		&&
    			 (("$!record.field3" == "" && $dataSource.fetchById($record.ID).field3) || ("$!record.field3" != "" && "$!record.field3" == "true"))
    	)
    			]]></serverCondition>
    	</validator>
    </validators>
    On update velocity is called. But for some reason (I don't know if one (=you in your EE calls to velocity?) can configure it) velocity does not short-circuit-evaluate the expressions. At first, ALL the fetchById()-methods are called and the $dataSource.fetchById($record.ID).fieldX) is replaced with the result from the DS-fetch, then the result is given to the Parser.
    So within very short time, 9 or 18 DS-fetches are issued, sometimes resulting in this error displayed in the client:
    Code:
    Invocation of method 'fetchById' in class com.isomorphic.sql.SQLDataSource threw exception java.sql.SQLException: Listener refused the connection with the following error: ORA-12519, TNS:no appropriate service handler found The Connection descriptor used by the client was: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(PORT=1521)(HOST=localhost))(CONNECT_DATA=(SID=xe))) at CustomValidator[line 10, column 84]
    The error is OK for me, as this is probably bad design on my behalf, but I thought you might want to know this can happen.

    I think I'll rewrite it using http://www.smartclient.com/smartgwte...l#serverObject as I suppose this is the correct way of doing it.

    Best regards,
    Blama

    #2
    Yes this should definitely be a DMI/serverObject.

    Just FYI this is just an aspect of Velocity and not something we can control - it's not a programming language, it's a template language, so it doesn't do short-circuit evaluation of boolean expressions, it just evaluates all expressions up front and then starts filling in the template.

    Comment


      #3
      Hi Isomorphic,

      I found this thread again via search for a problem and the Velocity here fits in another use case of mine.
      I wanted to look up the docs and noticed that $dataSource is not in the docs, only $dataSources.

      I assume I got the code in #1 form a sample, although it is not this one.

      Best regards
      Blama

      Comment


        #4
        You’re looking at the general Velocity Support doc, shared across multiple contexts. In the DataSource DMI context, $dataSource and some other, context-specific variables are available that are not available in other contexts.

        Comment


          #5
          Hi Isomorphic,

          yes, this is the validation context. In the docs I mention in #3 you write "(available in validators only)" twice, so I think this belongs here as well.

          I also do see now that *other* $variables are mentioned in the ds-validator docs, which makes it even more confusing.

          Best regards
          Blama

          Comment

          Working...
          X