开发者

JPA problem one-to-one association cascade= PERSIST

开发者 https://www.devze.com 2023-02-16 23:40 出处:网络
I have this ER model Message 0..1 <--> 0..1 MessageDetail PK:ID_MESSAGEPK: ID_DETA开发者_Python百科IL

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);
0

精彩评论

暂无评论...
验证码 换一张
取 消