mysql - 如何有条件地包含 Hibernate 注释?

标签 mysql scala hibernate playframework hana

我在 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

关于mysql - 如何有条件地包含 Hibernate 注释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47995473/

相关文章:

json - 如何将scala数组写入json文件?

java - 无法在此 ManagedType 上找到具有给定名称 [XXX] 的属性 [未知]

Mysql:如何仅使用一个命令获取 mysql 状态信息

mysql - 项目属性的 RSS 2 规范

mysql - SQL - 将多个字段放入一个字段中

java - hibernate如何维护多个java实例的缓存

java - GenericJDBCException 被 try/catch block 的错误部分捕获

mysql - mysql 更新问题 - 它更改了所有行

scala - 如何从 Spark 管道逻辑模型中提取变量权重?

scala - 将 RDD 写入 csv