Kotlin继承和JPA

彼得

我正在尝试使用Kotlin和JPA实现继承。我的抽象基类(用注释@Entity)包含ID(用@Id注释@GeneratedValue)和其他元数据,例如createDate等。我从Hibernate中遇到了几个错误,除了ID之外,每个字段都有一个错误:

org.hibernate.tuple.entity.PojoEntityTuplizer-HHH000112:惰性类的获取器不能是最终的:com.example.BaseEntity.createDate

正如我读过的,我需要为每个属性添加open关键字。

我对此有3个问题:

  1. 为什么我必须在超类中这样做,而在子类中却不需要?我没有覆盖这些属性。
  2. 为什么不抱怨ID?
  3. 如果没有open关键字,它似乎可以工作,那么为什么记录错误?

编辑:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
abstract class BaseEntity(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long = 0,
    val createdAt: Instant = Instant.now()
)

@Entity
class SubClass(
    val someProperty: String = ""
) : BaseEntity()

我正在为Gradle使用JPA插件,我相信它会创建noarg构造函数,这就是为什么我不必指定所有可为空的东西的原因。

谢谢!

丹尼斯·扎维捷夫(Denis Zavedeev)

记录的错误与延迟加载有关

extends在运行时休眠实体以启用它。通过延迟加载实体时拦截对属性的访问来完成此操作。

Kotlin违反了规则,final默认情况下所有类都存在。这就是我们建议添加open关键字的原因。

如果属性不是open休眠的,则无法拦截对它的访问,因为final方法不能被覆盖。因此,错误。

为什么不抱怨ID?

因为@Id总是加载。无需拦截对其的访问。

似乎没有open关键字就可以工作,那么为什么会记录错误?

这里的关键词是似乎它可能会引入一些细微的错误。

考虑以下几点@Entity

@Entity
public class Book {
  @Id
  private Long id;
  private String title;

  public final Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public final String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }
}

@Test

@Test
public void test() {
  EntityManager entityManager = entityManagerFactory.createEntityManager();
  entityManager.getTransaction().begin();
  // signal here
  Book book = new Book();
  book.setId(1L);
  book.setTitle("myTitle");  
  entityManager.persist(book);
  // noise
  entityManager.getTransaction().commit();
  entityManager.close();

  entityManager = entityManagerFactory.createEntityManager();
  entityManager.getTransaction().begin();
  // signal
  Book reference = entityManager.getReference(Book.class, 1L);
  String title = reference.getTitle();
  assertNull(title); // passes

  entityManager.getTransaction().commit();
  entityManager.close();
}

该测试通过了,但是没有通过(如果getTitle没有通过,则失败final)。这很难注意到

为什么我必须在超类中这样做,而在子类中却不需要?我没有覆盖这些属性。

像Hibernate长相放弃它看到时final @Entity

添加openSubClass您将宝贵的:

2019-05-02 23:27:27.500 ERROR 5609 --- [           main] o.h.tuple.entity.PojoEntityTuplizer      : HHH000112: Getters of lazy classes cannot be final: com.caco3.hibernateanswer.SubClass.someProperty 

另请参阅

聚苯乙烯

你忘了包括@MappedSuperclassBaseEntity

没有注释,它将失败,并显示类似以下内容:

org.hibernate.AnnotationException: No identifier specified for entity: com.caco3.hibernateanswer.SubClass

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章