Hibernate试图在spring中删除外键行

时间:2016-03-05 14:59:29

标签: java spring hibernate jpa

我正在尝试使用spring hibernate / jpa中的crudRepository delete操作从数据库中删除一个实体。实体(用户)与其他实体(组织)具有@OnetoMany关系。删除用户时,它还会尝试删除组织表中与外键对应的行,此时会抛出错误。

我不想删除组织表中的行,只想删除用户userRepository.delete(createdUser);。谁能告诉我为什么这不能按预期工作?

User.java

/**
 * The user's organisation
 */
@NotNull
@SerializedName("organisation")
@Expose
@ManyToOne
@JoinColumn(name = "organisation_id")
private Organisation organisation;

Organisation.java

/**
 * The organisation's domain name
 */
@NotNull
private String domainName;

@OneToMany(mappedBy = "organisation")
private Set<User> users;

UserServiceTest

@Test
public void create_SaveUserNewEntryToDatabase_ShouldReturnSingleUser() throws UserExistsException {
    long numberOfDbEntries = userRepository.count();
    User newUser = new User("jane@ibmtest.com", "Jane", "Claire", "Jones", new Long(98765), new Long(54321));
    User createdUser = userService.create(newUser);

    assertNotNull(createdUser);
    assertEquals(numberOfDbEntries+1, userRepository.count());
    assertEquals(createdUser.getFirstName(), "Jane");
    assertEquals(createdUser.getMiddleName(), "Claire");
    assertEquals(createdUser.getLastName(), "Jones");
    assertEquals(createdUser.getEmail(), "jane@ibmtest.com");
    assertEquals(createdUser.getOrganisation(), new Long(98765));
    assertEquals(createdUser.getUserRole(), new Long(54321));

    userRepository.delete(createdUser);  <------
    assertEquals(numberOfDbEntries, userRepository.count());
}

栈跟踪

org.dbunit.DatabaseUnitException: Exception processing table name='user'
    at org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:232)
    at com.github.springtestdbunit.DbUnitRunner.setupOrTeardown(DbUnitRunner.java:194)
    at com.github.springtestdbunit.DbUnitRunner.beforeTestMethod(DbUnitRunner.java:66)
    at com.github.springtestdbunit.DbUnitTestExecutionListener.beforeTestMethod(DbUnitTestExecutionListener.java:186)
    at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:265)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`watchmaker_db`.`user`, CONSTRAINT `FK_t2c7mdyen6pg5d1hpwyw6ox4e` FOREIGN KEY (`organisation_id`) REFERENCES `organisation` (`id`))
    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:422)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
    at com.mysql.jdbc.Util.getInstance(Util.java:387)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:932)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
    at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1192)
    at org.dbunit.database.statement.SimplePreparedStatement.addBatch(SimplePreparedStatement.java:80)
    at org.dbunit.database.statement.AutomaticPreparedBatchStatement.addBatch(AutomaticPreparedBatchStatement.java:70)
    at org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:214)
    ... 25 more

1 个答案:

答案 0 :(得分:0)

好吧,我原本期望测试能够正常运行,因为你使用的是foreign key。当我用HSQLDB尝试它时我工作了,它也有约束,所以我不确定那里发生了什么。直接使用Organization POJO尝试一下。从中删除User并重新保存Organization

Organization o =organizationRepository.findAll().iterator().next();
o.getUsers().remove(0);
organizationRepository.save(o);

编辑:也许你的设置中有一些手动SQL插件在你进入测试之前就失败了。