gpt4 book ai didi

java - 删除未保存的对象不会引发异常

转载 作者:行者123 更新时间:2023-12-01 16:51:32 24 4
gpt4 key购买 nike

我正在为我的 Dao Spring 应用程序编写测试。我发现当我删除未保存的项目时,不会像我预期的那样调用异常,我不知道为什么。

型号:

@Entity
public class Ingredient {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String condition;
private int quantity;

public Ingredient() {

}
}

Dao 实现:

@Override
public void delete(Object o) throws DaoException {
try {
Session session = mSessionFactory.openSession();
session.beginTransaction();
session.delete(o);
session.getTransaction().commit();
session.close();
} catch (Exception ex) {
throw new DaoException(ex, String.format("Problem deleting %s object (delete method).", o));
}
}

我的测试,期待 DaoException:

@Test
public void testDeleteNotSavedThrowsDaoException() throws Exception {
Ingredient ingredient = new Ingredient("Not saved ingredient","", 1);
ingredientDao.delete(ingredient);
}

最佳答案

Hibernate 的 Javadoc Session#delete(Object)状态:

Remove a persistent instance from the datastore. The argument may be an instance associated with the receiving Session or a transient instance with an identifier associated with existing persistent state.

因此,传递 transient 实体(就像您所做的那样)并不是错误。此外,Session#delete 方法没有声明任何异常,因此它没有定义当您传入数据库中不存在的 ID 的实体时会发生什么。正如您所看到的 - 没有发生任何事情 - 您请求实体不存在于数据库中,它一开始就不在那里,所以没有理由抛出异常(至少根据 Hibernate )。

将此与基本 SQL DELETE FROM X WHERE ID = Y 进行比较 - 这不会检查 ID=Y 的记录是否存在,无论哪种方式都会成功(更新 0 或 1 行)。

更新在意识到传入的 transient 实体具有null ID之后。

我深入研究了 Hibernate 5.2.2 Session 的源代码,似乎如果传入的实体没有 ID,则甚至不会执行 DELETE 查询该实体的表。

参见DefaultDeleteEventListener#onDelete(DeleteEvent, Set):

if (ForeignKeys.isTransient( persister.getEntityName(), entity, null, source ) ) {
// yes, your entity is transient according to ForeignKeys.isTransient
deleteTransientEntity( source, entity, event.isCascadeDeleteEnabled(), persister, transientEntities );
return;
}

现在

protected void deleteTransientEntity(
EventSource session,
Object entity,
boolean cascadeDeleteEnabled,
EntityPersister persister,
Set transientEntities) {
LOG.handlingTransientEntity(); // Only log it
if ( transientEntities.contains( entity ) ) {
LOG.trace( "Already handled transient entity; skipping" );
return;
}
transientEntities.add( entity );
// Cascade deletion to related entities
cascadeBeforeDelete( session, persister, entity, null, transientEntities );
cascadeAfterDelete( session, persister, entity, transientEntities );
}

这只会在日志中打印“HHH000114:在删除处理中处理 transient 实体”,并且对实体不执行任何操作(但是,如果有任何 - ,它会将删除级联到相关实体)不是你的情况)。

再说一次 - 传入没有 ID 的 transient 实体是可以的 - 它根本不会在数据库上运行 DELETE

关于java - 删除未保存的对象不会引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39140299/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com