JPA проблема каскад один-к-одному = PERSIST - PullRequest
1 голос
/ 16 марта 2011

У меня есть эта модель ER

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

И относительное сопоставление объектов:

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

Этот тест показывает, как я хочу обрабатывать объекты:

@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();
    }

Когда я сохраняю eventMessage на eventMessageAnagrafica, он не сохраняет FK.Существует два способа сохранить подстилающую связь:

1) добавить эту строку кода: eventMessageAnagrafica.setOnlineEventMessage(eventMessage); и сохранить дочерний объект: entityManager.persist(eventMessageAnagrafica);

2) изменить родительский установщик, как показано ниже:

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

Есть ли какой-нибудь другой чистый способ сделать это?PS Первоначально FK был в родительской таблице Message, но администратор БД сказал мне, что это не очень хороший дизайн ER.

С уважением, Массимо

Ответы [ 2 ]

2 голосов
/ 16 марта 2011

Ответственность за поддержание согласованности между сторонами двунаправленных отношений между объектами в памяти.При сохранении отношений провайдер JPA смотрит на сторону-владельца отношений, то есть на сторону без mappedBy.

Я думаю, что второй подход является наиболее чистым, поскольку он поддерживает согласованность автоматически, так что вы можетене забудь это сделать.В качестве альтернативы вы можете создать специальную функцию для связывания этих сущностей, кроме установщика, и ограничить доступ к установщикам.

0 голосов
/ 22 октября 2013
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);
...