亲爱的同事们,我带着以下人员来找你:
我正在使用EclipseLink作为我的应用程序的ORM,并尝试在我的一个实体(文章)上实现Soft Delete,并在删除具有OneToMany关系的Catagory时级联删除这些文章。
当我删除文章时,一切都按预期工作,但当我删除一个有n条文章的类别时,我会得到一个例外。我正在使用DescriptorCustomizer来完成软删除。
DescriptorCustomizer(参见 org.eclipse.persistence.config.DescriptorCustomizer ),具有以下实现:
public class ArticleCustomizer implements DescriptorCustomizer {
@Override
public void customize(ClassDescriptor classDescriptor) throws Exception {
classDescriptor.getQueryManager().setDeleteSQLString("UPDATE article SET ACTIVE = '0' WHERE id = #id");
}
}
我要保存的实体:
AbstractItem
@Entity
@Table(name = "item")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class AbstractItem extends BaseEntity {
@ManyToOne
protected Category category;
}
第
@Entity
@DiscriminatorValue("article")
@Customizer(value=ArticleCustomizer.class)
public class Article extends AbstractItem {
}
分类
@Entity
@Customizer(value=CategoryCustomizer.class)
public class Category extends BaseEntity {
@OneToMany(cascade = CascadeType.REMOVE)
@JoinTable(name = "category_items", joinColumns = @JoinColumn(name = "category_id"), inverseJoinColumns = @JoinColumn(name = "item_id"))
protected List<AbstractItem> items = new ArrayList<AbstractItem>();
@OneToMany(cascade = CascadeType.REMOVE)
@JoinTable(name = "category_subcategories", joinColumns = @JoinColumn(name = "category_id"), inverseJoinColumns = @JoinColumn(name = "parent_category_id"))
protected List<Category> categories = new ArrayList<Category>();
}
当我尝试级联删除具有n条文章的类别时的错误:
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'ACTIVE' in 'field list'
Error Code: 1054
Call: UPDATE article SET ACTIVE = '0' WHERE id = ?
bind => [null]
我可以看到id被绑定为null,但是我不明白为什么。有人可以指导我朝正确的方向发展吗?
谢谢!
答案 0 :(得分:3)
我很抱歉你的时间已经过去了。解决方案就在我面前:
classDescriptor.getQueryManager().setDeleteSQLString("UPDATE item SET ACTIVE = '0' WHERE id = #ID");
自定义程序的正确表应该是 ITEM 而不是 ARTICLE 。奇怪的是,它适用于单个文章删除,并不适用于级联。
第二个问题是:
#id instead of #ID
它区分大小写。
感谢您的帮助!
答案 1 :(得分:0)
每当一个类实现DescriptorCustomizer
时,我建议将其编码包装在:
public static class MyCustomizer implements DescriptorCustomizer {
@Override
public void customize(ClassDescriptor descriptor) throws Exception {
try {
...
... your functionality
...
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
原因是DescriptorCustomizer
导致无声失败,
当日志记录设置低于FINER
时(这非常详细)。然后异常不会传播到“外部”,你也不会注意到它们,也不能找出失败的原因。
或者,您可以将EMF属性PersistenceUnitProperties.LOGGING_LEVEL
级别设置为SessionLog.FINER_LABEL
。