【问题标题】:JPA and "anonymous" classes in scalascala中的JPA和“匿名”类
【发布时间】:2017-04-07 21:51:01
【问题描述】:

我有点卡住了,不明白发生了什么。 这个不行

@Entity
@DynamicInsert
@DynamicUpdate
@SelectBeforeUpdate
@Table
class Entity {
  @Column(nullable = false)
  var owner: String = _
}


    val myEntity = new Entity() {
            owner = "some owner 1"
          }
      session.persist(myEntity)

Hibernate 抛出异常:

java.lang.IllegalArgumentException: Unknown entity:persistence.dao.EntityDaoTest$$anonfun$13$$anonfun$14$$anon$5
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:777)

这个有效:

val myEntity = new Entity()
entity.owner = "some owner 1"
session.persist(myEntity)

为什么?为什么 hibernate 无法识别我的 Entity 实例?

更新: @Sheinbergon,谢谢,很清楚。我完全忘记了注释丢失了。有没有可能用一些快捷方式设置实体字段? 写作

val myEntity = new MyEntity()
myEntity.owner = "some owner"
myEntity.someOtherProperty = "value"

超级无聊

还有一个问题 这个有效:

val parent = new Parent
    parent.owner = "Our parent"
    parent.addChild(new Child() {
      name = "First parent's child"
      addGrandChild(new GrandChild() {
        name = "Grand child name"
        addGrandGrandChild(new GrandGrandChild() {
          name = "Grand Grand child name"
          address = new Address() {
            id = 1L
          }
        })
      })
    })

为什么? Child、GrandChild、GrandGrandChild 也是匿名创建的。 addChild、addGrandChild、addGrandGrandChild 只是列表修改器。

def addChild(child: Child): Unit = {
    if (children == null) {
      children = new util.ArrayList[Child]()
    }
    if (Option(child.parent).isEmpty) {
      child.parent = this
    }
    children.add(child)
  }

【问题讨论】:

  • 请“接受”我的回答(其中任何一个),因为它对您有帮助。我在下面的答案中添加了另一部分,该部分与您提出的新子问题有关
  • 完成,谢谢!现在很清楚了

标签: scala hibernate anonymous-class


【解决方案1】:

您在这里所做的是在 Scala 中匿名实例化一个类,以及...创建您的类 Entity 的匿名实现(就像在 Java 中匿名实例化接口)。

你可以通过打印类名来看到它 - 在这两种情况下都是println(myEntity.getClass)

应用于原始类的注释不适用于匿名类(反射仍然可以在超类中找到它们,但这取决于扫描它们的代码),我想这就是你得到各种 JPA 异常的原因

回答您添加的子问题

  • 关于快捷方式 - 为什么不将伴随对象用于工厂或将此类转换为案例类(使用默认值),从而实现更好、更灵活的初始化。
  • 关于第二个对象图(并假设您的每个类都已注释) - 这再次取决于反射代码如何处理它扫描的对象。有可能(而且更有可能,因为它不会扫描集合的每个成员以查找注释)它从集合的已擦除类型(可能在 Java 的反射 API 中将其 FQDN 类名获取为 ParameterizedType)获取注释定义而不是来自集合的实际成员,这就是它起作用的原因。 我不太确定它对字段定义有什么作用(它们只存在于“超级”类中),但这里没有“魔法”,只是普通的旧反射扫描。

【讨论】:

  • 这里没有匿名函数,它不是“某种”,而是完全像 Java 匿名类(也可以扩展类)。否则正确。
  • 类名中的anonfun是因为这段代码里面是一些未显示的匿名函数。
  • @AlexeyRomanov 谢谢你的cmets,我完善了我的答案:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-29
  • 2022-06-23
  • 1970-01-01
相关资源
最近更新 更多