java - per - jpa herencia
MappedSuperclass-Change SequenceGenerator en Subclase (3)
Estoy usando JPA2 con Hibernate e intento introducir una clase base común para mis entidades. Hasta ahora se ve así:
@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 tabla hay una secuencia $entityname_seq
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.
Con EclipseLink, puede utilizar un Customizer
. DescriptorCustomizer
interfaz DescriptorCustomizer
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 tu superclase mapeada:
@MappedSuperclass
@Customizer(SequenceCustomizer.class)
public abstract class AbstractEntity implements Serializable {
...
}
En JPA eso no se puede hacer con anotaciones. La anotación en sí no puede ser anulada. La entidad hereda toda la información de mapeo de MappedSuperClass . Solo hay dos anotaciones que se pueden usar para redefinir asignaciones heredadas de la superClase asignada:
- AttributeOverride para anular las asignaciones de columnas y
- AssociationOverride para anular unir columnas / tabla.
Ninguno de ellos ayuda con GeneratedValue.
Sí, es posible. Puede anular el nombre del generador predeterminado 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 lo hizo en EclipseLink 2.x.
editar
- Según el comentario, parece estar funcionando con EclipseLink 2.6.1-RC1.