2010-04-29 30 views
2

编辑:解决了,但我不知道现在有什么不同。如果任何人都可以解释发生了什么不同,我会很感激。JPA间接集变化不反映在春季前端

它的工作,现在的方式是通过合并只是家长,不是孩子可言,就像这样:

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

现在,它似乎是工作,但我不太明白为什么这会工作,而我以前的尝试没有。

原始尝试/问题:

我在使用Spring JPA和IndirectSets的问题。我有两个实体,Parent和Child,定义如下。我有一个Spring表单,我试图创建一个新的Child并将其链接到一个现有的Parent,然后将所有内容都反映在数据库和Web界面中。发生了什么是它被放入数据库,但用户界面似乎并不认同。

链接到彼此的关系一对多像这样的两个实体:他们每个人的

@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或单个实体另一个属性。

我遇到的问题是,现在,我正试图通过父母页面中的链接创建一个与现有父级链接的新子级。下面是控制器的重要位(请注意,我放在JPA FOO在这里控制器,使其更清晰;实际的JpaDaoSupport实际上是另一个类,适当的分层):

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

就像我说的,我可以浏览表格并填写孩子的新值 - 父母的详细资料甚至不会显示。当它回到控制器时,它会通过并将其保存到底层数据库,但界面从不反映它。一旦我重新启动应用程序,它就在那里并适当地填充。

我能做些什么来澄清这一点?我试图调用额外的合并,尝试刷新(这给了一个事务异常),一切都只是写我自己的数据库访问代码。我已经确定每个类都有一个合适的equals()和hashCode(),对其进行完整的JPA调试以查看它是否正在进行适当的SQL调用(它似乎没有对Child表进行任何新调用)通过调试器(全部在IndirectSets中,如预期的那样,并且在保存和显示父对象需要新的内存地址之间)。我的下一步是什么?

回答

0

我是不确定这与您的问题有关,但为什么您的Parent类中有childLinkID属性?这看起来很奇怪,尤其是因为您正在使用相应的列进行连接。我想知道如何使用这个映射工作,我会解决这个问题。你可以尝试没有(也删除referencedColumnName,你不需要这个)?

顺便说一下,为什么不用相同的方法设置ParentChild之间的链接的双方?这使代码难以阅读并维护IMO。


您编辑的问题,而我回答,改变了级联从ParentChild,但是这看起来像一个变通,真正的问题的,我不知道你会不会面临其他问题。请按照我的建议修正您的地图。

+0

原因是在造成这个问题的真正模型中,我简化了这个,我有真实世界的数据需要独立使用它作为父类的属性,这是直接映射给这里的孩子。实际上,我还需要实施其他两个子类,每个子类都引用父代的/ different/property。 (我没有设计数据模型,以解决你的下一个问题/建议。) 要回答第二个问题,这是因为我添加了从父母到孩子的链接作为此问题的修复(并修复它) 。这在真实的代码中被改变了。 – Jon 2010-04-30 01:11:50

+0

我还更改了实体,以便将来自getXXX方法的JPA注释移至变量声明本身,我忽略了这些变量声明。那可以解决这个问题吗? – Jon 2010-04-30 01:13:37

+0

@Jon 1)我不知道我是否理解需要'childLinkID'属性,我想知道JPA如何处理整个事情2)*“这是因为我添加了父母之间的链接作为解决此问题的补丁” * - 这是必需的**双向关联,您必须设置链接的两侧。 3)*“我还更改了实体,以便将JPA注释从getXXX方法移至变量声明本身”* - 这不会改变任何内容。实际上,我仍然认为有一些深奥的东西,改变层叠效应的作用。 – 2010-04-30 01:58:28