Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 21 di 68
  • livello ninja
Indice lezioni

JPA: gestire tabelle con nomi relazionali diversi

Come utilizzare JPA per gestire classi nel contesto di diverse Entities in cui le tabelle associate contengono gli stessi campi ma con nomi relazionali diversi.
Come utilizzare JPA per gestire classi nel contesto di diverse Entities in cui le tabelle associate contengono gli stessi campi ma con nomi relazionali diversi.
Link copiato negli appunti

Cosa fare se volessimo riutilizzare la classe Address all'interno di diverse Entities in cui le tabelle associate contengono gli stessi campi ma con nomi relazionali diversi? Immaginiamo di avere un Entity Order che contiene gli stessi campi di Address per l'indirizzo di spedizione, ma con nomi sulla tabella ORDER_TABLE come a STREET_SHIPMENT, CITY_SHIPMENT, STATE_SHIPMENT. Come possiamo utilizzare Address come classe Embedded nell'Entity Order?

La soluzione fornita da JPA risiede nell'utilizzo dell'annotation @AttributeOverrides che consente di ridefinire di volta in volta il nome della colonna associata.

@Entity
 @Table(name="ORDER_TABLE")
 public class Order {
  ......
  private Address address;
  ......
  @Embedded
  @AttributeOverrides({
  @AttributeOverride(name="street", column=@Column(name="STREET_SHIPMENT")),
  @AttributeOverride(name="city", column=@Column(name="CITY_SHIPMENT")),
  @AttributeOverride(name="state", column=@Column(name="STATE_SHIPMENT"))
  })
  public Address getAddress(){
  }
  .....
 }

Abbiamo mostrato come utilizzando l'annotation @Id sia possibile specificare un campo di un Entity come identificativo dell'Entity stessa. I valori sul tale campo vengono generati automaticamente attraverso l'uso di una di tre possibili strategie:

  1. Identity generator
  2. Sequence generator
  3. Table generator

Tutte queste strategie fanno uso dell'annotation @GeneratedValue; in tali situazioni un vincolo Identity può essere utilizzato per la generazione dei valori della chiave primaria. Tutto ciò che dobbiamo fare a livello di codice è applicare @GeneratedValue sul metodo get annotato con @Id:

@Entity
   @Table(name="CUSTOMER_TABLE")
   public class Customer{
    ....
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="CUSTOMER_ID")
    public long getId(){....}
    ....
    }

Il codice assume che un vincolo Identity sia definito sulla colonna CUSTOMER_ID in CUSTOMER_TABLE. Il valore sul campo chiave dell'Entity sarà disponibile dopo l'operazione di persistenza che salva un'istanza dell'Entity sul database.

Per utilizzare un Sequence Generator, dobbiamo per prima cosa definire una sequence a livello di database
da collegare al campo chiave dell'Entity. Costruiremo ed eseguiremo preliminarmente un'istruzione
SQL del tipo:

CREATE SEQUENCE CUSTOMER_SEQUENCE START WITH 1 INCREMENT BY 10;

Successivamente definiamo il Sequence Generator a livello di Entity utilizzando @SequenceGenerator e
specifichiamo l'uso del sequence generator con l'attributo generator di @GeneratedValue che punta
al nome del generatore

@Entity
 @Table(name="CUSTOMER_TABLE")
 @SequenceGenerator(name="CUSTOMER_SEQUENCE_GEN",sequenceName="CUSTOMER_SEQUENCE")
 public class Customer {
  ....
  @Id
  @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="CUSTOMER_SEQUENCE_GEN")
  @Column(name="CUSTOMER_ID")
  public long getId(){..}
  ....
 }

Esaminiamo ora la strategia Table Generator. In questa caso si utilizza una tabella che memorizza
nomi di sequence e valori associati:

CREATE TABLE SEQUENCE_TABLE (
 SEQUENCE_NAME VARCHAR NOT NULL,
 SEQUENCE_VALUE NUMBER NOT NULL,
 PRIMARY KEY (SEQUENCE_NAME)
 )

Il passo successivo è quello di inserire un'entry per il campo chiave id dell'Entity Customer:

INSERT INTO SEQUENCE_TABLE(SEQUENCE_NAME,SEQUENCE_VALUE) VALUES('CUSTOMER_SEQUENCE',1)

Possiamo vedere questi due step come equivalenti al singolo step del Sequence Generator. Anche se la strategia
Table Generator è più complessa ha il vantaggio che la stessa Sequence Table ospita una molteplicità di sequence
fornendo un controllo centralizzato sulla generazione delle chiavi primarie. A livello di codice l'uso di un Table
generator è molto simile ad un Sequence Generator:

@Entity
@Table(name="CUSTOMER_TABLE")
@TableGenerator(name="TABLE_GENERATOR",
                 table="SEQUENCE_TABLE",
                 pkColumnName="SEQUENCE_NAME",
                 valueColumnName="SEQUENCE_VALUE",
                 pkColumnValue="CUSTOMER_SEQUENCE")
 public class Customer {
   ....
  @Id
  @GeneratedValue(strategy=GenerationType.TABLE,generator="TABLE_GENERATOR")
  @Column(name="CUSTOMER_ID")
  public long getId(){..}
  ....
  }

Come possiamo notare l'annotation @TableGenerator consente di specificare il nome della tabella generatrice,
i nomi delle colonne e la particolare sequence che intendiamo usare (attributo pkColumnValue) a livello di Entity sul campo annotato con @Id.

Ti consigliamo anche