我有一个实体,我想加入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,则我没有要指定的父列。
如何映射此类并将用户名作为条件传递? (它来自身份验证数据)或者如果我偏离轨道,我怎么能以不同的方式做到这一点。
答案 0 :(得分:0)
您可以使用派生身份。
Parent
课程将保持不变;但是你要指定一个@OneToOne
映射回到孩子的父母,Child
和ChildKey
类看起来像这样:
@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 = ?
我可能不清楚我在原始问题中寻找的最终结果。发布此答案以防其他人帮助。