Hibernate 一对多关系与关系上的属性

发布于 2025-01-02 21:05:28 字数 2758 浏览 1 评论 0原文

基本的休眠问题。

我有一个名为 Song 的类和一个名为 Artwork 的类,它们都是独立存在的。然后,Song 的实例可以包含多个 Artwork,当它们存在时,就会有特定于该关系的属性,因此我创建了另一个名为 CoverArt 的类两者之间的联系。我正在使用 hibernate 的注释并遇到问题。

如果我在构建数据库时将所有三个类注释为 @Entity ,则会收到错误 >'org.hibernate.MappingException: 无法确定类型: Artwork, at table: CoverArt, for columns: [org.hibernate.mapping.Column(artwork)]'

如果我将 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;
    }
}

Basic Hibernate question.

I have a class called Song and a class called Artwork, both exist independently. Then an instance of Song can contain multiple Artworks and when they do there are attribute particular to that relationship so I have created another class called CoverArt that links between the two. I'm using annotations for the hibernate stuff and having problems.

If I annotate all three classes as @Entity when I build the database I get the error >'org.hibernate.MappingException: Could not determine type for: Artwork, at table: CoverArt, for columns: [org.hibernate.mapping.Column(artwork)]'

If I change CoverArt to @Embeddable, as it only exists in the context of a Song I get the error

'org.hibernate.annotations.common.AssertionFailure: Declaring class is not found in the inheritance state hierarchy: com.jthink.songlayer.CoverArt'

I can't work out what these messages are saying, what I have wrong. Here is the relevant code from the three classes

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

离笑几人歌 2025-01-09 21:05:28

CoverArt 类应该是一个实体。

Song 有一个 CoverArt 实例列表,因此您应该将

@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 它是哪一个。如果您不告诉它,它会假设它是一个简单的列,这是错误的。

The CoverArt class should be an entity.

The Song has a list of CoverArt instances, you should thus have

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

Each CoverArt links to an Artwork, so you should also have an association. It's not clear if it's a ManyToOne or a OneToOne, tough. I'll suppose it's a OneToOne:

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

It's pretty simple. Each time an entity has a reference to another entity, or a collection of another entity instances, you have an assosiation. And an association can be a OneToMany, OneToOne, ManyToOne or ManyToMany. You have to tell Hibernate which one it is. If you don't tell it, it assumes it's a simple Column which is wrong.

帝王念 2025-01-09 21:05:28

首先,您应该告诉我们您希望所有这些在数据库中看起来如何。
我想你想要这样的东西:

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

所以一首歌曲“有很多”封面艺术,每个封面艺术“有一个”艺术作品。

如果这是正确的,则:

  • 在 CoverArt 类中使用 @Entity 而不是 @Embeddable 注释 CoverArt
  • 用 @ManyToOne 注释字段“artwork” 用
  • @OneToMany 替换 Song 类中字段“coverArt”上的 @ElementCollection。将字段“coverArt”重命名为“coverArts”会很好,因为它是一个集合,而不是单个实例。

First of all You should tell us how do You want all that to look like in database.
I assume You want something like that:

table 'songs'
table 'artworks'
table 'cover_arts' with fkeys: song_id and artwork_id

So a Song "has many" CoverArts and each CoverArt "has one" Artwork.

If this is correct, then:

  • Annotate CoverArt with @Entity instead of @Embeddable
  • inside CoverArt class annotate field 'artwork' with @ManyToOne
  • replace @ElementCollection on field 'coverArt' inside Song class with @OneToMany. It would be nice to rename field 'coverArt' to 'coverArts' as it is a collection, not a single instance.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文