JPA getSingleResult() or null

Viewed 253447

I have an insertOrUpdate method which inserts an Entity when it doesn't exist or update it if it does. To enable this, I have to findByIdAndForeignKey, if it returned null insert if not then update. The problem is how do I check if it exists? So I tried getSingleResult. But it throws an exception if the

public Profile findByUserNameAndPropertyName(String userName, String propertyName) {
    String namedQuery = Profile.class.getSimpleName() + ".findByUserNameAndPropertyName";
    Query query = entityManager.createNamedQuery(namedQuery);
    query.setParameter("name", userName);
    query.setParameter("propName", propertyName);
    Object result = query.getSingleResult();
    if (result == null) return null;
    return (Profile) result;
}

but getSingleResult throws an Exception.

Thanks

22 Answers

Throwing an exception is how getSingleResult() indicates it can't be found. Personally I can't stand this kind of API. It forces spurious exception handling for no real benefit. You just have to wrap the code in a try-catch block.

Alternatively you can query for a list and see if its empty. That doesn't throw an exception. Actually since you're not doing a primary key lookup technically there could be multiple results (even if one, both or the combination of your foreign keys or constraints makes this impossible in practice) so this is probably the more appropriate solution.

I've done (in Java 8):

query.getResultList().stream().findFirst().orElse(null);

From JPA 2.2, instead of .getResultList() and checking if list is empty or creating a stream you can return stream and take first element.

.getResultStream()
.findFirst()
.orElse(null);

So don't do that!

You have two options:

  1. Run a selection to obtain the COUNT of your result set, and only pull in the data if this count is non-zero; or

  2. Use the other kind of query (that gets a result set) and check if it has 0 or more results. It should have 1, so pull that out of your result collection and you're done.

I'd go with the second suggestion, in agreement with Cletus. It gives better performance than (potentially) 2 queries. Also less work.

I solved this by using List<?> myList = query.getResultList(); and checking if myList.size() equals to zero.

Look this code :

return query.getResultList().stream().findFirst().orElse(null);

When findFirst() is called maybe can be throwed a NullPointerException.

the best aproach is:

return query.getResultList().stream().filter(Objects::nonNull).findFirst().orElse(null);

I achieved this by getting a result list then checking if it is empty

public boolean exist(String value) {
        List<Object> options = getEntityManager().createNamedQuery("AppUsers.findByEmail").setParameter('email', value).getResultList();
        return !options.isEmpty();
    }

It is so annoying that getSingleResult() throws exceptions

Throws:

  1. NoResultException - if there is no result
  2. NonUniqueResultException - if more than one result and some other exception that you can get more info on from their documentation

I prefer @Serafins answer if you can use the new JPA features, but this is one fairly straight forward way to do it which I'm surprised hasn't been mentioned here before:

    try {
        return (Profile) query.getSingleResult();
    } catch (NoResultException ignore) {
        return null;
    }
            `public Example validate(String param1) {
                // TODO Auto-generated method stub

                Example example = new Example();
                
                Query query =null;
                Object[] myResult =null;
                
                try {

                      query = sessionFactory.getCurrentSession()
                      .createQuery("select column from table where 
                      column=:p_param1");
                      query.setParameter("p_param1",param1);
                  }
                
                        myResult = (Object[])query.getSingleResult();//As your problem occurs here where the query has no records it is throwing an exception
                    
                        String obj1 = (String) myResult[0];
                        String obj2 = (String) myResult[1];
                        
                        

example.setobj1(ISSUtil.convertNullToSpace(obj1)) example.setobj2(ISSUtil.convertNullToSpace(obj2));

                return example;
                
                }catch(Exception e) {
                    e.printStackTrace();
                      
                 example.setobj1(ISSUtil.convertNullToSpace(""));//setting 
                 objects to "" in exception block
                 example.setobj1(ISSUtil.convertNullToSpace(""));
                }
                return example;
            }`

Answer : Obviously when there is no records getsingleresult will throw an exception i have handled it by setting the objects to "" in the exception block even though it enter the exception you JSON object will set to ""/empty Hope this is not a perfect answer but it might help If some needs to modify my code more precisely and correct me always welcome.

Thats works to me:

Optional<Object> opt = Optional.ofNullable(nativeQuery.getSingleResult());
return opt.isPresent() ? opt.get() : null;
Related