2010-03-05 64 views
7

Tengo algo de código:¿Cómo se genera mi id con JPA utilizando Hibernate con el dialecto Oracle 10g?

@Id 
@SequenceGenerator(name = "SOMETHING_SEQ") 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SOMETHING_SEQ") 
@Column(name = "SOMETHING", nullable = false) 
private Long id; 

Cómo está proporcionando hibernación mi identificación?

Veo en mi base de datos una secuencia única llamada 'hibernate_sequence' y ninguna otra hibernación 'tablas especiales'.

Respuesta

9

En realidad, aquí el SOMETHING_SEQ es el nombre de la secuencia que ha configurado alguna parte en tu configuración de hibernación Y hibernate_sequence es el nombre de la secuencia en la base de datos. En la configuración se vería algo como a continuación,

<sequence-generator name="SOMETHING_SEQ" 
    sequence-name="hibernate_sequence" 
    allocation-size="<any_number_value>"/> 

Puede omitir completamente esta configuración mediante el uso de la anotación. Entonces su anotación @SequenceGenerator necesitaría proporcionar algunos parámetros más. A continuación está el ejemplo.

@SequenceGenerator(name="SOMETHING_SEQ", sequenceName="hibernate_sequence", allocationSize=10) 

Por ejemplo, múltiples clases de entidad haría algo así a continuación,

@Entity 
public class Entity1 { 
    @Id 
    @SequenceGenerator(name = "entity1Seq", sequenceName="ENTITY1_SEQ", allocationSize=1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "entity1Seq") 
    @Column(name = "ID", nullable = false) 
    private Long id; 

    ... 
    ... 

} 

@Entity 
public class Entity2 { 
    @Id 
    @SequenceGenerator(name = "entity2Seq", sequenceName="ENTITY2_SEQ", allocationSize=10) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "entity2Seq") 
    @Column(name = "ID", nullable = false) 
    private Long id; 

    ... 
    ... 

} 
+0

Gracias. Pero en mi caso, ¿cómo está hibernate proporcionando mi id? Como cuando guardo mi entidad con un valor nulo para mi Identificación larga, mágicamente se inserta automáticamente. ¿Es a través de alguna tabla especial, o usando esa hibernate_sequence? O..? – JavaRocky

+0

Usando el 'hibernate-seq', y por supuesto cuando dijiste Hibernate para generarlo, no debes proporcionar ninguno. O incluso si proporciona algún valor por ejemplo, ese valor se sobrescribirá. –

+0

¿Estás diciendo que varias entidades comparten esta misma secuencia de hibernación? – JavaRocky

0

En Oracle no tiene el tipo auto_increment como en MySQL. Entonces, para generar una columna auto_increment necesitas usar una secuencia.

Este es un ejemplo de cómo puede lograr esto.

create table test (id number, testdata varchar2(255)); 


create sequence test_seq 
start with 1 
increment by 1 
nomaxvalue; 

create trigger test_trigger 
before insert on test 
for each row 
begin 
select test_seq.nextval into :new.id from dual; 
end; 

Así que crea una secuencia y usa un disparador antes de insertar cada fila para agregar su identificación.

Así que Hibernate tiene que estar haciendo algo como esto, o en lugar de utilizar la activación haciendo

insert into test values(test_seq.nextval, 'no trigger needed!'); 

Nota: El ejemplo tomado de here

+0

Thank-you. De hecho, Oracle no tiene la capacidad auto_increment. Sin embargo, cuando guardo mi @ Entity, dejo mis campos @Id nulos. Que luego el EntityManager de alguna manera genera una identificación de alguna parte y la inserta. Lo sé cuando habilito la salida de SQL a la consola. Entonces volviendo a mi pregunta, ¿de dónde viene esta identificación con mi configuración? – JavaRocky

+0

usa la secuencia de seguro. Ahora, si usa el desencadenador, o la inserción en línea, configure hibernate para mostrar sql o verifique si se generó un desencadenante – Lombo

+0

Hibernate no utiliza un desencadenador, solo obtiene el 'nextval' en la inserción. –

4

Con el fin de nombrar la secuencia que tiene que establecer el sequenceName en su @SequenceGenerator anotación:

@GeneratedValue(name="gen", strategy = GeneratorType.SEQUENCE) 
@SequenceGenerator(name="gen", sequenceName="Sequence_Name", allocationSize = 1) 
@Id 
public Long getId() 
{ 
    // ... 
} 

De tenga en cuenta que si usa un generador preexistente, su allocationSize debe coincidir con el tamaño de asignación de ese generador.

4

¿Cómo está hibernate providing my id?

Bueno, te dijo explícitamente el motor de APP para generar identificador de forma automática (con la anotación @GeneratedValue) utilizando una estrategia de tipo SEQUENCE lo que indica que una secuencia de bases de datos se debe utilizar para generar el identificador. En caso de que se pregunte, las secuencias son objetos específicos de la base de datos (por ejemplo, Oracle) que se pueden utilizar para generar enteros únicos.

que veo en mi base de datos existe una única secuencia llamado 'hibernate_sequence'

no ha utilizado el elemento sequenceName anotación en su @SequenceGenerator para especificar el nombre del objeto de secuencia de base de datos para utilizar de modo de hibernación creó un objeto de secuencia predeterminado durante la generación del esquema (que por defecto es hibernate_sequence). Para especificar una secuencia, hazlo así:

@Id 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_entity_seq_gen") 
@SequenceGenerator(name = "my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ") 
private Long id; 
+0

Igualmente buena respuesta – JavaRocky

Cuestiones relacionadas