Java - невозможно получить значения из извлеченного сериализованного объекта - PullRequest
0 голосов
/ 10 декабря 2011

Этот код до сих пор доставлял мне немало хлопот, но я действительно пишу первый класс для использования подготовленного состояния, Oracle и сериализации. Поэтому я прошу вашего терпения. Ниже приведен код:

 public static boolean storeInfo(Reservation rsv) throws
        IOException, SQLException{
    try {
          //Connection to DB
          Connection con = null;
          Class.forName("oracle.jdbc.driver.OracleDriver");
          con=DriverManager.getConnection(
            "jdbc:oracle:thin:@odsdsd",
            "SMBDB",
            "hpdbsmb");
          con.setAutoCommit(false);
          ByteArrayOutputStream bos = new ByteArrayOutputStream() ;
          ObjectOutputStream out = new ObjectOutputStream(bos);
          out.writeObject(rsv);
          out.flush();
          out.close();
          byte[] buf = bos.toByteArray();
          //inserting into database
          PreparedStatement prepareStatement = con.prepareStatement("INSERT INTO 
           SMD_RESERVATION_INSTANCES VALUES(?,?,?)");
          localIDTest = getUniqueID();
          System.out.println("ID: "+localIDTest);
          prepareStatement.setString(1, localIDTest);
          prepareStatement.setBytes(2, buf);
          prepareStatement.setString(3, "Pending");
          prepareStatement.executeUpdate();
          prepareStatement.close();
          con.commit();
   }catch(SQLException sqle){
       System.err.print(sqle);
   }
   catch(ClassNotFoundException cnfe){
       System.err.print(cnfe);
   }
    return false;
   }


   public static Reservation retrieveReservation()throws IOException,
        SQLException{
   Reservation testRsv = new Reservation();
   try {
        Connection con = null;

        Class.forName("oracle.jdbc.driver.OracleDriver");
        con=DriverManager.getConnection(
            "jdbc:oracle:thin:@dsdsds",
            "SMBDB",
            "hpdbsmb");
        con.setAutoCommit(false);
       try {

            PreparedStatement prepareStatement = con.prepareStatement("SELECT * FROM 
             SMD_RESERVATION_INSTANCES WHERE id = ?");         
            prepareStatement.setString(1, localIDTest);
            ResultSet rset = prepareStatement.executeQuery();
            prepareStatement.executeUpdate();
            //prepareStatement.close();
            con.commit();
            if(rset.next()){
                retrievedID = rset.getString("ID");
                Blob blob = rset.getBlob("RESERVATIONINST");
                status = rset.getString("STATUS");
                long blobLength = blob.length();
                int pos = 1;   // position is 1-based
                //int len = 10;
                byte[] bytes = blob.getBytes(pos,(int) blobLength);
                InputStream is = blob.getBinaryStream();
                ObjectInputStream ois = new ObjectInputStream(is);
                testRsv=(Reservation)ois.readObject();
            }


        rset.close();
        con.close();
         }catch(IOException ioe){
              System.err.print(ioe);
          }
       }catch(ClassNotFoundException cnfe){
          System.err.print(cnfe);
      }
    return testRsv;

   }

   public static void displayRsvContent(){

    try{
        Reservation rsvtester = new Reservation();
        rsvtester.badgeNo = 750752;
        rsvtester.networkID = "GHAMKS1C";
        storeInfo(rsvtester);
        rsvReturned = retrieveReservation();
        if(rsvReturned == null){
            System.out.println("Null Reservation!");
        }else{
            System.out.println("Badge: " + rsvReturned.badgeNo);
            System.out.println("Network: " + rsvReturned.networkID);
        }

    }catch(SQLException sqle){
            System.err.print(sqle);
    }catch(IOException ioe){
        System.err.print(ioe);
    }
  }


public static void main(String[]args){
    displayRsvContent();
}

Это просто проверка того, что хранение и извлечение объекта сделано правильно. Я создаю экземпляр Reservation и присваиваю значения его переменных, чтобы посмотреть, действительно ли они сохранены. Сюрприз-сюрприз, они не отображаются при загрузке. Вот что я получаю:

ID: ec561507-7138-4468-98a3-7756219f216e
Badge: 0
Network: null

Почему это происходит, хотя я просто присваиваю его перед сохранением объекта? Идентификатор показывает, хотя это правильно.

P.S. Бронирование:

public class Reservation implements
   java.io.Serializable{

String eventTitle;
public Date startDate;
public Date endDate;
String requestType;
public int terminals;
String lastName;
String firstName;
String middleInitials;
public transient int badgeNo;
public transient String networkID;
String telephoneNo;
String orgCode;
String orgName;
String justification;
String insideCheckRange;
int mapSize;



MapStorage mapStorage = new MapStorage();


public Reservation(int badgeNo, String networkID) {
    this.badgeNo = badgeNo;
    this.networkID = networkID;
}


    public Reservation(){

    }

public Reservation(String eventTitle, Date startDate, Date endDate, String requestType, int terminals, String lastName, String firstName, String middleInitials, int badgeNo, String networkID, String telephoneNo, String orgCode, String justification) {
    //create in here

    this.eventTitle = eventTitle;
    this.startDate = startDate;
    this.endDate = endDate;
    this.requestType = requestType;
    this.terminals = terminals;
    this.lastName = lastName;
    this.firstName = firstName;
    this.middleInitials = middleInitials;
    this.badgeNo = badgeNo;
    this.networkID = networkID;
    this.telephoneNo = telephoneNo;
    this.orgCode = orgCode;
    this.justification = justification;
}



 public boolean checkRange() {    



        DateTime startx = new DateTime(startDate.getTime());
        DateTime endx = new DateTime(endDate.getTime());

        //booking status
        boolean possible = false;

        //Booking type: 1 = Project, 2 = Training

        /*
        if(requestType.equals("Project")){
            bookingType = 1;
        }else if(requestType.equals("Training")){
            bookingType = 2;

        }
        */
        //produces submap
        //mapSize = bookingType;
        TreeMap<DateTime, Integer> mapLoaded = null;
        try{
         mapLoaded = mapStorage.RetrieveMap();
        }catch(IOException ioe)
        {
            System.err.print(ioe);
        }
        if(requestType.equals("Project"))
        {
            //Project
            //insideCheckRange = "In first for loop";
            //fetch all values for keys in the map between start and end
                for (Integer capacity : mapLoaded.subMap(startx, endx).values()) {


                    if(capacity >= terminals)
                        //yes then its possible, set to true
                        possible = true;
                    else if(capacity < terminals)
                        //not then set it to false
                        possible = false;

                }

                if(possible == true)
                {

                    //if it is possible to accomodate request
                    for (DateTime x : mapLoaded.subMap(startx, endx).keySet()) {
                    {
                        //for dates n, update value for next operation
                        mapLoaded.put(x, mapLoaded.get(x) - terminals);
                    }
                }
                }else{
                 //nothing now
                }
        }else if(requestType.equals("Training")){
            //Training
             for (Integer capacity : mapLoaded.subMap(startx, endx).values()) {
                    //Provides an insight into capacity accomodation possibility
                    //testValue++;
                    terminals = 1;
                    if(capacity >= terminals)
                        possible = true;
                    else if(capacity < terminals)
                        possible = false;

                }


                if(possible == true)
                {
                    for (DateTime x : mapLoaded.subMap(startx, endx).keySet()) {
                    {
                        //46 so that all seats are reserved
                        mapLoaded.put(x, mapLoaded.get(x) - 46);

                    }
                }
                }else{
                 //nothing now
                }

        }


        return possible;
}

}

Ответы [ 2 ]

2 голосов
/ 10 декабря 2011

Если у вас есть transient поля в Reservation, которые бы это объясняли.

Но я думаю, что проблема в том, что вы на самом деле отображаете фиктивную Reservation, которую вы создали в началеretrieveReservation().

Почему?Потому что rset.next() возвращает false.

Почему?Хорошо, взгляните на это:

   PreparedStatement prepareStatement = con.prepareStatement("SELECT * FROM 
         SMD_RESERVATION_INSTANCES WHERE id = ?");         
   prepareStatement.setString(1, localIDTest);
   ResultSet rset = prepareStatement.executeQuery();
   prepareStatement.executeUpdate();
   //prepareStatement.close();
   con.commit();

Это довольно случайно.Вам не нужно указывать executeQuery и executeUpdate в одном и том же подготовленном утверждении.И нет необходимости commit() в этот момент, потому что это запрос!

Итак, я думаю, что ваш ложный вызов executeUpdate закрывает ResultSet, поэтому, когда вы звоните rset.next(), он возвращает false.(Другая возможная причина возврата rset.next() - ложь, если предыдущая вставка завершилась неудачно / не зафиксирована.)

В любом случае, если rset.next() возвращает ложь, ваш код даже не пытается десериализовать полученный объект... и в итоге вы возвращаете фиктивный объект.

0 голосов
/ 10 декабря 2011

В вашем Reservation классе есть переходные поля:

public transient int badgeNo;
public transient String networkID;

Сериализация Java будет избегать хранения переходных полей :

Вы должны пометить переходныелюбое поле, которое либо нельзя сериализовать, либо любое поле, которое вы не хотите сериализовать.Сериализация не заботится о модификаторах доступа, таких как private - все нетранзитивные поля считаются частью постоянного состояния объекта и имеют право на постоянство.

Простое решение состоит в том, чтобы сделать эти поля непереходными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...