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.
Réponses
Trop de publicités?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);
}
}
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;
}
}
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.
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"