2011-09-16 3 views
1

J'ai une question de cartographie JPA à faire.Problème avec JPA Mappage un-à-plusieurs avec jointable

Nous avons une relation un-à-plusieurs entre deux entités (Sale et Pig). Les classes suivent à la fin de ce message pour illustrer. «Vente» est un événement sur un «Cochon», comme beaucoup d'autres dans le système («Inspection» est un autre exemple). Cependant, 'Sale' est le seul événement qui a une relation un-à-plusieurs avec 'Pig', les autres ont un One-to-One. Ainsi, pour cartographier tous les événements d'un 'Pig', nous utilisons une entité 'PigEvent'. Nous sauvegardons (insérons) un objet 'PigEvent' en même temps que l'utilisateur insère un 'Pig' dans le système.

Nous voulons utiliser cette entité ('PigEvent') comme le 'jointable' du mappage Sale.getPigs(). Cependant, un problème survient: - lorsqu'une nouvelle 'Vente' est insérée, hibernate essaie d'insérer un nouveau 'PigEvent' pour chaque 'Pig' dans la 'Vente' (cela génère une exception PK dupliquée, car PigEvent déjà existe) - lorsqu'une nouvelle « vente » est supprimée, mise en veille prolongée supprime de la PigEvent 'pour chaque « Pig » dans la « vente » (ce faisant, nous perdons les autres Évènements de la relation)

nous comprenons que c'est le comportement normal de ce type de mapping (One-to-Many avec jointable). Nous voulons savoir comment configurer JPA/Hibernate pour charger simplement Sale.getPigs() (dans SELECT), mais dans les opérations INSERT, UPDATE, DELETE dans 'Sale' n'agissez pas du tout dans ce mapping (Sale. les cochons()).

Nous utilisons Hibernate 3.6.2.

Merci d'avance.

@Entity 
public class Pig extends Persistente implements Serializable {} 

@Entity 
public class PigEvent extends Persistente { 
@OneToOne 
@JoinColumn(name="idpig") 
private Pig pig; 

@OneToOne 
@JoinColumn(name="idapproval") 
private Inspection approval 

@OneToOne 
@JoinColumn(name="idsale") 
private Sale sale; 
} 


@Entity 
public class Inspection extends Persistente{ 
     @OneToOne 
     @JoinColumn(name="idSuino") 
     private Pig pig; 
} 


@Entity 
public class Sale extends Persistente{ 
@MOneToMany 
@JoinTable(name="e33PigEvent",[email protected](columnNames="idpig"), 
     joinColumns={@JoinColumn(name="idsale",insertable=false,updatable=false)}, 
     inverseJoinColumns={@JoinColumn(name="idpig",insertable=false,updatable=false)}) 
public Set<Pig> getPigs() {} 
} 

Table Structure: 
CREATE TABLE `e33Pig` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`) 
) 


CREATE TABLE `e33PigEvent` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `idPig` int(11) NOT NULL, 
    `idInspection` int(11) DEFAULT NULL, 
    `idSale` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `idPig` (`idPig`), 
    CONSTRAINT `fk_e33eventossuino_e33aprovacao1` FOREIGN KEY (`idInspection`) REFERENCES `e33Inspection` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, 
    CONSTRAINT `fk_e33eventossuino_e33suino1` FOREIGN KEY (`idPig`) REFERENCES `e33Pig` (`id`), 
    CONSTRAINT `fk_e33eventossuino_e33venda1` FOREIGN KEY (`idSale`) REFERENCES `e33Sale` (`id`) ON DELETE SET NULL ON UPDATE CASCADE 
); 

CREATE TABLE `e33Sale` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`) 
); 

CREATE TABLE e33Inspection (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `idsuino` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    CONSTRAINT `fk_e33Inspection_e33suino1` FOREIGN KEY (`idPig`) REFERENCES `e33Pig` (`id`) 
) ; 
+0

Donc, est la table e33PigEvent pour mapper l'entité PigEvent, et pour mapper l'association ManyToMany? Pourquoi nous parlez-vous d'une association OneToMany, et la cartographie en utilisant ManyToMany? –

+0

Salut JB, Il était faux sur l'exemple de code ... est @OneToMany. Merci – Rodrigo

+0

Vous n'avez pas répondu à la première question. À quelles tables sont toutes ces entités mappées? –

Répondre

0

Vous ne pouvez pas utiliser la même table (e33PigEvent) pour mapper une entité (PigEvent) et une association (l'association OneToMany). Si la table est mise en correspondance avec une entité, alors vous n'avez pas une association OneToMany entre la vente et de porc plus: vous avez un OneToMany entre Sale et PigEvent, cartographiée par une clé étrangère dans e33PigEvent, et un OneToOne entre PigEvent et Pig, aussi mappé par une clé étrangère dans e33PigEvent. Si vous mappez un OneToMany à l'aide d'un JoinTable, Hibernate gère les insertions et les suppressions dans ce tableau lui-même, chaque fois que vous ajoutez ou supprimez des porcs de la collection. Étant donné que vous avez des colonnes supplémentaires dans la table de jointure, vous devez créer des instances PigEvent vous-même et ajouter ces instances à la collection d'événements de la vente.

+0

JB Nizet, Merci pour la réponse. Le problème lié directement à Sale et PigEvent est les autres événements, le surcoût causé par les jointures supplémentaires pour charger un PigEvent. Donc, nous pouvons faire ce que vous suggérez ou quitter Sales.pigs @ Transient, non? – Rodrigo

+0

Oui.Il devrait être @Transient, et il devrait renvoyer un ensemble de porcs construit dynamiquement en itérant tous les événements porc et en ajoutant chaque cochon à l'ensemble retourné. Mais ce n'est que du code Java ordinaire: rien à propos d'Hibernate. –

Questions connexes