4

I have the table, the snippet below.

    package test;

    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.Table;
    import javax.persistence.UniqueConstraint;

    @Entity
    @Table(uniqueConstraints = { @UniqueConstraint(columnNames = "code")},
           name = "coupons")
    public class Coupon implements  Serializable {

        private static final long serialVersionUID = 5534534530153298987L;

        @Id
        @GeneratedValue
        @Column(name = "id")
        private long id;

        @Column(name = "available_count")
        private Integer availableCount = 1;

        public Integer getAvailableCount() {
            return availableCount;
        }

        public void setAvailableCount(Integer availableCount) {
            this.availableCount = availableCount;
        }
    }

How to make constraint to allow for availableCount be only non-negative?

sergtk
  • 10,714
  • 15
  • 75
  • 130

4 Answers4

5

If you need an actual database constraint, and your schema is generated by Hibernate, you can use @Check annotation:

@Entity
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = "code")},
        name = "coupons")
@Check(constraints = "available_count >= 0")
public class Coupon implements  Serializable { ... }
axtavt
  • 239,438
  • 41
  • 511
  • 482
3

make use of Hibernate Validator project

Péter Török
  • 114,404
  • 31
  • 268
  • 329
lweller
  • 11,077
  • 3
  • 34
  • 38
2

You can use @Min.

public class Coupon implements Serializable {

    @Min(0)
    @Column(name = "available_count")
    private Integer availableCount = 1;

}

Min documentation: The value of the field or property must be an integer value greater than or equal to the number in the value element

Check all JPA constaints here

They are valid to be used in Hibernate

Sebastian D'Agostino
  • 1,575
  • 2
  • 27
  • 44
1

The easy way would be to make it like this:

public void setAvailableCount(Integer availableCount) {
    if(availableCount < 0){
        throw new IllegalArgumentExcpetion("Must be possive value");
    }
    this.availableCount = availableCount;
}

This won't create a databse constraint.

edit:

If you take use of JPA-Annotations, you can create an @PrePerist-Annotated method:

@PrePersist
public void something(){
    if(availableCount < 0){
        throw new IllegalArgumentExcpetion("Must be possive value");
    }
}

The commit should fail, loading should work.

Christian Kuetbach
  • 15,850
  • 5
  • 43
  • 79
  • :) I do now in exactly such way, but it seems ugly for me - I am looking for something hibernate native, e.g. as in SQL we have CONSTRAINT – sergtk Jan 18 '11 at 14:33
  • I have had problems enforcing constraints in setters in Hibernate. If you try to load an object from the database, and `availableCount` has a negative value (ideally obviously that won't happen... but Murphy's law will intervene, at least in my case it does) then when Hibernate loads an object from the DB, it will call this method, the exception will be thrown, and the loading of the object will fail. This also gives you no chance to correct the invalid data, apart from going directly to the database without using Hibernate. – Adrian Smith Jan 18 '11 at 14:34
  • It seems to be ugly. In fact I don't know a beauty way to do this. – Christian Kuetbach Jan 18 '11 at 14:36
  • @Adrian Smith Anyway how did you enforce constraint? Can you please add a reference here? – sergtk Jan 18 '11 at 14:40
  • 1
    I think I wrote two methods, `setAvailableCount`, used by Hibernate, and I made it `private` (Hibernate could still use it, but people using my code couldn't), and then created another method, like `updateAvailableCount`, which was available to people using my code, and which contained the `if` statement. But I wasn't very happy with this solution. The updated answer includes the `@PrePersist` - I dind't know about that - that would seem to be a better solution. – Adrian Smith Jan 18 '11 at 14:54
  • Please test, that the method is called. I only know, that it has to be called within a JEE5 compliant Applicationserver. – Christian Kuetbach Jan 18 '11 at 14:57