Estoy desarrollando una aplicación que utiliza:

  • Java 1.7
  • JPA (incluido en javaee-api 7.0)
  • Hibernate 4.3.8.Final
  • PostgreSQL-JDBC 9.4-1200-jdbc41
  • PostgreSQL 9.3.6

Y me gustaría usar el PostgreSQL tipo de datos de texto para algunos atributos de la Cadena. Hasta donde yo sé, en JPA esta debe ser la correcta anotación, el uso de texto en PostgreSQL:

@Entity
public class Product{
    ...
    @Lob
    private String description;
    ....
}

Cuando me anotar mis entidad como esta, me encuentro con errores que se parecen a este:
http://www.shredzone.de/cilla/page/299/string-lobs-on-postgresql-with-hibernate-36.html

En resumen: parece que hibernan y jdbc no van de la mano para clob/texto-tipos.

La solución que se ha descrito es de trabajo:

@Entity
public class Product{
    ...
    @Lob
    @Type(type = "org.hibernate.type.TextType")
    private String description;
    ...
}

Pero esto tiene una importante desventaja: El código fuente de las necesidades de hibernación en tiempo de compilación, lo que debería ser innecesario (Que es una de las razones para el uso de JPA en el primer lugar).

Otra forma es utilizar la columna de anotación como este:

@Entity
public class Product{
    ...
    @Column(columnDefinition = "text")
    private String description;
    ...
}

Que funciona muy bien, PERO:
Ahora estoy atascado con bases de datos que tienen un tipo de texto (y también llamado el texto 😉 ) y si otra base de datos que será utilizado en el futuro las anotaciones puede ser pasado por alto fácilmente. Así, el posible error puede ser difícil de encontrar, porque el tipo de datos se define en una Cadena y por lo tanto no puede ser encontrado antes de la ejecución.

Hay una solución, que es tan fácil, yo no lo vea? Estoy muy seguro de que no soy el único usando JPA en combinación con Hibernate y PostgreSQL. Así que estoy un poco confundido que no puedo encontrar más preguntas como esta.

Sólo para completar la pregunta, la persistence.xml se parece a esto:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
  xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="entityManager">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>com.app.model.Product</class>
    <properties>
      <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
      <property name="javax.persistence.jdbc.url"
        value="jdbc:postgresql://localhost:5432/awesomedb" />
      <property name="javax.persistence.jdbc.user" value="usr" />
      <property name="javax.persistence.jdbc.password" value="pwd" />
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
      <property name="hibernate.jdbc.use_streams_for_binary" value="false" />
      <property name="hibernate.hbm2ddl.auto" value="create-drop" />
      <property name="show_sql" value="true" />
    </properties>
  </persistence-unit>
</persistence>

ACTUALIZACIÓN:

  • Ya que estamos hablando de lo que es realmente un problema de implementación (auto-generado DDL), no puede crear manualmente la tabla como TEXTO en Postgres y no se especifica nada en la clase?
  • Sí, me gustaría ser capaz de generar la base de datos desde el estado de hibernación.
  • Así que…desea utilizar un estándar de SQL característica, pero no quiere correr el riesgo de incompatibilidad con bases de datos que no tienen los no-característica estándar?
  • Cuando decimos esto, suena mal 😀 Mi forma preferida sería yo uso las anotaciones de JPA-modo descrito en el primer lugar (Simplemente @Lob). Y vamos a hibernar/jdbc hacer la magia en el fondo. Como sé, un @Lob String debe resultar en clob en DB2, Oracle, longvarchar en H2/HSQLDB, longtext o text en MySQL y text en PostgreSQL. Mi problema es, que hibernate y jdbc de postgresql crear un error, donde no debe haber ningún problema.
  • Pero el texto y lob no son la misma cosa semánticamente.
  • Sí, usted puede agregar el @Lob a más tipos, eso es correcto. Pero hasta donde yo sé, el tipo de un @Lob anotado Cadena debe resultar en el postgresql tipo de texto. En la producción que el caso en cuestión. Pero no puedo acceder a la generada campo de base de datos debido a hibernar y controlador jdbc no se comprometen con cada uno de los otros. No debería importar que el texto no es de SQL estándar, en el primer lugar.
  • Yo estaba buscando el contrario te quería y tu pregunta, fue mi respuesta. Curioso. Acabo de añadir el columnDefinition = "text". Gracias.

InformationsquelleAutor knoe | 2015-02-18

4 Comentarios

  1. 6

    Desde el text tipo no es parte del estándar SQL no es oficial JPA manera, supongo.

    Sin embargo, la text tipo es bastante similar a varchar, pero sin límite de longitud. Usted puede sugerencia de la implementación de JPA con el length propiedad de @Column:

    @Column(length=10485760)
    private String description;

    Actualización: 10 MiB parece ser la longitud máxima para varchar en postgresql. El text es casi ilimitado, según el documentación:

    En cualquier caso, la larga cadena de caracteres que se pueden almacenar
    es alrededor de 1 GB.

    • Sí, esto funciona en la mayoría de los casos, cuando la mesa no debe ser generado por la aplicación. Esto se traduce en un PostgreSQL columna de tipo varchar(1000000000). Que es limitado, el tipo de texto se define a la tienda de texto sin ningún tipo de limitación.
    • Por lo que yo sé de Hibernación y PostgreSQL del controlador jdbc, realmente no son compatibles el uno con el otro en este punto, hibernate intenta obtener un clob, porque la lob de anotación y el controlador jdbc ofrece el contenido de la unidad de negocio de la dirección. Yo no sé cual es el camino correcto, pero la duda se debe acordar una solución, por lo que el usuario final puede utilizar este material. Porque es simplemente feo toparse con este problema.
    • También puede utilizar varchar sin un límite en Postgres. En Postgres, no hay realmente ninguna diferencia en absoluto entre text o varchar entonces sólo tiene que ir con lo que la ofuscación de la capa funciona mejor con
    • Por CIERTO: he intentado esto justo ahora, y me sale esto: PSQL ERROR: length for type varchar cannot exceed 10485760 @a_horse_with_no_name Sí, esto es exactamente lo mismo que el uso de la @Column(columnDefinition="text"), cuando llego a la derecha. Este sería el mismo como la solución de los dos a partir de la pregunta original.
    • Actualizado mi respuesta. Yo no recomendaría auto-DDL generada por un sistema de producción.
    • Bien, esto funciona. Es limitada y, en mi opinión no es realmente una buena manera. Pero agradezco su ayuda! Parece, que no hay otro camino que he pasado por alto, tal vez debería de contacto de la hibernación/jdbc-los desarrolladores de controladores.
    • Yo también frente a esta situación, me voy con la columnDefinition y la fuerza de todos para texto y deshacerse de cualquier tipo de tipo varchar, char. Puedo tomar la carga de proveedor tipo de datos específico, pero no es la gran cosa para mí como sólo tenemos candidato único al utilizar RDBMS -> PostgreSQL, otras soluciones que se han ido. En realidad espero que no habrá ningún tipo char, varchar en el futuro y sólo de texto 🙂

  2. 3

    Si quieres utilizar llano JPA sólo podría reasignar el utilizado CLOB tipo en el Dialecto como este:

    public class PGSQLMapDialect extends PostgreSQL9Dialect {
    
    
      @Override
      public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
        if (Types.CLOB == sqlTypeDescriptor.getSqlType()) {
          return LongVarcharTypeDescriptor.INSTANCE;
        }
        return super.remapSqlTypeDescriptor(sqlTypeDescriptor);
      }
    
    
    }

    Para que no se utilice el CLOB asignación del controlador JDBC que utiliza un OID de la columna y tiendas/carga el texto a través de la gran manipulación de objetos.
    Esto sería simplemente el resultado en setString y getString llamadas en el createt columna de texto en el Postgres JDBC Conductor a través de la VarcharTypeDescriptor clase.

    • Se ve interesante, voy a darle una oportunidad. Pero todavía no veo por qué esto debería ser necesaria en absoluto.
    • Usted no necesita – en las obras que ya están utilizando CLOB desde el Controlador JDBC con Oid para trabajar con la Cadena. Si desea cambiar que podrían abordarse mejor en el Controlador JDBC – en mi humilde opinión la Hibernación está bien aquí.
    • La desventaja de utilizar las obras «ya» CLOB como esto es extremadamente pobre rendimiento – en mi humilde opinión esto no es fino
    • No puede estar bien, pero no hiberna la responsabilidad de arreglar eso – que es la razón por la que he escrito debe resolver este para el controlador jdbc de los desarrolladores.
    • Por favor explique cómo cable este en – creo que esto me va a ayudar a ejecutar las pruebas JUnit con Derby, y desplegar a MariaDB, con MariadDB columna de definición de tipo de anotaciones en el código.
    • Esto debe ser aceptado respuesta!

  3. 3

    Yo sólo tenía que añadir esta anotación:

    @Column(columnDefinition="TEXT")

    No trabajan por su propia cuenta. Tuve que volver a crear la tabla en la base de datos.

    DROP TABLE yourtable o simplemente alterar el tipo de columna a text con ALTER TABLE declaración

  4. 1

    Me gustaría ir con simple private String description;. El tipo de columna es sólo un problema si usted está generando la base de datos desde el código, porque va a ser generados como varchar en lugar de text.

    Es genial código en la base de datos agnóstico manera, y sin ningún tipo de JPA proveedor de cosas específicas, pero hay casos en que esto simplemente no es posible. Si la realidad es que va a tener para el soporte de múltiples tipos de base de datos con todos sus detalles específicos, entonces usted tiene que dar cuenta de los detalles en algún lugar. Una opción es utilizar columnDefinition para definir el tipo de columna. Otra es dejar el código tal y como es, y acaba de cambiar el tipo de columna en la base de datos. Prefiero la segunda.

    • Sí, quiero generar DB de código. Si yo no la necesitaría. Me di cuenta de que @Column(columnDefinition = «longvarchar») private String descripcion; acaba de funcionar bien, porque la hibernación/controlador jdbc combinación de espera de texto y no un clob-dirección. Cual es el problema con el tiempo/texto de error desde el enlace. Pero la creación de la tabla acaba de fallar, porque postgresql no sabe el tipo de longvarchar. Si pudiera definir un alias como longvarchar=texto en PostgreSQL por mí mismo, esto podría ser interesante…
    • Que es más o menos el mismo que el de su solución, porque el columnDefiniton sólo se utiliza en la definición de la tabla.
    • no hay absolutamente ninguna diferencia entre varchar y text en Postgres.
    • Eso es correcto, pero la columna generada por una Cadena sin anotación es de tipo varchar(255), pero no quiero que se limite, que es el problema en el primer lugar.

Dejar respuesta

Please enter your comment!
Please enter your name here