MappedSuperclass-Change SequenceGenerator dans la sous-classe

J'utilise JPA2 avec Hibernate et j'essaie d'introduire une classe de base commune pour mes entités. Jusqu'à présent, il ressemble à ceci:

@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;
    }
}

Cependant, pour chaque table il y a une séquence $entityname_seq Que je veux utiliser comme générateur de séquence. Comment puis-je définir cela à partir de ma sous-classe? Je pense que je dois remplacer @GeneratedValue et créer un nouveau SequenceGenerator avec @SequenceGenerator.

21
demandé sur atamanroman 2011-12-21 16:35:52

3 réponses

Oui, c'est possible. Vous pouvez remplacer le nom du générateur par défaut avec l'annotation @SequenceGenerator.

  • classe de 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;
        }
    }
  • Séquence (SQL)

    create sequence role_seq;
  • Classe Dérivée

    @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;
        }   
    }
  • Cette approche a bien fonctionné dans Hibernate 4.1.x, mais ce n'est pas le cas dans EclipseLink 2.X.

Modifier

  • selon le commentaire, il semble fonctionner avec EclipseLink 2.6.1-RC1.
28
répondu rbento 2015-08-11 15:00:52

Dans JPA qui ne peut pas être fait avec des annotations. L'Annotation elle-même ne peut pas être remplacée. Entity hérite de toutes les informations de mappage de MappedSuperClass . Il n'y a que deux annotations qui peuvent être utilisées pour redéfinir les mappages hérités de la superclasse mappée:

  1. AttributeOverride pour remplacer les mappages de colonnes et
  2. AssociationOverride{[2] } pour remplacer les colonnes de jointure / table.

Aucun d'entre eux n'aide avec GeneratedValue.

11
répondu Mikko Maunu 2012-07-17 19:00:57

Avec EclipseLink, vous pouvez utiliser un Customizer. DescriptorCustomizer interface définit un moyen de personnaliser toutes les informations sur un descripteur jpa (aka une entité persistante).

public class SequenceCustomizer implements DescriptorCustomizer {

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

Et dans votre superclasse mappée:

@MappedSuperclass
@Customizer(SequenceCustomizer.class)
public abstract class AbstractEntity implements Serializable {
    ...
}
2
répondu Juan Francisco Montanaro 2015-10-16 14:25:54