CascadeType.Persist不使用JPA中的主键生成器类型表

时间:2011-11-21 09:44:27

标签: jpa

我在使用CascadeType.Persist进行JPA / Standalone项目时出现问题。我有一个Parent实体,它有一个Child实体列表,应该与Parent一起持久化,Parent的主键是使用Table(GeneratorType.TABLE)生成的,我用一个表来生成主键。

在家长中我有:

    @OneToMany(mappedBy="parent",fetch=FetchType.EAGER,cascade= {CascadeType.PERSIST,CascadeType.DETACH})
    List<Child> children;
    //Getter and Setter

    @PostPersist
    public void setParentID(){
    System.out.println("Inside Postpersist");
    for(Child ch : this.children){
        ch.setParent(this);
                    System.out.println(ch.getParent().getParentId());
    }
}

在孩子:

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "Parent_ID")
    private Parent parent;

在DB中,我有一个非null设置为Parent表的Parent_ID列。当我持有一个Parent实体并且它已经设置了Child实体列表时,它会抛出一个

    ConstraintViolationException: Cannot insert the value NULL into column 'Parent_ID', table 'jpaTest.Child', column does not allow nulls.

因为Parent对于所有Child实体都为null,尽管它将ParentId集打印到使用@PostPersist注释的方法中的每个Child实体

但是,当我将主键生成策略从TABLE类型更改为AUTO时,不会发生父和子的持久性。这是怎么回事以及为什么会这样。

提供者是Hibernate。我的数据库服务器是mssql。

3 个答案:

答案 0 :(得分:2)

这种方法看起来有点弱,因为规范不会过多地支持修改生命周期回调中的其他实体:

  

通常,便携式应用程序的生命周期方法不应该   调用EntityManager或Query操作,访问其他实体   实例,或修改同一持久性内的关系   上下文。

此外,您无法保证在父级中子级 @PostPersist 的级联顺序:

  

关于回调方法是否依赖于实现   在生命周期事件级联之前或之后调用   相关实体。应用程序不应该依赖于此顺序。

答案 1 :(得分:2)

是的,它没有省略级联持久性。我所要做的就是将Parent对象设置为Child,同时将Child实体添加到Parent中的子项列表中,因为它是双向关系。

在家长中:

    public void setParentToChild(Child ch){
    if(this.getChildren()==null){
        this.children = new ArrayList<Children>();
    }
            this.children.add(cb);
            //this is what worked. Also set the Parent to Child
    cb.setCustomer(this);
}

现在在创建新的Parent和Child时,我调用此方法将child添加到parent。而JPA在业务代码中没有任何设置。谢谢你们。

答案 2 :(得分:1)

我的猜测是,孩子的父字段必须在持久化之前初始化,而不是在@PostPersist方法之后,可能在级联完成后调用。