0

REMEBER KIDS!!! You should check if variable is null ;). Sorry for a question that has so simple solution. Brain lag is real! If anyone has idea how to configurate persistence.xml to check validation before persist (update) please comment, this issue i haven't solved yet.

I was trying to create custom validation annotation in hibernate. Sadly during testing (using Validator and ValidatorFactory) I get, sadly I have no idea why:

javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.

This is my annotation:

@Documented
@Constraint(validatedBy=PeselValidator.class)
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyPesel {
    String message() default "{wrong.pesel.format}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
public class PeselValidator implements ConstraintValidator<MyPesel,String>{

    @Override
    public boolean isValid(String arg0, ConstraintValidatorContext arg1) {
        IF(ARG0==NULL)
RETURN FALSE; //!!!!!!!!!!!!!!
        //arg0.matches("^\\d{4}[1-31]\\d{5}$")
        if(arg0.length()==11)  
            return true;
        else
            return false;
    }

}

This is my author code:

@Entity
public class Author {
    @Id
    @GeneratedValue
    private int Id;

    @NotNull
    @Size(min=5,max=30)
    private String name;

    @NotNull
    @MyPesel
    private String pesel;

    @ManyToMany
    @JoinColumn(name="book_id")
    private Collection<Book> book= new ArrayList<>();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPesel() {
        return pesel;
    }

    public void setPesel(String pesel) {
        this.pesel = pesel;
    }
}

And test:

@Test
    public void goodBookBadAuthor() {
        Book book=new Book();
        book.setTitle("quite good title");
        book.getAuthor().add(new Author());
        Author author=new Author();
        author.setName("y");
        author.setPesel("abc");
        book.getAuthor().add(author);
        Validator validator=validatorFactory.getValidator();

        Set<ConstraintViolation<Book>> constraintViolations=validator.validate(book);

        assertEquals(2,constraintViolations.size());
    }

Second issue is that, even if I don't use @Pesel test are ok but when I want to add something to the database with entityManager (using persist()) hibernate doesn't check ma validations. I read that changing validation mode is required. I ve changed it but it doesn't work. I really hope you guys can help me. There is my persistence.xml.

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
    version="2.1">

    <persistence-unit name="ormBook">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <class>bean.Book</class>
        <class>bean.Author</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />

            <property name="javax.persistence.jdbc.url"
                value="jdbc:mysql://127.0.0.1:3307/db_hibernate_3?useSSL=true&amp;serverTimezone=UTC&amp;logger=Slf4JLogger&amp;profileSQL=true" />

            <property name="javax.persistence.jdbc.user" value="root" />

            <property name="javax.persistence.jdbc.password" value="jbjb123" />
                  <property name="javax.persistence.validation.mode" value="AUTO"/>
     <property name="javax.persistence.validation.group.pre-persist" value="javax.validation.groups.Default" />
       <property name="javax.persistence.validation.group.pre-update" value="javax.validation.groups.Default" />
       <property name="javax.persistence.validation.group.pre-remove" value=""/>       
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />


            <property name="hibernate.connection.isolation" value="2" />
            <property name="hibernate.hbm2ddl.auto" value="create" />
            <property name="hibernate.connection.pool_size" value="10" />
        </properties>
    </persistence-unit>

</persistence>
ogarogar
  • 323
  • 2
  • 14
  • Why not just use the @Length validation for this? See https://stackoverflow.com/questions/7084706/hibernate-validator-length-how-to-specify-separate-message-for-min-and-max – Chad Jul 21 '17 at 17:53
  • Actually I left only length to make things simpler. There will be more complex condition that includes regrex. – ogarogar Jul 21 '17 at 17:55

1 Answers1

1

In that case I believe you can just use the @Pattern annotation, I believe.

In my experience, writing the custom annotations just makes things more complicated and the validations provided by hibernate are good for everything you might need.

Everything else should probably be handled in the layer above.

Chad
  • 166
  • 7
  • You are right. I wanted to try make my own annotation and no complex example came to my bind, so I decided to make it like that. Anyway thank you for alternative solution !!! – ogarogar Jul 21 '17 at 19:12