Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    problema lettura oggetto da mssql

    Ciao ragazzi ho un problema che mi sta facendo ammattire. Ho sviluppato un applicativo che deve andare a scrivere e poi recuperare un oggetto da una tabella di un database. Fino a che ho sviluppato il codice sul mio pc dove avevo un server mysql andava tutto bene, mentre quando sono andato ad installare l'applicazione sulla macchina che la ospiterà che ha un db MSSQL sono nati i problemi. Ho cercato in rete ma non sono riuscito a trovare una soluzione che risolvesse contemporaneamente lettura e scrittura.
    La scrittura l'ho risolta in questo modo
    codice:
    public static long writeJavaObject(Connection conn, Object object) throws Exception {
    		ByteArrayOutputStream baos = new ByteArrayOutputStream();
    		ObjectOutputStream oos = new ObjectOutputStream(baos);
    		oos.writeObject( object);
    		
    		byte[] uBytes = baos.toByteArray();
    		
    		String className = object.getClass().getName();
    		String q = "INSERT INTO productions (name, object_value) VALUES ('"+className+"', '"+uBytes+"')";
    		PreparedStatement pstmt = conn.prepareStatement(q);
    //			conn.prepareStatement(WRITE_OBJECT_SQL);
    		pstmt.executeUpdate();
    		// set input parameters
    //		pstmt.setString(1, className);
    //		pstmt.setBlob(2, (Blob) object);
    ////		pstmt.setBlob(0, null)(2, uBytes);
    //		pstmt.executeUpdate();
    
    		//		    // get the generated key for the id
    		//		    ResultSet rs = pstmt.getGeneratedKeys();
    		//		    int id = -1;
    		//		    if (rs.next()) {
    		//		      id = rs.getInt(1);
    		//		    }
    		//
    		//		    rs.close();
    		pstmt.close();
    		System.out.println("writeJavaObject: done serializing: " + className);
    		for(int i = 0; i < uBytes.length; i++) System.out.print(uBytes[i]+" ");
    		System.out.println();
    		System.out.println("BYTES LENGTH "+uBytes.length);
    		return 0;
    	}
    mentre la lettura che genera l'eccezione (java mssql java.io.StreamCorruptedException: invalid stream header) è la seguente:
    codice:
    public static Object readJavaObject(Connection conn, long id) throws Exception {
    		PreparedStatement pstmt = conn.prepareStatement(READ_OBJECT_SQL);
    		pstmt.setLong(1, id);
    		ResultSet rs = pstmt.executeQuery();
    		rs.next();
    		//		    Object object = rs.getObject(1);
    		//		    String className = object.getClass().getName();
    
    		rs.getString(1).getBytes();
    
    		byte[] buf =rs.getString(1).getBytes();
    		ByteArrayInputStream a = new ByteArrayInputStream(buf);
    		System.out.println("BYTES read LENGTH "+buf.length);
    
    		ObjectInputStream objectIn = null;
    		if (buf != null)
    			objectIn = new ObjectInputStream(a);
    
    		Object object = objectIn.readObject();
    
    		rs.close();
    
    		pstmt.close();
    		System.out.println("readJavaObject: done de-serializing: " + object.getClass().getName());
    		return object;
    
    	}
    Sapresti indicarmi l'errore?

    Grazie mille

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Non è così che si effettua la deserializzazione da un campo BLOB (e mi pare piuttosto strano che funzionasse precedentemente, forse era un caso, piuttosto fortuito, di congruenza fra charset della macchina e quella di MySQL).

    codice:
    ResultSet rs = pstmt.executeQuery();
    Blob b = rs.getBlob(1);
    ObjectInputStream ois = new ObjectInputStream( b.getBinaryStream() );
    Object obj = ois.readObject();
    Non puoi prendere il valore del primo campo, convertirlo in String per prenderne i byte... la conversione in String implica una "traduzione" dei byte di dati verso il charset in uso sulla macchina... questo, nel 99% dei casi, è deleterio.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Ciao e grazie della risposta. Ma quindi secondo te l'inserimento va bene così? il campo che ospita l'oggetto nel DB è un varchar(MAX) cosa ne pensi?

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Anche la scrittura andrebbe fatta in modo leggermente diverso.
    Hai a disposizione le PreparedStatement, ma non le stai usando nel modo corretto.

    Scrittura di un oggetto all'interno di un DB:
    codice:
    // L'oggetto da scrivere è obj
    ...
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(baos);
    out.writeObject(obj);
    out.close();
    
    String sql = "productions (name, object_value) VALUES (?,?)";
    PreparedStatement pstmt = conn.prepareStatement( sql );
    pstmt.setString(1, className);
    pstmt.setBytes(2, baos.toByteArray());
    int retNum = pstmt.executeUpdate();
    Il campo che ospita l'oggetto dovrebbe essere definito di tipo BLOB. Definirlo di tipo VARCHAR, oltre a limitarti il campo ad una lunghezza massima di 255 caratteri (nessuno ti garantisce che un oggetto sia necessariamente più piccolo di 255 bytes), potrebbe anche causarti problemi relativi al charset usato dal DBMS.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Si grazie del codice ma "BLOB" non c'è come campo in MSSQL c'è solo in MYSQL. Qual'è secondo te l'analogo??? potrebbe essere VARBINARY?

    Grazie mille

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    L'analogo è uno tra TEXT, NTEXT o IMAGE, se non ricordo male.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.