Hibernate软删除仍然删除我的记录

3

我试图使用Hibernate实现软删除,但出于某种原因我的记录仍然被删除了。有没有人能帮忙看一下。

public class SoftDeleteEventListener extends DefaultDeleteEventListener {

private static final long serialVersionUID = 1L;

@SuppressWarnings("rawtypes")
@Override
public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException {
    Object dbEntity = event.getObject();

    if (dbEntity instanceof Entity) 
    {
        ((Entity)dbEntity).setDeleted(true);
        ((Entity)dbEntity).setDeletedOn(new Date());

        EntityPersister persister = event.getSession().getEntityPersister( event.getEntityName(), dbEntity);
        EntityEntry entityEntry = event.getSession().getPersistenceContext().getEntry(dbEntity);

        cascadeBeforeDelete(event.getSession(), persister, dbEntity, entityEntry, transientEntities);
        cascadeAfterDelete(event.getSession(), persister, dbEntity, transientEntities);
    } else {
        super.onDelete(event, transientEntities);
    }
}

这是我注册会话/监听器的方式:

Configuration configuration = new Configuration();
        configuration.configure();
        StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
        sessionFactory = configuration.buildSessionFactory(ssrb.build());

        EventListenerRegistry registry = ((SessionFactoryImpl)sessionFactory).getServiceRegistry().getService(
        EventListenerRegistry.class);
        registry.getEventListenerGroup(EventType.DELETE).appendListener(new SoftDeleteEventListener());

1
软删除是什么意思? - ThomasEdwin
软删除是指我更新记录并将其标记为已删除,这在以下代码中表示: ((Entity)dbEntity).setDeleted(true); ((Entity)dbEntity).setDeletedOn(new Date()); - MrX
基本上将记录标记为已删除,而不是物理删除记录。 - MrX
为什么不添加一个列来标记记录是否被软删除了呢? - ThomasEdwin
这就是我所做的,所有将保存到数据库中的对象都扩展了一个包含2个字段deleted/deleted_on的Entity类,用于标记记录为已删除。我想要做的是覆盖Hibernate的delete方法,以便如果记录是Entity类型,则将其标记为已删除,而不是删除记录。 - MrX
1个回答

1
解决此问题的步骤如下:
  1. 你需要定义一个deleted列。

  2. 此外,你需要使用注解对实体进行注释:

     @SQLDelete(sql="UPDATE customer SET deleted = true WHERE id = ?")
    
这比使用Hibernate拦截器简单得多。
我会尝试一个更简单的版本:
if (dbEntity instanceof Entity) 
{
    ((Entity)dbEntity).setDeleted(true);
    ((Entity)dbEntity).setDeletedOn(new Date());

    event.getSession().mergedbEntity
} else {
    super.onDelete(event, transientEntities);
}

1
所以所有的对象都继承自一个实体类,该类不指定id字段,而是由子类来实现id。你的解决方案需要我在所有子类中添加@SQLDelete,这不是我想要做的...我宁愿监听删除事件,检查对象是否扩展了实体对象,如果是,则只更新已删除的字段像这样的代码应该更易于维护。 - MrX
这也是一种方法。您可以检查实体是否实现了软删除接口并应用逻辑。 - Vlad Mihalcea
我的问题中提供了代码示例,但我无法使其正常工作。你有什么想法它出了什么问题吗? - MrX
但这样做不会覆盖 hibernate 的默认删除方法。 - MrX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接