簡體   English   中英

是否可以保留列表 <E> 帶有休眠注釋,其中E是接口?

[英]Is it possible to persist a List<E> with hibernate annotations, where E is an interface?

這似乎應該很簡單,但是我很難提出一個優雅的解決方案。

讓我們以一個基本文件系統為例,該系統由兩個帶有hibernate注釋的類FileFolder組成

我們將把這兩個類的通用屬性抽象到FileSystemObject接口中:

public interface FileSystemObject {
    public String getName();
    public URI getWhere();
}

和兩個類:

檔案

@Entity
@Table(name = "FILE")
public class File implements FileSystemObject, Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "FILE_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(name = "NAME", nullable = false)
    @Index(name = "FILE_NAME", columnNames={"NAME"})
    private String name;

    @Column(nullable = false)
    private URI where;

    public File() {}

    public File(String name, URI where) {
        this.name = name;
        this.where = where;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public URI getWhere() {
        return where;
    }

    public void setWhere(URI where) {
        this.where = where;
    }
}

資料夾

@Entity
@Table(name = "FOLDER")
public class Folder implements FileSystemObject, Serializable {

    private static final long serialVersionUID = 2L;

    @Id
    @Column(name = "FOLDER_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(name = "NAME", nullable = false)
    @Index(name = "FOLDER_NAME", columnNames={"NAME"})
    private String name;

    @Column(nullable = false)
    private URI where;

    @CollectionOfElements
    @JoinTable(name = "FOLDER_CONTENTS",
               joinColumns = @JoinColumn(name = "FOLDER_ID"))
    private List<FileSystemObject> contents;

    public Folder() {}

    public Folder(String name, URI where, List<FileSystemObject> contents) {
        this.name = name;
        this.where = where;
        this.contents = contents;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public URI getWhere() {
        return where;
    }

    public void setWhere(URI where) {
        this.where = where;
    }

    public List<FileSystemObject> getContents() {
        return contents;
    }

    public void setContents(List<FileSystemObject> contents) {
        this.contents = contents;
    }
}

從邏輯上講, Folder的內容可以是FileFolder ,因此目錄List的類型為FileSystemObject是有意義的。

現在,假設當我嘗試生成一些模式時,所有內容都在pom.xml中正確設置了:

mvn hibernate3:hbm2ddl

它引發以下錯誤:

Failed to execute goal org.codehaus.mojo:hibernate3-maven-plugin:2.0:hbm2ddl (generate-ddl) on
project foo: Execution generate-ddl of goal org.codehaus.mojo:hibernate3-maven
plugin:2.0:hbm2ddl failed: Could not determine type for: com.foo.data.FileSystemObject, for
columns: [org.hibernate.mapping.Column(element)] -> [Help 1]

希望有人可以對此有所啟發!

該類型可能有一個Interface,但是它不適用於您配置實體的方式。 為了將兩種Entity類型組合在同一個集合中,它們需要共享一個本身就是Entity的公共超類型。 (也就是說,您需要像FileSystemObject這樣的東西作為它們都繼承的通用超類,該超類在該級別定義ID。)

問題是,請考慮以下查詢:

select c from Folder f, f.contents c where f.name = 'FOLDER' and c.id = 3;

如果同時存在ID為3的文件夾和文件,應該如何知道您想要什么? 這就是為什么如果它們要屬於同一集合,則需要共享一個公共超類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM