Rytis Alekna
Rytis Alekna

Reputation: 1377

Java bean persistence pattern

I'm new to JPA and I'm trying some getting started example projects. I tried GraniteDS sample project ("Hello, World" app) and I found a method hello that updates or inserts java bean. It looks somehow bad for me but on other hand I'm not sure how it should look nicer.

UPDATE I don't like that Query must throw an exception to know that no results with Welcome entities exist. Is there any way to check if there any records in elegant way?

    package info.alekna.project.services;

import java.util.List;
import java.util.Date;
import java.text.SimpleDateFormat;

import javax.persistence.Query;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.NoResultException;

import org.granite.tide.data.DataEnabled;
import org.granite.tide.data.DataEnabled.PublishMode;


import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import info.alekna.project.entities.Welcome;


@Service
@DataEnabled(topic="welcomeTopic", publish=PublishMode.ON_SUCCESS)
public class WelcomeServiceImpl implements WelcomeService {

    @PersistenceContext
    private EntityManager entityManager;


    @Transactional
    public Welcome hello(String name) {
        if (name == null || name.trim().length() == 0)
            throw new RuntimeException("Name cannot be null or empty");

        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
        Welcome welcome = null;
        try {
            Query q = entityManager.createQuery("select w from Welcome w where w.name = :name");
            q.setParameter("name", name);
            welcome = (Welcome)q.getSingleResult();
            welcome.setMessage("Welcome " + name + " (" + sdf.format(new Date()) + ")");
        }
        catch (NoResultException e) {
            welcome = new Welcome();
            welcome.setName(name);
            welcome.setMessage("Welcome " + name + " (" + sdf.format(new Date()) + ")");
            entityManager.persist(welcome);
        }
        return welcome;
    }


    @Transactional(readOnly=true)
    public List<Welcome> findAll() {
        return entityManager.createQuery("select w from Welcome w order by w.name", Welcome.class).getResultList();
    }
}

Upvotes: 1

Views: 243

Answers (2)

vainolo
vainolo

Reputation: 6987

(Answering the question in the comments) You can always use q.getResultList() and check the size of the list. The problem with doing this is that it causes a full run on the table, and if this is not needed, it should be avoided.

It is kind of logical to throw NoResultException if you explicitly call getSingleResult since it IS an exceptional state :-)

Upvotes: 1

&#211;scar L&#243;pez
&#211;scar L&#243;pez

Reputation: 235984

Well, you could call getResultList() on the Query and check if the resulting List's size() is exactly one.

But if you're absolutely certain that the query must return exactly one result, then it makes sense to call getSingleResult() and catch both NoResultException and NonUniqueResultException - if either of those exceptions occur, it's because the assumption that only one result was to be returned was wrong, and it should be handled as an error.

Upvotes: 1

Related Questions