Hibernate OnDelete Cascade不适用于MySql但适用于postgres和Ms-Sql

时间:2014-09-02 15:08:32

标签: java mysql hibernate jpa hibernate-cascade

我有2个实体。 帖子实体和发布实体,使用来自帖子>主题的OnetoOne映射。

主题实体包含众多帖子。我知道我应该使用OnetoMany而不是OnetoOne,但为了避免所有收集问题我使用OnetoOne

现在的问题是,当我删除主题时,还必须删除与之关联的所有帖子。 我使用

成功完成了这项工作
@OnDelete(action = OnDeleteAction.CASCADE)

但它仅适用于Postgres和Ms-SQl,但不适用于MySql(也尝试过InnoDb)。在架构生成查询中未生成 on delete cascade

以下是代码

//Thread Entity
@Id
@GeneratedValue
@Column(name = "thread_id")
private int ThreadID;

//Post Entity
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "post_id")
private int PostID;

@OneToOne()
@OnDelete(action = OnDeleteAction.CASCADE)
private thread ThreadID;

使用以下查询从主题实体中删除项目时出现以下错误

session.delete(session.load(thread.class,1));
  

2014年9月2日下午8:33:51 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions   警告:SQL错误:1451,SQLState:23000   2014年9月2日下午8:33:51 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions   错误:无法删除或更新父行:外键约束失败(forumpost_tbl,CONSTRAINT FK_bfbv5nknqj7ppd5630scimhtb FOREIGN KEY(ThreadID_thread_id)参考thread_tblthread_id))   org.hibernate.exception.ConstraintViolationException:无法执行语句       at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)       在org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)       在org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)       在org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)       at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:136)       在org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:58)       在org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3343)       在org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3546)       在org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:100)       在org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377)       在org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:369)       在org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:293)       at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:339)       在org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)       在org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234)       在org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)       at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)       at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)       在test.main(test.java:84)   引起:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:无法删除或更新父行:外键约束失败(forumpost_tbl,CONSTRAINT FK_bfbv5nknqj7ppd5630scimhtb FOREIGN KEY( ThreadID_thread_id)参考thread_tblthread_id))   HibernateException:无法执行语句       at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)       at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)       at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)       at java.lang.reflect.Constructor.newInstance(Constructor.java:408)       在com.mysql.jdbc.Util.handleNewInstance(Util.java:411)       在com.mysql.jdbc.Util.getInstance(Util.java:386)       在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1040)       在com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120)       在com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052)       在com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503)       在com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)       在com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2794)       在com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)       在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)       在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375)       在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)       at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133)       ......还有14个   建立成功(总时间:2秒)

请帮助我找到解决方法。

1 个答案:

答案 0 :(得分:13)

这就是我基于Spring Boot解决此问题的方法。

<强>解决方案

// application.properties  
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect

spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

<强>解释
如下所示,似乎MySQL5InnoDBDialect.java中CascadeDelete的默认值仅支持Cascade。

// MySQLDialect.java
@Override
    public boolean supportsCascadeDelete() {
        return false;
    }

// MySQL5InnoDBDialect.java
@Override
    public boolean supportsCascadeDelete() {
        return true;
    }