我有以下包含@Lob的可嵌入类:
@Embeddable
public class EntityState {
private Integer version;
@Lob
@XmlJavaTypeAdapter(CharArrayAdapter.class)
private char[] xmlState;
...
}
我还有以下嵌入式类,其中包含上述嵌入式:
@Embeddable
public class EntityEvent {
@NotNull
private String note;
private EntityState entityState;
...
}
最后,我有许多实体类,它们包含一个名为history的属性,它是一个EntityEvents列表。以下是一个例子:
@Entity
public class Company {
@NotNull
@ElementCollection
private List<EntityEvent> history;
...
}
当我在GlassFish 4.1中部署我的应用程序时,EclipseLink在我的Derby 10.11.1.1数据库中创建以下表:
当我创建新公司时,我的应用程序会创建一个EntityEvent并将EntityEvent添加到公司历史记录中。
当我修改公司时,我的申请会执行以下操作:
问题是当我尝试删除具有多个EntityEvents的历史记录的实体时,我收到以下错误:
异常[EclipseLink-4002](Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd):org.eclipse.persistence.exceptions.DatabaseException内部异常:java.sql.SQLSyntaxErrorException:&#39; CLOB之间的比较(UCS_BASIC) )&#39;和&#39; CLOB(UCS_BASIC)&#39;不受支持。类型必须具有可比性。字符串类型还必须具有匹配的排序规则。如果排序规则不匹配,可能的解决方案是转换操作数以强制它们进行默认排序规则(例如SELECT tablename FROM sys.systables WHERE CAST(tablename AS VARCHAR(128))=&#39; T1&#39;)
错误代码:20000调用:DELETE FROM Company_HISTORY WHERE(((((((((((CHANGES =?)AND(CLIENTTYPE =?))AND(CREATED =?))AND(IPADDRESS =?))AND(注意=?))AND(TYPE =?))AND(VERSION =?))AND(XMLSTATE =?))AND(CREATER_ID =?))AND(Company_ID =?))bind =&gt; [10个参数绑定]
我在以下链接中找到了一些对此问题的引用:
我尝试了上面引用的stackoverflow文章中描述的@OrderColumn技术,但这在EclipseLink中不起作用。
对我有用的解决方案是将EclipseLink非标准@CascadeOnDelete注释添加到我的实体,如下所示:
@Entity
public class Company {
@NotNull
@ElementCollection
@CascadeOnDelete
private List<EntityEvent> history;
...
}
执行此更改并重建我的数据库后,我的COMPANY_HISTORY表有一个新定义:
我的问题的解决方案让我感到惊讶,因为它看起来很重复。我的理解是,当删除实体时,JPA应删除与实体关联的所有可嵌入项。 EclipseLink具有以下链接中记录的非标准注释这一事实使我认为EclipseLink有一个错误,而不是修复错误创建一个新的@CascadeOnDelete注释,以便错误将被数据库级联删除功能所掩盖。
所以我的问题是为什么。为什么EclipseLink使用@ElementCollection支持@CascadeOnDelete?
答案 0 :(得分:1)
CascadeOnDelete只是一个功能,它指定您已指定&#34; On删除级联&#34;表中的选项,以便JPA不需要发出SQL来删除相应的引用。此SQL可以应用于任何引用,这就是CascadeOnDelete处理元素集合映射和任何其他引用映射的原因。
您的问题与数据库中的lob比较限制有关,并且由于没有唯一标识元素集合行的ID字段,因此此限制会干扰EclipseLink尝试确保仅删除所需的方式行。如果您愿意在表中添加订单列,为什么不将EntityEvent作为实体?或者您可以按照here所述自定义EclipseLink,以便它使用外键和orderBy字段或任何字段组合作为主键来唯一标识行而不是包含lob字段。