Wednesday 7 April 2010

ADF BC 11g Groovy expressions implicit type conversions

Under JDeveloper 11g ADF Business Components introduced the support for Groovy expressions. Among other benefits this allows JDeveloper programmers to skip many trivial Java programming tasks with a shorthand Groovy expression. Grant Ronald's Introduction to Groovy Support in JDeveloper and Oracle ADF 11g provides a good compliment to the Fusion Guide on Groovy expressions.

The Groovy support includes the ability to reference attributes of Entity Objects and View Objects. For instance you may create a transient attribute TotalCost in an InvoiceLines Entity Object based on the Groovy expression "Cost * Quantity" referencing the same named Entity Object attributes:


As you become more familiar with the use of Groovy expressions you'll realize you can also call the functions of the underlying attribute type. For instance a String attribute FullName would support the Groovy expression "FullName.toLowerCase()".

However there is a catch. When calling functions of a specific attribute, say calling the oracle.jbo.domain.Number add() function on the Quantity Number attribute, at runtime you might discover a runtime error such as:

(oracle.jbo.JboException) JBO-29000: Unexpected exception caught: groovy.lang.MissingMethodException, msg=No signature of method: java.lang.Long.add() is applicable for argument types: (java.lang.Integer) values: [1]

This comes as a surprise as the Fusion Guide tells us the Number attribute type is backed by the oracle.jbo.domain.Number class supplied by Oracle.

What's happening is that the Groovy expression evaluator is undertaking some implicit datatype conversions/casts on our behalf with the underlying attributes. In order to make this easier to understand I've documented the type conversions for you. The following table gives you the Type Name as selected in the EO/VO attribute editor, the Java Type you'll see in the resulting EntityImpl and ViewRowImpl classes, and then the Groovy Type they'll be cast to during a Groovy expression evaluation.

You'll note with the Groovy Types sometimes they are in fact the oracle.jbo.domain class, but in others they're the parent class. And for some types there is no oracle.jbo.domain equivalent, just a java.lang type. It's all a bit inconsistent but hopefully the table gives you the appropriate type for your attribute:

Type NameJava TypeGroovy Type
Arrayoracle.jbo.domain.Array-
BFileDomainoracle.jbo.domain.BFileDomain-
BigDecimaljava.math.BigDecimaljava.math.BigDecimal
BlobDomainoracle.jbo.domain.BlobDomainoracle.jbo.domain.BlobDomain
Booleanjava.lang.Booleanjava.lang.Boolean
Bytejava.lang.Bytejava.lang.Byte
Charoracle.jbo.domain.Charjava.lang.String
Characterjava.lang.Characterjava.lang.Character
ClobDomainoracle.jbo.domain.ClobDomainoracle.jbo.domain.ClobDomain
DBSequenceoracle.jbo.domain.DBSequencejava.lang.Long
Dateoracle.jbo.domain.Datejava.sql.Date
Doublejava.lang.Doublejava.lang.Double
Floatjava.lang.Floatjava.lang.Float
Integerjava.lang.Integerjava.lang.Integer
Longjava.lang.Longjava.lang.Long
NClobDomainoracle.jbo.domain.NClobDomainoracle.jbo.domain.NClobDomain
Numberoracle.jbo.domain.Numberjava.lang.Long
Objectjava.lang.Objectjava.lang.Object
OrdAudioDomainoracle.ord.im.OrdAudioDomainoracle.ord.im.OrdAudioDomain
OrdDocDomainoracle.ord.im.OrdDomainoracle.ord.im.OrdDomain
OrdImageDomainoracle.ord.im.OrdImageDomainoracle.ord.im.OrdImageDomain
OrdImageSignatureDomainoracle.ord.im.OrdImageSignatureDomainoracle.ord.im.OrdImageSignatureDomain
OrdVideoDomainoracle.ord.im.OrdVideoDomainoracle.ord.im.OrdVideoDomain
REForacle.sql.REF-
Raworacle.jbo.domain.Raw-
RowIDoracle.jbo.domain.RowIDjava.lang.String
Shortjava.lang.Shortjava.lang.Short
Stringjava.lang.Stringjava.lang.String
Timestamporacle.jbo.domain.Timestampjava.sql.Timestamp
TimestampLTZoracle.jbo.domain.TimestampLTZjava.sql.Timestamp
TimestampTZoracle.jbo.domain.TimestampTZjava.sql.Timestamp

You'll note I've missed a few Groovy Types, I simply couldn't determine the equivalent type.

This post was specifically written against JDeveloper 11g 11.1.1.2.0 build 5536. It's quite possibly in the future Oracle will tweak the data types to make it more consistent so be careful to check my facts.

1 comment:

Unknown said...

We definitely need a unififed type system in ADF;)