2009-05-05 33 views
10

Tengo dos clases de entidad anotadas de la siguiente maneraahorro bidireccional ManyToMany

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

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

Si puedo almacenar una instancia de la clase 'B', las relaciones se almacenan en la base de datos y el captador en la clase 'A' devolverá el subconjunto correcto de B's. Sin embargo, si realizo cambios en la lista de Bs en 'A', ¿los cambios no se almacenan en la base de datos?

Mi pregunta es, ¿cómo puedo hacer para que los cambios en cualquiera de las clases están "en cascada" a la otra clase?

EDIT: He intentado diferentes variaciones de la eliminación de la mappedBy parámetros y definir un joinTable (y columnas), pero he sido incapaz de encontrar la combinación correcta.

+0

Qué aplicación APP está usando? –

Respuesta

16

La respuesta más corta parece ser que no se puede y tiene sentido. En una asociación multidireccional bidireccional, una de las partes debe ser maestra y se utiliza para conservar los cambios en la tabla de combinación subyacente. Como JPA no mantendrá ambos lados de la asociación, podría terminar con una situación de memoria que no podría volver a cargarse una vez almacenada en la base de datos. Ejemplo:

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

Si este estado podría ser persistente, que terminaría con las siguientes entradas en la tabla de unión:

a1_id, b_id 
a2_id, b_id 

Pero durante la carga, ¿cómo APP saber que la intención de solamente deja b saber sobre a2 y no a1? y ¿qué pasa con a2 que no debería saber acerca de b?

Es por eso que usted debe mantener la asociación bidireccional usted mismo (y hacer que el ejemplo anterior sea imposible de alcanzar, incluso en la memoria) y JPA solo persistirá en función del estado de un lado del mismo.

0

¿Ha tryed añadiendo el parámetro mappedBy en el campo A en la clase B al igual que

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

Esto no funcionará, de hecho es una parametrización ilegal. El parámetro mappedBy define la propiedad del campo y, por lo tanto, no es posible usar ese parámetro para ambas colecciones, ya que no pueden ser propiedad entre sí. –

3

Ha especificado el inverso unirse columnas?

@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; 
    .. 
} 

Eso supone una tabla de unión llamada A_B con columnas A_ID y B_ID.

+0

Probé esta solución también, pero no tuve suerte :( –

+2

no debería ser el mappedBy igual a 'a' minúscula en lugar de la clase? – Ced

0

tal vez hay un pequeño error en la respuesta de a_m. En mi opinión, hay que:

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

medida que la relación es bidireccional así como las actualizaciones de la aplicación un lado de la relación, el otro lado también debe recibir información actualizada, y estar en sintonía. En JPA, como en Java, en general, es el responsabilidad de la aplicación, o el modelo de objetos para mantener relaciones . Si su aplicación se agrega a un lado de una relación , entonces debe agregar al otro lado.

Esto puede resolverse mediante métodos de agregar o establecer en el modelo de objeto que maneja ambos lados de las relaciones, por lo que el código de aplicación no necesita preocuparse por ello.Hay dos formas de hacerlo, , solo puede agregar el código de mantenimiento de relación a un lado de la relación, y solo usar el colocador desde un lado (como haciendo que el otro lado esté protegido) o agregarlo a ambos lados y asegurar que evita un bucle infinito.

Fuente: OneToMany#Getters_and_Setters