user4080876
user4080876

Reputation:

JPA query returns Object[] instead of desired entity

I use this code to do a query to a sql server database:

List<Continent> continents = new ArrayList<>();
        List<Object[]> tuples = (List<Object[]>) em.createNativeQuery("SELECT * FROM Continents").getResultList();
        for (Object[] tuple : tuples) {

            System.out.println(tuple[0]);

        }
        return continents;

I use this code because I can't get the desired entity type (Continent) straight out of the database.

How should my query look like?

This is the start of my continent class:

@Entity
@Table
public class Continent implements Serializable {
    @Column(name = "Name")
    private StringProperty name;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ContinentID")
    private IntegerProperty continentId;
    @OneToMany(mappedBy="continent")
    private Connection connection;
    List<Country> countries;


    public Continent(String naam) throws SQLException {
        name = new SimpleStringProperty(naam);
        continentId = new SimpleIntegerProperty();
    }

    protected Continent()
    {}

This is my persistence.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="HOGENT1415_11" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>domain.Continent</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:sqlserver://localhost:1433;databaseName=HOGENT1415_11"/>
      <property name="javax.persistence.jdbc.user" value="sa"/>
      <property name="javax.persistence.jdbc.driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
      <property name="javax.persistence.jdbc.password" value="root"/>
    </properties>
  </persistence-unit>
</persistence>

Upvotes: 3

Views: 4975

Answers (3)

Christian
Christian

Reputation: 779

For a simple query like this its better to just use em.createQuery rather than em.createNativeQuery, that is assuming that the class Continent is being managed by the entity manager em.

List continents = (List)em.createQuery("SELECT c FROM Continent c").getResultList();

Upvotes: 0

Vladimir
Vladimir

Reputation: 9743

You should provide resulting class, if you are using native query:

List<Continent> tuples = em.createNativeQuery("SELECT * FROM Continents", Continent.class).getResultList();

or just use jpql query:

List<Continent> tuples = em.createQuery("SELECT c FROM Continent c", Continent.class).getResultList();

In second example result class is optional, but this way you get TypedQuery and can avoid casting. Note that in case of jpql you provide entity name, not table name like in native query.

Upvotes: 5

FMC
FMC

Reputation: 660

You could do

for (Object[] tuple : tuples) 
{
   continents.add((Continent) tuple[0]));
}

To populate your list.

Edit:

Based on your comment you can do this instead:

for (Object[] tuple : tuples) 
{
    Continent c = new Continent();
    c.setID(tuple[0]);
    c.setName(tuple[1]);
    continents.add(c);
}

Upvotes: 0

Related Questions