2010-12-30 8 views
15

¿Existe alguna manera de especificar secuencias distintas para cada tabla en Hibernate, si el ID está definido en una superclase mapeada?Especificación de secuencia distinta por tabla en Hibernar en las subclases

Todas las entidades en nuestra aplicación se extienden una superclase llamada DataObject así:

@MappedSuperclass 
public abstract class DataObject implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE) 
    @Column(name = "id") 
    private int id; 
} 

@Entity 
@Table(name = "entity_a") 
public class EntityA extends DataObject { ... } 

@Entity 
@Table(name = "entity_b") 
public class EntityB extends DataObject { ... } 

Esto hace que todas las entidades a utilizar una secuencia compartida, el valor predeterminado hibernate_sequence.

Lo que me gustaría hacer es utilizar una secuencia separada para cada entidad, por ejemplo entity_a_sequence y entity_b_sequence en el ejemplo anterior. Si la ID se especifica en las subclases, entonces podría usar la anotación @SequenceGenerator para especificar una secuencia para cada entidad, pero en este caso la ID está en la superclase. Dado que el ID está en la superclase, ¿hay alguna forma de que pueda usar una secuencia separada para cada entidad? Y si es así, ¿cómo?

(Estamos utilizando PostgreSQL 8.3, en caso de que sea relevante)

Respuesta

25

¿Ha intentado hacerlo de esta manera?

@MappedSuperclass 
public abstract class DataObject implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idgen") 
    @Column(name = "id") 
    private int id; 
} 

@Entity 
@SequenceGenerator(initialValue = 1, name = "idgen", sequenceName = "entityaseq") 
@Table(name = "entity_a") 
public class EntityA extends DataObject { 

} 

@Entity 
@SequenceGenerator(initialValue = 1, name = "idgen", sequenceName = "entitybseq") 
@Table(name = "entity_b") 
public class EntityB extends DataObject { 

} 

Lo siento, no tengo el entorno necesario para probarlo ahora pero lo intentaré más adelante.

+1

Sí, funciona! Probé algo similar, pero seguí obteniendo una 'org.hibernate.AnotationException: Unknown Id.generator: idgen'. Sin embargo, tu código funcionó bien; resulta que olvidé incluir el '@ SequenceGenerator' en una de las subclases en mi primer intento. Entonces la respuesta es que funciona, siempre y cuando cada subclase de entidad tenga la anotación @SequenceGenerator en ella. – gutch

1

generación TABLA stretergy utiliza secuencia db separada para cada tabla pero es poco caro operación

0

IHMO hay una mejor manera de hacer esto:

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private int id; 

Funciona en mi aplicación.

+1

Utiliza el método nativo de la base de datos para generar ID (por ejemplo, auto_increment en MySQL) y es muy ineficiente para inserciones masivas, ya que las inserciones deben realizarse una a una para obtener las ID generadas del controlador de la base de datos. – Frans

3

Utilizamos esta en la superclase abstracta de todas nuestras entidades JPA:

@Id 
@GeneratedValue(generator = "pooled") 
@GenericGenerator(name = "pooled", strategy = "org.hibernate.id.enhanced.TableGenerator", parameters = { 
     @org.hibernate.annotations.Parameter(name = "value_column_name", value = "sequence_next_hi_value"), 
     @org.hibernate.annotations.Parameter(name = "prefer_entity_table_as_segment_value", value = "true"), 
     @org.hibernate.annotations.Parameter(name = "optimizer", value = "pooled-lo"), 
     @org.hibernate.annotations.Parameter(name = "increment_size", value = "100")}) 
private Long id; 

Es un poco prolijo, pero permite establecer el prefer_entity_table_as_segment_value lo que significa que no es necesario repetir el campo id o la anotaciones de generador en las subclases.

Cuestiones relacionadas