【问题标题】:ElementCollection with same collectiontable具有相同集合表的 ElementCollection
【发布时间】:2014-10-02 11:20:51
【问题描述】:

我想存储emailIds,当表格发生更改时需要通知它。 我只有一张包含 ownerid 和 emailid 列的表格。我想将emailid 存储在单独的行中,而不是逗号分隔的列表中。我不需要所有者表,因为我没有所有者的任何其他信息。我只想保存电子邮件 ID,但要保存到单独的行中。

我如何在休眠中做到这一点。

我尝试使用类似的东西

@Table(name = "OwnerEmailIds")
@Entity
public class OwnerEmailIds implements Serializable {
private static final long serialVersionUID = 5906661729869048121L;

@Column(name = "OwnerID", nullable = false)
private String ownerId;


@ElementCollection(fetch=FetchType.EAGER) // must use eager as we close the session before returning
   @CollectionTable(name="OwnerEmailIds", joinColumns=@JoinColumn(name="vendorId"))
   @Column(name = "emailId")
private Set<String> EmailIds = new HashSet<String>();

但这里的问题是我的集合表与实体表相同。

由于我的 emailIds 列不为空,当我尝试保存对象时,它失败并出现 sql 错误,说明 emailid 列不能为空。

【问题讨论】:

  • 您打算如何使用此表中的数据?您将如何使用休眠进行查询?
  • 我从不同的网络服务获取 ownerID,我只需要从数据库中获取 emailids。

标签: java sql hibernate annotations


【解决方案1】:

为了能够将实体映射到表,Hibernate 需要一个唯一的 id 属性,该属性映射到表上的唯一(主)键。

正如您所说,您没有这个,如果这是您的应用程序使用的唯一表,那么 Hibernate 可能不是最佳选择。

您仍然可以通过执行本机 SQL 查询通过 Hibernate 从数据库中获取所需的信息:

SQLQuery q = session.createSQLQuery("select OwnerID from OwnerEmailIds where emailId = :email");
q.setScalar("OwnerID", StandardBasicTypes.LONG);
q.setParameter("email", emailId)
List<Long> ids = (List<Long>) q.list();

也可以使用本机查询来存储 id,但在这里您必须考虑已经存在的数据,因此有点困难。

【讨论】:

    【解决方案2】:

    我认为您要求的是将集合放在多行中并重复其他值,在您的情况下,将插入电子邮件列表,并且将为其电子邮件重复 owner_id。

    Hibernate 没有为此提供任何配置。您必须手动完成。

    您可以使用以下结构和代码执行您想要的操作。您必须有一个主键,在这里您可以将您的电子邮件 id 作为主键,也可以添加一个自增整数 id。

    @Table(name = "OwnerEmailIds")
    @Entity
    public class OwnerEmailIds implements Serializable {
        private static final long serialVersionUID = 5906661729869048121L;
    
        @Column(name = "OwnerID", nullable = false)
        private String ownerId;
    
        @Id   
        @Column(name = "emailId")
        private String emailId;
    
        //setter and getters
    }
    

    然后您遍历电子邮件 ID 列表并创建以下对象,然后单独保存它们。您不能创建集合对象并配置 hibernate 以将它们存储在当前表中的多行中。

    //loop throught the list of email ids
    OwnerEmailIds oei = new OwnerEmailIds();
    oei.setOwnerId("first last name");
    oei.setEmailId("some@somedomain.com");
    session.save(oei);
    

    如果您将 emailId 作为主键,那么您必须确保没有两个所有者拥有相同的电子邮件 ID。如果是这种情况,那么您必须添加另一个 auto_increment 主键。

    【讨论】:

    • 如果我不需要数据库中的 Owners 表怎么办。我只需要存储所有者的电子邮件 ID?
    • 那么你只需要 OwnerEmailId 表并自己创建集合并将它们全部保存。
    • 是的,我的模型要求每位所有者拥有多个电子邮件 ID。我想将它们存储在单独的行中
    • 我想你要问的是你想要一个实现,你存储一个对象,它应该创建与提供的列表中一样多的行。
    • 我认为在hibernate中是不可能的,简单的规则是一个对象总是代表一行。
    猜你喜欢
    • 2019-03-11
    • 2017-09-15
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多