JPA IndirectSet更改未反映在Spring前端中 [英] JPA IndirectSet changes not reflected in Spring frontend

查看:78
本文介绍了JPA IndirectSet更改未反映在Spring前端中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已解决,但我不知道现在有什么不同.如果有人能以不同的方式解释发生的事情,我将不胜感激.

Solved, but I don't know what was different now. If anyone can explain what happened differently, I'd appreciate it.

现在的工作方式是仅合并父级,而不合并子级,就像这样:

The way it's working now is by merging only the Parent, not the Child at all, like so:

Parent parent = child.getParent();
parent.getChildren().add(child);
getJpaTemplate().merge(parent);

现在,它似乎正在工作,但是我不太明白为什么在我上一次尝试没有奏效的情况下它会工作.

Now, it seems to be working, but I don't quite get why this would work while my previous attempt didn't.

原始尝试/问题:

我在使用Spring JPA和IndirectSets时遇到问题.我有两个实体,父级和子级,定义如下.我有一个Spring表单,我试图在其中创建一个新的Child,并将其链接到现有的Parent,然后将所有内容反映在数据库和Web界面中.发生的事情是将其放入数据库中,但用户界面似乎并不相同.

I'm having an issue with Spring JPA and IndirectSets. I have two entities, Parent and Child, defined below. I have a Spring form in which I'm trying to create a new Child and link it to an existing Parent, then have everything reflected in the database and in the web interface. What's happening is that it gets put into the database, but the UI doesn't seem to agree.

以OneToMany关系彼此链接的两个实体,如下所示:

The two entities that are linked to each other in a OneToMany relationship like so:

@Entity
@Table(name = "parent", catalog = "myschema", uniqueConstraints = @UniqueConstraint(columnNames = "ChildLinkID"))
public class Parent {
    private Integer id;
    private String childLinkID;

    private Set<Child> children = new HashSet<Child>(0);

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    public Integer getId() {
        return this.id;
    }

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

    @Column(name = "ChildLinkID", unique = true, nullable = false, length = 6)
    public String getChildLinkID() {
        return this.childLinkID;
    }

    public void setChildLinkID(String childLinkID) {
        this.childLinkID = childLinkID;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "parent")
    public Set<Child> getChildren() {
        return this.children;
    }

    public void setChildren(Set<Child> children) {
        this.children = children;
    }
}

@Entity
@Table(name = "child", catalog = "myschema")
public class Child extends
    private Integer id;
    private Parent parent;

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    public Integer getId() {
        return this.id;
    }

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

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ChildLinkID", referencedColumnName = "ChildLinkID", nullable = false)
    public Parent getParent() {
        return this.parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }
}

当然,它们每个都有简单的属性.现在的问题是,当我在Spring界面中编辑这些简单的属性时,一切都可以很好地工作.我可以保留这些类型的新实体,并且使用JPATemplate在所有父对象(getJpaTemplate().find(从父代p中选择p"))上查找时,或在ID或单个实体上查找时,它们都会出现另一个财产.

And of course, assorted simple properties on each of them. Now, the problem is that when I edit those simple properties from my Spring interface, everything works beautifully. I can persist new entities of these types and they'll appear when using the JPATemplate to do a find on, say, all Parents (getJpaTemplate().find("select p from Parent p")) or on individual entities by ID or another property.

我遇到的问题是,现在,我正在尝试通过父级"页面上的链接创建一个链接到现有父级的新子级.这是Controller的重要部分(请注意,我已经在这里将JPA foo放置在控制器中以使其更清楚;实际的JpaDaoSupport实际上是在另一个类中,适当地分层了):

The problem I'm running into is that now, I'm trying to create a new Child linked to an existing Parent through a link from the Parent's page. Here's the important bits of the Controller (note that I've placed the JPA foo in the controller here to make it clearer; the actual JpaDaoSupport is actually in another class, appropriately tiered):

protected Object formBackingObject(HttpServletRequest request) throws Exception {
    String parentArg = request.getParameter("parent");
    int parentId = Integer.parseInt(parentArg);
    Parent parent = getJpaTemplate().find(Parent.class, parentId);
    Child child = new Child();
    child.setParent(parent);
    NewChildCommand command = new NewChildCommand();
    command.setChild(child);
    return command;
}

protected ModelAndView onSubmit(Object cmd) throws Exception {
    NewChildCommand command = (NewChildCommand)cmd;
    Child child = command.getChild();
    child.getParent().getChildren().add(child);
    getJpaTemplate().merge(child);
    return new ModelAndView(new RedirectView(getSuccessView()));
}

就像我说的那样,我可以遍历表格并为孩子填写新值-甚至不会显示父母的详细信息.当它返回到控制器时,它将遍历并将其保存到基础数据库中,但是接口从不反映它.重新启动应用程序后,所有内容都已存在并且已正确填充.

Like I said, I can run through the form and fill in the new values for the Child -- the Parent's details aren't even displayed. When it gets back to the controller, it goes through and saves it to the underlying database, but the interface never reflects it. Once I restart the app, it's all there and populated appropriately.

该如何解决?我试图调用额外的合并,尝试刷新(这给事务带来了异常),除了编写自己的数据库访问代码外,其他一切都没有.我确保每个类都具有适当的equals()和hashCode(),并已进行全面的JPA调试,以查看是否正在进行适当的SQL调用(似乎未对Child表进行任何新的调用)并逐步执行通过调试器(如预期的那样,所有这些都在IndirectSets中,并且在保存和显示Parent之间,该对象将占用一个新的内存地址).我的下一步是什么?

What can I do to clear this up? I've tried to call extra merges, tried refreshes (which gave a transaction exception), everything short of just writing my own database access code. I've made sure that every class has an appropriate equals() and hashCode(), have full JPA debugging on to see that it's making appropriate SQL calls (it doesn't seem to make any new calls to the Child table) and stepped through in the debugger (it's all in IndirectSets, as expected, and between saving and displaying the Parent the object takes on a new memory address). What's my next step?

推荐答案

我不确定 这与您的问题有关,但是为什么您在Parent类?这似乎真的很奇怪,尤其是因为您正在使用相应的列进行联接.我不知道事情如何与这种映射一起工作,我会解决这个问题.您可以尝试不使用吗(也可以删除referencedColumnName,您不需要此功能)?

I'm not sure this has something to do with your problem but why do you have a childLinkID property in your Parent class? This seems really weird, especially since you're using the corresponding column for the join. I wonder how things can work with this mapping and I would fix this. Can you try without (also remove the referencedColumnName, you don't need this)?

顺便说一句,为什么不以相同的方法设置ParentChild之间的链接的两侧?这使得代码难以阅读和维护IMO.

And by the way, why don't you set both sides of the link between Parent and Child in the same method? This makes the code hard to read and to maintain IMO.

您在我回答时编辑了问题,并将级联从Parent更改为Child,但这看起来可以解决实际问题,并且我不确定您不会遇到其他问题.请按照我的建议尝试修复您的映射.

You edited the question while I was answering and changed the cascading from Parent to Child but this looks like a work around of the real issue and I'm not sure you won't face other problems. Please try to fix your mapping as I suggested.

这篇关于JPA IndirectSet更改未反映在Spring前端中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆