我有一个有趣的“问题”,即现象。
快速信息:
_BaseEntity
是@MappedSuperclass
,可以处理ID,hashCode,equals,compareTo等,并且在我所有的项目中都能正常工作@Expose
是 GSON 标记@JoinTable
还是没有区别,或者没有解决问题的答案... Thema->TopThema
,并且明确没有TopThema->Thema
工作示例 当我设置了这样的实体
@Entity
@Table(name = Thema.TABLE_NAME)
public class Thema extends _BaseEntity {
static public final String TABLE_NAME = UEntity.TABLE_PREFIX + "Thema";
@Expose @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
private TopThema topThema;
}
我可以简单地 EntityManager.remove()。
。
示例无法正常工作:
但是,如果是这样定义的
@Entity
@Table(name = Thema.TABLE_NAME)
public class Thema extends _BaseEntity {
static public final String TABLE_NAME = UEntity.TABLE_PREFIX + "Thema";
@Expose @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinTable(name = TABLE_NAME + "_topThema")
private TopThema topThema;
}
(具有@JoinTable(name = TABLE_NAME + "_topThema")
定义的中间表“ GP_Thema_topThema”,然后 EntityManager.remove()引发异常:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 无法删除或更新父行:外键约束失败 ({
test_PT_local
。GP_Thema_topThema
,约束FK_GP_Thema_topThema_topThema_ID
外键(topThema_ID
) 参考文献GP_TopThema
(ID
)
我知道使用额外的@JoinTable
并没有多大意义,这时引用也可以只保存在“ GP_Thema”中作为“ GP_Thema”。“ TOPTHEMA_ID”。
另外:两种Entity定义在Java方面都可以很好地工作。
但是出于兴趣:为什么即使我设置了@JoinTable
和GP_Thema_topThema
,JPA仍无法删除cascade = CascadeType.ALL
orphanRemoval = true
中的条目?
更新:由于@JoinTable
,我也无法
-首先删除TopThema,然后删除Thema(在TopThema上抛出MySQLIntegrityConstraintViolationException
删除)
-det Thema.topThema = null,然后更新(再次抛出MySQLIntegrityConstraintViolationException
)
答案 0 :(得分:1)
不是JPA无法删除实体,而是实际数据库。您正在寻找的是可延期的约束,而这在MySQL中是不可能的。
有关可约束的here
的Mysql文档通常,与MySQL一样,在插入,删除或更新许多行的SQL语句中,InnoDB逐行检查UNIQUE和FOREIGN KEY约束。在执行外键检查时,InnoDB在必须查看的子记录或父记录上设置共享的行级锁。 InnoDB立即检查外键约束;该检查不会推迟到事务提交。根据SQL标准,默认行为应推迟检查。也就是说,仅在处理了整个SQL语句之后才检查约束。在InnoDB实现延迟约束检查之前,某些事情是不可能的,例如删除使用外键引用其自身的记录
您是否考虑过切换到PostgreSQL?
DEFERRED约束直到事务提交才检查
答案 1 :(得分:0)
作为旁注,您可以使用JPA和MySQL删除Thema
实体...为此,只需将@JoinTable
(GP_Thema_topThema)的外键声明为“ ON DELETE”即可。级联” ...
示例:
CREATE TABLE GP_Thema_topThema(
thema_ID integer NOT NULL,
topThema_ID integer NOT NULL,
FOREIGN KEY (thema_ID)
REFERENCES thema (id)
ON DELETE CASCADE,
FOREIGN KEY (topThema_ID)
REFERENCES top_thema(id)
ON DELETE CASCADE
)
这样,如果数据库收到删除Thema
实体的命令,那么任何相关的GP_Thema_topThema
实体(或元组)也将被删除...