2016-07-05 238 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