2015-01-20 2 views
0

У меня возникли некоторые странные ситуации, когда у меня есть, например, объект, называемый Статьи, которая имеет отношение к Поставщику, но также поставщику Связаться Лицо. Например:JPA отображение проблемы при отображении двух объектов с же `JoinColumn`

ERD

Поставщик связан со статьей на Supplier_Id, а ContactpersonSupplier связан со статьей обоими Supplier_Id (к SupplierID) и Supplier_Contactperson_Id (к Id).

Итак, теперь мы нанесем все отношения на Article:

@JoinColumn(name = "Supplier_Id") 
private Supplier supplier; 

@JoinColumns({ 
    @JoinColumn(name = "Supplier_Id"), 
    @JoinColumn(name = "Supplier_Contactperson_Id") 
private SupplierContactperson supplierContactperson; 

Это не работает, потому что мы картографирования Supplier_Id дважды, один раз supplier и один раз для supplierContactperson. Если вы сделаете это, вы получите следующее исключение:

org.hibernate.MappingException: Repeated column in mapping for entity: Article column: Supplier_Id (should be mapped with insert="false" update="false") 

В обычной ситуации вы бы связать их так: Article ->ContactpersonSupplier ->Supplier, и тогда не будет никаких проблем.

Однако ContactpersonSupplier не требуется, но Supplier не требуется. Это означает, что, если мы покинем контактного лица, мы не сможем предоставить поставщика.

Мы не можем использовать insertable = false, updatable = false по той же причине, если мы поместим эти значения на supplier, мы не сможем добавить поставщика, если контактное лицо не предоставлено.
Мы также не можем добавить их на supplierContactperson, потому что JPA/Hibernate требует, чтобы вы положили его на все @JoinColumn внутри @JoinColumns, и если мы это сделаем, мы не сможем сохранить контактного лица.

Одна идея состоит в том, чтобы просто сопоставить идентификаторы вместо использования связанных объектов, но нам интересно, есть ли альтернативный подход, который может работать. Итак, вопрос в том, как мы должны решить эту проблему с отображением?

Следует отметить, что структура данных не может быть изменена.

+0

Вместо государства "это не работает", обеспечивают точное сообщение об ошибке вы получаете пожалуйста. Также, если я посмотрю на схему, я бы понял, что у контакт-провайдера есть свой уникальный идентификатор, а Article.supplier_contact_person отображает его непосредственно. – Gimby

+0

@ Gimby Я думал, что ошибка была описана довольно хорошо в следующей части моего вопроса (что Hibernate выбрасывает исключение сопоставления и говорит, что вы должны помещать 'insert = false' и' update = false' на одно из двух соединений, потому что вы не может быть отображено дважды). В любом случае, я описал отношения между моими таблицами немного больше и представил сообщение об ошибке. – g00glen00b

ответ

2

это работало для меня:

@JoinColumn(name = "Supplier_Id",insertable=false,updatable=false) 
private Supplier supplier; 

@JoinColumns({ 
    @JoinColumn(name = "Supplier_Id",insertable=false,updatable=false), 
    @JoinColumn(name = "Supplier_Contactperson_Id",insertable=false,updatable=false) 
private SupplierContactperson supplierContactperson; 

@Column(name="Supplier_Id") 
private String supplier_id; 
@Column (name = "Supplier_Contactperson_Id") 
private String supplier_contact_Person_id; 

, а затем в сеттеры для setSupplierContactPerson (contactPerson)

supplierContactPerson = contactPerson; 
if (contactPerson!=null){ 
     supplier_id = contactPerson.getSupplierID(); 
     supplier_contact_Person_id = contactPerson.getSupplierContactPersonID(); 
} 

для setSupplier (поставщик):

supplier = supplier; 
if (supplier != null){ 
    supplier_id = supplier.getId(); 

}

+0

Даже не думал об этом, но на самом деле это может сработать. Вероятно, я бы добавил оператор 'else', чтобы отключить поставщика/контактного лица. – g00glen00b

0

Для отображения только идентификатора ContactPersonSupplier возникли проблемы: вы можете отправить контактное лицо от поставщика A и поставщика B, а база данных не будет жаловаться. Поскольку поставщик необходим, я бы попробовал: 1. Поместите insert = false, update = false в JoinColumn ("поставщик_id") поля контактного лица, чтобы избежать жалоб от JPA. 2.изменить (если еще нет) setSupplierContactPerson() с

if (contactPerson != null){ 
    setSupplier(contactPerson.getSupplier()); 
} else { 
    setSupplier(null); 
} 

Другой вариант заключается в изменении getSupplier() с

if (contactPerson != null){ 
    return contactPerson.getSupplier(); 
} 
return supplier; 
+0

Если я помещаю 'insertable = false, updatable = false' в этот joincolumn, также жалуется:« Смешивание вставленных и не вставленных столбцов в свойство не допускается: Article.supplierContactperson', вероятно, потому, что он должен иметь как столбцы внутри '@ JoinColumns', чтобы иметь одно и то же« состояние ». Однако, если я поместил его в оба столбца, я полагаю, что больше не могу спасти. – g00glen00b

+1

Вам нужно будет поместить их в поле «Поставщик», но поскольку это обязательно, а другое нет, это не решит вашу проблему. Если вы используете только contactPersonId и выполняете модификацию для получателя, вы получите поведение, которое вы ищете, но все же можно будет изменить данные непосредственно в базе данных и сделать несоответствия. Тем не менее, это лучший подход, который я могу думать о – dtortola

Смежные вопросы