我在两个类Project和ProductCatalogItem之间有一个双向的多对多映射。 Project hbm文件中定义的映射如下 -
<set name="catalogItems" table="PAS_PRODUCT_CATALOG_PROJECT"
inverse="false" lazy="true" cascade="all-delete-orphan">
<key column="PROJECT_ID_" />
<many-to-many column="PRODUCT_CATALOG_ITEM_ID_" class="com.palamida.appsec.model.ProductCatalogItem" />
</set>
ProductCatalogItem中的映射定义如下 -
<set name="itemInProjects" table="PAS_PRODUCT_CATALOG_PROJECT"
inverse="true" lazy="true">
<key column="PRODUCT_CATALOG_ITEM_ID_" />
<many-to-many column="PROJECT_ID_" class="com.palamida.appsec.model.Project" />
</set>
定义了三个表格 - PROJECT,PRODUCT_CATALOG_ITEM和PAS_PRODUCT_CATALOG_PROJECT(联接表)
Project类具有catalogItems
private Set<ProductCatalogItem> catalogItems = new HashSet<ProductCatalogItem>();
ProductCatalogItem具有itemsInProject
private Set<Project> itemInProjects = new HashSet<Project>();
每个属性都有适当的getter和setter。 从ProductCatalogItem添加/删除项目的逻辑如下 -
public void updateProductCatalogItemsToProject(Project project,
Map<EntityOperationEnum,Set<ProductCatalogItem>> modifiedCatalogItems) {
if (project != null && modifiedCatalogItems != null && !modifiedCatalogItems.isEmpty()) {
Set<ProductCatalogItem> newCatalogItems = modifiedCatalogItems.get(EntityOperationEnum.ADD);
Set<ProductCatalogItem> deleteCatalogItems = modifiedCatalogItems.get(EntityOperationEnum.REMOVE);
if (newCatalogItems != null && !newCatalogItems.isEmpty()) {
project.getCatalogItems().addAll(newCatalogItems);
}
if (deleteCatalogItems != null && !deleteCatalogItems .isEmpty()) {
project.getCatalogItems().removeAll(deleteCatalogItems );
}
}
}
当只有要添加的元素时,数据将插入到链接表中。但是当要删除项目时,我会遇到以下异常 -
org.springframework.dao.InvalidDataAccessResourceUsageException: could not initialize a collection: [com.palamida.appsec.model.ProductCatalogItem.childProductCatalogItems#17]; SQL [select childprodu0_.PROJECT_ID_ as PROJECT9_89_1_, childprodu0_.ID_ as ID1_1_, childprodu0_.ID_ as ID1_89_0_, childprodu0_.VERSION_ as VERSION2_89_0_, childprodu0_.ITEM_NUMBER_ as ITEM3_89_0_, childprodu0_.ITEM_NAME_ as ITEM4_89_0_, childprodu0_.ITEM_DESCRIPTION_ as ITEM5_89_0_, childprodu0_.PLATFORM_NAME_ as PLATFORM6_89_0_, childprodu0_.RELEASE_NAME_ as RELEASE7_89_0_, childprodu0_.PARENT_ID_ as PARENT8_89_0_ from PAS_PRODUCT_CATALOG_ITEM childprodu0_ where childprodu0_.PROJECT_ID_=? order by childprodu0_.ITEM_NAME_ asc]; nested exception is org.hibernate.exception.SQLGrammarException: could not initialize a collection: [com.palamida.appsec.model.ProductCatalogItem.childProductCatalogItems#17]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:635)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'childprodu0_.PROJECT_ID_' in 'field list'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57
SELECT是否应该根据PROJECT_ID_在PAS_PRODUCT_CATALOG_PROJECT表上加入?我没有看到这种情况发生。地图中是否有任何遗漏? 你能帮帮我吗?
答案 0 :(得分:0)
我发现了这个问题。我的映射是cascade =&#34; all-delete-orphan&#34;。根据hibernate docs
It does not usually make sense to enable cascade on a many-to-one or many-to-many association.
In fact the @ManyToOne and @ManyToMany don't even offer a orphanRemoval attribute.
Cascading is often useful for one-to-one and one-to-many associations.
因此,当我尝试从关联中删除时,hibernate尝试使用连接列&#34; PROJECT_ID _&#34;将其从CATALOG_ITEM表中删除。因此错误。 一旦我将其修改为&#34; all&#34;,事情就开始起作用了。