首页 文章

使用复合键将Hibernate注释映射到连接表

提问于
浏览
0

我有一个实体,我想加入OneToOne和一个带有复合键的表(省略getter / setters):

@Entity
@Table(name = "parent")
public class Parent {
  @Id
  private String parentId;
  @Column(name = "data")
  private String data;
  @OneToOne
  private Child child;
}

和:

@Entity
@IdClass(ChildKey.class)
@Table(name = "child")
public class Child{
  @Id
  private String parentId;
  @Id
  private String username;
  @Column(name = "data")
  private String childData;
}

public class ChildKey implements Serializable {
  private String parentId;
  private String username;
}

Parent没有Child实体中'username'字段的概念 . 我需要将其作为标准传递 . 在DB中,child的主键是parentId和username .

如果我没有指定JoinColumn,则hibernate会尝试使用字段child_username和child_parentId进行映射 . 如果我只指定一个Joincolumn,我会得到一个损坏的映射 . 如果我指定两个JoinColumns,我没有要指定的父列 .

如何映射此类并将用户名作为条件传递? (它来自身份验证数据)或者如果我偏离轨道,我该如何以不同的方式执行此操作 .

2 回答

  • 0

    您可以使用派生身份 .

    Parent 课程将保持不变;但是你要指定一个 @OneToOne 映射回到孩子的父级, ChildChildKey 类看起来像这样:

    @Entity
    @IdClass(ChildKey.class)
    @Table(name = "child")
    public class Child{
      @Id
      @OneToOne(mappedBy="child")
      private Parent parent;
      @Id
      private String username;
      @Column(name = "data")
      private String childData;
    }
    
    public class ChildKey implements Serializable {
      private String parent; // name matches name of the @Id field and type matches type of Parent @Id field
      private String username; // name and type match those of the @Id field
    }
    

    JPA 2.1规范第2.4.1节讨论了派生身份 .

  • 0

    我最终做的是在Child类上定义@Filter,如下所示:

    @Entity
    @IdClass(ChildKey.class)
    @Table(name = "child")
    @FilterDef(name = "usernameFilter", parameters = {
            @ParamDef( name = "username", type="string")
    })
    public class Child { ... }
    

    在Parent类中,我使用对过滤器的引用来注释集合:

    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "parentId")
    @Filter(name="usernameFilter", condition = "username = :username")
    private List<Child> children;
    

    最后,在我的DAO中,我按名称参数化了过滤器,如下所示:

    Filter filter = currentSession().enableFilter("usernameFilter");
    filter.setParameter("username", user.getUsername());
    

    这样做会产生我想到的确切SQL,这是JOIN条件中带有变量的附加子句:

    SELECT 
        ...
    FROM
        parent this_
            LEFT OUTER JOIN
        child child_ ON this_.parentId = child_.parentId
            AND child_.username = ?
    

    我可能不清楚我在原始问题中寻找的最终结果 . 发布此答案以防其他人帮助 .

相关问题