Scala + EclipseLink: JPA annotations treated as abstract traits, cannot be instantiated -
i writing scala backend uses eclipselink data abstraction layer.
i find having problems right out of box, although several tutorials have followed indicated no such thing. example, 1 of entities this:
@mappedsuperclass abstract class entity { @id @generatedvalue(strategy = generationtype.auto) @expose @beanproperty protected var id: int = 0 } @entity class user extends entity { @expose @temporal(temporaltype.timestamp) @beanproperty var createdat: date @expose @temporal(temporaltype.timestamp) @beanproperty var updatedat: date @expose @temporal(temporaltype.timestamp) @beanproperty var dateofbirth: date @expose @beanproperty var twostepverificationcode: string @expose @beanproperty var firstname: string @expose @beanproperty var lastname: string @expose @beanproperty var email: string @expose @beanproperty var description: string @expose @beanproperty var password: string @expose @beanproperty var salt: string }
upon compiling, however, whole set of errors related annotations:
entity.scala:45: trait id abstract; cannot instantiated @id ^ entity.scala:46: trait generatedvalue abstract; cannot instantiated @generatedvalue(strategy = generationtype.auto) ^ user.scala:14: class entity abstract; cannot instantiated @entity ^ user.scala:17: trait temporal abstract; cannot instantiated @temporal(temporaltype.timestamp) ^ user.scala:22: trait temporal abstract; cannot instantiated @temporal(temporaltype.timestamp) ^ user.scala:27: trait temporal abstract; cannot instantiated @temporal(temporaltype.timestamp) ^
what missing, , how can work around it?
remember in scala field must assigned not abstract, assign fields default-value.
like this:
@column(name = "external_reference") var externalreference: option[string] = none @manytoone(optional = false) @joincolumn(name = "account_id") @net.sf.oval.constraint.notnull var accountcode: accountcode = null
if use jpa-2.1 have converters handy:
//// start converters option of primitive-types. /* note: not autoapply because scala generates byte-code option[java.lang.object] el isn't able apply them automatically. */ @converter class optionlongconverter extends attributeconverter[option[long], lang.long]{ def converttodatabasecolumn(attribute: option[long]): lang.long = { attribute.map(long2long).ornull } def converttoentityattribute(dbdata: lang.long): option[long] = { if (dbdata eq null) none else some(dbdata) } } @converter class optionintconverter extends attributeconverter[option[int], lang.integer]{ def converttodatabasecolumn(attribute: option[int]): lang.integer = { attribute.map(int2integer).ornull } def converttoentityattribute(dbdata: lang.integer): option[int] = { if (dbdata eq null) none else some(dbdata) } }
use this:
@convert(converter = classof[optionintconverter]) var code: option[int] = none
for reference-types converters may auto-applied:
@converter(autoapply = true) class optionbigdecimalconverter extends attributeconverter[option[bigdecimal], jbigdecimal]{ def converttodatabasecolumn(attribute: option[bigdecimal]): jbigdecimal = { attribute.map(_.bigdecimal).ornull } def converttoentityattribute(dbdata: jbigdecimal): option[bigdecimal] = { if (dbdata eq null) none else some(dbdata) } } @converter(autoapply = true) class optionstringconverter extends attributeconverter[option[string], string] { def converttodatabasecolumn(attribute: option[string]): string = { attribute.ornull } def converttoentityattribute(dbdata: string): option[string] = option(dbdata) } @converter(autoapply = true) class optiondatetimeconverter extends attributeconverter[option[datetime], timestamp] { def converttodatabasecolumn(attribute: option[datetime]): timestamp = { attribute.map(v => new timestamp(v.getmillis)).ornull } def converttoentityattribute(dbdata: timestamp): option[datetime] = { option(dbdata).map(v => new datetime(v.gettime)) } } @converter(autoapply = true) class optionlocaldateconverter extends attributeconverter[option[localdate], date] { def converttodatabasecolumn(attribute: option[localdate]): date = { attribute.map(v => new date(v.todatemidnight.getmillis)).ornull } def converttoentityattribute(dbdata: date): option[localdate] = { option(dbdata).map(v => new localdate(v.gettime)) } }
so code works, without needing specify converter on mapped-field:
@column(name = "external_reference") var externalreference: option[string] = none
Comments
Post a Comment