2011-08-22 64 views
2

我有一个类,看起来像这样:我如何用JPA表达这个约束?

public enum Scope { 
    A, B, C... 
} 

@Entity 
public class User { 

    ... 

    Scope scope; // enum, see above 

    @ElementCollecton 
    List<Long> numbers; 

    ... 
} 

我的问题是,我不知道该如何表达以下约束带或者JPA或直接在我的Postgres数据库: 只能有一个具有数字y的范围x的用户。

为了澄清我的意思是,一些伪代码:

这是有效的(鲍勃3不与汤姆斯3 colide因为Bob有不同的范围): 汤姆(范围= A,数= [ (范围= A,编号= [5,6,7]),鲍勃(范围= B,编号= [3,42,100])

但是,这是无效的(Carls 4违反约束条件,因为Tom的范围相同,列表中也有4个): Tom(scope = A,numbers = [1,2,3,4]),Carl(scope = A,number = [4,5,6,7]),鲍勃(范围= B,数字= [3,42,100])

感谢您的帮助, Fabian

+0

感谢JEE6引入的bean验证,您可以使用任何验证逻辑构建自定义验证器。一个简单的例子可以在这里找到(只是从谷歌搜索结果中快速选择):http://silentwalker.wordpress.com/2009/04/07/custom-validation-in-hibernate/ – ifischer

+0

这看起来像一个答案@ifischer。 – Snicolas

+0

自定义验证器将在java级别强制约束,但它看起来像popopaule正在数据库级别寻找约束。 – digitaljoel

回答

1

您可以做的一件事是向JPA说谎元素集合的外键,然后对集合表中的范围+数字组合添加普通的唯一约束。

@Column(name="SCOPE") 
@Enumerated(EnumType.STRING)//or whatever 
private Scope scope; 

@ElementCollection 
@CollectionTable(name= "NUMBERS" , 
    joinColumns={ @JoinColumn(name = "USER_ID", referencedColumnName = "ID"), 
        @JoinColumn(name = "USER_SCOPE", referencedColumnName = "SCOPE") }), 
@Column(name="NUMBER") 
private List<Long> numbers; 

显然USER_SCOPE是在标准化的模型完全没有必要,但告诉JPA这是你可以欺骗供应商到保持柱为您关键的一部分。