如何在多个表中使用OneToMany关联

时间:2017-10-11 10:38:03

标签: spring-mvc spring-data-jpa jpql

enter image description here我正在尝试使用我的模型类加入三个表。这是我的模型类, Users.java

@Entity
@Table(name = "users")
public class Users implements Serializable{

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
public String username;
public String password;
public Integer privid;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "pid")
private Set<Privillages> priviJoin;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "actid")
private Set<Actions> actionJoin;



public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}
@Column(name = "username")
public String getUsername() {
    return username;
}
public void setUsername(String username) {
    this.username = username;
}
@Column(name = "password")
public String getPassword() {
    return password;
}
public void setPassword(String password) {
    this.password = password;
}

@Column(name = "privid")
public Integer getPrivid() {
    return privid;
}
public void setPrivid(Integer privid) {
    this.privid = privid;
}


public Set<Privillages> getPriviJoin() {
    return priviJoin;
}

public void setPriviJoin(Set<Privillages> priviJoin) {
    this.priviJoin = priviJoin;
}

public Set<Actions> getActionJoin() {
    return actionJoin;
}

public void setActionJoin(Set<Actions> actionJoin) {
    this.actionJoin = actionJoin;
}

public Users() {
}
}

和Privillages.java,

@Entity
@Table(name = "privillages")
public class Privillages implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer id;

@Column(name = "pname")
public String pname;


@ManyToOne(optional = false)
@JoinColumn(name = "pid", referencedColumnName = "privid")
public Users pid;

public Integer getId() {
    return id;
}
public void setId(Integer id) {
    this.id = id;
}


public String getPname() {
    return pname;
}
public void setPname(String pname) {
    this.pname = pname;
}

public Users getPid() {
    return pid;
}
public void setPid(Users pid) {
    this.pid = pid;
}

public Privillages(){
} 
}

和Actions.java

@Entity
@Table(name = "actions")
public class Actions implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer id;


@Column(name = "actname")
public String actname;

@ManyToOne(optional = false)
@JoinColumn(name = "actid", referencedColumnName = "privid")
public Users actid;



public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public String getActname() {
    return actname;
}

public void setActname(String actname) {
    this.actname = actname;
}

public Users getActid() {
    return actid;
}

public void setActid(Users actid) {
    this.actid = actid;
}
public  Actions(){
}
}

我的存储库包含以下代码

@Query(value = "SELECT u.*,p.*,a.* FROM users u "
            + "INNER JOIN privillages p ON u.privid = p.pid "
            + "INNER JOIN  actions a ON u.privid = a.actid", 
 nativeQuery=true)
Set<Users> findByUsername();

我的控制器操作是,

@RequestMapping(value = "/joinResult", method = RequestMethod.GET)
    public ModelAndView joinResultShow(Model model)
        {
            model.addAttribute("joinData",userRepo.findByUsername());
            ModelAndView viewObj = new ModelAndView("fleethome");
            return viewObj;
        }

我的观点就像是,

<table>
        <th> Username </th>
        <th> Privillage </th>
        <th> Action </th>
            <tr th:each="message : ${joinData}">

              <td th:text="${message.username}"></td>
              <td><span th:each="privi : ${message.priviJoin}"
                 th:text="${privi.pname}"></span></td>
              <td><span th:each="action : ${message.actionJoin}"
                 th:text="${action.actname}"></span></td>
            </tr>
    </table>

我正在尝试与我的主要模型用户一起加入Privillages和Actions。用户 - 权限有一对多。而且用户 - 动作也有一对多。当我加入Privillages用户时,它运作良好。我成功加入了两张桌子。

现在我还需要与用户一起加入Actions类。我正在尝试从每个Model类中显示一个列。当我实现我之前关注的用于加入Users-Privillages的过程在这里不起作用时,我再添加一个表。

我收到错误,

 There was an unexpected error (type=Internal Server Error, status=500).
 Exception evaluating SpringEL expression: "message.pname" (fleethome:65)

任何人都可以帮助我加入我之前加入的附加表格。??

1 个答案:

答案 0 :(得分:1)

如果没有模型实体更改,您可能无法做到这一点。 如果我找到了你,你想要从db初始化多个相关集合的实体类。但是这不能像你的情况一样工作,因为MultipleBagFetchException: cannot simultaneously fetch multiple bags。与fetch = FetchType.EAGER的多个集合基本相同。如果可以,轻松修复将Collection<Privillages>更改为Set<Privillages>或更改为ActionsMore info

至于Exception evaluating SpringEL expression: "message.pid.username",实际的原因是你试图使用joinData,好像它是一些数据库表记录,而是你应该像使用java类一样使用它。因为你已经从hibernate获得了Set<User> joinData。可以尝试像

这样的东西
<tr th:each="message : ${joinData}">

    <td th:text="${message.username}"></td>
    <td><span th:each="privi : ${message.priviJoin}"
              th:text="${privi.pname}"></span></td>
    <td><span th:each="action : ${message.actionJoin}"
              th:text="${action.actname}"></span></td>

</tr>

如果您想要与您提供的图像相同的输出,可以尝试:

<div  th:remove="tag" th:each="message : ${joinData}">
    <div th:remove="tag" th:each="privi : ${message.priviJoin}">
        <div th:remove="tag" th:each="action : ${message.actionJoin}">
            <tr>
                <td th:text="${message.username}"></td>
                <td th:text="${privi.pname}"></td>
                <td th:text="${action.actname}"></td>
            </tr>
        </div>
    </div>
</div>