可能有人向我解释如何任何相关的注释(@Any
,@AnyMetaDef
,@AnyMetaDefs
并@ManyToAny
在实践中)的工作.我很难找到任何有用的文档(仅JavaDoc并不是很有帮助).
到目前为止,我已经收集到它们以某种方式启用对抽象和扩展类的引用.如果是这种情况,为什么没有@OneToAny
注释?这个"任何"指的是单个"任何"或多个"任何"吗?
一个简短,实用和说明的例子将非常受欢迎(不必编译).
编辑:尽管我希望接受回复作为答案并给予应有的信用,但我发现Smink和Sakana的答案都非常有用.因为我不能接受几个回复作为答案,遗憾的是我不会将其作为答案.
希望这篇文章能够为这个主题带来一些启示:
有时我们需要将关联属性映射到不具有共同祖先实体的不同类型的实体 - 因此简单的多态关联不起作用.
例如,我们假设有三个不同的应用程序来管理媒体库 - 第一个应用程序管理书籍借阅,第二个应用程序管理DVD,第三个VHS.应用程序没有任何共同之处.现在我们要开发一个管理所有三种媒体类型的新应用程序,并重用现有的Book,DVD和VHS实体.由于Book,DVD和VHS类来自不同的应用程序,因此它们没有任何祖先实体 - 共同的祖先是java.lang.Object.我们仍然希望有一个Borrow实体可以引用任何可能的媒体类型.
要解决这种类型的引用,我们可以使用任何映射.此映射始终包含多个列:一列包含当前映射属性引用的实体的类型,另一列包括实体的标识,例如,如果我们引用一本书,则第一列将包含标记Book实体类型和第二个实体类型将包含特定书籍的ID.
@Entity @Table(name = "BORROW") public class Borrow{ @Id @GeneratedValue private Long id; @Any(metaColumn = @Column(name = "ITEM_TYPE")) @AnyMetaDef(idType = "long", metaType = "string", metaValues = { @MetaValue(targetEntity = Book.class, value = "B"), @MetaValue(targetEntity = VHS.class, value = "V"), @MetaValue(targetEntity = DVD.class, value = "D") }) @JoinColumn(name="ITEM_ID") private Object item; ....... public Object getItem() { return item; } public void setItem(Object item) { this.item = item; } }
@Any注释定义了与多个表中的类的多态关联.这种类型的映射始终需要多个列.第一列包含关联实体的类型.其余列包含标识符.为这种关联指定外键约束是不可能的,因此这绝不是映射(多态)关联的常用方法.您应该仅在非常特殊的情况下使用它(例如,审计日志,用户会话数据等).@Any注释描述了包含元数据信息的列.要链接元数据信息的值和实际实体类型,请使用@AnyDef和@AnyDefs注释.
@Any( metaColumn = @Column( name = "property_type" ), fetch=FetchType.EAGER ) @AnyMetaDef( idType = "integer", metaType = "string", metaValues = { @MetaValue( value = "S", targetEntity = StringProperty.class ), @MetaValue( value = "I", targetEntity = IntegerProperty.class ) } ) @JoinColumn( name = "property_id" ) public Property getMainProperty() { return mainProperty; }
idType表示目标实体标识符属性类型,metaType表示元数据类型(通常为String).请注意,@ AnyDef可以被共享和重用.在这种情况下,建议将其作为包元数据放置.
//on a package @AnyMetaDef( name="property" idType = "integer", metaType = "string", metaValues = { @MetaValue( value = "S", targetEntity = StringProperty.class ), @MetaValue( value = "I", targetEntity = IntegerProperty.class ) } ) package org.hibernate.test.annotations.any; //in a class @Any( metaDef="property", metaColumn = @Column( name = "property_type" ), fetch=FetchType.EAGER ) @JoinColumn( name = "property_id" ) public Property getMainProperty() { return mainProperty; }
@ManyToAny允许多个表与多个表的多态关联.这种类型的映射始终需要多个列.第一列包含关联实体的类型.其余列包含标识符.为这种关联指定外键约束是不可能的,因此这绝不是映射(多态)关联的常用方法.您应该仅在非常特殊的情况下使用它(例如,审计日志,用户会话数据等).
@ManyToAny( metaColumn = @Column( name = "property_type" ) ) @AnyMetaDef( idType = "integer", metaType = "string", metaValues = { @MetaValue( value = "S", targetEntity = StringProperty.class ), @MetaValue( value = "I", targetEntity = IntegerProperty.class ) } ) @Cascade( { org.hibernate.annotations.CascadeType.ALL } ) @JoinTable( name = "obj_properties", joinColumns = @JoinColumn( name = "obj_id" ), inverseJoinColumns = @JoinColumn( name = "property_id" ) ) public ListgetGeneralProperties() {
Src:Hibernate Annotations参考指南3.4.0GA
希望能帮助到你!