Puis-je configurer JPA/Hibernate pour persister Boolean
types comme Y/N
? Dans la base de données (la colonne est définie comme varchar2(1)
.) Actuellement, ils sont stockés sous la forme 0/1
La base de données est OracleConfigurer hibernate (en utilisant JPA) pour stocker Y/N pour le type Boolean au lieu de 0/1
Répondre
La seule façon dont j'ai compris comment faire cela est d'avoir deux propriétés pour ma classe. le booléen pour l'API de programmation qui n'est pas inclus dans le mapping C'est getter et setter qui référencent une variable char privée qui est Y/N. J'ai alors une autre propriété protégée qui est incluse dans le mapping hibernate et ses getters et setters font référence au private variables Type de caractères directement.
Hibernate a intégré "yes_no" qui ferait ce que vous voulez. Il mappé à une colonne CHAR (1) dans la base de données.
cartographie de base: <property name="some_flag" type="yes_no"/>
mapping Annotation (extensions Hibernate):
@Type(type="yes_no")
public boolean getFlag();
Pour ceux qui sont intéressés, il y a aussi un type "true_false" qui va stocker "T" ou "F". –
Cela a fonctionné, mais je ne pouvais pas l'utiliser parce que c'est une annotation spécifique d'hibernation. Merci d'avoir répondu. Pourrait l'utiliser dans un projet différent. – sengs
c'est pour hibernate 4 et plus tard, cela signifie pour Java 1.6 et plus tard. doent travail pour hibernate 3. * –
Pour même faire mieux cartographie booléenne à Y/N, ajoutez à votre configuration de mise en veille prolongée:
<!-- 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>
Maintenant, vous pouvez utiliser des booléens dans HQL, par exemple:
"FROM " + SomeDomainClass.class.getName() + " somedomainclass " +
"WHERE somedomainclass.someboolean = false"
Ceci est global. Pas adéquat pour les propriétés singulières. – maxxyme
A faire De manière générique JPA utilisant les annotations getter, l'exemple ci-dessous fonctionne pour moi avec Hibernate 3.5.4 et Oracle 11g. Notez que le getter et le setter mappés (getOpenedYnString
et setOpenedYnString
) sont des méthodes privées. Ces méthodes fournissent le mappage mais tous les accès par programme à la classe utilisent les méthodes getOpenedYn
et setOpenedYn
.
private String openedYn;
@Transient
public Boolean getOpenedYn() {
return toBoolean(openedYn);
}
public void setOpenedYn(Boolean openedYn) {
setOpenedYnString(toYesNo(openedYn));
}
@Column(name = "OPENED_YN", length = 1)
private String getOpenedYnString() {
return openedYn;
}
private void setOpenedYnString(String openedYn) {
this.openedYn = openedYn;
}
est ici la classe util avec des méthodes statiques toYesNo
et toBoolean
:
public class JpaUtil {
private static final String NO = "N";
private static final String YES = "Y";
public static String toYesNo(Boolean value) {
if (value == null)
return null;
else if (value)
return YES;
else
return NO;
}
public static Boolean toBoolean(String yesNo) {
if (yesNo == null)
return null;
else if (YES.equals(yesNo))
return true;
else if (NO.equals(yesNo))
return false;
else
throw new RuntimeException("unexpected yes/no value:" + yesNo);
}
}
pourquoi le vote vers le bas? –
Je ne sais pas, mais corrigé que je pouvais. – peterh
Ceci est JPA pur sans utiliser getters/setters. A partir de 2013/2014 est la meilleure réponse sans utiliser des annotations spécifiques à Hibernate, mais s'il vous plaît noter que cette solution est JPA 2.1, et n'a pas été disponible lorsque la question a été posée:
@Entity
public class Person {
@Convert(converter=BooleanToStringConverter.class)
private Boolean isAlive;
...
}
Et puis:
@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);
}
}
Edit:
La mise en œuvre considère avant tout différent du caractère "Y", y compris null
, comme false
. Est-ce exact? Certaines personnes considèrent ceci comme incorrect, et croient que null
dans la base de données devrait être null
en Java.
Mais si vous revenez null
en Java, il vous donnera un NullPointerException
si votre champ est un booléen primitive. En d'autres termes, à moins que certains de vos champs utilisent effectivement la classe Boolean, il est préférable de considérer null
comme false
et d'utiliser l'implémentation ci-dessus.Alors Hibernate n'émettra aucune exception quel que soit le contenu de la base de données.
Et si vous ne voulez accepter null
et émettent des exceptions si le contenu de la base de données ne sont pas strictement correcte, alors je suppose que vous ne devriez pas accepter des caractères en dehors de « Y », « N » et null
. Rendez-le cohérent, et n'acceptez aucune variation comme «y», «n», «0» et «1», ce qui ne fera que vous rendre la vie plus difficile plus tard. Ceci est une application plus stricte:
@Override
public String convertToDatabaseColumn(Boolean value) {
if (value == null) return null;
else return value ? "Y" : "N";
}
@Override
public Boolean convertToEntityAttribute(String value) {
if (value == null) return null;
else if (value.equals("Y")) return true;
else if (value.equals("N")) return false;
else throw new IllegalStateException("Invalid boolean character: " + value);
}
Et encore une autre option, si vous voulez permettre null
en Java, mais pas dans la base de données:
@Override
public String convertToDatabaseColumn(Boolean value) {
if (value == null) return "-";
else return value ? "Y" : "N";
}
@Override
public Boolean convertToEntityAttribute(String value) {
if (value.equals("-") return null;
else if (value.equals("Y")) return true;
else if (value.equals("N")) return false;
else throw new IllegalStateException("Invalid boolean character: " + value);
}
Le convertisseur montre l'idée, mais ne fonctionne bien sûr pas. Le convertisseur utilise les valeurs possibles de "Y", "N" et "T". Je ne suis pas sûr que l'on doive omettre le cas d'avoir une valeur nulle à la suite d'une conversion. – Matthias
@Matthias Oui, T était une faute de frappe. Je l'ai corrigé. Merci. – MarcG
J'ai eu un problème en utilisant le champ Y/N avec JPQL et posté une question de suivi ici: http://stackoverflow.com/questions/39581225/unable-to-render-boolean-literal-value-when-using-attributeconverter- for-boole –
utilisant des convertisseurs JPA 2.1 est la meilleure solution, Toutefois, si vous utilisez une version antérieure de JPA, je peux vous recommander une solution supplémentaire (ou solution de contournement). Créez une énumération appelée BooleanWrapper avec 2 valeurs de T et F et ajoutez-y la méthode suivante pour obtenir la valeur encapsulée: public Boolean getValue() { return this == T; }
, mappez-la avec @Enumerated (EnumType.STRING).
J'ai utilisé le concept de la réponse postée par @marcg et cela fonctionne très bien avec JPA 2.1. Son code n'était pas tout à fait correct, alors j'ai posté mon implémentation de travail. Cela convertira les champs d'entité Boolean
en une colonne de caractères Y/N 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 conversion:
/**
* 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 émoticônes et êtes juste malade et fatigué de Y/N ou T/F dans votre base de données. Dans ce cas, la colonne de votre base de données doit comporter deux caractères au lieu d'un. Probablement pas un gros problème.
/**
* 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) {
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;
}
}
Le déballage 'b.booleanValue()' est-il nécessaire? –
- 1. Comment configurer IE7 pour télécharger le type de fichier au lieu de l'ouvrir dans le navigateur
- 2. Comment configurer Artifactory en utilisant PostgreSQL au lieu de MySQL?
- 3. Hibernate Query Conseils pour JPA
- 4. JPA paresseux Hibernate utilisant SOAP
- 5. Comment afficher 1 au lieu de 01 dans ToString();
- 6. Hibernate: Créer des tables MySQL InnoDB au lieu de MyISAM
- 7. cartographie JPA/Hibernate pour stocker des mois et des jours-de-mois
- 8. En utilisant HttpModule au lieu de Global.asax
- 9. Configurer Rails pour sortir la sortie HTML au lieu de XHTML
- 10. inserts en vrac JPA/Hibernate lente
- 11. JPA/Hibernate: validation basée sur le code des requêtes jpa
- 12. MethodInfo pour EntityCollection au lieu de Queryable
- 13. Association OneToOne Hibernate/JPA personnalisée
- 14. En utilisant des méthodes de chaîne au lieu de Regex
- 15. en utilisant l'ancre au lieu de soumettre (post)
- 16. Comment configurer Hibernate pour utiliser SSL pour communiquer avec le serveur de base de données?
- 17. JPA/Hibernate nombre maximum de jointures?
- 18. jquery UI Tabs en utilisant DIV au lieu de UL pour la navigation
- 19. en utilisant une variable pour imageNamed au lieu d'une chaîne codée en dur
- 20. Comment pouvez-vous configurer Rails pour utiliser blueprint-css au lieu de l'échafaudage par défaut css?
- 21. Problème de carte avec JPA/Hibernate/PG
- 22. Comment avoir 2 collections du même type dans JPA?
- 23. Db migrate - Hibernate/JPA - hbm2ddl - outils diff
- 24. Reconnaissance vocale pour Julius en utilisant l'audio au lieu du microphone
- 25. En utilisant l'expression LINQ lieu de NHIbernate.Criterion
- 26. Drools Flow Persistance avec MySQL (jpa, hibernate)
- 27. Je souhaite insérer un fichier dans Oracle en utilisant le type de colonne BLOB sur Hibernate?
- 28. JPA et Hibernate Fetch ignorant les associations?
- 29. Besoin d'aide pour stocker la valeur dynamique en utilisant arraylist
- 30. Comment configurer Eclipse pour compiler en utilisant -std = c99?
Je devais faire quelque chose de similaire - J'ai changé le type du membre de Boolean à String. Dans les getters et setters (qui ont obtenu et mis Boolean) j'ai écrit le code pour convertir Y/N à la valeur booléenne correspondante. – sengs
L'autre réponse de ChssPly76 est la bonne. – bernardn
@bernardn Non, c'est le meilleur. – alexander