```aigogl execute: false //| output: true //| echo: false //| label: fig-rel-employe-seqid-PK //| fig-cap: An Employee with a composite Key/Id //| vscode: {languageId: java} // PRINT SCHEMA String script=“%”;
IJava.getKernelInstance().getMagics().applyCellMagic(“rdbmsSchema”, List.of(“ex_idseq”),script); return null;
:::
::::
### Sequence et Batch
La génération de clés avec une séquence peut être optimisée en utilisant un `allocationSize` plus grand que 1.
Cela permet de pré-allouer un bloc de valeurs pour les entités, réduisant ainsi le nombre d'appels à la séquence.
```java
// Exemple de configuration optimisée
@Entity
public class Order {
@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "order_seq"
)
@SequenceGenerator(
name = "order_seq",
sequenceName = "ORDER_SEQ",
initialValue = 1,
allocationSize = 50 // Optimisation batch
)
private Long id;
}
générateur TABLE
Le générateur TABLE demande d’attribuer des clés primaires à l’entité en utilisant une table de base de données, c’est le plus portable mais le moins performant.
```aigogl execute: false //| output: true //| echo: false //| label: fig-rel-employe-composite-idtable //| fig-cap: An Employee with a composite Key/Id //| vscode: {languageId: java} // PRINT SCHEMA String script=“%”;
IJava.getKernelInstance().getMagics().applyCellMagic(“rdbmsSchema”, List.of(“ex_idtable”),script); return null;
:::
::::
### UUIDs
- Les UUIDs sont des identifiants universels uniques, générés aléatoirement.
- Avantages: unicité globale, distribution, sans coordination centrale
- Inconvénients: taille (16 octets), performance index, non séquentiel
- Pour la pagination ajouter un index sur un attribut date de création
- Usage: microservices, systèmes distribués, réplication multi-maîtres
:::: {.columns}
::: {.column}
::: {#cell-fig-class-employee-uuid-PK .cell filename='null' quarto-private-1='{"key":"vscode","value":{"languageId":"java"}}' execution_count=5}
::: {#fig-class-employee-uuid-pk .cell-output .cell-output-display .cell-output-markdown}
```Java
@Getter
@Setter
@ToString
@RequiredArgsConstructor(staticName = "of")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "CUSTOMER", schema = "EX_UUID")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID uuid;
@Column(length = 50, nullable = false)
@NonNull
private String name;
}
EmployeePK.java
```aigogl execute: false //| output: true //| echo: false //| label: fig-rel-customer-uuid //| fig-cap: A Customer with a UUID //| vscode: {languageId: java} // PRINT SCHEMA String script=“%”;
IJava.getKernelInstance().getMagics().applyCellMagic(“rdbmsSchema”, List.of(“ex_uuid”),script); return null;
:::
::: {.column}
:::
::::
## Les clés composites
- Types de clés
- **Clé atomique**
- **Natural** (Clé naturelle) : attribut métier unique (email, SIRET)
- **Surrogate** (Clé artificielle) : identifiant technique unique (Long, UUID)
- **Clé composite**
- **Natural** : combinaison d'attributs métier (année + département + matricule)
- **Surrogate** : combinaison d'identifiants techniques (shardId + sequenceId)
- JPA propose deux approches pour gérer les clés composites:
- `@EmbeddedId` : encapsule les attributs dans une classe dédiée
- `@IdClass` : distribue les attributs dans l'entité
### Embedded Id
- Utilisation de l'annotation `@EmbeddedId`
- Encapsulation des attributs de la clé dans une classe dédiée
- La classe embarquée doit être annotée `@Embeddable`
- Doit implémenter Serializable
- Nécessite equals() et hashCode()
```{java} execute: false
//| output: true
//| echo: false
//| label: fig-rel-employe-composite-id
//| fig-cap: An Employee with a composite Key/Id
//| tags: [remove-input]
//| vscode: {languageId: java}
// PRINT SCHEMA
String script="%";
IJava.getKernelInstance().getMagics().applyCellMagic("rdbmsSchema",
List.of("ex_embedded_id"),script);
return null;
Id Class
- Utilisation de l’annotation
@IdClass dans l’entité.
- Les attributs de la clé sont définis dans l’entité
- Une classe séparée définit la structure de la clé
- Les noms des attributs doivent correspondre
- Plus simple pour les requêtes JPQL
```aigogl execute: false //| output: true //| echo: false //| label: fig-rel-employe-composite-id-idclass //| fig-cap: An Employee with a composite Key/Id //| tags: [remove-input] //| vscode: {languageId: java} // PRINT SCHEMA String script=“%”;
IJava.getKernelInstance().getMagics().applyCellMagic(“rdbmsSchema”, List.of(“ex_idclass”),script); return null;
::: {#cell-fig-class-employee-idclass .cell filename='null' quarto-private-1='{"key":"vscode","value":{"languageId":"java"}}' execution_count=11}
::: {#fig-class-employee-idclass .cell-output .cell-output-display .cell-output-markdown}
```Java
@Setter
@Getter
@Entity(name="EmployeIdClass")
@Table(name="EMPLOYE", schema = "EX_IDCLASS")
@IdClass(EmployeePK.class)
public class Employee {
@Id
private String department;
@Id
private int rankInDepartment;
private String name;
}
Employee.java