gpt4 book ai didi

Workaround to continue process after DataIntegrityViolationException(在发生DataIntegrityViolationException异常后继续处理的解决方法)

转载 作者:bug小助手 更新时间:2023-10-25 11:04:05 30 4
gpt4 key购买 nike



I need to create entity and optionally update it if it's already exist. If I catch DataIntegrityViolationException and try to process in catch then i'm getting error org.hibernate.AssertionFailure: null id in com.dating.entities.Complaint entry (don't flush the Session after an exception occurs)
How to deal with it to process further and update? I can think of TransactionTemplate but looks overcomplicated.
(@Transactional(noRollbackFor = DataIntegrityViolationException.class)doesn't help)

我需要创建实体,如果它已经存在,还可以选择更新它。如果我捕获DataIntegrityViolationException并尝试在Catch中进行处理,则会收到错误org.hibernate.AssertionFailure:com.dating.entitis.Complete Entry(发生异常后不刷新会话)中的空id。如何处理它以进一步处理和更新?我可以想到TransactionTemplate,但看起来过于复杂。(@Transaction(noRollback For=DataIntegrityViolationException.class)无济于事)


    @Transactional
public void create(Entity arg) {
try {
eRepository.save(arg);
} catch (DataIntegrityViolationException e) {
eRepository.findExisting(arg.user, arg.reason).ifPresent(e -> //here AssertionFailure error
eRepository.save(e.setComment(arg.comment))
);
}

更多回答
优秀答案推荐

The correct JPA way to update an entity is to get the entity that you want to update , then change its state and that 's it. No need to call repository.save() actually as Hibernate will generate the update SQL to update the entity when the transaction commit if it finds there are state changes in the entities that are loaded in that transaction.

更新实体的正确JPA方法是获取您想要更新的实体,然后更改它的状态,这样就可以了。实际上不需要调用repository.save(),因为如果发现在该事务中加载的实体中存在状态更改,则Hibernate将在事务提交时生成更新SQL来更新实体。


Quote from this :

引述如下:



Entities in managed/persistent state may be manipulated by the application, and any changes will be automatically detected and persisted when the persistence context is flushed. There is no need to call a particular method to make your modifications persistent.



So a simpler way is that you first check if the entity exist or not . If yes , update it . Otherwise , create it.

因此,一种更简单的方法是,首先检查实体是否存在。如果是,则更新它。否则,就创建它。


Something like :

类似于:


@Transactional
public void create(Entity arg) {

Optional<E> entity = eRepository.findExisting(arg.user, arg.reason);

if(entity.isPresent()){
//entity exist , so update the entity
entity.get().setComment(arg.comment);
}else {
//entity not exist, so create it.
eRepository.save(arg);
}
}




  1. Code like this suffice


    eRepository.findExisting(arg.user, arg.reason).ifPresentOrElse(e -> {
e.setComment(arg.comment); // does your setComment() return `this` ?
eRepository.save(e);
},
e -> eRepository.save(arg)
);


  1. [if above doesn't work] Make sure your entity describes primary key (@Id annotation), and check if your database contains entities with null ids. Normally, primary key should be unique and not null (and database should enforce it)



  2. Do not use try-catch to build business logic if possible, it is kind of antipattern




更多回答

thanks, it's similar to solution above. I'd like to find proper way to just update only if there is already existing same record. It doesn't look like something sophisticated. And what if this code is high-loaded? Additional read will affect performance.

谢谢,这和上面的解决方案类似。我想找到适当的方法,只有在已经存在相同的记录时才进行更新。它看起来不像是什么复杂的东西。如果这个代码是高负载的呢?额外的读取会影响性能。

regarding second 'save' - transaction probably aborted and 'save' probably required. When I first wrote the code before testing I haven't used it, hoping for the best )

关于第二个‘SAVE’-事务可能已中止,可能需要‘SAVE’。当我在测试前第一次编写代码时,我还没有使用过它,希望能有最好的结果。)

for the performance , don't think you need to worry too much at the beginning state . You can add an index in DB table. Together it only involves one record only , it would still be very fast.

对于表现,不要认为你需要在开始状态时太担心。您可以在DB表中添加索引。加在一起只涉及一项记录,仍然是非常快的。

I can even always try delete old record before adding new. My concerns is that I have to work with DB in a different unnatural way due to spring limitations...

我甚至可以在添加新记录之前尝试删除旧记录。我担心的是,由于春季的限制,我必须以一种不同的非自然方式使用DB……

just follow my suggestion and get the job done and move one. it is very natural . And don't need to over worry the performance .it is a kind of premature optimization. don't make the simple thing become complicated

只要照我的建议做,把工作做完,然后再动一步。这是非常自然的。而且不需要过度担心性能。这是一种过早的优化。不要把简单的事情变得复杂

well, yes, could be like #1, but then it will be always additional read. Although in my case it's not critical but i wanted to find out correct way to deal with such cases.

嗯,是的,可能会像#1,但它将总是额外的阅读。虽然对我来说,这不是关键,但我想找出正确的方法来处理这类案件。

about #3 - why try {} catch became intipattern? ) it's powerful construction. Sure, it's not needed in cases where it could be replaced with if-else, but for more complex cases with multiple steps, or where you can't just use if-else without additional i/o - why not?

关于#3-为什么尝试{}捕获成为初始模式?)这是一种强有力的建筑。当然,在可以用If-Else替换的情况下不需要它,但对于具有多个步骤的更复杂的情况,或者在没有额外I/O的情况下不能只使用If-Else-有何不可?

@littleAlien in short - I believe additional read is better in 99% situations

@littleAlien简而言之-我相信99%的情况下额外阅读会更好

@littleAlien There are some factors, such as - 1. code style - developers intend to use exceptions only for "exceptional situations", in this case, non-existing entity does not clearly denote invalid program state. 2. This way you-re forcing exceptional situation in your database, which will generate confusing false error logs and may slow down database itself when creating a lot of entries. Also, here is a discussion on exception performance itself and many more:) stackoverflow.com/questions/299068/…

@littleAlien有一些因素,比如-1.代码风格-开发人员只打算在异常情况下使用异常,在这种情况下,不存在的实体并不明确表示无效的程序状态。2.这种方式是在数据库中强制出现异常情况,这将生成令人困惑的错误日志,并且在创建大量条目时可能会降低数据库本身的速度。此外,这里还讨论了异常性能本身以及更多内容:)stackoverflow.com/Questions/299068/…

@littleAlien of course it is natural trying to optimize database round trips, but in absolutely most cases, additional single-row select with index scan is no problem. It is maybe worth thinking in case of updates or selecting many rows

@littleAlien当然,尝试优化数据库往返是很自然的,但在绝对大多数情况下,使用索引扫描进行额外的单行选择是没有问题的。在更新或选择许多行的情况下,可能值得考虑

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