I am trying to implement a rather complicated mapping in JPA. I need something similar to this example. The There are several kinds of Writers and several kinds of Writings.
Each writing needs to have a persistable author field. It does not matter the dynamic type of the author. This is why I have it set to the Static abstract type.
The authro however should carry two lists, specifying the novels and poems each has written.
I am getting errors saying that I cannot use a MappedSuperClass as the target of a persistable field. Does anyone know how to accomplish what I am trying to accomplish?
I also want the writer to own this bidirectional relationship. so mapped by should be on the Novel or Poem side. However it appears that mapped by can only be on the OneToMany side…. It does not seem like a strange case where one thing owns many things… why can’t i do this…
Thanks very much fopr the help
@MappedSuperclass
@Access(AccessType.PROPERTY)
public abstract class AbstractWriter implements Serializable{
private Long id;
private String name;
private String email;
private ArrayList<Novel> novels;
private ArrayList<Poem> poems;
@OneToMany(mappedBy="author")
public ArrayList<Novel> getNovels() {
return novels;
}
public void setNovels(ArrayList<Novel> novels) {
this.novels = novels;
}
@OneToMany(mappedBy="author")
public ArrayList<Poems> getPoems() {
return poems;
}
public void setPoems(ArrayList<Poem> poems) {
this.poems = poems;
}
@Column(nullable=false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Id @GeneratedValue(strategy= GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
@Entity
public class ProfessionalWriter extends AbstractWriter {
}
@Entity
public class StudentWriter extends AbstractWriter {
}
@MappedSuperclass
public abstract class AbstractWriting implements Serializable{
private Long id;
private String title;
private AbstractWriter author;
private byte[] words;
@ManyToOne
public AbstractWriter getAuthor() {
return author;
}
public void setAuthor(AbstractWriter author) {
this.author = author;
}
@Id @GeneratedValue(strategy= GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Lob
public byte[] getWords() {
return words;
}
public void setWords(byte[] words) {
this.words = words;
}
@Column(nullable=false)
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
@Entity
public class Novel extends AbstractWriting {
}
@Entity
public class Poem extends AbstractWriting {
}
The abstract classes should be annotated with @Entity, rather than @MappedSuperclass. And you should of course choose an inheritance strategy.
Regarding the owning side: owning an association doesn’t have any semantic meaning. It just means that it’s this side of the association that is used by JPA to know if the association exists. JPA indeed mandates that the many side owns the association mapping, whic is logical since it’s in the table associated to the many side that the foreign key is. For you, it just means that when a poem is added to an author, this poem should reference its author, because that’s what will make the association persistent.
Also, you should not use ArrayList, but List. EclipseLink will use its own List implementation to support lazy-loading, cascades, etc. And BTW, it’s good practice to program to interfaces rather than implementations.