2016-03-05 51 views
0

我想從春季休眠/ jpa中使用crudRepository刪除操作從數據庫中刪除一個實體。實體(用戶)與其他實體(組織)有@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("[email protected]", "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(), "[email protected]"); 
    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

異常是從安裝方法拋出的DBUnit異常。這不是你的測試方法拋出的。 –

+0

但是這是由 引起的:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:無法添加或更新子行:外鍵約束失敗('watchmaker_db'.'user',CONSTRAINT'FK_t2c7mdyen6pg5d1hpwyw6ox4e' FOREIGN KEY('organisation_id')REFERENCES'organisation'('id')) – SJC

+0

我不認爲這個異常是由你描述的問題引起的。爲什麼不在Hibernate配置中激活SQL日誌記錄,並查看哪些SQL語句在測試中由Hibernate有效執行?由DBUnit.beforeTestMethod引起的 –

回答

0

嗯,我本來期望的測試工作,因爲你使用的是foreign key。當我使用HSQLDB嘗試它時,我也工作過,它也有限制,所以我不確定那裏發生了什麼。直接試用Organization POJO。從中刪除User並重新保存Organization

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

編輯:也許你有一些手動SQL插入你的設置失敗之前,你到你的測試。

+0

這個解決方案很好,但是當你再次添加組織時,它會在組織結尾添加組織,這會破壞序列。在這種情況下做什麼? – Ajit