alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Play Framework/Scala example source code file (JPA.java)

This example Play Framework source code file (JPA.java) is included in my "Source Code Warehouse" project. The intent of this project is to help you more easily find Play Framework (and Scala) source code examples by using tags.

All credit for the original source code belongs to Play Framework; I'm just trying to make examples easier to find. (For my Scala work, see my Scala examples and tutorials.)

Play Framework tags/keywords

concurrent, db, entitymanager, entitymanagerfactory, entitytransaction, jpa, library, no, override, play, play framework, runtimeexception, t, threadlocal, throwable

The JPA.java Play Framework example source code

/*
 * Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
 */
package play.db.jpa;

import play.*;
import play.libs.F;
import play.mvc.Http;
import scala.concurrent.ExecutionContext;

import javax.persistence.*;

/**
 * JPA Helpers.
 */
public class JPA {

    // Only used when there's no HTTP context
    static ThreadLocal<EntityManager> currentEntityManager = new ThreadLocal<EntityManager>();

    /**
     * Get the EntityManager for specified persistence unit for this thread.
     */
    public static EntityManager em(String key) {
        Application app = Play.application();
        if(app == null) {
            throw new RuntimeException("No application running");
        }

        JPAPlugin jpaPlugin = app.plugin(JPAPlugin.class);
        if(jpaPlugin == null) {
            throw new RuntimeException("No JPA EntityManagerFactory configured for name [" + key + "]");
        }

        EntityManager em = jpaPlugin.em(key);
        if(em == null) {
            throw new RuntimeException("No JPA EntityManagerFactory configured for name [" + key + "]");
        }

        return em;
    } 

    /**
     * Get the default EntityManager for this thread.
     */
    public static EntityManager em() {
        Http.Context context = Http.Context.current.get();
        if (context != null) {
            EntityManager em = (EntityManager) context.args.get("currentEntityManager");
            if (em == null) {
                throw new RuntimeException("No EntityManager bound to this thread. Try to annotate your action method with @play.db.jpa.Transactional");
            }
            return em;
        }
        // Not a web request
        EntityManager em = currentEntityManager.get();
        if(em == null) {
            throw new RuntimeException("No EntityManager bound to this thread. Try wrapping this call in JPA.withTransaction, or ensure that the HTTP context is setup on this thread.");
        }
        return em;
    }

    /**
     * Bind an EntityManager to the current thread.
     */
    public static void bindForCurrentThread(EntityManager em) {
        Http.Context context = Http.Context.current.get();
        if (context != null) {
            if (em == null) {
                context.args.remove("currentEntityManager");
            } else {
                context.args.put("currentEntityManager", em);
            }
        } else {
            currentEntityManager.set(em);
        }
    }

    /**
     * Run a block of code in a JPA transaction.
     *
     * @param block Block of code to execute.
     */
    public static <T> T withTransaction(play.libs.F.Function0<T> block) throws Throwable {
        return withTransaction("default", false, block);
    }

    /**
     * Run a block of asynchronous code in a JPA transaction.
     *
     * @param block Block of code to execute.
     */
    public static <T> F.Promise<T> withTransactionAsync(play.libs.F.Function0<F.Promise<T>> block) throws Throwable {
        return withTransactionAsync("default", false, block);
    }

    /**
     * Run a block of code in a JPA transaction.
     *
     * @param block Block of code to execute.
     */
    public static void withTransaction(final play.libs.F.Callback0 block) {
        try {
            withTransaction("default", false, new play.libs.F.Function0<Void>() {
                public Void apply() throws Throwable {
                    block.invoke();
                    return null;
                }
            });
        } catch(Throwable t) {
            throw new RuntimeException(t);
        }
    }

    /**
     * Run a block of code in a JPA transaction.
     *
     * @param name The persistence unit name
     * @param readOnly Is the transaction read-only?
     * @param block Block of code to execute.
     */
    public static <T> T withTransaction(String name, boolean readOnly, play.libs.F.Function0<T> block) throws Throwable {
        EntityManager em = null;
        EntityTransaction tx = null;
        try {

            em = JPA.em(name);
            JPA.bindForCurrentThread(em);

            if(!readOnly) {
                tx = em.getTransaction();
                tx.begin();
            }

            T result = block.apply();

            if(tx != null) {
                if(tx.getRollbackOnly()) {
                    tx.rollback();
                } else {
                    tx.commit();
                }
            }

            return result;

        } catch(Throwable t) {
            if(tx != null) {
                try { tx.rollback(); } catch(Throwable e) {}
            }
            throw t;
        } finally {
            JPA.bindForCurrentThread(null);
            if(em != null) {
                em.close();
            }
        }
    }

    /**
     * Run a block of asynchronous code in a JPA transaction.
     *
     * @param name The persistence unit name
     * @param readOnly Is the transaction read-only?
     * @param block Block of code to execute.
     */
    public static <T> F.Promise<T> withTransactionAsync(String name, boolean readOnly, play.libs.F.Function0<F.Promise<T>> block) throws Throwable {
        EntityManager em = null;
        EntityTransaction tx = null;
        try {

            em = JPA.em(name);
            JPA.bindForCurrentThread(em);

            if(!readOnly) {
                tx = em.getTransaction();
                tx.begin();
            }

            F.Promise<T> result = block.apply();

            final EntityManager fem = em;
            final EntityTransaction ftx = tx;

            F.Promise<T> committedResult = result.map(new F.Function<T, T>() {
                @Override
                public T apply(T t) throws Throwable {
                    try {
                        if(ftx != null) {
                            if(ftx.getRollbackOnly()) {
                                ftx.rollback();
                            } else {
                                ftx.commit();
                            }
                        }
                    } finally {
                        fem.close();
                    }
                    return t;
                }
            });

            committedResult.onFailure(new F.Callback<Throwable>() {
                @Override
                public void invoke(Throwable t) {
                    if (ftx != null) {
                        try { if (ftx.isActive()) ftx.rollback(); } catch(Throwable e) {}
                    }
                    fem.close();
                }
            });

            return committedResult;

        } catch(Throwable t) {
            if(tx != null) {
                try { tx.rollback(); } catch(Throwable e) {}
            }
            if(em != null) {
                em.close();
            }
            throw t;
        } finally {
            JPA.bindForCurrentThread(null);
        }
    }
}

Other Play Framework source code examples

Here is a short list of links related to this Play Framework JPA.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.