当我们有复合键(两列或更多列)作为第二个参数传递给JPAEntityManager.find(Object.class,CompositeKey)时,如何查找引用?
我的尝试- 我创建了一个 Arraylist ,并添加了形成CompositeKey的值,然后将该列表传递给 find 方法。
例如:在我的情况下, userid 和 projectid 一起是UserProject表的键,并且这两个已添加到名为list的arraylist中,这将作为第二个参数传递给EntityManager的find方法,如下所示:
List<Integer> list = new ArrayList<Integer>();
list.add(userProjectDO.getUserid());
list.add(userProjectDO.getProjectid());
UserProject userProject = em.find(UserProject.class,list);
但是,即使表上存在userid和projectId,也总是返回null。有人遇到过类似的问题吗?解?
答案 0 :(得分:0)
JPA的EntityManager#find不接受数组作为键,而接受Object
。由于您在谈论复合键,因此应该在单独的类中实现您的键,该类通过列出所有键的单独属性来表示复合键。例如,您可以使用EmbeddedId来实现。
例如:
您应该定义组合键类并使用@Embeddable
进行注释:
public class UserProjectKey implements Serializable{
private String userId;
private String projectId;
//constructors, getters, setters
}
并在您的实体中将其用作@EmbeddedId
。
要通过键进行搜索,您可以执行以下操作:
UserProjectKey key = new UserProjectKey("userIdExample", "projectIdExample");
em.find(UserProject.class, key);
答案 1 :(得分:0)
我发现了另一种方法,即编写namedQuery搜索表。发布实现以防万一,对任何人都有帮助。
final Query query = em.createNamedQuery("UserProject.findByAll");
UserProject实体类:
@Entity
@Table(name = "userproject", schema = "public")
@NamedQueries({ @NamedQuery(name = "UserProject.findByAll", query = "SELECT a FROM UserProject a where a.userid = :userid and a.projectid = :projectid"),
@NamedQuery(name = "UserProject.findByUserId", query = "SELECT a FROM UserProject a where a.userid = :userid"),
@NamedQuery(name = "UserProject.findById", query = "SELECT a FROM UserProject a where a.id = :id" )})
public class UserProject implements Serializable {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "userid")
private Integer userid;
@Column(name = "projectid")
private Integer projectid;
@Column(name = "created")
private Timestamp created;
@Column(name = "modified")
private Timestamp modified;
@Column(name = "modifiedbyid")
private Integer modifiedbyid;
@Column(name = "role")
private String role;
public Integer getId() {
return id;
}
public void setId(final Integer id) {
this.id = id;
}
public Integer getUserid() {
return userid;
}
public void setUserid(final Integer userid) {
this.userid = userid;
}
public void setProjectid(final Integer projectid) {
this.projectid = projectid;
}
public Timestamp getCreated() {
return created;
}
public void setCreated(final Timestamp created) {
this.created = created;
}
public Timestamp getModified() {
return modified;
}
public void setModified(final Timestamp modified) {
this.modified = modified;
}
public Integer getModifiedbyid() {
return modifiedbyid;
}
public void setModifiedbyid(final Integer modifiedbyid) {
this.modifiedbyid = modifiedbyid;
}
public String getRole() {
return role;
}
public void setRole(final String role) {
this.role = role;
}
}
最后将查询参数设置为:CompositeKey values(userid,projectid)为:
final Query query = em.createNamedQuery("UserProject.findByAll");
query.setParameter("userid",userProjectDO.getUserid());
query.setParameter("projectid",userProjectDO.getProjectid());
List<UserProject> userProjectList = query.getResultList();
userProjectList 将包含与CompositeKey(userId,projectId)匹配的行
我看到的这种方法的一个优势是,根据需要,我可以在实体类中编写N个命名查询。例如:如果我们需要处理从该表创建的视图。首先创建视图,然后编写另一个命名查询以对其进行处理,就可以轻松实现。