2012-02-07 142 views
1

基本休眠问题。休眠一对多关系与关系上的属性

我有一个叫做Song的类和一个叫Artwork的类,两者都是独立存在的。然后一个Song的实例可以包含多个Artwork,当他们做的时候,这个关系的属性是特定的,所以我创建了另一个类,名为CoverArt,这两个类之间的链接。我使用注释来解决冬眠的问题。

如果我在构建数据库时将所有三个类注释为@Entity,则会收到错误>'org.hibernate.MappingException:无法确定类型:图形,表格:CoverArt,列:[org.hibernate。 mapping.Column(稿)“

如果我改变CoverArt@Embeddable,因为它只能在Song我得到的错误

的情况下存在” org.hibernate.annotations.common.AssertionFailure:在继承状态层次结构中找不到声明类:com.jthink.songlayer.CoverArt'

我无法弄清这些信息在说什么,我有什么不对。下面是从三类

Song相关代码:

@Entity 
public class Song 
{ 
    @Id 
    @GeneratedValue 
    private Integer recNo; 

    @ElementCollection(fetch=FetchType.EAGER) 
    @IndexColumn(name = "POSITION") 
    private List<CoverArt> coverArt; 

..... 

CoverArt

@Embeddable 
public class CoverArt 
{ 
    private String imageType; 
    private String description; 
    private Artwork artwork; 

    @Id 
    @GeneratedValue 
    private Integer id; 

    public CoverArt() 
    { 

    } 

    public String getImageType() 
    { 
     return imageType; 
    } 

    public void setImageType(String imageType) 
    { 
     this.imageType = imageType; 
    } 

    public String getDescription() 
    { 
     return description; 
    } 

    public void setDescription(String description) 
    { 
     this.description = description; 
    } 

    public Artwork getArtwork() 
    { 
     return artwork; 
    } 

    public void setArtwork(Artwork artwork) 
    { 
     this.artwork = artwork; 
    } 
} 

Artwork

@Entity 
public class Artwork 
{ 

    public Artwork() 
    { 

    } 

    public Artwork(byte[] imageData) 
    { 
     this.imageData=imageData; 
    } 

    @Id 
    @GeneratedValue 
    private Integer id; 


    @Lob 
    private byte[] imageData; 
    private String mimeType; 
    private int  width; 
    private int  height; 

    public byte[] getImageData() 
    { 
     return imageData; 
    } 

    public void setImageData(byte[] imageData) 
    { 
     this.imageData = imageData; 
    } 

    public String getMimeType() 
    { 
     return mimeType; 
    } 

    public void setMimeType(String mimeType) 
    { 
     this.mimeType = mimeType; 
    } 

    public int getWidth() 
    { 
     return width; 
    } 

    public void setWidth(int width) 
    { 
     this.width = width; 
    } 

    public int getHeight() 
    { 
     return height; 
    } 

    public void setHeight(int height) 
    { 
     this.height = height; 
    } 
} 

回答

2

CoverArt类应该是一个实体。

SongCoverArt实例的列表,你应该这样有

@OneToMany 
@JoinColumn(...) 
private List<CoverArt> coverArts; // note the final s, since it's plural 

每个CoverArt链接到Artwork,所以你也应该有一个协会。目前还不清楚它是一个ManyToOne还是OneToOne,很难。我会假设这是OneToOne:

@OneToOne 
@JoinColumn(...) 
private Artwork artwork; 

这很简单。每当一个实体有一个对另一个实体的引用,或者对另一个实体实例的集合时,你就有一个协作。一个关联可以是OneToMany,OneToOne,ManyToOne或ManyToMany。你必须告诉Hibernate它是哪一个。如果你不告诉它,它认为它是一个简单的列,这是错误的。

+0

Thankyou在Song中添加OneToMany和在Artwork中添加OneToOne已经完成了技巧,我不需要使用JoinColumn。但是,为什么CoverArt必须是一个只存在于歌曲背景下的实体,是因为它是链接到一个实体? – 2012-02-07 15:34:28

+0

您可以将其设为嵌入式对象,但这只会使其变得更加困难,并且您无法像使用实体一样查询它们。当一些东西必须映射到它自己的表格时,我通常更喜欢使用一个实体。 – 2012-02-07 17:20:19

+0

并让我的代码使用这个工作我需要做@OneToMany(fetch = FetchType.EAGER)希望不会隐藏我的代码中的问题。 – 2012-02-07 17:31:56

0

首先您应该告诉我们您希望在数据库中看起来如何。 我想,你希望这样的事情:

表“歌曲” 表“艺术品” 表“cover_arts”与fkeys:song_id和artwork_id

那么一首歌“有很多个” CoverArts每个封面作品“已一件“艺术品。

如果这是正确的,那么:

  • 标注封面作品为@Entity,而不是@Embeddable
  • 与@ManyToOne
  • 现场“封面艺术取代@ElementCollection封面作品类注释字段 '作品' 内'在@OneToMany的Song类中。将字段'coverArt'重命名为'coverArts'会很好,因为它是一个集合,而不是单个实例。
+0

Thankyou听起来像其他海报正确,虽然有趣的是你说使用ManyToOne而不是OneToOne – 2012-02-07 15:40:30