Java 是否可以保留列表<;E>;对于hibernate注释,其中E是一个接口?

Java 是否可以保留列表<;E>;对于hibernate注释,其中E是一个接口?,java,hibernate,list,interface,annotations,Java,Hibernate,List,Interface,Annotations,这似乎应该是相当简单的,但我很难想出一个优雅的解决方案 让我们使用一个基本文件系统的例子,它由两个hibernate注释类组成,file和Folder 我们将把这两个类的公共属性抽象为FileSystemObject接口: public interface FileSystemObject { public String getName(); public URI getWhere(); } 以及两类: 文件: @Entity @Table(name = "FILE") pub

这似乎应该是相当简单的,但我很难想出一个优雅的解决方案

让我们使用一个基本文件系统的例子,它由两个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;
    }
}
文件夹

@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;
    }
}
它抛出以下错误:

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]

希望有人能对此有所启发

那里的类型可能有一个接口,但它不会以您配置实体的方式工作。为了将两种实体类型合并到同一个集合中,它们需要共享一个本身就是实体的公共超类型。(也就是说,您需要像FileSystemObject这样的东西作为它们都继承自的公共超类,在该级别定义ID。)

问题是,考虑这个查询:

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

如果有一个文件夹和一个文件都有id 3,它怎么知道你想要什么?这就是为什么如果它们要在同一个集合中,它们需要共享一个公共超类。

那里的类型可能有一个接口,但它不会以您配置实体的方式工作。为了将两种实体类型合并到同一个集合中,它们需要共享一个本身就是实体的公共超类型。(也就是说,您需要像FileSystemObject这样的东西作为它们都继承自的公共超类,在该级别定义ID。)

问题是,考虑这个查询:

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

如果有一个文件夹和一个文件都有id 3,它怎么知道你想要什么?这就是为什么如果他们要在同一个集合中,他们需要共享一个共同的超类。

太棒了,谢谢你的快速回答!我曾试图避免使用FileSystemObject类,但现在我明白了为什么持久性需要它了。太棒了,谢谢你的快速回答!我试图避免使用FileSystemObject类,但现在我明白了为什么持久性需要它。