代码之家  ›  专栏  ›  技术社区  ›  KCL

节省双向人工

  •  11
  • KCL  · 技术社区  · 17 年前

    我有两个实体类,注释如下

    @Entity
    class A {
       @ManyToMany(mappedBy="A", cascade=CascadeType.ALL)
       private List<B> b;
     ..
    }
    
    @Entity
    class B {
       @ManyToMany(cascade=CascadeType.ALL)
       private List<A> a;
     ..
    }
    

    如果存储类“b”的实例,则关系存储在数据库中,类“a”中的getter将返回B的正确子集。但是,如果更改“a”中的b s列表,则更改不会存储在数据库中?

    我的问题是,如何才能使这两个类中的更改“级联”到另一个类?

    编辑:我尝试过删除mappedby参数和定义jointable(和列)的不同变体,但找不到正确的组合。

    5 回复  |  直到 13 年前
        1
  •  16
  •   Louis Jacomet    17 年前

    最短的答案似乎是你不能,这是有道理的。在双向多对多关联中,一方必须是主关联,并用于持久化对基础联接表的更改。由于JPA不会维护关联的两边,所以最终可能会出现一种内存情况,一旦存储在数据库中,就无法重新加载这种情况。 例子:

    A a1 = new A();
    A a2 = new A();
    B b = new B();
    a1.getB().add(b);
    b.getA().add(a2);
    

    如果此状态可以持久化,您将在联接表中得到以下条目:

    a1_id, b_id
    a2_id, b_id
    

    但是在装载之后,JPA怎么知道你只想让B知道A2而不是A1?不应该知道b的a2呢?

    这就是为什么您必须自己维护双向关联(并使上面的示例不可能到达,甚至在内存中)并且JPA将仅基于其一侧的状态而持久。

        2
  •  3
  •   A_M    17 年前

    是否指定了反向联接列?

    @Entity
    class A {
       @ManyToMany(mappedBy="A", cascade=CascadeType.ALL)
       private List <B> b;
       ..
    }
    
    @Entity 
    class B { 
       @ManyToMany 
       @JoinTable (
           name="A_B",
           joinColumns = {@JoinColumn(name="A_ID")},
           inverseJoinColumns = {@JoinColumn(name="B_ID")}
       )
       private List<A> a; 
       .. 
    } 
    

    假设有一个名为a_b的联接表,其中包含列a_id和b_id。

        3
  •  1
  •   Tomasz    13 年前

    因为这种关系是双向的,所以应用程序会更新 关系的一方,另一方也应该得到更新, 并保持同步。在JPA中,一般在Java中 它是 应用程序或对象模型维护的职责 关系。 如果应用程序添加到 关系,然后它必须添加到另一边。

    这可以通过在对象模型中添加或设置方法来解决。 它处理关系的两边,因此应用程序代码 不用担心。有两种方法可以解决这个问题, 您只能将关系维护代码添加到一侧 只使用一侧的setter(例如 使另一侧受到保护),或将其添加到两侧并确保 避免无限循环。

    来源: OneToMany#Getters_and_Setters

        4
  •  0
  •   mR_fr0g    17 年前

    是否尝试将mappedby参数添加到类B中的a字段中,就像这样?

    @Entity
    class B {
       @ManyToMany(cascade=CascadeType.ALL, mappedBy = "b")
       private List<A> a;
     ..
    }
    
        5
  •  0
  •   Jozeph    16 年前

    也许在答案中有一个小错误。 我认为应该是:

       @Entity
       class B { 
       @ManyToMany 
       @JoinTable (
           name="A_B",
           joinColumns = {@JoinColumn(name="B_ID")},
           inverseJoinColumns = {@JoinColumn(name="A_ID")}
       )
       private List a; 
       .. 
    }