Java 级联JPA中的设置和hibernate中的外键冲突

Java 级联JPA中的设置和hibernate中的外键冲突,java,hibernate,jpa,cascade,entities,Java,Hibernate,Jpa,Cascade,Entities,我有两门课: 母公司 孩子 在数据库中,子表有一个列ParentId->典型的一(父)->多(子)关系 现在我创建了两个实体,它们 public class Parent { @OneToMany(mappedBy="Parent", fetch = FetchType.EAGER, cascade = CascadeType.ALL) public Set<Child> getChildern() { ... } } public cl

我有两门课:

  • 母公司
  • 孩子
  • 在数据库中,子表有一个列ParentId->典型的一(父)->多(子)关系

    现在我创建了两个实体,它们

    public class Parent
    {
        @OneToMany(mappedBy="Parent", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
        public Set<Child> getChildern()
        {
          ...
        }
    }
    
    public class Child
    {
       @ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
       @JoinColumn(name="ParentId")
       public Parent getParent()
       { ... }
    }
    
    公共类父类
    {
    @OneToMany(mappedBy=“Parent”,fetch=FetchType.EAGER,cascade=CascadeType.ALL)
    公共集getChildern()
    {
    ...
    }
    }
    公营儿童
    {
    @manytone(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
    @JoinColumn(name=“ParentId”)
    公共父getParent()
    { ... }
    }
    
    现在我有两个场景:

  • 父对象被删除->应该发生什么
  • 孩子被删除->应该发生什么
  • 奖金问题:

  • 我是否总是需要创建关键的一个一个和多个一个的部分,或者我可以只创建多个一个,而不关心我有孩子的父母
  • 对于没有子级的父级,什么会导致hibernate向我发送一条违反外键约束的消息

  • 首先,我很惊讶这段代码能工作。IMO
    mappedBy=“Parent”
    实际上应该是
    mappedBy=“Parent”
    (注意小写字母“p”),因为
    子类的父属性称为
    Parent
    ,而不是
    Parent

    其次,我建议您将注释放在属性上,而不是放在访问器方法上。我发现它构成了整个代码

    • 可读性更强
    • 更容易维护,因为
    问题的答案取决于“删除”的确切含义。我猜你的意思是“通过持久性管理器删除”

    但是,如果您确实执行了
    parent.getChildren().remove(x)
    ,那么您需要设置为
    OneToMany
    ,以防您期望/希望JPA提供者删除子对象

    问题1

    将删除父级和所有子级。这是常见的情况

    问题2

    将删除父级和所有子级。这是一个相当奇怪的用例。通常,级联删除仅应用于一对多关系

    奖金1

    Java和JPA中的所有关系都是单向的,如果 源对象引用目标对象不能保证 目标对象也与源对象有关系

    从优秀的

    奖金2


    不知道。
    ConstraintViolationException
    是否来自底层数据库?或者换句话说,这两个表的DDL是什么样子的?它是由Hibernate生成的吗?

    首先,我很惊讶这段代码能正常工作。IMO
    mappedBy=“Parent”
    实际上应该是
    mappedBy=“Parent”
    (注意小写字母“p”),因为
    子类的父属性称为
    Parent
    ,而不是
    Parent

    其次,我建议您将注释放在属性上,而不是放在访问器方法上。我发现它构成了整个代码

    • 可读性更强
    • 更容易维护,因为
    问题的答案取决于“删除”的确切含义。我猜你的意思是“通过持久性管理器删除”

    但是,如果您确实执行了
    parent.getChildren().remove(x)
    ,那么您需要设置为
    OneToMany
    ,以防您期望/希望JPA提供者删除子对象

    问题1

    将删除父级和所有子级。这是常见的情况

    问题2

    将删除父级和所有子级。这是一个相当奇怪的用例。通常,级联删除仅应用于一对多关系

    奖金1

    Java和JPA中的所有关系都是单向的,如果 源对象引用目标对象不能保证 目标对象也与源对象有关系

    从优秀的

    奖金2


    不知道。
    ConstraintViolationException
    是否来自底层数据库?或者换句话说,这两个表的DDL是什么样子的?它是由Hibernate生成的吗?

    可能您会在此处找到所有答案:抱歉,它没有回答我的问题:(可能您会在此处找到所有答案:抱歉,它没有回答我的问题:(这是一个简单的示例代码,您没有看到如何调用我的私有字段。没有生成查询,休眠会中断,当我自己使用id生成删除查询时,一切正常。我实际上想禁止任何自动cascasion,我应该使用哪些设置然后parent=persist,child=nothing?关于rd双方都没有关系,想象一下,你有5个parent类型的实体和100000个child类型的实体,即使加载一个lazy_,这也是一个杀手。我在加载子对象时使用了大量筛选的特定查询。“想禁止任何自动cascasion”-那就不要定义它。如果你省略了
    cascade
    参数。但是,我想你真正想要的是孩子总是自动持久化,对吧?然后在
    manytone
    中省略
    cascade
    并在
    OneToMany
    中设置
    cascade=CascadeType.PERSIST
    。这就是我所做的:)现在怎么样,一切都好?如果你把4个问题分成1个问题,真的很难知道你的问题是否解决了。这是一个简单的示例代码,你还没有看到我的私有字段是如何调用的。没有生成查询,休眠中断,当我自己使用id生成删除查询时,一切都很好。我实际上想禁止任何查询自动cascasion,我应该使用哪些设置,然后parent=persist,child=nothing?关于双方都没有关系的问题,假设你有5个parent类型的实体和100000个child类型的实体,即使加载一个lazy_,它也是一个