2015-11-30 2 views
0

Когда я настойчив WorkAction мне нужно хранить Id FK для WorkflowInstanceПовторные столбец отображения для объекта

WorkAction wa = new WorkAction(); 
wa.setWorkflowInstance(wfi); 
waDao.persist(wa); 

Однако в таблице WorkAction колонка Ф.К., workflow_instance_id завершаться быть пустым.

Оказывается, в Entity для WorkAction я сопоставляются WorkflowInstance используя , insertable = false, updatable = false как этот

@ManyToOne 
@JoinColumn(name = "workflow_instance_id", referencedColumnName = "workflow_instance_id", insertable = false, updatable = false) 
private WorkflowInstance workflowInstance; 

Когда я снял его, я получил Repeated column in mapping for entity: WorkAction column: workflow_instance_id Но в WorkAction лица я не видел workflow_instance_id карту снова, т.е. у меня не было private Long workflow_instance_id;

Но потом я заметил в моем WorkAction сущности, я сопоставляюсь WorkflowInstancePlayer, используя формулу, которая ссылается workflow_instamce_id

@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumnsOrFormulas({ @JoinColumnOrFormula(formula = @JoinFormula(value = "(SELECT a.role_class_id FROM WF_WORK_ACTION_CLASS a WHERE a.work_action_class_id = work_action_class_id)", referencedColumnName = "role_class_id")), 
     @JoinColumnOrFormula(column = @JoinColumn(name = "workflow_instance_id", referencedColumnName = "workflow_instance_id", insertable=false, updatable=false)) }) 
private WorkflowInstancePlayer player; 

Даже после добавления insertable=false, updatable=false к этому картографированию у меня все еще есть проблема. Когда я закомментируйте @JoinColumnsOrFormulas я могу удалить insertable=false, updatable=false на WorkflowInstance и workflow_instance_id тогда не равно нулю, но тогда я потеряю WorkflowInstancePlayer

Как обойти это?

+0

Есть ли конкретная причина не добавлять частный рабочий класс Workflow_instance_id к классу WorkAction и использовать его для сохранения? – Ghokun

+0

Да, потому что это также приведет к повторному столбцу при сопоставлении ошибки сущности. – jeff

+0

Это не так, если вы добавите insertable = false, updatable = false к вашим объединенным свойствам. – Ghokun

ответ

1

Используйте insertable = false, updatable = false в своих анкетах @JoinColumn.

public class WorkAction { 

    @Column(name="workflow_instance_id") 
    private Long workflow_instance_id; 

    @ManyToOne 
    @JoinColumn(name = "workflow_instance_id", referencedColumnName = "workflow_instance_id", insertable = false, updatable = false) 
    private WorkflowInstance workflowInstance; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumnsOrFormulas({ 
     @JoinColumnOrFormula(formula = @JoinFormula(value = "(SELECT a.role_class_id FROM WF_WORK_ACTION_CLASS a WHERE a.work_action_class_id = work_action_class_id)", referencedColumnName = "role_class_id")), 
     @JoinColumnOrFormula(column = @JoinColumn(name = "workflow_instance_id", referencedColumnName = "workflow_instance_id", insertable=false, updatable=false)) }) 
    private WorkflowInstancePlayer player; 
} 

UPDATE

я воспроизвел тот же случай, как вы делали. Я думаю, что это какая-то ошибка, потому что isUpdatable и isInsertable возвращает true.

protected void checkColumnDuplication(Set distinctColumns, Iterator columns) 
throws MappingException { 
    while (columns.hasNext()) { 
     Selectable columnOrFormula = (Selectable) columns.next(); 
     if (!columnOrFormula.isFormula()) { 
      Column col = (Column) columnOrFormula; 
      if (!distinctColumns.add(col.getName())) { 
       throw new MappingException( 
         "Repeated column in mapping for entity: " + 
         getEntityName() + 
         " column: " + 
         col.getName() + 
         " (should be mapped with insert=\"false\" update=\"false\")" 
        ); 
      } 
     } 
    } 
} 

protected void checkPropertyColumnDuplication(Set distinctColumns, Iterator properties) 
throws MappingException { 
    while (properties.hasNext()) { 
     Property prop = (Property) properties.next(); 
     if (prop.getValue() instanceof Component) { //TODO: remove use of instanceof! 
      Component component = (Component) prop.getValue(); 
      checkPropertyColumnDuplication(distinctColumns, component.getPropertyIterator()); 
     } 
     else { 
      if (prop.isUpdateable() || prop.isInsertable()) { 
       checkColumnDuplication(distinctColumns, prop.getColumnIterator()); 
      } 
     } 
    } 
} 

Исходный код из org.hibernate.mapping.PersistentClass

+0

Я ценю, что вы пытаетесь помочь, но это вызывает проблему с повторным сопоставлением столбцов. Технически это действительно не отличается от того, что я пытался, когда у меня не было insertable = false, updatable = false в JoinColumn for WorkflowInstance. Что-то подозрительное с сумасшедшими JoinColumnsOrFormulas, потому что у меня нет этой проблемы с другими «нормальными» объектами – jeff

+0

У меня почти такая же структура классов, но я не могу проверить прямо сейчас. Завтра я отправлю завтра, если вы еще этого не выяснили. – Ghokun

+0

так что означает ваше обновление? Я привинчен? Итак, Hibernate игнорирует insertable = false, updatable = false на JoinColumnOrFormula ?? – jeff

0

Работа Вокруг

Единственный способ получить это Entity для компиляции с именем столбца (workflow_instance_id) в двух отображений, один является стандартом @JoinColumn и другой @JoinColumn в @JoinColumnOrFormula, и иметь возможность сохранить этот объект с заполненным полем workflow_instance_id, должно было оставаться insertable = false, updatable = false на моем сопоставлении WorkflowInstance без формулы

@ManyToOne 
@JoinColumn(name = "workflow_instance_id", referencedColumnName = "workflow_instance_id", insertable = false, updatable = false) 
private WorkflowInstance workflowInstance; 

сделать нормальный менеджер сущности сохраняется на сущности

WorkAction wa = new WorkAction(); 
//wa.setWorkflowInstance(wfi); is ignored 
wa.set other stuff; 
waDao.persist(wa); 

затем сделать NativeQueryUpdate для заполнения столбца workflow_instance_id.

waDao.updateWfi(wa.getWfi_work_item_action_id(), wfi.getWorkflow_instance_id()); 


public void updateWfi(Long wfi_work_item_action_id, Long workflow_instance_id) { 
Query query = em.createNativeQuery("UPDATE table_name SET workflow_instance_id = :workflow_instance_id WHERE wfi_work_item_action_id = :wfi_work_item_action_id"); 
Смежные вопросы