Как найти ссылку, когда ключ к методу find (Object.Class, {CompositeKey}) является составным ключом? - PullRequest
0 голосов
/ 16 ноября 2018

Как найти ссылку, когда у нас есть составной ключ (два или более столбцов) для передачи в качестве второго параметра в объект JPA entityManager.find (Object.class, композитный ключ)?

Моя попытка- Я создал Arraylist и добавил значения, формирующие композитный ключ, а затем передал этот список методу find .

Например: в моей ситуации ИД пользователя и projectid вместе являются ключом для таблицы UserProject, и эти два были добавлены в массив, названный списком, который будет передан в качестве второго параметра метода поиска entityManager, как показано ниже:

List<Integer> list = new ArrayList<Integer>();
        list.add(userProjectDO.getUserid());
        list.add(userProjectDO.getProjectid());

        UserProject userProject = em.find(UserProject.class,list);

Но это всегда возвращается как ноль, даже если в таблице есть ID пользователя и ИД проекта. Кто-нибудь был в подобной проблеме? Решение?

Ответы [ 2 ]

0 голосов
/ 17 ноября 2018

Я нашел другой подход, т. Е. Написание 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;
    }
}

И, наконец, установите параметры запроса, то есть значения композитного ключа (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 будет содержать строку, совпадающую с композитный ключ (userId, projectId)

Одно преимущество, которое я вижу с этим подходом, заключается в том, что я могу написать N количество именованных запросоввнутри класса сущности согласно потребности / требованию.Например: если нам нужно работать с представлением, созданным из этой таблицы.Этого легко достичь, создав сначала представление, а затем написав еще один именованный запрос для работы с ним.

0 голосов
/ 16 ноября 2018

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);
...