2015-12-11 5 views
1

Я использую Play Framework 2.4. Я хочу, чтобы моделировать набор классов с этой цепочки наследования:Модельный класс, используемый как тип поля сам по себе, вызывает ошибку в Ebean

Research <- Publication <- Article 

Проблема заключается в том, я хотел бы класс публикации ссылаться на другие объекты этого класса, как это:

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

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

Это работает, когда я не наследую от публикации. Когда я добавить наследуя из статьи:

@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; 
} 

ответ

2

В вашем первом примере публикация является @Entity. После этого неожиданно появляется @Mappedsuperclass

Я не понимаю, что вы хотите здесь. Хотите, чтобы одна публикация была связана с другими публикациями? Потому что это отношения ManyToMany.

И для отношений ManyToMany вам необходимо указать аргумент «mappedBy».

То же самое касается статей и публикаций. Одна статья может появляться во многих публикациях, и многие публикации могут содержать одну и ту же статью.

Разве это не должно быть специально для вашей установки?

EDIT: играл с ним немного, эта установка работает:

@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 отношения всегда должны иметь "владельца".

В случае публикации для публикации это поле myReferences. Вот почему поле «referencedBy» имеет аргумент «mappedBy» в аннотации @ManyToMany.

Публикация не может заранее знать, какие будущие публикации будут ссылаться на них, а прошлые публикации не изменятся, чтобы ссылаться на эту новую.

Значит, вы можете только сказать о новой публикации, которую старые упоминают.

И какие статьи он содержит.

Вы можете добавить их в обе стороны, но лучше всего использовать 1 направление и придерживаться его.

Надеюсь, это поможет.

+0

Благодарим вас за ответ. Ваш код работает. Однако я не хочу, чтобы «Article» наследовал «Исследование». Он должен унаследовать от «Публикации» (существуют разные публикации, такие как статьи и книги, которые могут ссылаться друг на друга). Вот почему в моем втором примере кода я изменяю аннотацию 'Публикации' на' @ MappedSuperclass'. Добавление класса 'Article', который наследуется от' Publication' вызывает 'java.lang.RuntimeException: ошибка с ассоциацией с [class models.research.Publication] из [models.research.publication.Article.referencedBy]. Является ли класс models.research.Publication зарегистрированным? ' – nuoritoveri

+0

@nuoritoveri.' MappedSuperClass' - это класс, содержащий поля, которые унаследуют от каждого '@ Entity', который наследуется от него. Это не модель в базе данных, и поэтому вы не можете ссылаться на нее с помощью аннотации '@ ManyToOne' или' @ OneToMany'. Если вы хотите связать статью с публикацией, публикация должна быть '@ Entity'. Ebean позаботится о создании поля 'publication_id' в таблице статей. –

+0

Я не мог заставить наследование работать, поэтому я решил использовать композицию вместо наследования ('Article',' Book' и т. Д. Имеют поле '@ OneToOne' типа' Publication'). Ваш ответ помог мне установить отношение '@ ManyToMany'. Большое спасибо! – nuoritoveri

 Смежные вопросы

  • Нет связанных вопросов^_^