2016-06-20 8 views
1

ich ein persistend Buch Klasse mit den folgenden Eigenschaften habenFehlerhafte Boolean Mapping Hibernate (ArrayIndexOutOfBoundsException)

  • Property -> HibernateMappingType -> javatype
  • id -> long -> long
  • Titel -> Text -> String
  • Autor -> string -> String
  • systemId -> long -> long
  • Status -> bool ean -> boolean
  • fullClassification -> string -> string

Und sieht meine Tabellenbeschreibung wie folgt aus: Book Table Diagram

So weit scheint alles gut, aber wenn ich versuche, alle Werte zu holen in die Tabelle erhalte ich die folgende Ausnahmemeldung:

20:04:43,832 TRACE BasicExtractor:61 - extracted value ([classifi1_1_0_] : [BIGINT]) - [11] 
20:04:43,832 TRACE BasicExtractor:61 - extracted value ([collecti1_2_1_] : [BIGINT]) - [11] 
20:04:43,833 TRACE BasicExtractor:61 - extracted value ([book_id1_0_2_] : [BIGINT]) - [1] 
20:04:43,839 TRACE BasicExtractor:61 - extracted value ([classifi2_1_0_] : [VARCHAR]) - [Prueba] 
20:04:43,841 TRACE BasicExtractor:61 - extracted value ([collecti2_2_1_] : [VARCHAR]) - [Prueba] 
20:04:43,841 TRACE BasicExtractor:61 - extracted value ([book_tit2_0_2_] : [LONGVARCHAR]) - [Libro de Prueba (No Existe) ] 
20:04:43,842 TRACE BasicExtractor:61 - extracted value ([book_aut3_0_2_] : [LONGVARCHAR]) - [Jonathan Pichardo] 
20:04:43,842 TRACE BasicExtractor:61 - extracted value ([book_sys4_0_2_] : [BIGINT]) - [190996] 
java.lang.ArrayIndexOutOfBoundsException: 57 
    at com.mysql.cj.mysqla.MysqlaUtils.bitToLong(MysqlaUtils.java:68) 
    at com.mysql.cj.core.io.MysqlTextValueDecoder.decodeBit(MysqlTextValueDecoder.java:231) 
    at com.mysql.cj.jdbc.ResultSetRow.decodeAndCreateReturnValue(ResultSetRow.java:170) 
    at com.mysql.cj.jdbc.ResultSetRow.getValueFromBytes(ResultSetRow.java:269) 
    at com.mysql.cj.jdbc.BufferRow.getValue(BufferRow.java:349) 
    at com.mysql.cj.jdbc.ResultSetImpl.getNonStringValueFromRow(ResultSetImpl.java:813) 
    at com.mysql.cj.jdbc.ResultSetImpl.getBoolean(ResultSetImpl.java:904) 
    at com.mysql.cj.jdbc.ResultSetImpl.getBoolean(ResultSetImpl.java:908) 
    at org.hibernate.type.descriptor.sql.BooleanTypeDescriptor$2.doExtract(BooleanTypeDescriptor.java:59) 
    at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47) 

etc etc etc

Der Code, den ich ausführe ist:

Sitzungssitzung = SessionFactoryHandler.buildIfNeeded(). openSession();

Criteria crit = session.createCriteria(Book.class); 

    crit.list(); 

    session.close(); 

    SessionFactoryHandler.closeFactory(); 

Wie ich es geschieht auf der Status Eigenschaft verstehe ich weiß nur nicht, warum, wenn ich die Zuordnungseigenschaft im XML-Kommentar funktioniert es perfekt, aber damit es wirft immer die gleiche Ausnahme mit der gleicher Index 57, macht den Wert dieser Spalte in der Datenbank (die nur eine Registrierung hat) keinen Unterschied.

Die Mapping-Datei ist wie folgt:

<hibernate-mapping package="com.cetys.librarymanagement"> 
    <class name="com.cetys.librarymanagement.Core.DomainModels.Book" table="book"> 
     <meta attribute="class-description"> 
      This class contains the whole description of a Book, 
      according to the specification in ALTAIR system. 
     </meta> 
     <id name="id" type="long" column="book_id"> 
     </id> 
     <property name="title" column="book_title" type="text" length="500" not-null="true"/> 
     <property name="author" column="book_author" type="text" not-null="true"/> 
     <property name="systemId" column="book_system_id" type="long" not-null="true"/> 
     <property name="status" column="book_status" type="boolean" not-null="true"/> 
     <property name="fullClassification" column="book_full_classification" 
        type="string" not-null="true"/> 

     <many-to-one name="classification" column="classification_id" 
        class="com.cetys.librarymanagement.Core.DomainModels.Classification" not-null="true" 
        unique="false" cascade="save-update" fetch="join"/> 
     <many-to-one name="collection" column="collection_id" 
        class="com.cetys.librarymanagement.Core.DomainModels.Collection" not-null="false" 
        unique="false" cascade="save-update" fetch="join"/> 
    </class> 
</hibernate-mapping> 

Irgendwelche Ideen?

Antwort

5

Aus was ich sehe, versuchen Sie, den BIT-Typ in Ihrem Ruhezustandscode in Boolean Database to abzubilden.

Es gibt einen Fehler in MySQL mit BIT-Wert ab Version 5.0.3, da es keinen einzelnen BIT-Wert speichert. Es speichert etwas wie SET oder ENUM. Und das wirft oft Probleme auf, wenn Sie einen numerischen Vergleich durchführen.Für weitere Informationen hier überprüfen

http://www.xaprb.com/blog/2006/04/11/bit-values-in-mysql/

Sie Ihre DBA fragen konnte den Datentyp zu ändern, jedoch tinyint, falls dies nicht möglich ist, können Sie den Status Mapping von boolean ändern numeric_boolean, so wäre so etwas wie

sein
<property name="status" column="book_status" type="numeric_boolean" not-null="true"/> 
+0

Danke für die Info ersetzen. Es funktioniert perfekt mit tinyint, aber wenn ich den numeric_boolean-Typ hinzufüge und die Spalte als Bit belasse, funktioniert es nicht. –

+0

Diese Lösung speicherte meinen Tag für ein anderes Problem :) Apache Hive hat genau denselben Fehler, wenn ich es mit Debug-Modus ausführen. Nach dieser Lösung habe ich das Init-Skript von metastoredb geändert und es hat funktioniert. Was ich in hive-schema-1.2.0.mysql.sql wie folgt geändert habe; 'DEFERRED_REBUILD' Bit (1) NOT NULL, ' IS_COMPRESSED' Bit (1) NOT NULL, 'IS_STOREDASSUBDIRECTORIES' Bit (1) NOT NULL, zu ' DEFERRED_REBUILD' TINYINT (1) NULL NOT, 'IS_COMPRESSED' TINYINT (1) NICHT NULL, ' IS_STOREDASSUBDIRECTORIES' TINYINT (1) NOT NULL, – Vezir

3

Es gibt zwei Möglichkeiten, wie Sie können die Typumwandlung von Attribut erreichen

Durch Feld mit Anmerkungen versehen mit Type

@Type(type = "yes_no") 
private boolean isActive; 

im DB Y/N wird beibehalten.

durch einen Konverter

@Column 
@Convert(converter = BooleanConverter.class) 
private boolean isActive; 

Converter Klasse

public class BooleanConverter implements AttributeConverter<Boolean, Character> { 

    @Override 
    public Character convertToDatabaseColumn(Boolean attribute) { 
     if (attribute) 
      return 'Y'; 
     else 
      return 'N'; 
    } 

    @Override 
    public Boolean convertToEntityAttribute(Character dbData) { 
     if ('Y' == dbData) 
      return true; 
     else 
      return false; 
    } 

} 

in xml Schreiben können Sie das type Attribut mit dem Konverter Klassennamen oder yes_no

<property name="status" column="book_status" type="yes_no" not-null="true"/> 
+0

Ich mag diesen Ansatz, danke, in der Tat gab es mir einige Ideen, wie man andere Probleme lösen kann. –

+0

@Saravana würde dies ohne @Type ("yes_no") Annotation in der Entität nicht funktionieren? Möchten Sie nur XML verwenden? – pinkpanther

+0

Wenn Sie auf Annotation basieren, können Sie 'Convert' in Feld/Getter verwenden, wenn basierend auf' xml' Attribut 'type' verwenden, mischen Sie nicht beide approches – Saravana