模型 class 用作字段类型本身导致 Ebean 出错

Model class used as a field type in itself causes error in Ebean

我正在使用 Play Framework 2.4。我想用这个继承链为一组 classes 建模:

Research <- Publication <- Article

问题是,我希望发布 class 引用此 class 的其他对象,如下所示:

@MappedSuperclass
public abstract class Research extends Model {
    @Id
    public Long id;
}

@Entity
public class Publication extends Model {
    @ManyToOne
    public Publication translationOf;
}

这在我不继承 Publication 时有效。 当我添加继承自 Article:

@MappedSuperclass
public abstract class Publication extends Model {
    @ManyToOne
    public Publication translationOf;
}

@Entity
public class Article extends Publication { }

我得到:

java.lang.RuntimeException: Error with association
to [class models.research.Publication]
from [models.research.publication.Article.translationOf]. 
Is class models.research.Publication registered?

我认为配置 InheritanceType 显式可能会有所帮助,但添加 @Inheritance 标记会导致 NullPointerException 在堆栈跟踪中没有任何其他信息嵌套异常。例如在这种情况下会发生这种情况:

@MappedSuperclass
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype", discriminatorType = DiscriminatorType.STRING)
public abstract class Research extends Model {
    @Id
    public Long id;
    public String dtype;
}

@Entity
@DiscriminatorValue("P")
public class Publication extends Model {
    @ManyToOne
    public Publication translationOf;
}

在您的第一个示例中,Publication 是一个@Entity。在那之后它突然变成了@Mappedsuperclass

我不明白你想要什么。您希望将一份出版物链接到其他出版物吗?因为那是多对多关系。

对于多对多关系,您需要指定 "mappedBy" 参数。

文章和出版物也是如此。一篇文章可能出现在许多出版物中,许多出版物可能有相同的文章。

除非您的设置必须特别不同?

编辑:试了一下,这个设置有效:

@MappedSuperclass
public abstract class Research extends Model {

    @Id
    public Long id;
}


@Entity
public class Publication extends Research {

    @ManyToMany(cascade = CascadeType.ALL, mappedBy = "myReferences")
    // What other publications refer to this one?
    public List<Publication> referencedBy;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(
            name = "CROSS_REFERENCE",
            joinColumns = {
                    @JoinColumn(name = "MY_ID")
                    },
            inverseJoinColumns = {
                    @JoinColumn(name = "REFERENCER_ID")
            })
    // What publications am I referring to?
    public List<Publication> myReferences;

    // The list of articles in this publication.
    @ManyToMany(cascade = CascadeType.ALL)
    public List<Article> articles;
}


@Entity
public class Article extends Research {

    // The publications this article appears in.
    @ManyToMany(cascade = CascadeType.ALL, mappedBy = "articles")
    public List<Publication> publications;
}

ManyToMany 关系总是需要有一个 "owner".

在发布到发布的情况下,它是 myReferences 字段。这就是 "referencedBy" 字段在 @ManyToMany 注释中具有 "mappedBy" 参数的原因。

出版物无法提前知道未来哪些出版物会引用它们,而过去的出版物不会更改为引用这个新出版物。

所以你只能说新出版物引用了哪些旧出版物。

它包含哪些文章。

您可以在两个方向添加,但通常最好使用一个方向并坚持使用。

希望对您有所帮助。