2017-09-21 2 views
3

Toutes mes classes d'entités JPA mettre en œuvre une interface appelée entité qui est définie comme suit:Comment obtenir les noms de colonnes d'entités JPA

public interface Entity extends Serializable { 
// some methods 

} 

Certains des champs de mon entité JPA ont @Column annotation sur eux et certains ne le font pas. MyEntity classe est définie comme ci-dessous:

@Entity 
public class MyEntity implements Entity { 

    @Id 
    private Long id; // Assume that it is auto-generated using a sequence. 

    @Column(name="field1") 
    private String field1; 


    private SecureString field2; //SecureString is a custom class 

    //getters and setters 

} 

Ma méthode delete accepte une entité.

@Override 
public void delete(Entity baseEntity) { 

    em.remove(baseEntity); //em is entityManager 
} 

Chaque fois que la méthode de suppression est invoqué Je veux trois choses à l'intérieur de ma méthode de suppression:

1) Domaines de MyEntity qui sont de type SecureString

2) Nom de la colonne de ce champ particulier DB (Le champ peut ou peut ne pas avoir @Column annotation)

3) La valeur du champ id

Notez que lorsque la méthode delete() est invoquée, nous ne savons pas quelle entité elle est invoquée, il peut être pour MyEntity1, MyEntity2 etc.

J'ai essayé quelque chose à faire comme ci-dessous:

for (Field field : baseEntity.getClass().getFields()) { 
    if (SecureString.class.isAssignableFrom(field.getType())) { 
     // But the field doesn't have annotation @Column specified 
     Column column = field.getAnnotation(Column.class); 

     String columnName = column.name(); 
    } 
} 

Mais cela ne fonctionnera que si le champ a @Column annotation. De plus, cela ne me donne pas deux autres choses dont j'ai besoin. Des idées?

+0

'Nom de colonne de ce champ particulier dans DB (Le champ peut contenir ou non une annotation '@Column'). 'Créez-vous les tables de base de données ou autorisez-vous Hibernate à les créer? Si hibernate est en train de créer et que vous n'avez pas mentionné '@Column', le nom de la variable est utilisé par défaut pour le nom de la colonne. –

+0

@KaustubhKallianpur Je permets à hibernate de créer les tables de la base de données.Certains champs ont une annotation "@Column" et d'autres non. Je suis d'accord avec vous sur votre dernière déclaration. J'ai besoin d'une condition pour vérifier si un champ particulier est annoté avec '@Column' ou pas et basé sur ce nom de colonne doit être récupéré. – Aman

+0

Hibernate récupère une ligne entière et toutes les colonnes de cette ligne, et la stocke dans l'entité respective. Vous pouvez obtenir les valeurs de ces variables en utilisant les méthodes Getter fournies dans votre Entité. –

Répondre

3

Hibernate peut utiliser différents naming strategies pour mapper les noms de propriété, qui sont définis implicitement (sans @Column (name = "...")). Pour avoir un nom physique, vous devez plonger dans les internes d'Hibernate. D'abord, vous devez câbler un EntityManagerFactory à votre service.

@Autowired 
private EntityManagerFactory entityManagerFactory; 

Deuxièmement, vous devez récupérer un AbstractEntityPersister pour votre classe

SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class); 
    AbstractEntityPersister persister = ((AbstractEntityPersister)sessionFactory.getClassMetadata(baseEntity.getClass())); 

Troisièmement, vous y êtes presque avec votre code. Vous avez juste à gérer les deux cas - avec et sans annotation @Column. Essayez ceci:

for (Field field : baseEntity.getClass().getFields()) { 
    if (SecureString.class.isAssignableFrom(field.getType())) { 
     String columnName; 
     if (field.isAnnotationPresent(Column.class)) { 
      columnName = field.getAnnotation(Column.class).name(); 
     } else { 
      String[] columnNames = persister.getPropertyColumnNames(field.getName()); 
      if (columnNames.length > 0) { 
       columnName = columnNames[0]; 
      } 
     } 
    } 
} 

Notez que seuls les champs getPropertyColumnNames() récupère « la propriété », qui ne sont pas une partie de clé primaire. Pour récupérer les noms de colonnes clés, utilisez getKeyColumnNames().

Et environ id domaine. Avez-vous vraiment besoin d'avoir tous les @ Id dans les classes enfants? Peut-être serait préférable de déplacer @Id à Entity classe et marquer cette classe avec l'annotation @MappedSuperclass? Vous pouvez ensuite le récupérer simplement avec baseEntity.getId();