2010-06-10 37 views
1

我有以下型號如何檢查實體在JPA中未被引用?

@Entity 
class Element { 
    @Id 
    int id; 

    @Version 
    int version; 

    @ManyToOne 
    Type type; 
} 

@Entity 
class Type { 
    @Id 
    int id; 

    @Version 
    int version; 

    @OneToMany(mappedBy="type") 
    Collection<Element> elements; 

    @Basic(optional=false) 
    boolean disabled; 
} 

,並希望允許Type.disabled =真只有Type.elements是空的。有沒有辦法做到原子?

我想阻止在交易中插入元素,而其他交易禁用相應的類型。

更新:對不起,我沒有讓自己清楚。我不問如何觸發檢查,但如何防止順序是這樣的:

Transaction 1 checks that Type.elements is empty 
Transaction 2 checks that Type.disabled = false 
Transaction 1 updates Type and sets disabled = true 
Transaction 2 persists a new Element 
Transaction 2 commits 
Transaction 1 commits 

然後我有一個情況Type.elements是不是空的,Type.disabled =真(破不變)。我怎樣才能避免這種情況?在原生SQL中,我會使用悲觀鎖定,但JPA 1.0不支持這一點。使用樂觀鎖定可以解決問題嗎?

回答

0

而Bean驗證as suggested by Pascal更優雅,一個快速簡便的解決方案將是實體類中的實體生命週期偵聽器方法:

@PrePersist @PreUpdate 
protected void validate(){ 
    if(this.disabled && !this.elements.isEmpty()){ 
      throw new IllegalArgumentException(
        "Only types without elements may be disabled"); 
    } 
} 

或更好,但有一個斷言類(如使用JUnit或春天,它封裝了異常拋出):

@PrePersist @PreUpdate 
protected void validate(){ 
    Assert.same(// but this implies a bi-directional constraint 
      this.disabled, this.elements.isEmpty(), 
      "Only types without elements may be disabled and vice-versa" 
    ); 
} 
相關問題