Sunday, May 21, 2006

Hibernate Validator

Feature หนึ่งของ Rails ที่ผมชอบก็คือส่วนของ validation มันเป็นส่วนเดียวกับ Model
ใน Hibernate version 3.x นี้ ก็ได้มี Feature นี้ใส่เข้ามาเหมือนกัน
แต่แยกอยู่ใน package Hibernate Annotations

การ config validation จะใช้ Annotation เข้ามาช่วย
@Entity
public class Province {

private Long id;
private String name;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}

@Column
@NotNull
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

}


ประเด็นที่น่าสนใจ ก็คือ แล้วเราจะ check validate ตอนไหน
(ตอน submit form, ตอน save)
และด้วยวิธีใด

เอาวิธีแรกสุดก่อน ก็คือทำเป็น constrains ใน Database
กรณีนี้ ถ้าเราใช้ Schema Tool ของ Hibernate ทำการ generate sql
ตัว Schema Tool ก็จะสร้าง constrains ให้เป็นไปตามที่เรากำหนด
เช่นตัวอย่างของเรา มี @NotNull อยู่ ดังนั้น column name นี้ใน database
ก็ต้องเป็น not null ด้วย

วิธีถัดมา ก็คือระบุให้ Hibernate Throw Exception
ถ้ามีการพยายาม save Entity นี้
วิธีนี้ทำได้โดย ระบุ ValidateXXEventListener ใน Configuration
<event type="pre-update">
<listener
class="org.hibernate.validator.event.ValidatePreUpdateEventListener" />
</event>
<event type="pre-insert">
<listener
class="org.hibernate.validator.event.ValidatePreInsertEventListener" />
</event>

เขียน TestCase สำหรับกรณีนี้ได้แบบนี้
public void testValidate() throws Exception {
Province p = new Province();
try {
session.save(p);
fail("shold not be here");
} catch (PropertyValueException e) {

}
}


วิธีสุดท้าย ก็คือเราสามารถดึงเอาส่วน validate ไปทำที่ส่วน Presentation ก็ได้
โดยใช้ ClassValidator เข้ามาช่วย
ลองดูตัวอย่างของ TestCase กรณีนี้
public void testAppValidate() {
Province p = new Province();
ClassValidator<Province> pv = new ClassValidator<Province>(Province.class);
try {
pv.assertValid(p);
fail("fail");
} catch (InvalidStateException e) {
InvalidValue[] iv = pv.getInvalidValues(p);
assertEquals(1, iv.length);
assertEquals("name", iv[0].getPropertyName());
}
}

เราสามารถ override Validate Message ได้โดย
provide file ที่ชื่อ ValidatorMessages.properties
ตัวอย่าง file
validator.notNull=Hey. not null please

Related link from Roti

No comments: