Запрос JPQL с левым соединением

Я пытаюсь создать запрос JPQL, который объединил бы две таблицы вместе, и я мог бы настроить в них данные.

public void uploadSaveGame(User user, String saveData)
    {
        EntityTransaction entr=em.getTransaction();
        entr.begin();

        try{
             Query query = em.createQuery("UPDATE Saves s SET s.save = :saveData" +
"WHERE s.login = :user in (select sa.saveid,sa.Users.login, sa.savedata from Saves sa  "
                 + "LEFT JOIN sa.Users m WHERE sa.saves = m.users.saveid)", Save.class);
        query.setParameter("login", user);
        query.setParameter("saveData", saveData);
        query.executeUpdate(); 
        entr.commit();

        }catch(Exception e){
          entr.rollback();
        }

    }

У меня есть это:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.dke.ps.Tables;

import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @author michal
 */
@Entity
@Table(name = "saves")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Saves.findAll", query = "SELECT s FROM Saves s")
    , @NamedQuery(name = "Saves.findBySaveid", query = "SELECT s FROM Saves s WHERE s.saveid = :saveid")
    , @NamedQuery(name = "Saves.findBySavedata", query = "SELECT s FROM Saves s WHERE s.savedata = :savedata")})
public class Saves implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "saveid")
    private Integer saveid;
    @Column(name = "savedata")
    private String savedata;
    @JoinColumn(name = "userid", referencedColumnName = "userid")
    @ManyToOne(optional = false)
    private Users userid;
    @OneToMany(mappedBy = "saveid")
    private Collection<Users> usersCollection;

    public Saves() {
    }

    public Saves(Integer saveid) {
        this.saveid = saveid;
    }

    public Integer getSaveid() {
        return saveid;
    }

    public void setSaveid(Integer saveid) {
        this.saveid = saveid;
    }

    public String getSavedata() {
        return savedata;
    }

    public void setSavedata(String savedata) {
        this.savedata = savedata;
    }

    public Users getUserid() {
        return userid;
    }

    public void setUserid(Users userid) {
        this.userid = userid;
    }

    @XmlTransient
    public Collection<Users> getUsersCollection() {
        return usersCollection;
    }

    public void setUsersCollection(Collection<Users> usersCollection) {
        this.usersCollection = usersCollection;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (saveid != null ? saveid.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Saves)) {
            return false;
        }
        Saves other = (Saves) object;
        if ((this.saveid == null && other.saveid != null) || (this.saveid != null && !this.saveid.equals(other.saveid))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.dke.ps.Tables.Saves[ saveid=" + saveid + " ]";
    }

}

И класс пользователей:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.dke.ps.Tables;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @author michal
 */
@Entity
@Table(name = "users")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u")
    , @NamedQuery(name = "Users.findByUserid", query = "SELECT u FROM Users u WHERE u.userid = :userid")
    , @NamedQuery(name = "Users.findByLogin", query = "SELECT u FROM Users u WHERE u.login = :login")
    , @NamedQuery(name = "Users.findByPassword", query = "SELECT u FROM Users u WHERE u.password = :password")
    , @NamedQuery(name = "Users.findByEmail", query = "SELECT u FROM Users u WHERE u.email = :email")
    , @NamedQuery(name = "Users.findByDate", query = "SELECT u FROM Users u WHERE u.date = :date")})
public class Users implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "userid")
    private Integer userid;
    @Column(name = "login")
    private String login;
    @Column(name = "password")
    private String password;
    @Column(name = "email")
    private String email;
    @Column(name = "date")
    @Temporal(TemporalType.DATE)
    private Date date;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "userid")
    private Collection<Saves> savesCollection;
    @JoinColumn(name = "saveid", referencedColumnName = "saveid")
    @ManyToOne
    private Saves saveid;

    public Users() {
    }

    public Users(Integer userid) {
        this.userid = userid;
    }

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @XmlTransient
    public Collection<Saves> getSavesCollection() {
        return savesCollection;
    }

    public void setSavesCollection(Collection<Saves> savesCollection) {
        this.savesCollection = savesCollection;
    }

    public Saves getSaveid() {
        return saveid;
    }

    public void setSaveid(Saves saveid) {
        this.saveid = saveid;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (userid != null ? userid.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Users)) {
            return false;
        }
        Users other = (Users) object;
        if ((this.userid == null && other.userid != null) || (this.userid != null && !this.userid.equals(other.userid))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.dke.ps.Tables.Users[ userid=" + userid + " ]";
    }

}

Эти два класса были автоматически сгенерированы соединением с базой данных. Итак, в этом запросе я думаю, что должен работать с ними, а не напрямую с таблицами в базе данных. Это так?

К сожалению, я не редактирую никакие данные столбцов и не знаю, в чем проблема.

Сущность «Мои пользователи» имеет отношение «многие ко многим» с сущностью «Сохраняет».


person Aaka    schedule 30.05.2017    source источник
comment
В правильном ли порядке сделан запрос? Почему бы вам не попробовать и не посмотреть?   -  person Scary Wombat    schedule 30.05.2017
comment
Нет, запрос не в том порядке :) Я плохо написал   -  person Aaka    schedule 30.05.2017
comment
пожалуйста, добавьте регистратор или, по крайней мере, систему в исключение вместо того, чтобы просто откатывать транзакцию... я подозреваю, что генерируется молчаливое исключение   -  person Zeromus    schedule 30.05.2017


Ответы (1)


Если бы вы напечатали исключение, вы, вероятно, заметили бы, что у вас есть параметр :user, но вместо этого вы пытаетесь установить параметр входа в систему.

query.setParameter("login", user);
person Zeromus    schedule 30.05.2017