usadas una todos tablas tabla secuencias provienen para paquete obtener mapeo mapear los lista las ejemplo datos con componentes anotaciones java hibernate jpa

java - una - Configure hibernate(usando JPA) para almacenar Y/N para tipo Boolean en lugar de 0/1



mapear tablas hibernate (7)

El uso de convertidores JPA 2.1 es la mejor solución, sin embargo, si está utilizando la versión anterior de JPA, puedo recomendar una solución más (o solución alternativa). Cree una enumeración llamada BooleanWrapper con 2 valores de T y F y añádale el siguiente método para obtener el valor ajustado: public Boolean getValue() { return this == T; } public Boolean getValue() { return this == T; } , asócielo con @Enumerated (EnumType.STRING).

¿Puedo configurar JPA / hibernate para que persista en Boolean tipos Boolean como Y/N ? En la base de datos (la columna se define como varchar2(1) . Actualmente los almacena como 0/1 . La base de datos es Oracle.


Esto es JPA puro sin usar getters / setters. A partir de 2013/2014 es la mejor respuesta sin utilizar ninguna anotación específica de Hibernate, pero tenga en cuenta que esta solución es JPA 2.1 y no estaba disponible cuando se hizo la pregunta por primera vez:

@Entity public class Person { @Convert(converter=BooleanToStringConverter.class) private Boolean isAlive; ... }

Y entonces:

@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); } }

Editar:

La implementación anterior considera cualquier cosa diferente del carácter "Y", incluido null , como false . ¿Es eso correcto? Algunas personas aquí consideran que esto es incorrecto, y creen que la null en la base de datos debe ser null en Java.

Pero si devuelve null en Java, le dará una NullPointerException si su campo es un booleano primitivo . En otras palabras, a menos que algunos de sus campos usen realmente la clase Boolean , es mejor considerar null como false y usar la implementación anterior. Entonces Hibernate no emitirá ninguna excepción independientemente del contenido de la base de datos.

Y si desea aceptar excepciones null y emitir excepciones si el contenido de la base de datos no es estrictamente correcto, entonces supongo que no debe aceptar ningún carácter aparte de "Y", "N" y null . Consígalo coherente y no acepte ninguna variación como "y", "n", "0" y "1", lo que hará que su vida sea más difícil más adelante. Esta es una implementación más estricta:

@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); }

Y aún otra opción, si desea permitir null en Java pero no en la base de datos:

@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); }


Hibernate tiene incorporado un tipo "yes_no" que haría lo que usted desea. Se asigna a una columna CHAR (1) en la base de datos.

Mapeo básico: <property name="some_flag" type="yes_no"/>

Mapeo de anotaciones (extensiones de Hibernate):

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


La única forma en que he descubierto cómo hacerlo es tener dos propiedades para mi clase. Uno como booleano para la API de programación que no está incluida en la asignación. Es getter y setter reference una variable char privada que es Y / N. Luego tengo otra propiedad protegida que está incluida en el mapeo de hibernación y sus captadores y definidores hacen referencia a la variable de char privado directamente.


Para hacerlo de una manera genérica JPA utilizando anotaciones getter, el ejemplo siguiente funciona para mí con Hibernate 3.5.4 y Oracle 11g. Tenga en cuenta que el getter y setter getOpenedYnString ( getOpenedYnString y setOpenedYnString ) son métodos privados. Esos métodos proporcionan el mapeo pero todo el acceso programático a la clase está usando los métodos getOpenedYn y 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; }

Aquí está la clase util con métodos estáticos toYesNo y 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); } }


Para incluso hacer una mejor asignación booleana a Y / N, agregue a su configuración de hibernación:

<!-- 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>

Ahora puede usar booleanos en HQL, por ejemplo:

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


Usé el concepto de la respuesta publicada por @marcg y funciona muy bien con JPA 2.1. Su código no era del todo correcto, así que publiqué mi implementación en funcionamiento. Esto convertirá Boolean campos de entidad Boolean en una columna de caracteres Y / N en la base de datos.

De mi clase de entidad:

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

Mi clase de convertidor:

/** * 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; } }

Esta variante también es divertida si te gustan los emoticones y estás cansada de Y / N o T / F en tu base de datos. En este caso, su columna de base de datos debe tener dos caracteres en lugar de uno. Probablemente no es un gran problema.

/** * 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; } }