带左连接的JPQL查询

时间:2017-05-30 06:27:44

标签: java 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 + " ]";
    }

}

这两个类是由数据库连接自动生成的。因此,在该查询中,我认为我应该使用它们而不是直接使用数据库中的表。是这样吗?

不幸的是,我不编辑任何列数据,我不知道问题出在哪里

我的用户实体与保存实体具有多对多关系。

1 个答案:

答案 0 :(得分:1)

如果你打印了异常,你可能会注意到你有一个:user参数,但你试图设置一个登录参数

query.setParameter("login", user);