【问题标题】:JPA: Partial contraintJPA:部分约束
【发布时间】:2011-07-05 12:18:43
【问题描述】:

我的一个实体需要部分约束之类的东西。

@Entity
public class MyEntity 
{
  @NotNull
  private String name;

  @ManyToOne @NotNull
  private Type type;
}

仅针对单个 type 我需要 name 是唯一的。

这可以通过@UniqueConstraint 实现,还是我需要通过@PrePersist@PreUpdate 监听器来实现?到目前为止我还没有实现这样的监听器,但是即使我在这个监听器中检查了约束,它是否保证防止重复条目?

更新

假设约束应该只对type=special有效

  • 允许{id=1,type=normal,name=Test},{id=2,type=normal,name=Test}
  • 不允许:{id=3,type=special,name=Test},{id=4,type=special,name=Test}

【问题讨论】:

    标签: java jpa constraints jpa-2.0


    【解决方案1】:

    我对@UniqueContraint 的理解是它可能包含一个列名列表,这些列名共同定义了唯一性。

    见:unique constraint check in JPA

       @UniqueConstraint(columnNames={"name", "type"}) 
    

    我希望这可以强制跨名称和类型的唯一性。 (不过没时间测试。)

    编辑:

    啊哈。所以现在我明白了这个问题。这对于引入第三个属性的方法怎么样:

     int mySpecialValue;
    

    此属性没有公共设置器。相反,它的值由 setType() 设置,逻辑如下:

     public void setType(String theType){
    
          type = theType;          
    
          if ( "special".equals(type) ){
                  mySpecialValue = 0;
          } else {
                  mySpecialValue = makeUniqueInt(); // eg. some date twiddling
          }
    
     }
    

    现在设置唯一约束以包含 mySpecialValue。因此,对于所有特价商品,唯一性完全取决于名称,而对于其他商品,则始终存在差异化因素,因此名称可以重复。

           Allowed {id=1,type=normal,name=Test, msv = 343223 },
                    {id=2,type=normal,name=Test, msv = 777654 } <== not dup
           Not allowed: {id=3,type=special,name=Test, msv =0 },
                            {id=4,type=special,name=Test, msv =0} <== dup  
    

    【讨论】:

    • 它是如何回答问题的?
    • @djna 是的,这也是我的理解,我更新了我的例子来证明我需要什么。
    • @djna 有趣的解决方案,但完全符合我的需求。谢谢!
    【解决方案2】:

    请参阅conditional unique constraint 了解类似问题。我不认为听众是定义这样的事情的正确地方。我会在数据库中实现它,在视图上使用检查约束或唯一约束,或者作为应用程序中的功能检查。

    【讨论】:

    • 感谢您的提示,我假设我可以在数据库级别管理它,但我更希望在 JPA/Java 中实现它。
    • 您是否知道@UniqueConstraint 仅用于生成数据库模式DDL?约束只存在于数据库中。它在它被检查的数据库中,而不是在 JPA 引擎中。如果您在 Java 中实现它,请将其实现为功能检查。但请注意,如果两个并发事务并行检查然后并行插入,则不会防止重复。
    • 是的,我知道这一点。我应该在 JPA 中写 describe 这个。数据库模式是在开发过程中创建的,有时是新的,我将避免手动修改的需要。如果我在 @Singleton bean 中进行功能检查怎么办?这应该可以防止并行检查。
    • 我不会这样做。正如我所说,这种约束的位置是数据库。如果集群应用程序或使用 JPA 应用程序以外的其他方式访问数据库,则不会强制执行约束。即便如此,单身人士也将成为一个争论点。
    猜你喜欢
    • 2014-06-22
    • 2017-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多