5

我有 2 个实体。使用来自Post->Thread的 OnetoOne 映射的Thread实体和Post实体。

一个Thread实体包含许多Posts。我知道我应该使用 OnetoMany 而不是 OnetoOne,但是为了避免所有集合问题,我正在使用 OnetoOne

现在的问题是,当我删除一个Thread时,与之关联的所有帖子也必须被删除。我通过使用成功地做到了

@OnDelete(action = OnDeleteAction.CASCADE)

但它仅适用于 Postgres 和 Ms-SQl,但不适用于 MySql(也尝试过 InnoDb)。模式生成查询中不会生成on delete 级联。

以下是代码

//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;

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

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_bfbv5nknqj7ppd5630scimhtbFOREIGN KEY(ThreadID_thread_id)参考thread_tblthread_id)) org.hibernate.exception.ConstraintViolationException:无法在 org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java: 49) 在 org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110) 在 org.hibernate.engine 的 org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125) .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) 在 org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions (AbstractFlushingEventListener.java:339) 在 org.hibernate.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52) 在 org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234) 在 org.hibernate.internal。 org.hibernate.engine.transaction.internal.jdbc 上的 SessionImpl.managedFlush(SessionImpl.java:404)。JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175) at test.main(test.java:84) 原因:com.mysql.jdbc .exceptions.jdbc4.MySQLIntegrityConstraintViolationException:无法删除或更新父行:外键约束失败(forum. post_tbl, 约束外FK_bfbv5nknqj7ppd5630scimhtb键 ( ThreadID_thread_id) 参考thread_tbl(thread_id)) HibernateException:无法在 sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 在 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 的 sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 处执行语句在 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。com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2794) 在 com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155) 在 com.mysql.jdbc.PreparedStatement 的 sqlQueryDirect(MysqlIO.java:2664) .executeUpdate(PreparedStatement.java:2458) 在 com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375) 在 com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359) 在 org.hibernate.engine。 jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133) ... 还有 14 个 BUILD SUCCESSFUL(总时间:2 秒)executeUpdate(PreparedStatement.java:2458) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359) at org.hibernate.engine.jdbc .internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133) ... 还有 14 个 BUILD SUCCESSFUL(总时间:2 秒)executeUpdate(PreparedStatement.java:2458) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359) at org.hibernate.engine.jdbc .internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133) ... 还有 14 个 BUILD SUCCESSFUL(总时间:2 秒)

请帮我找到解决办法。

4

1 回答 1

14

这就是我基于 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;
    }
于 2015-03-09T13:50:29.263 回答