当我坚持WorkAction
时,我需要存储WorkflowInstance
WorkAction wa = new WorkAction();
wa.setWorkflowInstance(wfi);
waDao.persist(wa);
然而,在WorkAction
fk列的表格中,workflow_instance_id
最终为空。
在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
,而工作流_instance_id则不为空,但我会丢失WorkflowInstancePlayer
我该如何解决这个问题?
答案 0 :(得分: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;
}
<强>更新强>
我和你一样复制了同样的案例。我认为这是某种错误,因为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
答案 1 :(得分:0)
解决方法
使用两个映射中的列名(workflow_instance_id)编译此实体的唯一方法,一个是标准的@JoinColumn,另一个是@JoinColumnOrFormula中的@JoinColumn,并且能够使用workflow_instance_id字段保留此实体填充是为了在没有公式
的WorkflowInstance映射中保持insertable = false,updatable = false@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");
答案 2 :(得分:0)
必须首先指定具有insertable = false和updatable = false的列,然后再指定JoinFormula。
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumnsOrFormulas({
@JoinColumnOrFormula(column = @JoinColumn(name = "workflow_instance_id", referencedColumnName = "workflow_instance_id", insertable=false, updatable=false)),
@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"))
})
private WorkflowInstancePlayer player;
我也面临着类似的问题,现在错误消失了。