jpa如何创建与父实体具有相同ID的新实体(JOINED继承) [英] jpa how to create new entity with same id as parent entity (JOINED Inheritance)

查看:187
本文介绍了jpa如何创建与父实体具有相同ID的新实体(JOINED继承)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与更改实体保留其ID ,但是相反,我使用的是InheritanceType.JOINED而不是Table_per_class.

my question is very similar to Changing the type of an entity preserving its ID, but instead i´m using InheritanceType.JOINED instead of Table_per_class.

这意味着我不会更改任何表,而只是创建一个与超类具有相同ID的新子类.

This means i don´t to change any table, just to create a new subclass, with the same id as the superclass.

总而言之,我有一个Person类和一个Doctor,它扩展了Person并具有相同的id. 我需要从数据库中检索一个Person并将其设置为Doctor,保留Person实体中的所有数据,但为Doctor一个创建一些额外的数据.

To summarize, I have a Person class and a Doctor, which extends Person and has the same id of it. I need to retrieve a Person from the database and make it a Doctor, preserving all the data from the Person entity, but creating some extra data for the Doctor one.

尝试合并医生会生成一个新的ID,这对我无效.

Trying to merge the doctor generates a new id, which is not valid for me.

这是我首先尝试过的内容

Here´s what i´ve tried in first place

private Person getDoctor(Person person) {
            // Person already a doctor ==> OK
    if (person instanceof Doctor) {
        return person;
    }
            // Transient Person ==> //Transient Doctor OK
    if (person == null) {
        return new Doctor();
    }
            // Creates a Doctor from the person (only setting id...),
            // and merges it ==>
            fails as the id changes.
    Doctor doctor = new Doctor(person);
    return personDAO.merge(doctor);
}


sorry guys,first time here.

Here´s the code above:

    private Person getDoctor(Person person) {
    //Person already a doctor ==> OK 
       if (person instanceof Doctor) { 
            return person; 
    }


     //Transient Person ==> //Transient Doctor OK
        if (person == null) {
         return new Doctor(); 
        }
    //Creates a Doctor from the person (only setting id...), and merges it ==> fails as the id changes. 
    Doctor doctor = new Doctor(person);
    return personDAO.merge(doctor); 
    }


   @Inheritance(strategy = InheritanceType.JOINED)
   @Entity
   public class Person{
   }

   @Entity
   public class Doctor extends Person{
      public Doctor(Person person) {
        if (person != null) {
            this.setId(person.getId());
        }
    }
   }

推荐答案

就像您所链接的问题一样,答案是您无法使用Hibernate API做到这一点".

Just like in the question you've linked to, the answer is "you can't do this using Hibernate API".

原因实际上很清楚-Hibernate的目的是使持久性尽可能透明,因此,不能让您对持久性对象执行某些操作,而这些操作是普通Java无法实现的.一旦创建了Person的实例(用纯Java),它始终是一个Person.永远不会是Doctor.最好的办法是创建一个Doctor实例,并将Person的属性复制到该实例.

The reason is actually quite clear - Hibernate aims to make persistence as transparent as possible and, therefore, can't allow you do to things with persistent objects that you wouldn't be able to do with normal Java ones. Once you create an instance of Person (in plain java), it's always a Person. It will NEVER be a Doctor. The best you can do is to create a Doctor instance and copy Person's attributes to it.

但是,与普通的Java不同,使用Hibernate可以欺骗并实现所需的目标:-),但这必须通过本机SQL来完成.在您的方法中,您需要:

Unlike plain java, however, with Hibernate you can cheat and achieve what you want :-) but it has to be done via native SQL. In your method you'll need to:

  1. 从会话中驱逐Person实例(以及第二级缓存,如果适用)
  2. 将具有匹配ID(从Person实例获取)的行插入到Doctors表中.这是必须作为本机sql完成的部分,但是您可以将其定义为命名查询并将上述id设置为参数.请注意,如果对Doctor属性有任何限制,则需要确保插入的值满足它们.
  3. 重新加载Person实例-现在将作为Doctor加载.
  1. Evict Person instance from session (and 2nd level cache if applicable)
  2. Insert a row with matching ID (taken from Person instance) into Doctors table. That's the part that has to be done as native sql, but you can define it as named query and set the above id as parameter. Note that if have any constraints on Doctor properties, you'll need to make sure the values you insert satisfy them.
  3. Reload Person instance - which will now be loaded as Doctor.

这篇关于jpa如何创建与父实体具有相同ID的新实体(JOINED继承)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆