【问题标题】:EJB inheritance strategyEJB继承策略
【发布时间】:2013-01-27 17:25:46
【问题描述】:

重大更新:

好的,我发现我的问题比我想象的要复杂得多。我有这样的表:

Patient:
id
bloodtype
level (FK to level table)
doctor (FK to doctor table)
person (FK to person table)

Doctor:
id
person (FK)
speciality
level (FK to level)

Paramedic:
id
person (FK)

Person:
id
name
surname

Account:
id
login
pass

Level:
id
account (FK)
name (one of: 'patient' , 'paramedic' , 'doctor')

在实体类中,我现在在类Level 中使用@Inheritance(strategy= InheritanceType.JOINED) @DiscriminatorColumn(discriminatorType=DiscriminatorType.STRING,name="name")。检查某人是否是前任。患者我有功能:

public boolean ifPatient(String login) {
    account = accountfacade.getByLogin(login);
    for (Level l : account.getLevelCollection()) {
        if (l instanceof Patient) {
            return true;
        }
    }
    return false;
}

现在我的情况是:我以医生身份登录。我想添加一个病人。我有这样的事情:

public Doctor findDoctor(String login) {
        account = accountfacade.getByLogin(login);
        for (Doctor d : doctorfacade.findAll()) {
            if (d.getLevel().getAccount().getLogin().equals(login)) {
                doctor = d;
                return doctor;
            }
        }
    }
@Override
    public void addPatient(Account acc, Patient pat, Person per, String login) {
    Doctor d = findDoctor(login);
    accountfacade.create(acc);
    personfacade.create(per);
    Patient p = new Patient();
    p.setAccount(acc);
    p.setBlood(pat.getBlood());
// etc
    p.setPerson(per);
    d.getPatientCollection().add(p);
    acc.getLevelCollection().add(p);
    }

但它不起作用。总是完全奇怪的错误,例如表 Account 中主键的重复值(但我使用 TableGenerator...)或字段 Account 中的 NULL 值但对于 INSERT INTO Doctor(如何?!我正在创建新的 Patient,而不是 Doctor.. .)。我现在完全迷路了,所以我认为现在对我来说最重要的是知道在这种情况下我是否真的可以使用InheritanceType.JOINED

【问题讨论】:

  • 1) 收到答案后不要完全更改问题,创建一个新问题。 2)停止考虑表格,考虑实体。 3)一旦 2 完成,继承策略与操作无关(根据性能/表的大小/表的数量选择一个或另一个可能会很有趣,但除此之外,当你在使用实体)。

标签: jpa ejb


【解决方案1】:

更新:

您正在使用字段nazwa 作为鉴别器

@DiscriminatorColumn(discriminatorType=DiscriminatorType.STRING,name="nazwa")

框架将用于反序列化对象的类的名称存储在那里(它是PoziomDostepu 类的名称)。

据我所知,您为每个班级使用不同的表格,所以Strategy.JOINED 没有什么意义。

更多更新:

我说class 的意思是entity。您可以通过更改PoziomDostepu 的实体名称(例如“CacaCuloPedoPis”)并查看插入的新值来检查效果。

【讨论】:

  • 我在写完整篇文章之前不小心发了。是的,ids是生成的,我不用自己设置。但最重要的问题是字段 nazwa 由我设置,然后将其值更改为“PoziomDostepu”。我不知道发生了什么。
  • 你是对的。当我更改实体名称时,字段 nazwa 的值也发生了变化。请问您有什么不同的继承策略建议吗?
  • 您已经在使用TABLE_PER_CLASS。这只是正确设置注释的问题。 en.wikibooks.org/wiki/Java_Persistence/Inheritance
【解决方案2】:

看起来缺少的只是 PoziomDostepu 类上的 @DiscriminatorValue 注释以使用约束中的值之一,否则它默认为类名。 PoziomDostepu 的插入来自 this.poziom - 如果您不想插入 PoziomDostepu 实例,您可以使类抽象并确保此实例是子类。您不需要更改继承类型,因为这样做需要将数据库表更改为每个包含相同的字段。

【讨论】:

    【解决方案3】:

    好的,我已经完成了我想要的。它不优雅,但高效。表和继承策略是一样的。在端点中,我创建帐户和个人实体,然后创建 Patient 实体,但使用 EntityManager persist() 方法。我还需要手动设置级别的 ID ((Integer)poziomfacade.getEntityManager().createQuery("SELECT max(p.idpoziom) FROM PoziomDostepu p").getSingleResult())+1,因为 Level 实体类中的生成器不起作用。不过问题已经解决了,感谢每一个建设性的意见或回答。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-02
      • 2014-07-04
      • 2019-01-06
      • 2011-12-02
      • 1970-01-01
      • 2013-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多