2012-01-07 71 views
0

我想在JPA中实现一个相当复杂的映射。我需要类似于这个例子的东西。有几种作家和几种作品。 每个写作都需要一个可持久的作者字段。这与作者的动态类型无关。这就是为什么我将它设置为静态抽象类型。 然而,authro应该携带两个列表,指定每个已写入的小说和诗歌。JPA多态关系,静态和动态类型

我得到的错误说我不能使用MappedSuperClass作为持久化领域的目标。有人知道如何完成我想要完成的任务吗?

我也希望作家拥有这种双向的关系。如此映射应该在小说或诗方面。然而,似乎映射由只能在一对多侧....这似乎并不像其中一件事拥有很多事情一个奇怪的情况下......我为什么不能做到这一点...

非常感谢很多fopr的帮助

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

回答

1

抽象类应该用@Entity而不是@MappedSuperclass注释。你当然应该选择一个inheritance策略。

对于拥有方:拥有一个关联没有任何语义。这只是表示JPA使用关联的这一方来了解关联是否存在。 JPA的确要求许多方拥有关联映射,这是合乎逻辑的,因为它在与外键相关的许多方面的表中。对你而言,这只意味着,当一首诗添加到作者身上时,这首诗应该引用它的作者,因为这会使该协会持久。

而且,你不应该使用ArrayList,但名单。 EclipseLink将使用它自己的List实现来支持延迟加载,级联等。而且,顺便说一下,编程接口而不是实现是一种很好的做法。

+0

感谢您的回答。我会做出这些改变。你能建议我如何编程接口而不是实现。我不认为我很明白你的意思。 – b3bop 2012-01-07 21:39:48

+0

这意味着最好总是使用接口类型(例如List,Map)而不是具体类型(例如ArrayList,HashMap)。这样,如果您改变了主意并希望使用LinkedList(或TreeMap)而不是ArrayList,则只需在一个位置更改代码:列表的实例。剩下的代码不应该关心它是一个ArrayList还是一个LinkedList。它需要知道的是它是一个List。在JPA中,这是非常重要的,因为EclipseLink将有效地用EclipseLinkLazyList(实现List)替代您的列表。 – 2012-01-07 21:55:01

+0

非常有见地。非常感谢。 – b3bop 2012-01-07 21:55:53