You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Will Hoover <ja...@gmail.com> on 2012/05/02 20:12:36 UTC

OpenJPA 2.2.0 + Atomikos + Embedded Jetty

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>


RE: OpenJPA 2.2.0 + Atomikos + Embedded Jetty

Posted by Will Hoover <ja...@gmail.com>.
Unfortunately, it only proved that my persist call was being executed
outside of a transaction. It didn't give me much insight as to why.

I've since successfully migrated the project over to Spring + Atomikos +
Embedded Jetty. It seems to work with minimal overhead (when compared to an
EJB solution). It also accommodates for transaction support regardless if
it's called from within the web container or somewhere else in the
standalone application. I'm not sure that Atomikos nested transaction
support can be utilized with OpenJPA, but that would be another bonus verses
using an EJB container (AFIK, OpenEJB doesn't support nested transactions).

Thanks for your help Rick!

-----Original Message-----
From: Rick Curtis [mailto:curtisr7@gmail.com] 
Sent: Tuesday, May 08, 2012 12:25 PM
To: users@openjpa.apache.org
Subject: Re: OpenJPA 2.2.0 + Atomikos + Embedded Jetty

> You are correct. It isn't happening inside a transaction.
Did that fix your problem?

Thanks,
Rick

On Tue, May 8, 2012 at 11:20 AM, Will Hoover <ja...@gmail.com> wrote:

> Hi Rick,
>
> You are correct. It isn't happening inside a transaction.
>
> -----Original Message-----
> From: Rick Curtis [mailto:curtisr7@gmail.com]
> Sent: Tuesday, May 08, 2012 9:18 AM
> To: users@openjpa.apache.org
> Subject: Re: OpenJPA 2.2.0 + Atomikos + Embedded Jetty
>
> 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 <ja...@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*
>
>


-- 
*Rick Curtis*


Re: OpenJPA 2.2.0 + Atomikos + Embedded Jetty

Posted by Rick Curtis <cu...@gmail.com>.
> You are correct. It isn't happening inside a transaction.
Did that fix your problem?

Thanks,
Rick

On Tue, May 8, 2012 at 11:20 AM, Will Hoover <ja...@gmail.com> wrote:

> Hi Rick,
>
> You are correct. It isn't happening inside a transaction.
>
> -----Original Message-----
> From: Rick Curtis [mailto:curtisr7@gmail.com]
> Sent: Tuesday, May 08, 2012 9:18 AM
> To: users@openjpa.apache.org
> Subject: Re: OpenJPA 2.2.0 + Atomikos + Embedded Jetty
>
> 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 <ja...@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*
>
>


-- 
*Rick Curtis*

RE: OpenJPA 2.2.0 + Atomikos + Embedded Jetty

Posted by Will Hoover <ja...@gmail.com>.
Hi Rick,

You are correct. It isn't happening inside a transaction.

-----Original Message-----
From: Rick Curtis [mailto:curtisr7@gmail.com] 
Sent: Tuesday, May 08, 2012 9:18 AM
To: users@openjpa.apache.org
Subject: Re: OpenJPA 2.2.0 + Atomikos + Embedded Jetty

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 <ja...@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*


Re: OpenJPA 2.2.0 + Atomikos + Embedded Jetty

Posted by Rick Curtis <cu...@gmail.com>.
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 <ja...@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*