Scala 中的 JPA 和 "anonymous" 类
JPA and "anonymous" classes in scala
我有点卡住了,不明白发生了什么。
这个不行
@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$$anonfun$$anon
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:777)
这个有效:
val myEntity = new Entity()
entity.owner = "some owner 1"
session.persist(myEntity)
为什么?为什么休眠无法识别我的 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 中匿名实例化一个 class ,好吧......创建你的 class Entity
的匿名实现(就像匿名实例化一个接口在 Java).
您可以通过打印 class 名称来查看 - println(myEntity.getClass)
在这两种情况下
应用于原始class的注释不适用于匿名注释(反射仍然可以在超级class中找到它们,但这取决于扫描它们的代码)我想那是为什么你会收到各种 JPA 异常
回应您添加的子问题
- 关于快捷方式 - 为什么不为工厂使用伴随对象或将此 class 转换为案例 class(使用默认值),以实现更好、更灵活的初始化。
- 关于第二个对象图(并假设每个 classes 都被注释了)——这又取决于反射代码如何处理它扫描的对象。有可能(并且更有可能,因为它不会扫描集合中的每个成员以获取注释)它从已擦除的类型中获取注释定义(可能将其 FQDN class 名称作为
ParameterizedType
in Java 对集合的反射 API) 而不是来自集合的实际成员,这就是它起作用的原因。
我不太确定它对字段定义做了什么(它们只存在于 "super" class 中),但是这里没有 "magic",只有普通的旧反射扫描。
我有点卡住了,不明白发生了什么。 这个不行
@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$$anonfun$$anon
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:777)
这个有效:
val myEntity = new Entity()
entity.owner = "some owner 1"
session.persist(myEntity)
为什么?为什么休眠无法识别我的 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 中匿名实例化一个 class ,好吧......创建你的 class Entity
的匿名实现(就像匿名实例化一个接口在 Java).
您可以通过打印 class 名称来查看 - println(myEntity.getClass)
在这两种情况下
应用于原始class的注释不适用于匿名注释(反射仍然可以在超级class中找到它们,但这取决于扫描它们的代码)我想那是为什么你会收到各种 JPA 异常
回应您添加的子问题
- 关于快捷方式 - 为什么不为工厂使用伴随对象或将此 class 转换为案例 class(使用默认值),以实现更好、更灵活的初始化。
- 关于第二个对象图(并假设每个 classes 都被注释了)——这又取决于反射代码如何处理它扫描的对象。有可能(并且更有可能,因为它不会扫描集合中的每个成员以获取注释)它从已擦除的类型中获取注释定义(可能将其 FQDN class 名称作为
ParameterizedType
in Java 对集合的反射 API) 而不是来自集合的实际成员,这就是它起作用的原因。 我不太确定它对字段定义做了什么(它们只存在于 "super" class 中),但是这里没有 "magic",只有普通的旧反射扫描。