Using scala constants in constant expressions

回眸只為那壹抹淺笑 提交于 2020-01-24 13:58:06

问题


I have constants, that are made of other, smaller constants. For example

object MyConstants {
    final val TABLENAME = "table_name";
    final val FIELDNAME = "field_name";
    final val INDEXNAME = TABLENAME + "_" + FIELDNAME + "_ix"; // this one does not want to be constant
}

I want these to be true constants because I use them in annotations.

How do I make it work? (on scala 2.11)

What I want is

interface MyConstants {
    String TABLENAME = "table_name";
    String FIELDNAME = "field_name";
    String INDEXNAME = TABLENAME + "_" + FIELDNAME + "_ix";
}

but in scala. Scalac does not pick up constants for usage in annotations if it compiles them from java class/interface (see SI-5333) so I decided to put them in a scala object. It works for literals, and for expressions with literals, but not for expressions with other constants.

With this code:

import javax.persistence.Entity
import javax.persistence.Table
import org.hibernate.annotations.Index

object MyConstants {
    final val TABLENAME = "table_name";
    final val FIELDNAME = "field_name";
    final val INDEXNAME = TABLENAME + "_" + FIELDNAME + "_ix";
}

@Entity
@Table(name = MyConstants.TABLENAME)
@org.hibernate.annotations.Table(
    appliesTo = MyConstants.TABLENAME,
    indexes = Array(new Index(name = MyConstants.INDEXNAME, columnNames = Array(MyConstants.FIELDNAME)))) 
class MyEntity {
}

I get a following error on line indexes = ...

annotation argument needs to be a constant; found: MyConstants.INDEXNAME

Edit: After fiddling around with a few build configurations, I think this is actually a scala-ide specific issue. The code does indeed compile alright when I build project with gradle or sbt. I do use build tool for my actual projects, so in the end it's about having a few incomprehensible markers in the IDE - annoying, but has little to do with functionality.


回答1:


I used constants in JPA with scala. This code compiles, and I used it:

FreeDays.scala

@Entity
@Table(name = "free_days")
@NamedQueries(
  Array(
    new NamedQuery(name = JpaQueries.IS_FREE_DAYS, query = "SELECT f FROM FreeDays f WHERE f.dateOfFreeDay = :" + JpaQueries.DATE)
  )
)
class FreeDays {

  def this(id: Int, name: String, dateOfFreeDay: Date) = {
    this()
    this.id = id
    this.name = name
    this.dateOfFreeDay = dateOfFreeDay
  }

  @Id
  @GeneratedValue
  var id: Long = _

  var name: String = _

  @Column(name = "date_of_free_day")
  @Temporal(TemporalType.DATE)
  var dateOfFreeDay: Date = _
}

JpaQueries.scala

object JpaQueries extends JpaQueries

sealed trait JpaQueries {
  final val IS_FREE_DAYS = "IS_FREE_DAYS"
  final val DATE = "date"
}


来源:https://stackoverflow.com/questions/23695618/using-scala-constants-in-constant-expressions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!