Mappatura persistente del modello del modello di dominio senza esporre gli attributi dell'oggetto dominio

3

So che questa è una domanda comune, ma non ne ho trovata un'altra che risolva i miei dubbi.

Di solito, se il progetto è piccolo, ho annotazioni di persistenza nello stesso oggetto che rappresenta l'oggetto dominio. Ciò consente di caricare l'entità dal database e mantenere privati tutti i setter, assicurando che ogni istanza sia sempre in uno stato valido. Qualcosa come:

@Entity
class SomeEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String attribute1;
    private String attribute2;
    private String attribute3;
    // ... other attributes

    protected SomeEntity() {}

    /* Public getters */
    public Long getId() { ... }

    public String getAttribute1() { ... }

    public String getAttribute2() {  ... }

    /* Expose some behaviour */
    public void updateAttributes(String attribute1, String attribute2) { 
       /* do some validations before updating */
    }
}

Il mio problema appare se voglio avere un modello persistente diverso. Quindi avrei qualcosa di simile:

/* SomeEntity without persistent info */
class SomeEntity {
    private Long id;
    private String attribute1;
    private String attribute2;
    private String attribute3;
    // ... other attributes

    protected SomeEntity() {}

    /* Public getters */
    public Long getId() { ... }

    public String getAttribute1() { ... }

    public String getAttribute2() {  ... }

    /* Expose some behaviour */
    public void updateAttributes(String attribute1, String attribute2) { 
       /* do some validations before updating */
    }
}

e DAO:

@Entity
class SomeEntityDAO {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String attribute1;
    private String attribute2;
    private String attribute3;

    public SomeEntityDAO() {}

    /* All getters and setters */
}

La mia domanda è, come posso mappare SomeEntityDAO a SomeEntity senza esporre gli attributi di SomeEntity?

Se creo un costruttore come: public SomeEntity(String attribute1, String attribute2, ...) {} , allora chiunque può creare un'istanza non valida di SomeEntity. Lo stesso accade se faccio rendere pubblici tutti i setter in SomeEntity.

Inoltre non penso che sia una soluzione valida costruire l'oggetto usando updateAttributes() poiché questo eseguirà alcune validazioni che non desidero eseguire a questo punto (ci fidiamo dei dati che sono persistet nel database).

Sto pensando di proteggere tutti i setter, quindi il DAO può estendere l'Entity e avere accesso ai setter ... ma non sono sicuro che questa sia una buona opzione.

Qual è l'approccio migliore o più comune per risolvere questo problema?

    
posta Tobías 11.10.2017 - 12:03
fonte

1 risposta

-2

If I create a constructor like: public SomeEntity(String attribute1, String attribute2, ...) {}, then anyone can create an invalid instance of SomeEntity.

I modelli non dovrebbero essere responsabili della propria convalida perché la convalida è logica aziendale e la logica aziendale dovrebbe essere definita al di fuori del modello. Quindi consiglierei di rimuovere updateAttributes da SomeEntity , inserendo la logica altrove e dando a SomeEntity un costruttore pubblico.

In genere i modelli vengono creati da una specie di input (richiesta utente, input di file, input std), la logica di business dovrebbe convalidare questo input prima per costruire il tuo modello.

Probabilmente non è necessario convalidare i modelli caricati dal database perché si presume che siano già validi, ma è possibile utilizzare la stessa logica di convalida prima di convertire SomeEntityDAO in SomeEntity . Non importa se usi uno strumento di mappatura basato sulla riflessione.

    
risposta data 11.10.2017 - 21:07
fonte