Kueri JPQL dengan gabung kiri

Saya mencoba membuat kueri JPQL yang akan menggabungkan dua tabel dan saya dapat mengatur data di dalamnya.

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();
        }

    }

Saya memiliki entitas ini:

/*
 * 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 + " ]";
    }

}

Dan kelas Pengguna:

/*
 * 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 + " ]";
    }

}

Kedua kelas ini secara otomatis dihasilkan oleh koneksi database. Jadi, dalam kueri itu, saya rasa saya harus bekerja dengan mereka dan tidak langsung dengan tabel di database. Apakah benar demikian?

Sayangnya, saya tidak mengedit data kolom apa pun, dan saya tidak tahu di mana masalahnya

Entitas Pengguna Saya memiliki hubungan Banyak Ke Banyak dengan entitas Simpan.


person Aaka    schedule 30.05.2017    source sumber
comment
Apakah kueri dibuat dalam urutan yang benar? Mengapa Anda tidak mencobanya dan melihatnya?   -  person Scary Wombat    schedule 30.05.2017
comment
Tidak, kueri tidak dibuat dalam urutan yang benar :) Saya menulisnya dengan buruk   -  person Aaka    schedule 30.05.2017
comment
tolong tambahkan logger atau setidaknya sistem dalam pengecualian alih-alih hanya mengembalikan transaksi... saya curiga ada pengecualian diam yang dilemparkan   -  person Zeromus    schedule 30.05.2017


Jawaban (1)


Jika Anda mencetak pengecualian, Anda mungkin memperhatikan bahwa Anda memiliki parameter :user tetapi Anda malah mencoba menyetel parameter login

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