当前位置: 首页 > 知识库问答 >
问题:

Java hibernate-在@Embeddeble类中添加主键

皇甫鸿远
2023-03-14

我最近刚刚开始对hibernate湿透。我一直在关注一个关于hibernate的在线hibernate教程。在课程中,创建了两个类;User详情,地址。User详情类使用@Entity注释,而地址类使用@Embedable注释。

与其在UserDetails类中使用@GenericGenerator和@CollectionId注释来创建主键“ADDRESS\u ID”,不如在ADDRESS类中声明一个实例变量(private int ADDRESS\u ID),并使用@ID@GeneratedValue注释将该变量作为USER\u地址表的主键,这样会更简单、更实用吗?

谢啦

用户详细信息。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;
    }
}

一个ddress.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;
    }
}

共有2个答案

洪河
2023-03-14

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

根据冬眠医生的说法

可嵌入类型没有任何标识,由其所属实体管理。

你这样做似乎是个好习惯。

阴英武
2023-03-14

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

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

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

但要回答你的问题,哪种方法更好?

我认为他们做了同样的事情,但是在您的地址实体中使用@Id@GeneratedValue会像您所说的那样简单得多,最重要的是它会非常实用,因为您不必在包含您的Adress组件的每个实体中使用@Collection Id重新定义它,因此您的项目中将拥有更少和更干净的代码。

因此,按照性能、可读性和可维护性的顺序,在您的地址实体中使用Id将是最好的方法。

 类似资料:
  • 我想在IntelliJ中运行我的第一个程序,但我不能在添加配置部分截图中添加我的主类 确定按钮不起作用

  • 问题内容: 这是我尝试过的但失败了: 有人给小费吗? 问题答案: 添加列之后,您始终可以添加主键: 至于为什么脚本不起作用,您需要指定,而不仅仅是单词:

  • 本文向大家介绍SQL 添加主键,包括了SQL 添加主键的使用技巧和注意事项,需要的朋友参考一下 示例 这会将一个主键添加到该字段上的表employees ID。在括号中包含多个列名以及ID将创建一个Composite Primary Key。当添加多个列时,列名称必须用逗号分隔。            

  • 到目前为止,我一直为我的主题提供某种用Java编写的NavigationUtil-Class,并放在下。 我使用主题生成器和blade cli将主题升级到Liferay DXP。现在,java类似乎没有像在普通sdk项目中那样注册。 我现在是否必须将其与主题分离,或者是否有其他方法将java集成到主题中?

  • 对不起,我的英语不是我的母语,而且已经两点钟了,所以现在不能思考了。现在,在将hibernate与Java和PostgreSQL一起使用时,我遇到了下一个问题:我有如下实体Human和User(带有注释映射): 和数据库结构如下: 当我尝试运行我的项目(简单单元测试)时,我得到下一个错误: (我剪掉了日志的尾部,而它在JUnit方法中响应invokin)。 生成的查询(失败): 可以看到,它试图在