问题描述
我有一个Keyword
和KeywordType
作为实体.有很多类型很少的关键字.
当尝试保留类型的第二个关键字时,违反了唯一约束,并且事务被回滚.
在SO中搜索,我发现了几个可能性(其中一些来自不同的上下文,因此在这里我不确定它们的有效性)-和建议捕获Exception,这对于我来说是没有用的,因为我最终从我开始的地方开始,仍然需要以某种方式保留该关键字.
对于在不同情况下建议的锁定,同样适用.此处 此和帖子无法正常运行,因为我使用的是Oracle不是MySQL,而是希望将实现与Hibernate绑定在一起.
另一种解决方法是尝试首先在生成关键字的代码中检索类型,然后在找到关键字的情况下将其设置为关键字,否则将其创建为新关键字.
那么,什么是最好的-最健壮,可移植(针对不同的数据库和持久性提供程序)和理智的方法呢?
I have an Keyword
and a KeywordType
as entities. There are lots of keywords of few types.
When trying to persist the second keyword of a type, the unique constraint is violated and the transaction is rolled back.
Searching SO i found several possibilies (some of them from different contexts, so I'm not sure of their validity here) - this post and this post advise catching the Exception which would be of no use to me as I end up where I started and still need to somehow persist the keyword.
Same applies to locking proposed for a different situaltion here
Custom insert statements as proposed in this and this posts wouldn't work proper I guess, since I'm using Oracle and not MySQL and woulnd like to tie the implementation to Hibernate.
A different workaround would be trying to retrieve the type first in the code generating the keywords, and set it on the keyword if found or create a new one if not.
So, what would be the best - most robust, portable (for different databases and persistence providers) and sane approach here?
谢谢.
涉及的实体:
public class Keyword {
@Id
@GeneratedValue
private long id;
@Column(name = "VALUE")
private String value;
@ManyToOne
@JoinColumn(name = "TYPE_ID")
private KeywordType type;
...
}
和
@Entity
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = { "TYPE" }) })
public class KeywordType {
@Id
@GeneratedValue
private long id;
@Column(name = "TYPE")
private String type;
...
}
推荐答案
您的最后一个解决方案是正确的IMO.搜索关键字类型,如果找不到,请创建它.
Your last solution is the right one, IMO. Search for the keyword type, and if not found, create it.
捕获异常不是一个好选择,因为
Catching the exception is not a good option because
- 很难知道要捕获哪个异常并使您的代码可跨JPA和DB引擎移植
- 在发生此类异常后,JPA引擎将处于不确定状态,在这种情况下,您应始终回滚.
但是请注意,使用这种技术,您可能仍然有两个事务并行搜索同一类型,然后尝试并行插入.其中一项交易将回滚,但频率要低得多.
Note however that with this technique, you might still have two transactions searching for the same type in parallel, and then try to insert it in parallel. One of the transaction will rollback, but it will be much less frequent.
这篇关于防止JPA违反唯一约束的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!