3
Explaining the problem, I need to consult a function in POSTGRES:
SELECT * from pgr_dijkstra('SELECT gid AS id, source, target, length AS cost FROM ways', 11111, 22222);
"pgr_dijkstra" is a POSTGIS function, not a table. It returns me the shortest path between "source"(11111) and "target(2222)". The result is 6 columns: "seq, path_seq, Node, edge, cost and agg_cost".
Because "pgr_dijkstra" is a function I cannot simply create a class in my code and annotate it with @Entity, also adding @Id to "seq" and creating the other 5 fields (path_seq, Node, edge, cost and agg_cost). This would create a new table in the database. After searching a lot, I found a solution that I believe is far from ideal, which would not be good practice. NOTE: I am using Spring Boot + Java. The value of "source" and "target" will not be fixed, users will send via browser, put fixed only to test this part faster.
POJO class
public class Dijkstra3 {
public Integer seq;
public Integer path_seq;
public BigInteger node;
public BigInteger edge;
public double cost;
public double agg_cost;
public Dijkstra3(Integer seq, Integer path_seq, BigInteger node, BigInteger edge, double cost, double agg_cost) {
super();
this.seq = seq;
this.path_seq = path_seq;
this.node = node;
this.edge = edge;
this.cost = cost;
this.agg_cost = agg_cost;
}
//GETTERS ...
}
Mapping of the query
Abstract class with my @Sqlresultsetmapping and @Namednativequery. The @Sqlresultsetmapping annotation is mapping the resulting to Dijkstra3.class, which is my POJO. @Namednativequery is my query, which I will use, I point to the map "Dijkstramapping". I wrote down the class with @Mappedsuperclass, if I didn’t I would have to write it down with @Entity and a new table in the database would be created.
@SqlResultSetMapping(
name = "DijkstraMapping",
classes = {
@ConstructorResult(
columns = {
@ColumnResult(name="seq", type=Integer.class),
@ColumnResult(name="path_seq", type=Integer.class),
@ColumnResult(name="node", type=BigInteger.class),
@ColumnResult(name="edge", type=BigInteger.class),
@ColumnResult(name="cost", type=Double.class),
@ColumnResult(name="agg_cost", type=Double.class)
},
targetClass = Dijkstra3.class
)
}
)
@NamedNativeQueries({
@NamedNativeQuery(
name = "GetDijkstra",
query = "SELECT * from pgr_dijkstra('SELECT gid AS id, source, target, length AS cost FROM ways', 11111, 22222)",
resultSetMapping = "DijkstraMapping"
)
})
@MappedSuperclass
public abstract class DijkstraSqlMap{
}
Repository
@Repository
public class TestRepository2 {
@PersistenceContext
EntityManager em;
public List<Dijkstra3> callDijkstra(){
TypedQuery<Dijkstra3> query = em.createNamedQuery("GetDijkstra", Dijkstra3.class);
List<Dijkstra3> lista = query.getResultList();
return lista;
}
}
Controller or Service:
@Autowired
TestRepository2 testeRepository2;
...
List<Dijkstra3> callHelloWorld = testeRepository2.callDijkstra();
...
That works. After searching and testing everything I found, this was the best way I could find to get the result of a query using JPA, pass the data to an object / POJO, and mainly NOT CREATE A NEW TABLE IN THE DATABASE, because "pgr_dijkstra" is a function and its return data does not represent a table.
Is it correct to annotate the Dijkstrasqlmap class with @Mappedsuperclass so you just don’t need to annotate with @Entity? Is there any other better way to take the result of a query in the database and pass to an / POJO object without creating a new table in the database? I appreciate your time and help.
Look, I don’t master JPA but I’ve used
@MappedSuperclass
, I know she omits to create the table if it’s not a@Entity
(but have subclasses@Entity
s). Only that in my view the goal of it is to allow mapping heritage of classes (isolated reusable behavior and data in an abstraction) p/ the relational model when you have no need to persist in a "parent table", I see this by the name of the Annotation itself, And I understand that’s not what you’re using it for. I didn’t quite understand the relationship between the@MappedSuperclass
and the native/named query you are calling, so I don’t know how to opine anymore.– Piovezan