2016-07-05 113 views
0

我想要實現刪除指定用戶的方法,我已經嘗試了很多不同的方式,但它仍然會產生一些錯誤,這裏有我的課:休眠刪除用戶

@Entity 
    @Table(name = "roles", catalog = "demo", uniqueConstraints = @UniqueConstraint(columnNames = { "name" })) 
    public class Role { 

     private String name; 

     public Role() { 
     } 

     public Role(final String name) { 
      this.name = name; 
     } 

     @Id 
     @Column(name = "name", nullable = false, length = 50) 
     public String getRole() { 
      return this.name; 
     } 

     public void setRole(final String name) { 
      this.name = name; 
     } 

    } 

@Entity 
@Table(name="users", catalog="demo") 
public class User { 

    private String username; 
    private String password; 
    private boolean enabled; 
    private Set<Role> roles; 

    @Id 
    @Column(unique=true, nullable=false) 
    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    @Column(nullable=false) 
    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    @Column(nullable=false) 
    public boolean isEnabled(){ 
     return enabled; 
    } 

    public void setEnabled(boolean enabled) { 
     this.enabled = enabled; 
    } 

    @OneToMany(cascade=CascadeType.ALL) 
    @JoinTable(name="user_role", catalog="demo", 
       joinColumns = @JoinColumn(name = "user_id"), 
       inverseJoinColumns = @JoinColumn(name = "role_id")) 
    public Set<Role> getRoles() { 
     return roles; 
    } 

    public void setRoles(Set<Role> roles) { 
     this.roles = roles; 
    } 

} 

我的方法我已經寫了這麼遠:

@Override 
    public boolean deleteUser(final String username, String password){ 
     User user = findByUserName(username); 
     if(user != null){ 
      Serializable id = new String(username); 
      Object persistentInstance = sessionFactory.getCurrentSession().get(User.class, id); 
      if (persistentInstance != null) { 
       sessionFactory.getCurrentSession().delete(persistentInstance); 
      } 
      return true; 
     }else{ 
     return false; 
     } 
    } 

這裏是我得到了異常:

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [FK_AUTHORITY_ROLE]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement 
    at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:163) 
    at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:730) 
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:592) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) 
    at org.springframework.test.context.transaction.TransactionContext.endTransaction(TransactionContext.java:128) 
    at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:224) 
    at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:313) 
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:94) 
    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:678) 
    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: org.hibernate.exception.ConstraintViolationException: could not execute statement 
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:72) 
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) 
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126) 
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112) 
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:211) 
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62) 
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3400) 
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3630) 
    at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:114) 
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:465) 
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:351) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350) 
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56) 
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1258) 
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425) 
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) 
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177) 
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584) 
    ... 25 more 
Caused by: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: foreign key no action; FK_AUTHORITY_ROLE table: USER_ROLE 
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) 
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) 
    at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source) 
    at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown Source) 
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208) 
    ... 38 more 
Caused by: org.hsqldb.HsqlException: integrity constraint violation: foreign key no action; FK_AUTHORITY_ROLE table: USER_ROLE 
    at org.hsqldb.error.Error.error(Unknown Source) 
    at org.hsqldb.StatementDML.performReferentialActions(Unknown Source) 
    at org.hsqldb.StatementDML.delete(Unknown Source) 
    at org.hsqldb.StatementDML.executeDeleteStatement(Unknown Source) 
    at org.hsqldb.StatementDML.getResult(Unknown Source) 
    at org.hsqldb.StatementDMQL.execute(Unknown Source) 
    at org.hsqldb.Session.executeCompiledStatement(Unknown Source) 
    at org.hsqldb.Session.execute(Unknown Source) 
    ... 41 more 
+0

爲什麼要獲得兩次用戶?一次使用用戶名,一次使用已檢索用戶的ID?將'@ OneToMany'的'orphanRemoval'屬性設置爲'true'。 –

+0

@ M.Deinum我試過但仍然是相同的錯誤:// – imoteb

+0

在刪除它們之前獲取角色 –

回答

1

表user_role位於用戶和角色之間,沒有實體。

您正在使用CascadeType.ALL,但hibernate忽略與@JoinTable一起使用時的註釋。 CascadeType只能與其他實體一起使用,但不能直接引用數據庫表。

在這裏看到更多的信息:JPA CascadeType.REMOVE not working

生成實體並將其映射到用戶,而不是JoinTable或刪除用戶之前刪除user_role的表中的用戶角色映射。

另一個不錯的選擇是在數據庫中爲user_role連接表定義一個casade delete。

0

我真的不想設置hibernate只是爲了演示這一點,但我看到你正在寫很多代碼只是爲了做一個簡單的刪除。如果你的findUserByName()方法工作正常,並返回一個有效的用戶,那麼這應該足以從數據庫中刪除該用戶,我一直這樣做。

sessionFactory.getCurrentSession().delete(user); 

「user」是通過調用findUserByName(name)方法獲得的對象,並且假定您已經擁有SessionFactory的實例。

更新 我沒有看看你的堆棧跟蹤。看起來用戶被引用爲某個其他表中的外鍵,如果是這種情況,除非刪除引用它的所有字段,否則不能刪除該用戶。

+0

我不知道這是怎麼回答這個問題 – Zulfi

+0

我以前試過這個,它不工作:/ – imoteb

+0

@Zulfi這應該是在評論。但是如果你看看我的代表,你會發現我不能評論他人的帖子。只是想幫助。 – ivange94

0

你可能會得到這個錯誤,因爲當你deleteting一個USER1,有一個角色role1上有具有role1上 anothe用戶。

這是因爲cascade=CascadeType.ALLgetRoles。嘗試刪除該級聯,看看是否可行。

+0

剛剛試過,不工作:// – imoteb

+0

這個堆棧是一樣的嗎? – KuroObi

+0

是的,其相同 – imoteb