¿Enviar datos JPA del servidor al cliente?

I'm using Eclipse juno IDE.

I Have a client-server application. In the server side I have an Entity (Travels) and I Have another class that handle the JPA queries. I'm recieving the data from the database but when I'm trying to send it as a vector to the client i'm getting an exception in the client side , that says "Cant cast pack.db.Travels to java.util.vector"

Aquí está mi código: Entidad:

package pack.db;

import java.io.Serializable;
import java.sql.Date;
import java.sql.Time;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Travels implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    @Column(name="id")
    private int id;

    @Column(name="taxi_number")
    private String taxiNumber;

    @Column(name="travel_date")
    private Date   travelDate;

    @Column(name="travel_time")
    private Time   travelTime;

    @Column(name="cost")
    private Double travelCost;

    public Travels() {
        super();
    }

    public void setNumber(String number)
    {
        this.taxiNumber = number;
    }

    public void setDate(Date date)
    {
        this.travelDate = date;
    }

    public void setTime(Time time)
    {
        this.travelTime = time;
    }

    public void setCost(Double cost)
    {
        this.travelCost = cost;
    }
}

QueryClass

public Vector retrieveAllTravelsData(Date[] travelDate, Time[] travelTime) {
    List<Object[]> allTravels = (List<Object[]>)em.createQuery("SELECT t FROM Travels t WHERE t.travelDate between ?1 and ?2 and " +
                                              "t.travelTime between ?3 and ?4")
                               .setParameter(1, travelDate[0])
                               .setParameter(2, travelDate[1])
                               .setParameter(3, travelTime[0])
                               .setParameter(4, travelTime[1]).getResultList();
    return (Vector) allTravels;
}

So what I want to do is to send "allTravels" as a vector to the client side becasuse I need to populate a JTABLE in the client-side. so I tried to cast the return data from the query to OBJECT[] (because the constructor of the JTABLE need Object[][] for the rows) and send it.. but i'm still get the exception in client side that says "Cannot cast pack.db.Travel to java.util.Vector".. i don't think that i need to add the travel Entity in the client side.. so how can i send the data to the client?

To be more specific.. I have this code with JDBC implemntation

public Vector retrieveAllTravelsData(Date[] travelDate, Time[] travelTime) {
    Vector rows_data = new Vector();
    String sql = "SELECT * FROM taxis.travels " + " WHERE travel_date BETWEEN ? AND ? AND travel_time BETWEEN ? AND ?";
    try {
        statement = (PreparedStatement) connection.prepareStatement(sql);
        statement.setDate(1, travelDate[0]);
        statement.setDate(2, travelDate[1]);
        statement.setTime(3, travelTime[0]);
        statement.setTime(4, travelTime[1]);
        rs = statement.executeQuery();
        ResultSetMetaData meta = rs.getMetaData();
        int cols_count = meta.getColumnCount();

        while (rs.next()) {
            Vector record = new Vector();
            for (int i = 0; i < cols_count; i++) {
                record.add(rs.getString(i+1));
            }
            rows_data.addElement(record);
        }
    } catch (SQLException e) {
        while (e != null) {
            e.printStackTrace();
            e = e.getNextException();
        }
    }
    return rows_data;

Here i can get each column data from each column save it as a record and then put it in the Vector. so how that can be implemented by JPA? is it possible?

preguntado el 05 de septiembre de 12 a las 10:09

2 Respuestas

Casting an object to another class doesn't magically change the type of the object. It only allows referencing it as a more concrete class. So casting a List to Vector only works if the list is indeed a Vector.

getResultList() devuelve un List. That's what the javadoc says. The concrete class returned depends on the JPA provider, but I'm pretty sure none of them returns a Vector, since Vector is a class that should not be used anymore, since Java 1.2.

Moreover, this particular query doesn't return Object[], but instances of Travels (que debe ser nombrado Travel, BTW).

So the method should be:

public List<Travel> retrieveAllTravelsData(Date[] travelDate, Time[] travelTime) {
    List<Travel> allTravels = (List<Travel>) em.createQuery("SELECT t FROM Travel t WHERE t.travelDate between ?1 and ?2 and " +
                                              "t.travelTime between ?3 and ?4")
                               .setParameter(1, travelDate[0])
                               .setParameter(2, travelDate[1])
                               .setParameter(3, travelTime[0])
                               .setParameter(4, travelTime[1]).getResultList();
    return allTravels;
}

The server shouldn't care that the client-side needs a Vector to satisfy an old Swing class. If you really need a Vector at client-side, then create one from the returned list:

Vector<Travel> travelsAsVector = new Vector(travelsAsList);

Respondido el 05 de Septiembre de 12 a las 12:09

Hi JB Nizet, I know that the query returns instances of Travel, i just tried this way to check if it works and disabling the exception.. Thanks for your response, i'll try your suggestions - eliorsh

I'm able to send the data to client.. but when the client reads the data as 'Vector x = (Vector)from_server.readObject()' I'm getting an exception in the CLIENT SIDE that says: cant casting from pack.db.Travels to java.util.Vector. Now the pack.db.Travels is an Entity in the SERVER SIDE - eliorsh

What you get at client-side is what you send at server-side. If you send a List<Travel> at server-side, you'll get a List<Travel> at client-side. If you're confused, show us the updated code of the query, the code that sends the result at server-side, the code that reads it at client-side, and the complete stack trace of the exception. - JB Nizet

JB Nizet, as i said i'm able to get the data from the server. I checked what is the cause for the exception and it was the JTable c'tor in the client side.. for the rows the c'tor need Vector of Vectors and for the headers a Vector. so I'm trying to convert the list i'm getting from the query into Vector for displaying it in the table.. how can i do that? - eliorsh

Create a new (outer) Vector. Iterate through the List<Travel> you got from the server-side. For each Travel, create a new (inner) Vector. Populate this inner vector with the data you want to display from the Travel. Add the inner vector to the outer vector. Or, much better, create your own AbstractTableModel subclass using the List<Travel> directly. See docs.oracle.com/javase/tutorial/uiswing/components/… - JB Nizet

Ok i solve it like that:

public Vector retrieveAllTravelsData(Date[] travelDate, Time[] travelTime) {

    javax.persistence.Query q = (javax.persistence.Query)em.createNativeQuery("SELECT * 
             from Travels WHERE travel_date between ?1 and ?2")
            .setParameter(1, travelDate[0])
            .setParameter(2, travelDate[1])
            .setParameter(3, travelTime[0])
            .setParameter(4, travelTime[1]);
    List<Object[]> result = (List<Object[]>)q.getResultList();
    Vector rows = new Vector();
    for (int i = 0 ; i < result.size(); i++)
    {
        Vector rec = new Vector();
        for (int j = 0; j < columnCount; j++)
        {
            rec.add(result.get(i)[j].toString()); // returns the specific column value and add it to the vector
        }
        rows.addElement(rec);
    }
    return rows;
}

Respondido el 05 de Septiembre de 12 a las 17:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.