如何有条件地包含一个Hibernate注释?

ps0*_*604 13 mysql hibernate scala playframework hana

我在Play for Scala中有以下代码来访问带有Hibernate的SAP Hana表.我需要用MySql实现相同的代码,但问题是MySql不支持序列(它适用于AUTO_INCREMENT列)和代码中断,因为我必须@SequenceGenerator为Hana 指定.有没有办法编译这个代码,条件是排除@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 = _
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*lic 2

这个答案试图实现尤金的建议(所以如果它有效,请给予尤金以信用)。

给出以下@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
}
Run Code Online (Sandbox Code Playgroud)

如果我们@ifNotMysql @GeneratedValue(...) @SequenceGenerator这样写

@ifNotMysql 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
@SequenceGenerator(name="generator", sequenceName = "cliSeq", allocationSize = 1)    
var surrogateKey: Int = _
Run Code Online (Sandbox Code Playgroud)

target-mysql并像这样提供系统属性

sbt -Dtarget-mysql=true compile
Run Code Online (Sandbox Code Playgroud)

然后@SequenceGenerator注释将被排除并@GeneratedValue(strategy = GenerationType.IDENTITY)像这样添加

@GeneratedValue(strategy = GenerationType.IDENTITY)
var surrogateKey: Int = _
Run Code Online (Sandbox Code Playgroud)

该实现基于scalamacros/sbt-example-paradise