Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use an Array object as a parameter in Spring Repository @Query annotation?

Is it possible to use an Array object as a parameter in Spring Repository @Query annotation?

I'm trying to retrieve all rows in a table whose column node is present in an String array. Is it possible to do it at a time using the @Query annotation in Spring repository?

Here is my Location Entity:

@Entity
@Table(name = "LOCATIONS")
public class Location extends Measurement{

    private String latitude;
    private String nsIndicator;

    private String longitude;
    private String ewIndicator;

    @ManyToOne
    @JoinColumn(name="node")
    private Node node;
}

Where node references the Node class, and it is mapped in the database as a BIGINT.

I have a repository like this:

public interface LocationRepository extends CrudRepository<Location, Long>{

    @Query(value=
            "SELECT l1.node, l1.id, l1.latitude, l1.longitude " +
            "FROM LOCATIONS l1 WHERE l1.node IN (:ids)", 
            nativeQuery=true)
    List<Location> findMeasureByIds(@Param("ids") String[] ids);
}

There you can see the query that I'm trying to execute, but it's not working. I don't know if it's possible to use an array there, or parameters must be just Strings and/or Integers, I couldn't find it anywhere.

I've tried several combinations like using a simple String with the right format or a long array.. but nothing has worked so far.

Thanks in advance.

SOLUTION:

@Query(value="SELECT * FROM LOCATIONS l1 " + 
             "INNER JOIN (SELECT node, MAX(id) AS id FROM LOCATIONS GROUP BY node) l2 " + 
             "ON l1.node = l2.node AND l1.id = l2.id " + 
             "WHERE l1.node IN :ids", nativeQuery=true) 
List<Location> findLastLocationByIds(@Param("ids") Set<Long> ids);

I've added more functionality to the query because I needed to retrieve the last row inserted for each node identifier. So there's the MAX function and the INNER JOIN to do that work.

like image 299
Rafael Redrado Avatar asked Apr 08 '14 11:04

Rafael Redrado


1 Answers

Use a collection instead of an array (Set<String>), and make sure it's not empty (otherwise the query will be invalid.

Also, there's no reason to use a native query for that, and you shouldn't have parentheses around the parameter:

@Query("SELECT l1 FROM Location l1 WHERE l1.node.id IN :ids")
List<Location> findLocationsByNodeIds(@Param("ids") Set<String> ids);
like image 146
JB Nizet Avatar answered Nov 08 '22 21:11

JB Nizet