如何使用 Hibernate @Any 相关的注解?

2022-01-13 00:00:00 annotations orm java Hibernate

有人可以向我解释一下 Any 相关的注释(@Any@AnyMetaDef@AnyMetaDefs@ManyToAny) 在实践中工作.我很难找到任何关于这些的有用文档(仅 JavaDoc 不是很有帮助).

Could someone explain to me how Any-related annotations (@Any, @AnyMetaDef, @AnyMetaDefs and @ManyToAny) work in practice. I have a hard time finding any useful documentation (JavaDoc alone isn't very helpful) about these.

到目前为止,我已经收集到它们以某种方式启用对抽象类和扩展类的引用.如果是这种情况,为什么没有 @OneToAny 注释?这个any"是指一个any"还是多个any"?

I have thus far gathered that they somehow enable referencing to abstract and extended classes. If this is the case, why is there not an @OneToAny annotation? And is this 'any' referring to a single 'any', or multiple 'any'?

非常感谢一个简短、实用且说明性的示例(不必编译).

A short, practical and illustrating example would be very much appreciated (doesn't have to compile).

尽管我愿意接受作为答案的回复并在适当的时候给予信任,但我发现 Smink 和 Sakana 的答案都提供了丰富的信息.因为我不能接受多个回复作为答案,所以很遗憾,我将两者都标记为答案.

as much as I would like to accept replies as answers and give credit where due, I found both Smink's and Sakana's answers informative. Because I can't accept several replies as the answer, I will unfortunately mark neither as the answer.

推荐答案

希望这篇文章 为主题带来一些亮点:

Hope this article brings some light to the subject:

有时我们需要映射一个关联属性不同没有属性的实体类型共同祖先实体 - 如此简单多态关联不起作用工作.

Sometimes we need to map an association property to different types of entities that don't have a common ancestor entity - so a plain polymorphic association doesn't do the work.

例如,让我们假设管理媒体库的三个不同应用程序 - 第一个应用程序管理图书借阅,第二个应用程序管理 DVD,第三个应用程序管理 VHS.这些应用程序没有任何共同点.现在我们要开发一个新的应用程序来管理所有三种媒体类型并重用现有的 Book、DVD 和 VHS 实体.由于 Book、DVD 和 VHS 类来自不同的应用程序,它们没有任何祖先实体——共同的祖先是 java.lang.Object.我们仍然希望有一个 Borrow 实体,它可以引用任何可能的媒体类型.

For example let's assume three different applications which manage a media library - the first application manages books borrowing, the second one DVDs, and the third VHSs. The applications have nothing in common. Now we want to develop a new application that manages all three media types and reuses the exiting Book, DVD, and VHS entities. Since Book, DVD, and VHS classes came from different applications they don't have any ancestor entity - the common ancestor is java.lang.Object. Still we would like to have one Borrow entity which can refer to any of the possible media type.

为了解决这种类型的引用,我们可以使用 any 映射.此映射始终包含多个列:一列包含当前映射属性所引用的实体的类型,另一列包含实体的标识,例如,如果我们引用一本书,它的第一列将包含一个标记Book 实体类型,第二个将包含特定书籍的 id.

To solve this type of references we can use the any mapping. this mapping always includes more than one column: one column includes the type of the entity the current mapped property refers to and the other includes the identity of the entity, for example if we refer to a book it the first column will include a marker for the Book entity type and the second one will include the id of the specific book.

@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;
    }

}

相关文章