2012-10-10 13 views
1

這似乎應該是相當直接的,但我很難提出一個優雅的解決方案。是否有可能堅持列表<E> hibernate註釋,其中E是一個接口?

讓我們用一個基本的文件系統的例子,由兩個休眠標註類,文件文件夾的。

我們抽象出兩個階級的共同特性爲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; 
    } 
} 

從邏輯上講,文件夾的內容可能是文件文件夾,所以是有意義的內容列表是類型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] 

希望有人能提供一些線索點亮這個!

回答

1

該類型可能有一個接口,但它不會以您配置實體的方式工作。爲了將兩個實體類型合併到同一個集合中,他們需要共享一個本身就是實體的公共超類型。 (也就是說,你需要像FileSystemObject的是一個共同的超他們都繼承,即在該級別定義ID)

的問題是,考慮這個查詢:

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

如果有都是一個文件夾和一個ID爲3的文件,它應該如何知道你想要什麼?這就是爲什麼他們需要共享一個共同的超類,如果他們要在同一個集合中。

+0

太棒了,感謝您的快速回答!我試圖避免使用FileSystemObject類,但我現在明白爲什麼它需要持久性。 – Liam

相關問題