2010-05-10 5 views
1

J'écris une application basée sur une base de données déjà existante (postgreSQL) en utilisant JPA et Hibernate. Il y a une int2-column (activeYN) dans une table, qui est utilisée comme une valeur booléenne (0 => false (inactive), pas 0 => true (active)). Dans l'application Java, je veux utiliser cet attribut comme un booléen. Donc, je défini l'attribut comme ceci:Comment utiliser un champ de base de données int2 en tant que booléen en Java en utilisant JPA/Hibernate

@Entity 
public class ModelClass implements Serializable {  
    /*..... some Code .... */ 
    private boolean active; 

    @Column(name="activeYN") 
    public boolean isActive() { 
    return this.active; 
    } 
/* .... some other Code ... */ 

} 

Mais ist une exception parce Hibernate attend une base de données sur le terrain booléenne et non un int2. Puis-je faire cette cartographie de toute façon tout en utilisant un booléen en Java ??

J'ai une solution pour cela, mais je ne l'aime vraiment: Mon « aki » -solution est le suivant:

@Entity 
public class ModelClass implements Serializable {  
    /*..... some Code .... */ 
    private short active_USED_BY_JPA; //short because i need int2 

    /** 
    * @Deprecated this method is only used by JPA. Use the method isActive() 
    */ 
    @Column(name="activeYN") 
    public short getActive_USED_BY_JPA() { 
    return this.active_USED_BY_JPA; 
    } 

    /** 
    * @Deprecated this method is only used by JPA. 
    * Use the method setActive(boolean active) 
    */ 
    public void setActive_USED_BY_JPA(short active) { 
    this.active_USED_BY_JPA = active; 
    } 

    @Transient //jpa will ignore transient marked methods 
    public boolean isActive() { 
    return getActive_USED_BY_JPA() != 0; 
    } 

    @Transient 
    public void setActive(boolean active) { 
    this.setActive_USED_BY_JPA = active ? -1 : 0; 
    } 

/* .... some other Code ... */ 

} 

Existe-t-il d'autres solutions pour ce problème?

La valeur "hibernate.hbm2ddl.auto" dans la configuration d'hibernation est définie sur "valider".

(désolé, mon anglais est pas le meilleur, j'espère que vous comprenez quand même) ..

Répondre

1

Eh bien, le problème est que int2 est utilisé magasin entier signé de deux octets, quelle que soit la façon dont vous utilisez et Hibernate n'a pas de connaissance de votre logique pour traduire la valeur en boolean au niveau Java .

Donc, vous devez utiliser votre solution hacky (c.-à-lire la colonne int2 dans un short et le convertir dans votre entité) que vous pourriez peut-être faire les choses un peu plus sexy en déplaçant les annotations sur les attributs:

@Entity 
public class ModelClass implements Serializable {  
    /*..... some Code .... */ 

    @Column(name="activeYN") 
    private short active; 

    public boolean isActive() { 
    return this.active!=0; 
    } 
/* .... some other Code ... */ 

} 

Ou, si vous utilisez une extension JPA est pas un problème (JPA doesnt support types personnalisés), utilisez un custom type que vous déclarez avec l'annotation @Type:

@Entity 
public class ModelClass implements Serializable {  
    /*..... some Code .... */ 
    private boolean active; 


    @org.hibernate.annotations.Type(type = "my.package.ShortToBooleanUserType") 
    @Column(name="activeYN") 
    public boolean isActive() { 
    return this.active; 
    } 
/* .... some other Code ... */ 

} 

ShortToBooleanUserType est une classe qui implémente org.hibernate.UserType ou org.hibernate.CompositeUserType (reportez-vous à la documentation) et effectue la conversion dans les deux sens.

+0

Merci. J'ai pris votre deuxième solution, ça a bien marché. Je ne suis pas vraiment content d'utiliser des annotations spécifiques à hibernate, mais c'est quand même mieux que ma solution "hacky". Et je ne remplacerai jamais Hibernate avec un autre framework basé sur le JPA ... (j'espère) Votre première solution aurait aussi bien fonctionné, mais je ne l'aime pas, car Hibernate utilise des réflexions pour définir les attributs façon. Et puisque j'en ai déjà fini avec le reste des classes du modèle (en utilisant la méthode getter), je ne veux pas le changer. Et vous ne devriez pas utiliser les deux méthodes en même temps. –

1

Vous pouvez également essayer l'annotation spécifique à Hibernate:

@Type(type = "numeric_boolean") 
Questions connexes