【问题标题】:How to use OneToMany Association in more than one table如何在多个表中使用 OneToMany 关联
【发布时间】:2018-03-23 00:04:47
【问题描述】:

我正在尝试将三个表与我的模型类连接起来。这是我的模型类。

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

还有Privilages.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>

我正在尝试将权限和操作与我的主要模型用户一起加入。用户权限具有一对多。并且用户 - 操作也有一对多。当我以特权加入用户时,它运行良好。我成功加入了两个表。

现在我还需要与用户一起加入 Actions 类。我试图从每个模型类中显示一列。当我执行我之前加入用户权限的过程时,当我添加了一个表时,这里不起作用。

我收到类似的错误,

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

如何将我之前的加入加入额外的一个表?

【问题讨论】:

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


    【解决方案1】:

    如果不更改模型实体,您可能无法做到这一点。 如果我说得对,您希望获得具有从 db 初始化的多个相关集合的实体类。但这在您的情况下无法正常工作,因为MultipleBagFetchException: cannot simultaneously fetch multiple bags。与fetch = FetchType.EAGER 的多个集合基本相同的问题。如果可以的话,简单的解决方法是将Collection&lt;Privillages&gt; 更改为Set&lt;Privillages&gt;ActionsMore info


    至于Exception evaluating SpringEL expression: "message.pid.username",实际原因是您尝试使用joinData,就好像它是一些数据库表记录一样,但您应该像使用java类一样使用它。因为你已经从休眠中获得了Set&lt;User&gt; 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>
    

    【讨论】:

    • 好的,我会在此基础上进行更多探索。我是 Spring 和 Spring Data JPA 的新手,我正在尝试加入多个,正如您已经理解的那样。我将阅读有关此 Collection、Set 的更多信息,并将尝试这些。并感谢您的回复先生。
    • 我尝试了同样的设置。但是这次我在视图页面中收到一个错误 - “出现意外错误(类型=内部服务器错误,状态=500)。评估 SpringEL 表达式的异常:“message.pid.username”(fleethome:52)”。更新代码后,我还编辑了我的问题。我该如何解决这个问题?有时间可以看看我的代码和错误吗??
    • @MJacob 尝试使用model.addAttribute("joinData",userRepo.findByUsername()); return "fleethome" 而不是创建新模型。或者将viewObj.addAttribute("joinData",userRepo.findByUsername()); 放低一行。我认为你需要在你返回的`viewObj`模型上设置joinData
    • 好的..我会尝试的。但我的问题仍然存在,评论中提到的错误也在编辑问题中。我需要遵循什么方法来解决这个问题?你看到我的错误了吗?
    • @MJacob 您的错误是百里香的一部分,并说您不能像使用它一样使用message.pid.username,因为joinDataSet&lt;Users&gt; 所以messageUsers 并且没有pidUsers 中的字段
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    • 2014-11-15
    • 2015-02-02
    • 2021-12-11
    • 1970-01-01
    • 2015-07-19
    • 2023-03-31
    相关资源
    最近更新 更多