java.lang.IllegalArgumentException:org.hibernate.hql.internal.ast.QuerySyntaxException:连接所需的路径

问题描述 投票:0回答:4

我已阅读示例,但我有我的个人问题。

我有2张桌子:

Role:
  id, name
User:
  id, login, name, role_id

角色实体:

@Entity
@Table(name = "role")
public class Role {

@Id
@Column(name = "id")
private long id;

@Column(name = "name", length = 45)
private String name;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "role")
private Set<User> user = new HashSet<>();

//getters and setters

用户实体:

@Entity
@Table(name = "user")
public class User {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id",insertable = false, updatable = false)
private long id;

@Column(name = "login")
private String login;

@Column(name = "user_name")
private String userName;

@ManyToOne(fetch = FetchType.LAZY)
private Role role;

//getters and setters

和存储库:

public interface UserRepository extends JpaRepository<User, Long> {

String Q_GET_ALL_USERS = "from User u left join Role r on u.role_id=r.id";

@Query(Q_GET_ALL_USERS)
Collection<User> getAllUsers();

此代码显示:

引起:java.lang.IllegalArgumentException:org.hibernate.hql.internal.ast.QuerySyntaxException:连接所需的路径! [来自 com.example.jpa.model.User u 在 u.role_id=r.id 上左加入 Role r]

我的理解是,该实体不能包含

id
(在我的例子中为
Role
)作为参考,我应该删除此字段。但实体应该有
@Id

在这种情况下,我应该在“角色”中创建一个新列吗?或者我可以使用更漂亮的决定吗?

我将所有项目放入Bitbucket

java spring hibernate jpa join
4个回答
8
投票

要在 HQL (JPQL) 中使用联接,您不需要

on
子句

String Q_GET_ALL_USERS = "select u from User u left join u.role";

此查询没有任何意义,因为您在 where 子句中没有使用

role

如果您想获取具有提取角色的用户,您可以使用

join fetch

String Q_GET_ALL_USERS = "select u from User u left join fetch u.role";

更新

您的

User
Role
模式并不常用。我建议您从用户到角色建立
@ManyToMany
关联,并从
user
 中删除任何 
Role

关联
@Entity
@Table(name = "user")
public class User {

    @ManyToMany(fetch = FetchType.LAZY)
    private Set<Role> roles;

}

@Entity
@Table(name = "role")
public class Role {

    @Id
    @Column(name = "id")
    private long id;

    @Column(name = "name", length = 45)
    private String name;

}

4
投票

不,您应该在

User
中创建一个新列。

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "role_id")
private Role role;

3
投票

谢谢大家的回答。下面的正确实体和查询(加上表架构)。

表(查询)

CREATE TABLE role (
  id   INT         NOT NULL PRIMARY KEY,
  name VARCHAR(45) NOT NULL
);

CREATE TABLE user (
  id        INT         NOT NULL PRIMARY KEY IDENTITY,
  login     VARCHAR(45) NOT NULL,
  user_name VARCHAR(45) NOT NULL,
  role_id   INT         NOT NULL,
  FOREIGN KEY (role_id) REFERENCES role (id)
);

实体:

@Entity
@Table(name = "user")
public class User {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id",insertable = false, updatable = false)
private long id;

@Column(name = "login")
private String login;

@Column(name = "user_name")
private String userName;

@ManyToOne(fetch = FetchType.LAZY)
private Role role;

//getters and setters
}

@Entity
@Table(name = "role")
public class Role {

@Id
@Column(name = "id")
private long id;

@Column(name = "name", length = 45)
private String name;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "role")
private Set<User> user = new HashSet<>();

//getters and setters
}

存储库

public interface UserRepository extends JpaRepository<User, Long> {

String Q_GET_ALL_USERS = "select u from User u left join u.role";

@Query(Q_GET_ALL_USERS)
Collection<User> getAllUsers();
}

@v-ladynev提出替代决定(仅在

@ManyToMany
中使用
User
)。您可以在此answer下的评论中找到更多详细信息。 当我检查这个决定时,我会更新这个答案(我希望我不会忘记它:-))


0
投票

型号

@Entity
@Table(name = "sys_std_user")
public class StdUser {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "class_id")
    public int classId;
    @Column(name = "user_name")
    public String userName;
}

@Entity
@Table(name = "sys_std_profile")
public class StdProfile {
    @Id
    @Column(name = "pro_id")
    public int proId;
    @Column(name = "full_name")
    public String fullName;
}

控制器

@PersistenceUnit
private EntityManagerFactory emf;

@GetMapping("/join")
    public List actionJoinTable() {
        EntityManager em = emf.createEntityManager();
        List arr_cust = em
                .createQuery("SELECT u.classId, u.userName, p.fullName FROM StdUser u, StdProfile p WHERE u.classId=p.proId")
                .getResultList();
        return arr_cust;
    }

结果:

[
    [
        1,
        "Ram",
        "Ram Pukar Chaudhary"
    ],
    [
        2,
        "Raja",
        "Raja Kishor Shah"
    ]
]
© www.soinside.com 2019 - 2024. All rights reserved.