[英]Is it possible to persist a List<E> with hibernate annotations, where E is an interface?
这似乎应该很简单,但是我很难提出一个优雅的解决方案。
让我们以一个基本文件系统为例,该系统由两个带有hibernate注释的类File和Folder组成 。
我们将把这两个类的通用属性抽象到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的内容可以是File或Folder ,因此目录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.