jOOQ: Allowed-Character constraints?

醉酒当歌 提交于 2019-12-23 23:24:35

问题


I am considering moving from Hibernate to jOOQ but I can't find e.g. how to have Pattern-Constraints on a String like this in Hibernate:

@NotEmpty(message = "Firstname cannot be empty")
@Pattern(regexp = "^[a-zA-Z0-9_]*$", message = "First Name can only contain characters.")
private String firstname;

How would I do that in jOOQ?


回答1:


The "jOOQ way"

The "jOOQ way" to do such validation would be to create either:

  • A CHECK constraint in the database.
  • A trigger in the database.
  • A domain in the database.

After all, if you want to ensure data integrity, the database is where such constraints and integrity checks belong (possibly in addition to functionally equivalent client-side validation). Imagine a batch job, a Perl script, or even a JDBC statement that bypasses JSR-303 validation. You'll find yourself with corrupt data in no time.

If you do want to implement client-side validation, you can still use JSR-303 on your DTOs, which interact with your UI, for instance. But you will have to perform validation before passing the data to jOOQ for storage (as artbristol explained).

Using a Converter

You could, however, use your own custom type by declaring a Converter on individual columns and by registering such Converter with the source code generator.

Essentially, a Converter is:

public interface Converter<T, U> extends Serializable {
    U from(T databaseObject);
    T to(U userObject);
    Class<T> fromType();
    Class<U> toType();
}

In your case, you could implement your annotations as such:

public class NotEmptyAlphaNumericValidator implements Converter<String, String> {

    // Validation
    public String to(String userObject) {
        assertNotEmpty(userObject);
        assertMatches(userObject, "^[a-zA-Z0-9_]*$");
        return userObject;
    }

    // Boilerplate
    public String from(String databaseObject) { return databaseObject; }
    public Class<String> fromType() { return String.class; }
    public Class<String> toType() { return String.class; }
}

Note that this is more of a workaround, as Converter hasn't been designed for this use-case, even if it can perfectly implement it.

Using formal client-side validation

There's also a pending feature request #4543 to add more support for client-side validation. As of jOOQ 3.7, this is not yet implemented.




回答2:


I recommend you don't try to use jOOQ in a 'hibernate/JPA' way. Leave the jOOQ generated classes as they are and map to your own domain classes manually, which you are free to annotate however you like. You can then call a JSR validator before you attempt to persist them.

For example, jOOQ might generate the following class

public class BookRecord extends UpdatableRecordImpl<BookRecord> {

    private String firstname;

    public void setId(Integer value) { /* ... */ }

    public Integer getId() { /* ... */ }

}

You can create your own domain object

public class Book {

    @NotEmpty(message = "Firstname cannot be empty")
    @Pattern(regexp = "^[a-zA-Z0-9_]*$", message = "First Name can only contain characters.")
    private String firstname;

    public void setId(Integer value) { /* ... */ }

    public Integer getId() { /* ... */ }

}

and map by hand once you've retrieved a BookRecord, in your DAO layer

Book book = new Book();
book.setId(bookRecord.getId());
book.setFirstname(bookRecord.getFirstname());

This seems quite tedious (and ORM tries to spare you this tedium) but actually it scales quite well to complicated domain objects, in my opinion, and it's always easy to figure out the flow of data in your application.



来源:https://stackoverflow.com/questions/32690628/jooq-allowed-character-constraints

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!