2011-03-16 6 views
1

J'ai ce modèle ERproblème JPA un à une association cascade = PERSISTERONT

Message 0..1 <--> 0..1 MessageDetail 
    PK:ID_MESSAGE   PK: ID_DETAIL 
     NAME     DETAIL 
          FK: ID_MESSAGE 

Et le mapping objet relatif est:

class OnlineEventMessage { 
    @Id 
    @Column(name = "ID_EVENT_MESSAGE") 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ") 
    private Long idEventMessage; 

    @OneToOne(mappedBy="onlineEventMessage", cascade=CascadeType.PERSIST) 
    private EventMessageAnagrafica eventMessageAnagrafica; 
} 

public class EventMessageAnagrafica { 

    @Id 
    @Column(name = "ID_EVENT_MESSAGE_ANAG") 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ") 
    private Long idEventMessageAnagrafica; 

    @OneToOne(cascade=CascadeType.PERSIST) 
    @JoinColumn(name = "FK_ID_EVENT_MESSAGE") 
    private OnlineEventMessage<?> onlineEventMessage; 
} 

Ce test montre comment je voudrais gérer la objets:

@Test 
    public void testSaveItem() { 
     EntityManager entityManager = factoryCont0.createEntityManager(); 

     entityManager.getTransaction().begin(); 

     OnlineEventMessage<String> eventMessage = new OnlineEventMessage<String>(EventType.ONLINE_REIMPIANTO_CONTRATTO); 

     EventMessageAnagrafica eventMessageAnagrafica = new EventMessageAnagrafica(multichannelId); 
     eventMessage.setEventMessageAnagrafica(eventMessageAnagrafica); 

     entityManager.persist(eventMessage); 
     entityManager.getTransaction().commit(); 
     entityManager.close(); 
    } 

Quand je persiste le EventMessage sur le eventMessageAnagrafica il ne sauve pas le FK. Les deux façons d'économiser l'association underlaying sont:

1) ajouter cette ligne de code: eventMessageAnagrafica.setOnlineEventMessage(eventMessage); et enregistrer l'objet enfant: entityManager.persist(eventMessageAnagrafica);

2) modifier le setter parent comme ci-dessous:

public void setEventMessageAnagrafica(EventMessageAnagrafica eventMessageAnagrafica) { 
     this.eventMessageAnagrafica = eventMessageAnagrafica; 
     if (eventMessageAnagrafica != null) { 
      eventMessageAnagrafica.setOnlineEventMessage(this); 
     } 
    } 

Existe-t-il un autre moyen de le faire? P.S. Initialement, le FK était sur la table parent Message, mais le DBA m'a dit que ce n'était pas un bon design d'ER.

Amitiés Massimo

Répondre

2

préserver la cohérence entre les côtés de la relation bidirectionnelle entre les objets en mémoire est de votre responsabilité. Lors de la sauvegarde de la relation, le fournisseur JPA examine le côté propriétaire de la relation, c'est-à-dire sans mappedBy.

Je pense que la deuxième approche est la plus propre, car elle maintient la cohérence automatiquement, de sorte que vous ne pouvez pas oublier de le faire. Vous pouvez également créer une fonction spéciale pour associer ces entités, autre que setter, et restreindre l'accès aux setters.

0
entityManager.getTransaction().begin(); 

OnlineEventMessage<String> eventMessage = new OnlineEventMessage<String>(EventType.ONLINE_REIMPIANTO_CONTRATTO); 

EventMessageAnagrafica eventMessageAnagrafica = new EventMessageAnagrafica(multichannelId); 
eventMessage.setEventMessageAnagrafica(eventMessageAnagrafica); 

//add this line 
eventMessageAnagrafica.setEventMessage(eventMessage); 

entityManager.persist(eventMessage); 
Questions connexes