2011-12-21 26 views
19

Estoy usando JPA2 con Hibernate y trato de introducir una clase base común para mis entidades. Hasta el momento se ve así:MappedSuperclass - Change SequenceGenerator en la Subclase

@MappedSuperclass 
public abstract class BaseEntity { 

    @Id 
    private Long id; 

    @Override 
    public int hashCode() { 
     // ... 
    } 

    @Override 
    public boolean equals(Object obj) { 
     // ... 
    } 

    public Long getId() { 
     return this.id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 
} 

Sin embargo, para cada mesa theres una secuencia $entityname_seq el que quiero usar como mi generador de secuencias. ¿Cómo puedo configurar eso desde mi subclase? Creo que necesito anular @GeneratedValue y crear un nuevo SequenceGenerator con @SequenceGenerator.

Respuesta

25

Sí, es posible. Puede anular el nombre predeterminado del generador con la anotación @SequenceGenerator.

  • clase Base
@MappedSuperclass 
    public abstract class PersistentEntity implements Serializable 
    { 
     private static final long serialVersionUID = 1L; 

     @Id 
     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "default_gen") 
     protected Long id = 0L; 

     public Long getId() 
     { 
      return id; 
     } 

     public void setId(Long id) 
     { 
      this.id = id; 
     } 
    }
  • Secuencia (SQL)

    create sequence role_seq;
  • clase derivada

@Entity 
    @Table(name = "role") 
    @SequenceGenerator(name = "default_gen", sequenceName = "role_seq", allocationSize = 1) 
    public class Role extends PersistentEntity implements Serializable 
    { 
     private static final long serialVersionUID = 1L; 

     @NotNull 
     @Size(max = 32) 
     private String name; 

     public String getName() 
     { 
      return name; 
     } 

     public void setName(String name) 
     { 
      this.name = name; 
     } 
    }
  • Este enfoque funcionó bien en Hibernate 4.1.x, pero no en EclipseLink 2.x.

edición

  • Según el comentario, se parece estar funcionando con EclipseLink 2.6.1-RC1.
+1

He probado con EclipseLink 2.6.1-RC1 y funcionó también. – leonardoborges

+0

Eso es una gran noticia. ¡Gracias! Voy a editar la respuesta. – rbento

+0

Además, todas las subclases deben tener definido @SequenceGenerator; de lo contrario, se generarán errores para la asignación –

11

En JPA que no se puede hacer con anotaciones. La anotación en sí no puede ser anulada. La entidad hereda toda la información de asignación desde MappedSuperClass. Hay sólo dos anotaciones que se pueden utilizar para redefinir asignaciones heredadas de superClass mapeadas:

  1. AttributeOverride para anular asignaciones de columnas y
  2. AssociationOverride para anular unirse a columnas/tabla.

Ninguno de ellos contribuye con GeneratedValue.

2

Con EclipseLink, puede usar un Customizer. DescriptorCustomizer interfaz define una forma de personalizar toda la información sobre un descriptor jpa (también conocido como una entidad persistente).

public class SequenceCustomizer implements DescriptorCustomizer { 

    @Override 
    public void customize(ClassDescriptor descriptor) throws Exception { 
     descriptor.setSequenceNumberName(descriptor.getTableName()); 
    } 
} 

y en sus superclase mapeadas:

@MappedSuperclass 
@Customizer(SequenceCustomizer.class) 
public abstract class AbstractEntity implements Serializable { 
    ... 
}