Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Roo: use JPA entity as a DAO

The code below is what Spring Roo generates by default, the EntityManager is injected in your domain model POJOs with the rest of the methods to manage the entity (save, update, delete, findXXX, ...).

Maybe it is a more object-oriented approach (in contrast to the anemic domain model), but what I don't understand is:

  • Is there any performance issue when EntityManager is injected in every entity (imagine you retrieve 1000 entities from a database)

  • Shouldn't the transactional management (@Transactional annotations) go in a service layer? (imagine you want to operate with two different entities in an atomic way).

  • Can you think about other pros/cons of this code against a classical DAO layer?

The code looks like this (some methods are removed for clarity):

@Configurable
@Entity
@RooJavaBean
@RooToString
@RooEntity
public class Answer {

    @PersistenceContext
    transient EntityManager entityManager;

    @Transactional
    public void persist() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.persist(this);
    }

    @Transactional
    public void remove() {
        if (this.entityManager == null) this.entityManager = entityManager();
        if (this.entityManager.contains(this)) {
            this.entityManager.remove(this);
        } else {
            Answer attached = Answer.findAnswer(this.id);
            this.entityManager.remove(attached);
        }
    }

    @Transactional
    public Answer merge() {
        if (this.entityManager == null) this.entityManager = entityManager();
        Answer merged = this.entityManager.merge(this);
        this.entityManager.flush();
        return merged;
    }

    public static final EntityManager entityManager() {
        EntityManager em = new Answer().entityManager;
        if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
        return em;
    }

    public static long countAnswers() {
        return entityManager().createQuery("SELECT COUNT(o) FROM Answer o", Long.class).getSingleResult();
    }

    public static List<Answer> findAllAnswers() {
        return entityManager().createQuery("SELECT o FROM Answer o", Answer.class).getResultList();
    }

    ...
}
like image 545
Guido Avatar asked Sep 22 '11 23:09

Guido


1 Answers

  1. You will find more on this at the link in the third point.

  2. You don't get a Service layer in a typical Roo application. Your service methods are contained within the entity itself, hence it is possible to use @Transactional within your entity to ensure the particular method involves in a transaction. However, you will be able to get a separate service layer with the latest 1.2 version of Spring Roo, which will make it possible.

  3. ADM vs. DDD : A separate question on SO would help on this. Anyways, you can gain a lot of insight with this thread on SpringSource Roo forum. http://forum.springsource.org/showthread.php?77322-Spring-Roo-with-a-services-DAO-architecture

Cheers and all the best with Roo! :)

like image 171
bhagyas Avatar answered Oct 02 '22 19:10

bhagyas