JPA problem one-to-one association cascade= PERSIST
I have this ER model
Message 0..1 <--> 0..1 MessageDetail
PK:ID_MESSAGE PK: ID_DETA开发者_Python百科IL
NAME DETAIL
FK: ID_MESSAGE
And the relative Object mapping is:
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;
}
This test shows how I would like to handle the objects:
@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();
}
When I persist the eventMessage on the eventMessageAnagrafica it does not save the FK. The two ways to save the underlaying association are:
1) add this line of code : eventMessageAnagrafica.setOnlineEventMessage(eventMessage);
and save the child object: entityManager.persist(eventMessageAnagrafica);
2) change the parent setter as below:
public void setEventMessageAnagrafica(EventMessageAnagrafica eventMessageAnagrafica) {
this.eventMessageAnagrafica = eventMessageAnagrafica;
if (eventMessageAnagrafica != null) {
eventMessageAnagrafica.setOnlineEventMessage(this);
}
}
Is there any other clean way to accomplish this? P.S. Initially the FK was on the parent table Message, but the DBA told me that this wasn't a good ER design.
Kind regards Massimo
Maintaining consistency between sides of bidirectional relationship between objects in memory is your responsibility. When saving relationship, JPA provider looks at the owning side of the relationship, that is at the side without mappedBy
.
I think the second approach is the cleanest, since it maintains consistency automatically, so that you can't forget to do it. Alternatively you can create a special function for associating these entities, other than setter, and restrict access to setters.
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);
精彩评论