80 votes

Configurez hibernate (à l'aide de JPA) pour stocker Y / N pour le type Boolean au lieu de 0/1

Puis - je JPA de configuration / mise en veille prolongée persister Boolean types comme Y/N ? Dans la base de données (la colonne est définie comme varchar2(1) . Elle les stocke actuellement sous la forme 0/1 . La base de données est Oracle.

152voto

ChssPly76 Points 53452

Hibernate a un type "yes_no" intégré qui ferait ce que vous voulez. Il correspond à une colonne CHAR (1) de la base de données.

Cartographie de base: <property name="some_flag" type="yes_no"/>

Mappage d'annotation (extensions Hibernate):

 @Type(type="yes_no")
public boolean getFlag();
 

88voto

marcg Points 110

C'est du JPA pur sans utiliser de getters / setters. Depuis 2013/2014, c’est la meilleure solution sans utiliser d’annotations spécifiques à Hibernate, mais veuillez noter que cette solution est JPA 2.1 et n’était pas disponible lorsque la question a été posée pour la première fois:

 @Entity
public class Person {    

    @Convert(converter=BooleanToStringConverter.class)
    private Boolean isAlive;    
    ...
}
 

Et alors:

 @Converter
public class BooleanToStringConverter implements AttributeConverter<Boolean, String> {

    @Override
    public String convertToDatabaseColumn(Boolean value) {        
        return (value != null && value) ? "Y" : "N";            
        }    

    @Override
    public Boolean convertToEntityAttribute(String value) {
        return "Y".equals(value);
        }
    }
 

12voto

Jim Tough Points 4623

J'ai utilisé le concept de la réponse posté par @marcg et il fonctionne très bien avec JPA 2.1. Son code n'était pas tout à fait juste, je suis donc posté mon travail de mise en œuvre. Cela permettra de convertir Boolean champs d'entité pour un O/N caractère de la colonne dans la base de données.

De ma classe d'entité:

@Convert(converter=BooleanToYNStringConverter.class)
@Column(name="LOADED", length=1)
private Boolean isLoadedSuccessfully;

Ma classe de convertisseur:

/**
 * Converts a Boolean entity attribute to a single-character
 * Y/N string that will be stored in the database, and vice-versa
 * 
 * @author jtough
 */
public class BooleanToYNStringConverter 
        implements AttributeConverter<Boolean, String> {

    /**
     * This implementation will return "Y" if the parameter is Boolean.TRUE,
     * otherwise it will return "N" when the parameter is Boolean.FALSE. 
     * A null input value will yield a null return value.
     * @param b Boolean
     */
    @Override
    public String convertToDatabaseColumn(Boolean b) {
        if (b == null) {
            return null;
        }
        if (b.booleanValue()) {
            return "Y";
        }
        return "N";
    }

    /**
     * This implementation will return Boolean.TRUE if the string
     * is "Y" or "y", otherwise it will ignore the value and return
     * Boolean.FALSE (it does not actually look for "N") for any
     * other non-null string. A null input value will yield a null
     * return value.
     * @param s String
     */
    @Override
    public Boolean convertToEntityAttribute(String s) {
        if (s == null) {
            return null;
        }
        if (s.equals("Y") || s.equals("y")) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

}

Cette variante est aussi amusant si vous aimez les émoticônes et sont juste malade et fatigué de Y/N ou T/F dans votre base de données. Dans ce cas, votre base de données de la colonne doit être de deux personnages au lieu d'un. Probablement pas une grosse affaire.

/**
 * Converts a Boolean entity attribute to a happy face or sad face
 * that will be stored in the database, and vice-versa
 * 
 * @author jtough
 */
public class BooleanToHappySadConverter 
        implements AttributeConverter<Boolean, String> {

    public static final String HAPPY = ":)";
    public static final String SAD = ":(";

    /**
     * This implementation will return ":)" if the parameter is Boolean.TRUE,
     * otherwise it will return ":(" when the parameter is Boolean.FALSE. 
     * A null input value will yield a null return value.
     * @param b Boolean
     * @return String or null
     */
    @Override
    public String convertToDatabaseColumn(Boolean b) {
        if (b == null) {
            return null;
        }
        if (b.booleanValue()) {
            return HAPPY;
        }
        return SAD;
    }

    /**
     * This implementation will return Boolean.TRUE if the string
     * is ":)", otherwise it will ignore the value and return
     * Boolean.FALSE (it does not actually look for ":(") for any
     * other non-null string. A null input value will yield a null
     * return value.
     * @param s String
     * @return Boolean or null
     */
    @Override
    public Boolean convertToEntityAttribute(String s) {
        if (s == null) {
            return null;
        }
        if (HAPPY.equals(s)) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

}

9voto

Spencer Ruport Points 24589

La seule façon pour moi d’y arriver est d’avoir deux propriétés pour ma classe. Un comme booléen pour l'API de programmation qui n'est pas incluse dans le mappage. Son getter et son setter font référence à une variable de caractère privé qui est Y / N. J'ai ensuite une autre propriété protégée qui est incluse dans le mappage hibernate et ses getters et setters font directement référence à la variable private char.

2voto

M.A. Hogendoorn Points 11

Pour faire un meilleur mappage booléen sur Y / N, ajoutez à votre configuration Hibernate:

 <!-- when using type="yes_no" for booleans, the line below allow booleans in HQL expressions: -->
<property name="hibernate.query.substitutions">true 'Y', false 'N'</property>
 

Vous pouvez maintenant utiliser des booléens dans HQL, par exemple:

 "FROM " + SomeDomainClass.class.getName() + " somedomainclass " +
"WHERE somedomainclass.someboolean = false"
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X