How do I specify a static array in a Scala 2.8 annotation?
I've been building out some annotated domain classes in Scala 2.8.0 using Hibernate Annotations 3.4.0. It's been working fine, except that there are certain annotations which take an array as a parameter. For example, here's a Java annotation that I want to express in Scala:
@OneToMany(mappedBy="passport_id", cascade=CascadeType.PERSIST)
However, the annotation requires an array/set as input:
[ERROR] .../Passport.scala:50: error: type mismatch;
[INFO] found : javax.persistence.CascadeType(value PERSIST)
[INFO] required: Array[javax.persistence.CascadeType]
[INFO] @OneToMany(mappedBy="passport_id", cascade=CascadeType.PERSIST)
I've tried various parentheses, square/angle/curly brackets, and so on:
@OneToMany(mappedBy="passport_id", cascade=(CascadeType.PERSIST))
@OneToMany(mappedBy="passport_id", cascade=[CascadeType.PERSIST])
@OneToMany(mappedBy="passport_id", cascade=<CascadeType.PERSIST>)
@OneToMany(mappedBy="pass开发者_JAVA技巧port_id", cascade={CascadeType.PERSIST})
... but unfortunately I've reached the end of my understanding of Scala/Java annotations. Help is appreciated.
I'll add a few snippets from the spec to explain why Rex's solution works.
For Scala on the JVM, arguments to annotations that will be retained within the generated class must be constant expressions:
Instances of an annotation class inheriting from trait scala.ClassfileAnnotation will be stored in the generated class files. ... Additionally, on both Java and .NET, all constructor arguments must be constant expressions.
What are constant expressions?
6.24 Constant Expressions Constant expressions are expressions that the Scala compiler can evaluate to a constant. The definition of “constant expression” depends on the platform, but they include at least the expressions of the following forms:
- A literal of a value class, such as an integer
- A string literal
- A class constructed with Predef.classOf (§12.4)
- An element of an enumeration from the underlying platform
- A literal array, of the form Array(c1, . . . , cn), where all of the ci ’s are themselves constant expressions
- An identifier defined by a constant value definition (§4.1).
You should also be able to refactor the argument to a final val
. This doesn't seem to work for Arrays, however. I'll raise a bug.
class T(value: Any) extends ClassfileAnnotation
object Holder {
final val as = Array(1, 2, 3)
final val a = 1
}
@T(Holder.a)
@T(Holder.as) // annot.scala:9: error: annotation argument needs to be a constant; found: Holder.as
class Target
From Rex Kerr:
@OneToMany(mappedBy="passport_id", cascade=Array(CascadeType.PERSIST))
This worked. Thanks.
精彩评论