Parfois, je les trouve ensemble, parfois seuls ... d'autres fois, ils semblent faire la même chose.
Quelle est la différence?
Voici trois exemples. Que font-ils de différent? Pourquoi ne puis-je pas utiliser uniquement @GeneratedValue pour tous?
Exemple 1
@Id
@GeneratedValue(generator="increment")
@GenericGenerator(name="increment", strategy = "increment")
Long id;
Exemple 2
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE)
private int userId;
Exemple 3
@ElementCollection
@JoinTable(name="Address",
joinColumns=@JoinColumn(name="user_id")
)
@GenericGenerator(name="hilo-gen", strategy="hilo")
@CollectionId(columns = @Column(name="Address_id"), generator = "hilo-gen", type = @Type(type="long"))
Collection<Addr> listOfAddresses = new ArrayList<Addr>();
Lorsque vous utilisez un ORM , il est souvent nécessaire de générer une valeur de clé primaire.
L'annotation @GeneratedValue
Indique qu'une valeur pour une colonne, qui doit être annotée avec @Id
, Est générée. Les éléments strategy
et generator
de l'annotation décrivent comment la valeur générée est obtenue.
Il y a quatre valeurs possibles pour l'élément strategy
dans l'annotation @GeneratedValue
: IDENTITY
, AUTO
, TABLE
et SEQUENCE
. Voir plus .
Donc, pour répondre à la deuxième partie de votre question, l'extrait de code indique que la valeur de userId
sera obtenue par une séquence du base de données.
L'élément generator
de l'annotation @GeneratedValue
Indique le nom du générateur de clé primaire. Dans Part1 de votre question, l'extrait de code indique qu'un generator
nommé increment
sera utilisé pour obtenir le principal valeur clé. increment
est alors défini dans la prochaine annotation @GenericGenerator
. @GenericGenerator
Est une annotation hibernate utilisée pour désigner un générateur personnalisé, qui peut être une classe ou un raccourci vers un générateur fourni par Hibernate. increment
est un raccourci vers un générateur Hibernate qui:
génère des identificateurs de type long, short ou int qui ne sont uniques que lorsqu'un autre processus n'insère pas de données dans la même table. Ne pas utiliser dans un cluster.
Dans la troisième partie de votre question, le code utilise un générateur hilo
Hibernate qui:
utilise un algorithme hi/lo pour générer efficacement des identifiants de type long, short ou int, à partir d'une table et d'une colonne (respectivement, par défaut, hibernate_unique_key et next_hi) en tant que source de valeurs hi. L'algorithme hi/lo génère des identifiants uniques pour une base de données particulière.
Pour étendre la réponse de @ kevin-bowersox.
Relations entre les stratégies de génération de clé primaire d'Hibernate et un générateur spécifique, comme spécifié dans org.hibernate.id.IdentifierGeneratorFactory
static {
GENERATORS.put("uuid", UUIDHexGenerator.class); // "deprecated" for new use
GENERATORS.put("hilo", TableHiLoGenerator.class); // removed in Hibernate 5
GENERATORS.put("assigned", Assigned.class);
GENERATORS.put("identity", IdentityGenerator.class);
GENERATORS.put("select", SelectGenerator.class);
GENERATORS.put("sequence", SequenceGenerator.class);
GENERATORS.put("seqhilo", SequenceHiLoGenerator.class);
GENERATORS.put("increment", IncrementGenerator.class);
GENERATORS.put("foreign", ForeignGenerator.class);
GENERATORS.put("guid", GUIDGenerator.class);
GENERATORS.put("uuid.hex", UUIDHexGenerator.class); // uuid.hex is deprecated
GENERATORS.put("sequence-identity", SequenceIdentityGenerator.class);
}
Dans Hibernate 4.3, j'ai trouvé org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory
classe avec 3 autres stratégies:
register("uuid2", UUIDGenerator.class);
register("enhanced-sequence", SequenceStyleGenerator.class);
register("enhanced-table", TableGenerator.class);
Les quinze stratégies ci-dessus, plus native
, correspondent à seize stratégies de génération prises en charge dans Hibernate par défaut.
Exemple avec native
:
@GeneratedValue(generator = "nativeGenerator")
@GenericGenerator(name = "nativeGenerator", strategy = "native")
@Entity
@Table(name="Honey")
public class Honey implements Serializable{
private static final long serialVersionUID = 42L;
@Id
//@SequenceGenerator(name="honeySequence",sequenceName="HONEY_SEQ")
@org.hibernate.annotations.GenericGenerator(name="honeySequence", strategy = "sequence",
parameters = {
@Parameter(name="sequence", value="HONEY_SEQ") }
)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="honeySequence")
private int Id;
private String name;
private String taste;
Il est donc préférable d’utiliser @GenericGenerator pour votre propre architecture. Mais si vous êtes obligé d'utiliser @SequenceGenerator, vous devez modifier manuellement votre séquence pour avoir deux attributs supplémentaires allocationSize = 1 et initialValue = 1 . Et pour utiliser ces attributs, vous devez ajouter apropert dans votre fichier hibernate.cfg.xml
<property name="hibernate.id.new_generator_mappings">true</property>