Will -

I'm betting that the em.persist(..) call isn't happening inside a
transaction. Can you enable openjpa trace[1] and rerun your scenario?

[1] <property name="openjpa.Log" value="DefaultLevel=trace" />

Thanks,
Rick

On Wed, May 2, 2012 at 1:12 PM, Will Hoover <java.whoo...@gmail.com> wrote:

> I have successfully setup an OpenJPA (2.2.0) + Atomikos (3.7.1) + Embedded
> Jetty (8.1.2) stack (example code below). Everything seems to works without
> any errors, but OpenJPA doesn't seem to recognize dirty entities after a
> call to EntityManager#persist and a new EntityManager is created (see
> DefaultAppServlet.java below). Any idea why this would be happening?
>
> ServiceManager.java
>
> public class ServiceManager {
>
>        private static final Logger log =
> LoggerFactory.getLogger(ServiceManager.class);
>        public static final String DEFAULT_PERSISTENT_UNIT = "test-pu";
>        private static EntityManagerFactory factory;
>        private static WebServer webServer;
>
>        public static void startServices(final String persistentUnit) {
>                stopServices();
>                setEmFactory(null);
>                webServer = WebServer.start(9080);
>        }
>        public static void stopServices() {
>                if (webServer != null) {
>                        webServer.stop();
>                }
>                try {
>                        if (factory != null && factory.isOpen()) {
>                                factory.close();
>                        }
>                        factory = null;
>                } catch (final Exception e) {
>                        log.error("Unable to close " +
> EntityManagerFactory.class.getSimpleName(), e);
>                }
>        }
>        public static final EntityManagerFactory getEmFactory() {
>                return factory;
>        }
>        protected static final void setEmFactory(final EntityManagerFactory
> factory) {
>                if (ServiceManager.factory != null &&
> ServiceManager.factory.isOpen()) {
>                        ServiceManager.factory.close();
>                }
>                if (factory == null || !factory.isOpen()) {
>                        ServiceManager.factory = Persistence.
>
> createEntityManagerFactory(DEFAULT_PERSISTENT_UNIT,
>                                        System.getProperties());
>                }
>                ServiceManager.factory = factory;
>        }
> }
>
> WebServer.java
>
> public class WebServer {
>
>        private static final Logger log =
> LoggerFactory.getLogger(WebServer.class);
>        private final int portNumber;
>        private Server server;
>
>        private WebServer(final int portNumber) {
>                this.portNumber = portNumber <=0 ? 80 : portNumber;
>        }
>        public static final WebServer start() {
>                final WebServer webServer = new WebServer();
>                final Thread webServerAgent = new
> Thread(Thread.currentThread().getThreadGroup(), new Runnable() {
>                        @Override
>                        public void run() {
>                                webServer.startServer();
>                        }
>                }, WebServer.class.getSimpleName() + '-' +
> System.currentTimeMillis());
>                webServerAgent.setDaemon(true);
>                webServerAgent.start();
>                return webServer;
>        }
>        protected final void startServer() {
>                try {
>                        final Resource serverXml =
> Resource.newSystemResource("META-INF/jetty.xml");
>                        final XmlConfiguration configuration = new
> XmlConfiguration(serverXml.getInputStream());
>                        server = (Server) configuration.configure();
>                        // set the connector based upon user settings
>                        final SelectChannelConnector defaultConnnector = new
> SelectChannelConnector();
>                        defaultConnnector.setPort(getPortNumber());
>                        server.setConnectors(new Connector[] {
> defaultConnnector });
>
>                        final EnumSet<DispatcherType> dispatchers =
> EnumSet.range(DispatcherType.FORWARD, DispatcherType.ERROR);
>                        ServletContextHandler context = new
> ServletContextHandler(ServletContextHandler.SESSIONS);
>                        context.setContextPath("/");
>                        context.addFilter(TransactionFilter.class, "/*",
> dispatchers);
>                        context.addServlet(DefaultAppServlet.class, "/");
>                        server.setHandler(context);
>
>                        server.setDumpAfterStart(true);
>                        server.start();
>                        server.join();
>                } catch (final Throwable e) {
>                        log.error("Unable to start web server", e);
>                }
>        }
>        public final void stop() {
>                try {
>                        if (server != null && !server.isStopped() &&
> !server.isStopping()) {
>                                server.stop();
>                        }
>                        server.destroy();
>                } catch (final Exception e) {
>                        log.error("Unable to shutdown", e);
>                }
>        }
>        public int getPortNumber() {
>                return portNumber;
>        }
> }
>
> DefaultAppServlet.java
>
> public class DefaultAppServlet extends DefaultServlet {
>
>        private static final Logger log =
> LoggerFactory.getLogger(DefaultAppServlet.class);
>        public DefaultAppServlet() {
>                super();
>        }
>        @Override
>        protected void doGet(HttpServletRequest request, HttpServletResponse
> response) throws ServletException, IOException {
>                response.setContentType("text/html;charset=utf-8");
>                response.setStatus(HttpServletResponse.SC_OK);
>                response.getWriter().println("<h1>Hello Message
> World</h1>");
>                try {
>                EntityManager em =
> ServiceManager.getEmFactory().createEntityManager();
>                        final Message msg = new Message("Hello Persistence!
> " + System.currentTimeMillis());
>                em.persist(msg);
>                em.close();
>
>                // DOES NOT RECOGNIZE THE ENTITY JUST PERSISTED
>                EntityManager em2 =
> ServiceManager.getEmFactory().createEntityManager();
>                Query q = em2.createQuery("select m from Message m");
>                for (Message m : (List<Message>) q.getResultList()) {
>                    System.out.println(m.getMessage() + " (created on: " +
> m.getCreated() + ')');
>                    response.getWriter().println("<h3>" + m.getMessage() + "
> (created on: " + m.getCreated() + ')' + "</h3>");
>                }
>                em2.close();
>                } catch (Throwable t) {
>                        log.error("Error: ", t);
>                }
>        }
> }
>
> TransactionFilter.java
>
> public class TransactionFilter implements Filter {
>
>        public void doFilter(ServletRequest request, ServletResponse
> response, FilterChain chain) {
>                try {
>
>                        // start a new transaction for this request
>                        getTransaction().setTransactionTimeout(10000);
>                        getTransaction().begin();
>
>                        // delegate the request to the next filter, and
> eventually to the
>                        // target servlet or JSP
>                        chain.doFilter(request, response);
>
>                        // if no exception happened: commit the transaction
>                        getTransaction().commit();
>                } catch (final Throwable t) {
>                        // analyze exception to dermine of rollback is
> required or not
>                        // and then call rollback or commit on utx as
> appropriate
>                        t.printStackTrace();
>                        try {
>                                getTransaction().rollback();
>                        } catch (final Throwable t2) {
>                                t2.printStackTrace();
>                        }
>                }
>        }
>        @Override
>        public void destroy() {
>        }
>        @Override
>        public void init(FilterConfig filterConfig) throws ServletException
> {
>        }
>        protected TransactionManager getTransaction() {
>                try {
>                        // from Jetty JNDI configuration
>                        return (TransactionManager) new
> InitialContext().lookup("UserTransaction");
>                } catch (final NamingException e) {
>                        e.printStackTrace();
>                }
>                return null;
>        }
>
> }
>
> META-INF/persistence.xml
>
> <?xml version="1.0"?>
> <persistence xmlns="http://java.sun.com/xml/ns/persistence";
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
>        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
>        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd";
>        version="2.0">
>        <persistence-unit name="test-pu" transaction-type="JTA">
>
> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
>                <jta-data-source>jdbc/testDS</jta-data-source>
>                <class>com.example.jpa.entity.Message</class>
>                <properties>
>                        <property name="openjpa.jdbc.SynchronizeMappings"
> value="buildSchema(ForeignKeys=true)"/>
> <!--                    <property name="openjpa.jdbc.JDBCListeners" value="
> com.example.jpa.UGateJdbcListener"/> -->
> <!--                    <property name="openjpa.DynamicEnhancementAgent"
> value="false"/> -->
>                        <property name="openjpa.ConnectionFactoryProperties"
> value="PrettyPrint=true, PrettyPrintLineLength=72" />
>                        <property name="openjpa.Log"
> value="DefaultLevel=WARN, Tool=INFO, SQL=WARN"/>
>
>                        <property name="openjpa.ConnectionFactoryMode"
> value="managed" />
>                        <property name="openjpa.TransactionMode"
> value="managed" />
>                        <property name="openjpa.ManagedRuntime"
>
> value="jndi(TransactionManagerName=UserTransaction)" />
> <!--                    <property name="openjpa.ManagedRuntime" -->
> <!--
>
> value="invocation(TransactionManagerMethod=com.atomikos.icatch.jta.Transacti
> onManagerImp.getTransactionManager)" /> -->
>                </properties>
>        </persistence-unit>
> </persistence>
>
> Jetty (plus: jetty-all version 8.1.2) configuration
>
> <?xml version="1.0"?>
> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
> "http://www.eclipse.org/jetty/configure.dtd";>
> <Configure id="Server" class="org.eclipse.jetty.server.Server">
>        <!-- =========================================================== -->
>        <!-- Define a server aware DB XA connection data source -->
>        <!-- =========================================================== -->
>        <New id="xaDataSource" class="org.eclipse.jetty.plus.jndi.Resource">
>                <Arg></Arg>
>                <Arg>jdbc/testDS</Arg>
>                <Arg>
>                        <New id="atomikosDS"
> class="com.atomikos.jdbc.AtomikosDataSourceBean">
>                                <Set name="minPoolSize">2</Set>
>                                <Set name="maxPoolSize">50</Set>
>                                <Set
> name="xaDataSourceClassName">org.h2.jdbcx.JdbcDataSource</Set>
>                                <Set
> name="UniqueResourceName">jdbc/testDS</Set>
>                                <Set name="testQuery">SELECT 1 and SELECT 1
> FROM DUAL</Set>
>                                <Get name="xaProperties">
>                                        <Call name="setProperty">
>                                                <!-- Must be upper case -->
>                                                <Arg>URL</Arg>
>
>
> <Arg>jdbc:h2:~/test;AUTO_SERVER=TRUE;FILE_LOCK=SOCKET;TRACE_LEVEL_FILE=0;TRA
> CE_LEVEL_SYSTEM_OUT=1</Arg>
>                                        </Call>
>                                        <Call name="setProperty">
>                                                <Arg>user</Arg>
>                                                <Arg>sa</Arg>
>                                        </Call>
>                                        <Call name="setProperty">
>                                                <Arg>password</Arg>
>                                                <Arg>sa</Arg>
>                                        </Call>
>                                </Get>
>                        </New>
>                </Arg>
>        </New>
>        <!-- =========================================================== -->
>        <!-- Add a closer bean that will dispose of the DB DS -->
>        <!-- =========================================================== -->
>        <Ref id='Server'>
>                <Call name="addBean">
>                        <Arg>
>                                <New
> class="org.eclipse.jetty.jndi.DataSourceCloser">
>                                        <Arg>
>                                                <Ref id="atomikosDS" />
>                                        </Arg>
>                                </New>
>                        </Arg>
>                </Call>
>        </Ref>
>        <!-- =========================================================== -->
>        <!-- Define server transaction aware JTA implementation -->
>        <!-- =========================================================== -->
>        <New id="tx" class="org.eclipse.jetty.plus.jndi.Transaction">
>                <Arg>
>                        <New
> class="com.atomikos.icatch.jta.UserTransactionManager" />
>                </Arg>
>        </New>
>
>        ...
>
> </Configure>
>
>


-- 
*Rick Curtis*

Reply via email to