Hibernate删除用户

时间:2016-07-05 11:20:03

标签: java spring hibernate

我想实现一个删除给定用户的方法,我尝试了很多不同的方法,但它仍然会产生一些错误,这里是我的类:

    @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

3 个答案:

答案 0 :(得分:1)

表user_role位于用户和角色之间,没有实体。

您使用的是CascadeType.ALL,但与@JoinTable一起使用时,hibernate会忽略该注释。 CascadeType仅与其他实体一起使用,但不能直接引用数据库表。

有关详细信息,请参阅此处:JPA CascadeType.REMOVE not working

生成实体并将其映射到User而不是JoinTable,或者在删除用户之前从user_role表中删除用户角色映射。

另一个好的选择是在数据库中为user_role连接表定义一个casade删除。

答案 1 :(得分:0)

我真的不想设置hibernate只是为了演示这个,但我发现你正在编写很多代码只是为了做一个简单的删除。如果你的findUserByName()方法工作正常并返回一个有效的用户,那么这应该足以从数据库中删除该用户,我会一直这样做。

sessionFactory.getCurrentSession().delete(user);

&#34;用户&#34;是通过调用findUserByName(name)方法获得的对象,这假设您已经有一个SessionFactory实例。

<强>更新 我没看过你的堆栈跟踪。看起来用户被引用为其他表中的外键,如果是这种情况,除非删除引用它的所有字段,否则无法删除该用户。

答案 2 :(得分:0)

您收到此错误可能是因为当您删除具有 role1 角色的 user1 时,其他用户的 role1

这是因为cascade=CascadeType.ALL上的getRoles。尝试删除该级联,看看是否有效。