【问题标题】:Java hibernate - adding a primary key in an @Embeddable classJava hibernate - 在 @Embeddable 类中添加主键
【发布时间】:2017-12-03 23:22:18
【问题描述】:

我最近刚刚开始在休眠时弄湿我的脚。我一直在关注关于休眠的在线休眠教程。在本课中,创建了两个类;用户详细信息,地址。 UserDetails 类使用@Entity 注释,而 Address 类使用@Embeddable 注释。

与其在UserDetails类中使用@GenericGenerator和@CollectionId注解创建主键“ADDRESS_ID”,不如在Address中声明一个实例变量(private int ADDRESS_ID)更简单实用类,并使用@Id @GeneratedValue 注解使变量成为 USER_ADDRESS 表的主键?

谢谢

UserDetails.java

package dto;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.CollectionId;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;

@Entity
public class UserDetails {

    @Id
    @Column
    private int userId;

    @Column
    private String userName;

    @ElementCollection
    @JoinTable(name="USER_ADDRESS", joinColumns=@JoinColumn(name="USER_ID")) 
    @GenericGenerator(name = "sequence-gen", strategy = "sequence")
    @CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "sequence-gen", type = @Type(type="long"))
    private Collection<Address> listOfAddresses = new ArrayList<Address>();

    public Collection<Address> getListOfAddresses() {
        return listOfAddresses;
    }

    public void setListOfAddresses(Collection<Address> listOfAddresses) {
        this.listOfAddresses = listOfAddresses;
    }
    public Date getJoinedDate() {
        return joinedDate;
    }
    public void setJoinedDate(Date joinedDate) {
        this.joinedDate = joinedDate;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
}

地址.java

package dto;
import javax.persistence.Column;
import javax.persistence.Embeddable;

@Embeddable
public class Address {
    @Column(name="STREET_NAME")
    private String street;

    @Column(name="CITY_NAME")
    private String city;

    @Column(name="STATE_NAME")
    private String state;

    @Column(name="PIN_CODE")
    private String pincode;

    public String getStreet() {
        return street;
    }
    public void setStreet(String street) {
        this.street = street;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
    public String getPincode() {
        return pincode;
    }
    public void setPincode(String pincode) {
        this.pincode = pincode;
    }
}

【问题讨论】:

    标签: hibernate


    【解决方案1】:

    实际上,可嵌入类型(在 Hibernate 中称为 Component)中不需要 Id 属性,因为它们只是 值的组合 并且它们不支持共享引用,因此即使两个对象包含相同的组件值它们不会是相同的引用,而是只有两个具有相同值的对象,你可以看到它来自Hibernate Component Mapping

    与值类型一样,组件不支持共享引用。换句话说,两个人可以有相同的名字,但是两个人对象将包含两个独立的名字对象,它们的值只是“相同”。组件的空值语义是临时的。当重新加载包含对象时,Hibernate 将假定如果所有组件列都为空,那么整个组件都为空。这适用于大多数用途。

    所以这里基本上不需要Id 属性。


    但是要回答您关于哪种方法更好的问题?

    我认为他们做的事情完全相同,但是在您的 Address 实体中使用 @Id@GeneratedValue 会像您所说的那样简单得多,最重要的是它会非常实用,因为您不必这样做在包含您的 Adress 组件的每个实体中使用 @CollectionId 重新定义它,这样您的项目中的代码就会更少、更清晰。

    因此,在您的Adress 实体中使用@Id 将是按照performancereadabilitymaintainability 的顺序使用的最佳方式。

    【讨论】:

    • 这样做(在地址中添加 id),将以某种方式将地址转换为实体。那么在这种情况下,将地址设为关系的拥有方并因此获得经典的双向关系不是更好吗??
    • @AbassA 是的,最好将其设计为OneToMany 关系,但正如我所说,最好不要使用Id
    • 感谢您的详细解释。
    【解决方案2】:

    可嵌入类型是一种值类型,您也可以找到术语:组件。这些对象不是实体,而只是实体的一部分,这意味着它们的生命周期与实体绑定。

    根据休眠doc

    可嵌入类型没有任何标识,由它们管理 拥有实体。

    你进行的方式似乎是好的做法。

    【讨论】:

      猜你喜欢
      • 2020-10-17
      • 2012-04-22
      • 2010-10-31
      • 2020-05-06
      • 2013-02-19
      • 2015-05-30
      • 2016-05-22
      • 1970-01-01
      • 2011-08-01
      相关资源
      最近更新 更多