我在Play for Scala中具有下面的代码,以使用Hibernate访问SAP Hana表。我需要用MySql实现相同的代码,但是问题是MySql不支持序列(它与AUTO_INCREMENT列一起使用)并且代码中断,因为我必须为Hana指定@SequenceGenerator
。有没有一种方法可以用排除@SequenceGenerator
注释的条件来编译此代码,以便它同时适用于MySql和Hana?
@Entity
@Table(name = "clients")
class ClientJpa {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
@SequenceGenerator(name="generator", sequenceName = "cliSeq", allocationSize = 1)
var surrogateKey: Int = _
var code: String = _
var name: String = _
}
最佳答案
该答案尝试实现Eugene's suggestion(因此,如果可行,请感谢Eugene)。
给定@ifNotMysql
宏的以下定义
import scala.reflect.macros.blackbox
import scala.language.experimental.macros
import scala.annotation.{StaticAnnotation, compileTimeOnly}
object ifNotMysqlMacro {
val targetIsMySql = sys.props.get("target-mysql").contains("true")
def impl(c: blackbox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
def mysqlAnnots(annotations: Seq[c.universe.Tree]): Seq[c.universe.Tree] =
annotations
.filterNot(_.toString.contains("SequenceGenerator"))
.filterNot(_.toString.contains("GeneratedValue"))
.:+(q"""new GeneratedValue(strategy = GenerationType.IDENTITY)""")
val result = annottees.map(_.tree).toList match {
case q"@..$annots var $pat: $tpt = $expr" :: Nil =>
q"""
@..${if (targetIsMySql) mysqlAnnots(annots) else annots}
var $pat: $tpt = $expr
"""
}
c.Expr[Any](result)
}
}
@compileTimeOnly("enable macro paradise to expand macro annotations")
class ifNotMysql extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro ifNotMysqlMacro.impl
}
如果我们这样写
@ifNotMysql @GeneratedValue(...) @SequenceGenerator
@ifNotMysql
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
@SequenceGenerator(name="generator", sequenceName = "cliSeq", allocationSize = 1)
var surrogateKey: Int = _
并像这样提供系统属性
target-mysql
sbt -Dtarget-mysql=true compile
那么
@SequenceGenerator
注释将被排除,并添加@GeneratedValue(strategy = GenerationType.IDENTITY)
像这样@GeneratedValue(strategy = GenerationType.IDENTITY)
var surrogateKey: Int = _
此实现基于scalamacros/sbt-example-paradise