java @embeddable 与 @entity 用于映射集合

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12721556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 09:58:19  来源:igfitidea点击:

@embeddable vs @entity for a mapping a collection

javaspringhibernatejpaorm

提问by shazinltc

This must be quite naive but I have a doubt on when to use @Entityand @Embeddable.

这一定很幼稚,但我对何时使用@Entityand有疑问@Embeddable

Say I have a Userand Notificationclass.

说我有一个UserNotification类。

 @Entity
 public class User{
     //other properties
     @onetomany
     private List<Notification> notifications;
 }

 @Entity
 public class Notification{
     //properties
 }

I understand that there will be tables for class Userand Notification, and a third table for mapping. What if I do it like this?

我知道会有用于类User和的表Notification,以及用于映射的第三个表。如果我这样做呢?

 @Entity
 public class User {
     //other properties
     @ElementCollection
     private List<Notification> notifications;
 }

 @Embeddable
 public class Notification{
     //properties
 }

I know this won't create a table for Notification. But I can still store my notification objects. I went through the documentation, but couple of doubts:

我知道这不会为Notification. 但我仍然可以存储我的通知对象。我浏览了文档,但有几个疑问:

  1. Is it based on whether I want to see class B as a seperate table?
  2. Is there a performance difference b/w creating a table and an embeddable object?
  3. What can I not do with embeddable object that I can do with a table other than directly querying the table?
  1. 是否基于我是否希望将 B 类视为单独的表?
  2. 创建表和可嵌入对象是否存在黑白性能差异?
  3. 除了直接查询表之外,我可以对表执行哪些可嵌入对象?

NOTES

笔记

For anyone reading this question, this questiontoo might help you.

对于阅读此问题的任何人,此问题也可能对您有所帮助。

采纳答案by deepakraut

  1. Is it based on whether I want to see class B as a separate table?
  1. 是否基于我是否希望将 B 类视为单独的表?

Yes, when you use @Embedded, You embed that @Embeddableentity in @Entityclass, which makes it to add columns for embedded entity in same table of @Entityclass.

是的,当您使用 时@Embedded,您将该@Embeddable实体嵌入到@Entity类中,这使得它可以在同一个@Entity类表中为嵌入的实体添加列。

  1. Is there a performance difference b/w creating a table and an embeddable object?
  1. 创建表和可嵌入对象是否存在黑白性能差异?

When you use @Embedded, for table creation, one query is required, also for inserting and selecting a row. But if you don't use it, multiple queries are required, hence, use of @Embeddedyields more performance, we can say.

当您使用@Embedded,创建表时,需要一个查询,插入和选择一行也需要。但是如果你不使用它,则需要多次查询,因此@Embedded,我们可以说,使用会产生更高的性能。

  1. What can I not do with embeddable object that I can do with a table other than directly querying the table?
  1. 除了直接查询表之外,我可以对表执行哪些可嵌入对象?

Removing the respective embedded entity may be, but there may be integrity constraint violations for this.

可能会移除相应的嵌入实体,但可能会违反完整性约束。

回答by Anshu

In JPA, there's a couple ways to create composite key fields. Lets see the method using the @Embeddable annotation.
Let's start with the Entity class.

在 JPA 中,有几种方法可以创建复合键字段。让我们看看使用@Embeddable annotation.
让我们从 Entity 类开始。

@Entity
@Table
public class TraceRecord {
    @Id
    private TraceRecordPk id;

    @Version
    @Transient
    private int version;

    @Column(columnDefinition = "char")
    private String durationOfCall;

    @Column(columnDefinition = "char")
    private String digitsDialed;

    @Column(columnDefinition = "char")
    private String prefixCalled;

    @Column(columnDefinition = "char")
    private String areaCodeCalled;

    @Column(columnDefinition = "char")
    private String numberCalled;
}

This is a pretty simple Entity class with an @Id and @Version field and a few @Column definitions. Without going into too much detail, you'll see that the @Version field is also annotated @Transient. I've done this simply because my table also doesn't have a column for tracking versions, but my database is journaled, so I'm not too concerned about versioning. You'll also notice that the @Column fields have a value of “char” set on the columnDefinition attribute. This is because the fields in my table are defined as char and not varchar. If they were varchar, I wouldn't need to do this since a String maps to a varchar field by default.

这是一个非常简单的实体类,带有一个@Id 和@Version 字段以及一些@Column 定义。无需过多赘述,您会看到@Version 字段也被注解为@Transient。我这样做只是因为我的表也没有用于跟踪版本的列,但是我的数据库是日志记录的,所以我不太关心版本控制。您还会注意到 @Column 字段在 columnDefinition 属性上设置了“char”值。这是因为我的表中的字段被定义为 char 而不是 varchar。如果它们是 varchar,我就不需要这样做,因为默认情况下 String 映射到 varchar 字段。

The @Idfield is what I'm interested in right now. It's not a standard Java type, but a class I've defined myself. Here is that class.

这个@Id领域是我现在感兴趣的领域。它不是标准的 Java 类型,而是我自己定义的一个类。这是那堂课。

@Embeddable
public class TraceRecordPk implements Serializable {

    private static final long serialVersionUID = 1L;

    @Temporal(TemporalType.DATE)
    @Column
    private Date dateOfCall;

    @Column(columnDefinition="char")
    private String timeOfCall;

    @Column(columnDefinition="char")
    private String callingParty;

    /**
     * Constructor that takes values for all 3 members.
     *
     * @param dateOfCall Date the call was made
     * @param timeOfCall Time the call was made
     * @param callingParty Extension from which the call originated
     */
    public TraceRecordPk(Date dateOfCall, String timeOfCall, String callingParty) {
        this.dateOfCall = dateOfCall;
        this.timeOfCall = timeOfCall;
        this.callingParty = callingParty;
    }
}

To make this class capable of being an @Id field on an Entity class, it needs to be annotated with @Embeddable like I mentioned earlier. The 3 fields I've selected for my composite key are just normal @Column definitions. Rather than create getters/setters for each field, I've simply implemented a constructor that takes values for all 3 fields, making any instance immutable. When annotating a class with @Embeddable, that class will need to implement Serializable. So I've added a default serialVersionUID to accomodate.

为了使这个类能够成为实体类上的@Id 字段,它需要像我之前提到的那样用 @Embeddable 进行注释。我为复合键选择的 3 个字段只是普通的 @Column 定义。我没有为每个字段创建 getter/setter,而是简单地实现了一个构造函数,它接受所有 3 个字段的值,使任何实例不可变。使用 @Embeddable 注释类时,该类需要实现 Serializable。所以我添加了一个默认的 serialVersionUID 来适应。

Now that you have a class created and annotated with @Embeddable, you can now use it as the type for an @Id field in your Entity class. Simple stuff eh.

现在您已经创建了一个类并使用 进行了注释@Embeddable,您现在可以将其用作实体类中 @Id 字段的类型。简单的东西嗯。