JPA observers and @embeddable

I have a hierarchy of JPA object classes that all inherit from the BaseEntity class:

@MappedSuperclass
@EntityListeners( { ValidatorListener.class })
public abstract class BaseEntity implements Serializable {
    // other stuff
}

I want all objects that implement this interface to be automatically checked for saving and / or updating. Here is what I have.

My ValidatorListener:

public class ValidatorListener {

    private enum Type {
        PERSIST, UPDATE
    }

    @PrePersist
    public void checkPersist(final Object entity) {
        if (entity instanceof Validateable) {
            this.check((Validateable) entity, Type.PERSIST);
        }
    }

    @PreUpdate
    public void checkUpdate(final Object entity) {
        if (entity instanceof Validateable) {
            this.check((Validateable) entity, Type.UPDATE);
        }
    }

    private void check(final Validateable entity, final Type persist) {
        switch (persist) {
        case PERSIST:
            if (entity instanceof Persist) {
                ((Persist) entity).persist();
            }
            if (entity instanceof PersistOrUpdate) {
                ((PersistOrUpdate) entity).persistOrUpdate();
            }
            break;
        case UPDATE:
            if (entity instanceof Update) {
                ((Update) entity).update();
            }
            if (entity instanceof PersistOrUpdate) {
                ((PersistOrUpdate) entity).persistOrUpdate();
            }
            break;

        default:
            break;
        }
    }

}

and here is my Validateable interface with which it checks (the external interface is just a marker, the internal one contains methods):

public interface Validateable {

    interface Persist extends Validateable {
        void persist();
    }

    interface PersistOrUpdate extends Validateable {
        void persistOrUpdate();
    }

    interface Update extends Validateable {
        void update();
    }

}

This all works, however I would like to extend this behavior to the Embeddable classes. I know two solutions:

  • Call the inline object verification method manually from the entity verification method:

    public void persistOrUpdate(){
        // validate my own properties first
        // then manually validate the embeddable property:
        myEmbeddable.persistOrUpdate();
        // this works but I'd like something that I don't have to call manually
    }
    
  • use reflection by checking all the properties to see if their type is one of their interface types. It will work, but it is not very. Is there a more elegant solution?

+3
2

, . () .

:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Validators {
  String[] values();
}

, , :

@MappedSuperclass
@EntityListeners( { ValidatorListener.class })
@Validators({Type.PERSIST, Type.UPDATE})
public abstract class MyEntity extends BaseEntity implements Serializable, Validateable {
    // other stuff
    @Validators(Type.PERSIST)
    @Embedded
    public Address getAddress() {
        return address;
    }
}

, - Validateable, :

public interface Validateable {
  void validate(Type type);
}

:

  • , @Validators;
  • , ;
  • , Validateable;
  • , (, : ", Validators, Validatable " )
  • , validate, ;
  • , .

() ( Java - ). , Validateable, . , .

, , , .

+1

, :

http://pastebin.com/YPmt7ifm

spring BeanUtils . : - ?

0

Source: https://habr.com/ru/post/1747956/


All Articles