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

时间:2016-03-10 15:49:26

标签: java hibernate jpa

我有一个实体,我想加入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 :(得分: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节讨论了派生身份。

答案 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 = ?

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