Java 为什么在使用@JoinTable时忽略@DiscriminatorColumn?

Java 为什么在使用@JoinTable时忽略@DiscriminatorColumn?,java,hibernate,jpa,jakarta-ee,discriminator,Java,Hibernate,Jpa,Jakarta Ee,Discriminator,假设我有以下表格: ______________________ | LAWSUIT | |______________________| | ID | | TITLE | |______________________| \ \ \

假设我有以下表格:

 ______________________
|       LAWSUIT        |
|______________________|
| ID                   |
| TITLE                |
|______________________|
                        \
                         \
                          \
                             ______________________
                            | PERSONS_IN_THE_CASE  |
                            |______________________|
                            | ID_LAWSUIT           |
                            | ID_PERSON            |
                            |______________________|
                          /
                         /
                        /
 ______________________
|        PERSON        |
|______________________|
| ID                   |
| NAME                 |
| TYPE                 | TYPE values = "Plantiff, Defendant, Lawyer, Judge, ..."
|______________________|
(我知道规范化数据库可以为每个人类型创建一个表,但让我们坚持实际结构)

我用JPA(2.0)对不同的人进行了如下分类:

@实体
@表(name=“PERSON”)
@继承(策略=InheritanceType.SINGLE_表)
@鉴别器列(name=“TYPE”)
公共抽象类人物{
@实体
@鉴别器值(“Plantiff”)
公共类Plantiff扩展个人{
@实体
@鉴别器价值(“被告”)
公共类被告人{
@实体
@鉴别器价值(“律师”)
公营律师{
这是正确的,因为我可以查询单个类别,并且过滤器是自动的,例如Plantiff上的
findAll
将获得所有时间的Plantiff

现在我正试图通过案件中的
人员将他们与诉讼联系起来
@JoinTable:

@实体
@表(name=“诉讼”)
公开诉讼{
@身份证
长id;
字符串标题;
@独身癖
@JoinTable(name=“PERSONS”,
joinColumns=@JoinColumn(name=“ID\u”,referencedColumnName=“ID”),
inverseJoinColumns=@JoinColumn(name=“ID\u PERSON”,referencedColumnName=“ID”))
普兰提夫普兰提夫;
@许多
@JoinTable(name=“PERSONS”,
joinColumns=@JoinColumn(name=“ID\u”,referencedColumnName=“ID”),
inverseJoinColumns=@JoinColumn(name=“ID\u PERSON”,referencedColumnName=“ID”))
确定被告;
...
}
这就是问题的症结所在:未应用
@DiscriminatorValue
,它似乎被
@JoinTable
完全绕过了

事实上,
集合
不仅包含被告,还包含案件中的每个人
(关系表中的每个记录。例如,如果我有一个植物人、一名法官、两名被告和两名律师,上述
集合
将包含6人而不是2人)

如何使
@DiscriminatorValue
通过
@JoinTable
绑定工作?


编辑:我使用的是Hibernate 3.6.6.Final,而且(尽管我总是尽量避免)我对供应商特定的解决方案持开放态度,比如
@ForceDiscriminator
(不推荐)、
@DiscriminatorOptions(force=true)
等等。我在询问之前显然已经尝试过(但无法让它工作).

标准JPA中,没有办法共享联接表,并且在联接表中有一个额外的列作为一种类型的区分符,以区分它用于哪个关系

您可以使用一个单独的连接表,或者深入了解您的JPA提供商支持的供应商扩展;我知道DataNucleus JPA确实允许您需要的东西(请参阅,对于JDO,但它也适用于JPA)并期望其他提供商可能有一些方法来做到这一点,但你会使你的应用程序在JPA提供商方面不可移植


或者重新设计关系,如果这是您的项目的一个选项,简而言之,
@DiscriminatorColumn
似乎并不意味着为您区分层次结构。换句话说,如果所有内容都放在一个列表中,那么discriminator列在一个简单的级别上工作。当我开始尝试要求它分离时将实体划分成单独的列表,然后我说有问题,就像你一样

我基本上尝试了您描述的内容,但没有额外的
JoinColumn
注释,我无法插入,因为创建的
join表中有两个独立的
id
,一个用于一个类,一个用于另一个类,任何插入都不能同时满足这两个要求。使用额外的注释来控制jo在配置中,仍然存在问题。我可以插入内容,但无法检索

基本上,您可以将@MappedSuperclass视为设计考虑事项的解决方案。
Person
将是
MappedSuperclass
实体,它将是抽象的,律师、法官、原告、被告等将是具体的子类

@MappedSuperclass
public abstract class Content
{
   @Id @GeneratedValue private Integer  id;

   public Integer getId() {
       return id;
   }

}
作为康奈特的班级

@Entity
public class EnglishContent extends Content {

    @Override
    public String toString() {
        return "EnglishContent:"+getId();
    }
}

还有一些东西来支撑他们:

@Entity
public class Question {
    @Id @GeneratedValue private Integer id;

    @OneToMany(cascade=CascadeType.ALL)
    List<EnglishContent> englishContents;

    @OneToMany(cascade=CascadeType.ALL)
    List<SpanishContent> spanishContents;
    ... getters, setters, 
}
所以,不是相同的类,但它提供了单独的列表,具有多态性,而且看起来更简洁。当然,有更多的数据库表,但这不应该是主要考虑因素


希望这能有所帮助。

在hibernate 5.4.2中它仍然被忽略,我们的解决方法是使用hibernate中的
@Where
注释,仍然不是最佳的您试图为两个不同的事物重用联接表;这将导致混乱,因为它无法从联接表中知道它用于哪个关系,因此会误解事物。使用单独的连接表。一些JPA实现可能支持共享连接表(DataNucleus不支持IIRC,在一段时间内没有使用该功能),但这不是JPA的一部分spec@NeilStockton谢谢。事实上,案例中的人员也有一个列角色,指定该人员在该案例中所做的事情。这有什么帮助吗?这是一个旧项目(和数据库)我们现在正在迁移到JPA,如果可能的话,最好不要完全更改数据库我也不能让它正常工作,我得到“加载的对象属于错误的类”从Hibernate因为它的混乱。作为一个旁观者,认为在一个集体诉讼中,可以有不止一个原告,或者Joodor,或者其他原因。当然,诉讼只是一个假的例子,我的软件甚至不在这附近,但是谢谢。我也在使用Hibernate(在这个问题上忘了提到它)。我也得到了你同样的错误:/我会再处理一下。谢谢你,尼古拉斯,那是另一种方式。我们的问题是我们
@Entity
public class Question {
    @Id @GeneratedValue private Integer id;

    @OneToMany(cascade=CascadeType.ALL)
    List<EnglishContent> englishContents;

    @OneToMany(cascade=CascadeType.ALL)
    List<SpanishContent> spanishContents;
    ... getters, setters, 
}
    Question q = new Question();

    SpanishContent sc = new SpanishContent();
    List<SpanishContent> spanishContents = new ArrayList<SpanishContent>();
    spanishContents.add(sc);
    q.setSpanishContents(spanishContents);

    EnglishContent ec = new EnglishContent();
    List<EnglishContent> englishContents = new ArrayList<EnglishContent>();
    englishContents.add(ec);
    q.setEnglishContents(englishContents);

    em.persist(q);
    Question q = em.find(Question.class, 1);
    System.out.println(q);