2016-11-04 3 views
0

Я всегда говорил, что в случае двунаправленного отношения, которые вы сняли объект следующим образом:Как удалить объект с помощью внешнего первичного ключа в JPA?

  1. Breakdown отношения
  2. Update владелец объект
  3. Удалить объекты

Но теперь мой основной ключ является частью отношений, поэтому это невозможно.

Есть ли у кого-нибудь идеи о том, как удалить объект с основным внешним ключом в этом случае?

Я попытался установить свойство «mappedby» равным null, а не просто вызвать manager.remove (...), но есть всегда другой сущ.-Менеджер, который все еще имеет управляемый экземпляр удаленной сущности, поэтому i получите следующую ошибку:

During synchronization a new object was found through a relationship 
that was not marked cascade PERSIST 

Ниже я поставил код классов, которые я использую.

У данного класса есть OrderWeek. Этот первичный ключ также является составным ключом, что делает код немного менее удобочитаемым, но он не должен влиять на проблему, которую я испытываю.

public class OrderBill{ 
     @EmbeddedId 
     private OrderWeekPK orderWeekPK; 

     @OneToOne 
     @JoinColumns(value = { 
      @JoinColumn(name="weekNr", referencedColumnName = "weekNr"), 
      @JoinColumn(name="yearNr", referencedColumnName = "yearNr")}) 
     @MapsId 
     private OrderWeek orderWeek; 
    } 

public class OrderWeek{ 
    @OneToOne(mappedBy="orderWeek") 
    private OrderBill orderBill; 

    @EmbeddedId 
    private OrderWeekPK orderWeekPK; 
} 

@Embeddable 
public class OrderWeekPK implements Serializable{ 
    @Column(name="yearNr") 
    private int yearNr; 
    @Column(name="weekNr") 
    private int weekNr; 
} 

Есть ли какая-то стратегия для этого, что мне не хватает?

Update: сейчас я могу обойти проблему путем переключения Обладания и принадлежащей стороны (передачи mappedby к OrderBill классу). Теперь я могу разбить отношения, не касаясь внешнего первичного ключа.

Это «решение» по-прежнему меньше, чем идеал: OrderWeek теперь имеет избыточную колонку (weekNr2 и yearNr2, например), которое (или должен быть), идентичную первичного ключа

Может быть, это помогает людям с такой же до тех пор, пока не будет найдено фактическое решение.

+0

Непонятно, для чего вы используете аннотацию MapsId. Вы просто хотели отметить эти отношения как @Id?Это позволило бы OrderBill использовать OrderWeekPK в качестве своего pkClass. – Chris

+0

@Chris Это просто отметить это поле как внешний ключ, указав, что это поле использует pk OrderWeek. ([This] (http://www.thejavageek.com/2014/09/26/jpa-mapsid-example/) сайт может объяснить это лучше) Но хорошо заметили, я не понял, что не поставил \ @embeddedid для OrderBill в моем фрагменте кода здесь. Эта ошибка могла бы смутить многих людей, сразу же отредактирует. – Wouter

ответ

1

Вы могли бы покончить с @MapsId и вложиться в OrderBill, используя @Id в свойстве orderWeek и указав @IdClass (OrderWeekPK.class) на сущности - это может работать с вашими сопоставлениями, как они есть, но не является источником ошибки, которую вы упоминаете в своем сообщении.

Проблема в том, что у вас есть два объекта с двунаправленным отношением. Если вы измените отношения (например, null), вам необходимо объединить это изменение в контекст. Поэтому, чтобы удалить экземпляр OrderBill, вы должны вызвать em.remove на экземпляре, а также обнулить ссылку OrderWeek и вызвать слияние на OrderWeek. Это необходимо сделать в той же транзакции, и, хотя изменение в orderBill заказа OrderWeek в базе данных не является оператором, оно будет поддерживать кеш-insync и не позволит воскресить OrderBill (или исключения, которые вы видите)

Альтернативой является добавление тега удаления сирот в свойство orderBee OrderWeek, которое заставляет JPA автоматически вызывать em.remove, если вы отклоняете эту ссылку.