当find(Object.Class,{CompositeKey})方法的键是组合键时,如何查找引用?

时间:2018-11-16 13:21:57

标签: java jpa find entitymanager composite-key

当我们有复合键(两列或更多列)作为第二个参数传递给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。有人遇到过类似的问题吗?解?

2 个答案:

答案 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个命名查询。例如:如果我们需要处理从该表创建的视图。首先创建视图,然后编写另一个命名查询以对其进行处理,就可以轻松实现。