How to get single row from entity in JPA?
Table: Employee
#Id
private int empId;
private String empName;
...
JPA by default return List. I`m trying to fetch single row.
EmployeeRepository :-
public Employee findByEmpName(String empName);
Another way is to do it, #Query should be use.
#Query(value="select e from Employee e where empName = ?1 limit 1", nativeQuery=true)
public Employee findByEmpName(String empName);
How can i ensure that it return single row and correct result.
Any help appreciated.. Thanks in advance.
There is an out of the box solution, in repository you can name method as findFirstBy... or findTopBy..., that should do the thing.
You can find more in Spring reference documentation
You don't need to "ensure" anything.
If you dont have a collection of sort specified as return (e.g. List<Employee> instead of Employee ) and your query return more than one result it will launch a javax.persistence.NonUniqueResultException: result returns more than one elements.
If your query return more rows and you want only one of those either add a condition to differentiate which one of those rows you actually want or, if they are the same, add a good old distinct
How can i ensure that it return single row and correct result.
That's your job when writing the query
JPA have a method to fetch a single row getSingleResult, but it's recommended to fetch a list and extract the first element over getResultList.
See: Example
If you want to select only one row from the result set then you can limit number of records by using the query.setMaxResults method:while creating the jpa query.
example : criteria.setMaxResults(25); : it only fetch 25 records out of 100 records.
In case someone wants just a single row from a database using JpaRepository (spring-data-jpa), I found this very useful:
repository.findAll().stream().findFirst().orElseThrow(...)
Since this is a stream, I suppose that rows (or rather: Objects) are fetched row by row.
Related
Is there a way using a Spring JPA Repository Query to get a sub-list of the IDs that were not present in our table given a list of IDs?
Something like this:
#Query(value = "Some query returning a sublist of orderIds not in TABLE")
List<String> orderIdsNotInTable(#Param("orderIds") List<String> orderIds);
I found a link here but I cant think of how to make that a JPA Query.
EDIT: The goal here is to save on running memory so if there are thousands of ids and many calls happening at once I would like it to be handled without creating a second copy of all the ids potentially.
As from what your questions asks, my solution would be:
retrieve the list of IDs present in your database:
#Query("select t.id from Table t")
List<String> findAllIds();
Loop through the list of IDs you have and look up if the list of IDs from the database table does not contain your id.
List<String> idsNotContained= orderIds.stream()
.filter(!findAllIds()::contains)
.collect(Collectors.toList());
Building on #Pawan.Java solution, I would look for the ids and then apply the filtering.
List<String> findByIdIn(List<String> ids);
The list which is returned will contain the ids which exist, it is then just a matter of removing those ids from the original list.
original.stream().filter(i ->
!existingIds.contains(i)).collect(Collectors.toList());
If there is a large number of ids being passed in, then you might want to consider splitting them into parallel batches.
If your list is not too big, then an easy and efficient solution is to retrieve the IDs from the list that are in the table:
select t.id from Table t where t.id in (id1, id2, ...)
Then a simple comparison between initial and returned lists will give you the IDs that are not in the table.
#Query(value = "SELECT t.id FROM TABLE t WHERE t.id NOT IN :orderIds")
List<String> orderIdsNotInTable(#Param("orderIds") List<String> orderIds);
I don't know if I understood you correctly but can you try the solution above.
I am running into the issue where I am making a query from one table and trying to map and store the results it returns into another table. There is one field in my new table that's unique to that table while the other values being mapped have the same name from the original mapped table. Now the problem I have is that hibernate is saying that a unique field is not part of the result set so it can't map it. What can I do to let hibernate know that this field is only part of the new table and not part of the table it' gets mapped from?
Table A
name
age
Table B
name
age
height
#Query(
value = "select name, age, from table A group by (name, age)",
nativeQuery = true
)
List<TableB> mapData();
Hiberate Returns
The column name height was not found in this ResultSet.
I must remind you that such a return value can easily break the code design. For query operations on the same data table, the best option is to return the same pojo.
If you need to convert TableA to TableB in other logic, maybe you can search for "java object copy", for example: http://dozer.sourceforge.net/
select id,name,salary,city,state,country from employee where name like '%a%';
I need to map above query result to String array, position 0 always id, position 1 always name ...... position 5 always country.
Using JPA or MyBatis is there a way we can dynamically map the select query values into fixed position string array ?
I've never personally used JPA, but - after reading through it a bit - believe this should be correct.
TypedQuery<Object[]> query = entityManager.createQuery(
"SELECT id,name,salary,city,state,country FROM employee WHERE name LIKE '%a%'", Object[].class);
List<Object[]> results = query.getResultList();
where (Integer) results.get(index)[0] = id, (String) results.get(index)[1] = name, etc.
You can change Object[] to String[] if you would like an array of Strings.
Why do you want to use String array?
It is better to use an object list instead. It will be easier to get city of an employee using employee.getCity() versus array[3].
It makes for more readable code as well.
To use an object list, you need to create a model for your employee and annotate with #Entity and create a repository for that entity. JPA documentation should help do this easily
As Tobias Liefke suggested here, I have implemented an AttributeConverter to store list values into a single string column separated by commas.
Converter Class:
public class ListNumbersConverter implements AttributeConverter<List<Long>, String>
Field in Entity class:
#Column(name = "user_ids", nullable = false)
#Convert(converter = ListNumbersConverter.class)
private List<Long> userIds;
It is working fine but I can't query the records for specific list items. I tried using IN operator in JPQL query like below:
? in userIds
With this I get only a result if input param is the first element in the DB value. e.g: DB value is "1,2,3". I am able to retrieve this record if input param value is 1 for above mentioned query, but not able to retrieve if value is either 2 or 3. How do I have to write my query to retrieve all records that contain a specific item?
My database is MySQL.
Hibernate doesn't know how the converter maps the list to the column. It can't build a mapping from the JPQL ? in userIds to the matching SQL fragment, as it would need to know how your converter is implemented.
But you can always build that SQL fragment yourself, for example:
WHERE concat(',', entity.userIds, ',') LIKE concat('%,', ?, ',%')
The first concat is to ensure that the expression matches even the first and last value of the list (which wouldn't start or end with the separator).
There are other DB specific functions that could be used, but this example works on all database types I know of.
Another remark: You should not try to join userIds in the query - as it is of a basic type, even if it is a list. See the JavaDoc of #Convert:
The Convert annotation is used to specify the conversion of a Basic field or
property.
Nevertheless Hibernate will complain if you compare your attribute directly with a literal (entity.userIds = '1') because the type of the attribute doesn't match the type of the literal. But as long as you use a function like above for either side of the comparison it won't complain.
Suppose I have a list of IDs as follows:
EmployeeID
-------
ABCD
AECD
ABDF
ACDF
ACDE
I have a need to read the distinct values from a list of codes, while selecting only the first two characters of the column.
In other words, its similar to using the following query:
SELECT DISTINCT LEFT (EmployeeID,2) FROM TABLE1
My question is how do I map such a field in TOPLINK.
Note:I have created a class for the EmployeeID, but dont have an idea of mapping a partial field.
Ok... After looking at many workarounds, I seem to have a more suited solution.
I created an object for this particular scenario (the POJO has only the field for the holding the 2 Char ID, and its getter and setter methods).
During the mapping, I mapped the above field to the DB column in question (EmployeeID in the table described above).
Now I selected "Custom Queries" for the above object and entered the following query for "Read all" tab.
SELECT DISTINCT LEFT (EmployeeID,2) AS EmploeeID FROM TABLE1
All the read all operations on the object will now return the list of distinct first 2 characters of IDs.
Welcome anyone's opinion on this.