【问题标题】:Best way to prevent unique constraint violations with JPA使用 JPA 防止违反唯一约束的最佳方法
【发布时间】:2011-02-25 13:26:35
【问题描述】:

我有一个 Keyword 和一个 KeywordType 作为实体。有很多类型的关键字。

当试图持久化一个类型的第二个关键字时,违反了唯一性约束,事务被回滚。

搜索所以我发现了几种可能性(其中一些来自不同的上下文,所以我不确定它们的有效性) - this postthis post 建议捕获对 Exception 没有用处我最终到达了我开始的地方,但仍然需要以某种方式保留关键字。
同样适用于针对不同情况提出的锁定here
thisthis 帖子中提出的自定义插入语句我猜我不会正常工作,因为我使用的是 Oracle 而不是 MySQL 和希望将实现与 Hibernate 联系起来。

另一种解决方法是尝试首先在生成关键字的代码中检索类型,如果找到则将其设置在关键字上,否则创建一个新关键字。

那么,什么是最好的——最健壮、最便携(对于不同的数据库和持久性提供者)和最理智的方法呢?

谢谢。

涉及的实体:

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;
    ...
}

【问题讨论】:

  • 从应用程序的视图层来看,您知道“用户”是在创建新的关键字类型还是使用现有的关键字类型?
  • 使用来自文档分析的现有文件。它会改变解决方案吗?

标签: java jpa constraints unique


【解决方案1】:

IMO,您的最后一个解决方案是正确的。搜索关键字类型,如果找不到,则创建它。

捕获异常不是一个好的选择,因为

  • 很难知道要捕获哪个异常并使您的代码可跨 JPA 和 DB 引擎移植
  • 发生此类异常后,JPA 引擎将处于未确定状态,在这种情况下您应始终回滚。

但是请注意,使用这种技术,您可能仍然有两个事务并行搜索相同类型,然后尝试并行插入它。其中一项事务将回滚,但频率会低得多。

【讨论】:

    【解决方案2】:

    如果您使用 EJB 3.1 并且不介意序列化此操作,则使用容器管理并发的单例 bean 可以解决问题。

    @Singleton
    @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
    public class KeywordTypeManager
    {
        @Lock(LockType.WRITE)
        public void upsert(KeywordType keywordType)
        {
            // Only one thread can execute this at a time.
            // Your implementation here:
            // ...
        }
    
        @Inject
        private KeywordTypeDao keywordTypeDao;
    }
    

    【讨论】:

      【解决方案3】:

      我会选择这个选项:

      尝试不同的解决方法 首先在代码中检索类型 生成关键字,并将其设置为 如果找到关键字或创建一个新关键字 如果没有,则一个。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-04-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-03
        • 2018-06-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多