Author: rmannibucau Date: Fri Mar 15 14:31:53 2013 New Revision: 1456967 URL: http://svn.apache.org/r1456967 Log: TOMEE-798 handling re-creation of queries object when not under a transaction to be sure the query uses the right em and then the context is correctly closed after the invocation
Added: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/QueryOperation.java tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/jpa/ tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/jpa/JTAPuAndBmtTest.java Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaQuery.java tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaTypedQuery.java tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/reflection/Reflections.java tomee/tomee/trunk/pom.xml Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java?rev=1456967&r1=1456966&r2=1456967&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java Fri Mar 15 14:31:53 2013 @@ -16,11 +16,11 @@ */ package org.apache.openejb.persistence; -import org.apache.openejb.BeanContext; -import org.apache.openejb.core.ThreadContext; +import org.apache.openejb.OpenEJBRuntimeException; import org.apache.openejb.core.ivm.IntraVmArtifact; import org.apache.openejb.util.LogCategory; import org.apache.openejb.util.Logger; +import org.apache.openejb.util.reflection.Reflections; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; @@ -35,6 +35,8 @@ import javax.persistence.criteria.Criter import javax.persistence.metamodel.Metamodel; import java.io.ObjectStreamException; import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -54,6 +56,15 @@ public class JtaEntityManager implements private static final Logger baseLogger = Logger.getInstance(LogCategory.OPENEJB.createChild("persistence"), JtaEntityManager.class); + private static final Method CREATE_NAMED_QUERY_FROM_NAME = Reflections.findMethod("createNamedQuery", EntityManager.class, String.class); + private static final Method CREATE_QUERY_FROM_NAME = Reflections.findMethod("createQuery", EntityManager.class, String.class); + private static final Method CREATE_NATIVE_FROM_NAME = Reflections.findMethod("createNativeQuery", EntityManager.class, String.class); + private static final Method CREATE_NAMED_QUERY_FROM_NAME_CLASS = Reflections.findMethod("createNamedQuery", EntityManager.class, String.class, Class.class); + private static final Method CREATE_QUERY_FROM_NAME_CLASS = Reflections.findMethod("createQuery", EntityManager.class, String.class, Class.class); + private static final Method CREATE_QUERY_FROM_CRITERIA = Reflections.findMethod("createQuery", EntityManager.class, CriteriaQuery.class); + private static final Method CREATE_NATIVE_FROM_NAME_CLASS = Reflections.findMethod("createNativeQuery", EntityManager.class, String.class, Class.class); + private static final Method CREATE_NATIVE_FROM_NAME_MAPPING = Reflections.findMethod("createNativeQuery", EntityManager.class, String.class, String.class); + private final JtaEntityManagerRegistry registry; private final EntityManagerFactory entityManagerFactory; private final Map properties; @@ -259,9 +270,7 @@ public class JtaEntityManager implements public Query createQuery(String qlString) { final Timer timer = Op.createQuery.start(this); try { - EntityManager entityManager = getEntityManager(); - Query query = entityManager.createQuery(qlString); - return proxyIfNoTx(entityManager, query); + return proxyIfNoTx(CREATE_QUERY_FROM_NAME, qlString); } finally { timer.stop(); } @@ -270,9 +279,7 @@ public class JtaEntityManager implements public Query createNamedQuery(String name) { final Timer timer = Op.createNamedQuery.start(this); try { - EntityManager entityManager = getEntityManager(); - Query query = entityManager.createNamedQuery(name); - return proxyIfNoTx(entityManager, query); + return proxyIfNoTx(CREATE_NAMED_QUERY_FROM_NAME, name); } finally { timer.stop(); } @@ -281,9 +288,7 @@ public class JtaEntityManager implements public Query createNativeQuery(String sqlString) { final Timer timer = Op.createNativeQuery.start(this); try { - EntityManager entityManager = getEntityManager(); - Query query = entityManager.createNativeQuery(sqlString); - return proxyIfNoTx(entityManager, query); + return proxyIfNoTx(CREATE_NATIVE_FROM_NAME, sqlString); } finally { timer.stop(); } @@ -292,9 +297,7 @@ public class JtaEntityManager implements public Query createNativeQuery(String sqlString, Class resultClass) { final Timer timer = Op.createNativeQuery.start(this); try { - EntityManager entityManager = getEntityManager(); - Query query = entityManager.createNativeQuery(sqlString, resultClass); - return proxyIfNoTx(entityManager, query); + return proxyIfNoTx(CREATE_NATIVE_FROM_NAME_CLASS, sqlString, resultClass); } finally { timer.stop(); } @@ -303,26 +306,38 @@ public class JtaEntityManager implements public Query createNativeQuery(String sqlString, String resultSetMapping) { final Timer timer = Op.createNativeQuery.start(this); try { - EntityManager entityManager = getEntityManager(); - Query query = entityManager.createNativeQuery(sqlString, resultSetMapping); - return proxyIfNoTx(entityManager, query); + return proxyIfNoTx(CREATE_NATIVE_FROM_NAME_MAPPING, sqlString, resultSetMapping); } finally { timer.stop(); } } - private Query proxyIfNoTx(EntityManager entityManager, Query query) { + private Query proxyIfNoTx(Method method, Object... args) { if (!extended && !isTransactionActive()) { - return new JtaQuery(entityManager, this, query); + return new JtaQuery(getEntityManager(), this, method, args); } - return query; + return createQuery(Query.class, getEntityManager(), method, args); } - private <T> TypedQuery<T> proxyIfNoTx(EntityManager entityManager, TypedQuery<T> query) { + private <T> TypedQuery<T> typedProxyIfNoTx(Method method, Object... args) { if (!extended && !isTransactionActive()) { - return new JtaTypedQuery<T>(entityManager, this, query); + return new JtaTypedQuery<T>(getEntityManager(), this, method, args); + } + return createQuery(TypedQuery.class, getEntityManager(), method, args); + } + + <T> T createQuery(final Class<T> expected, final EntityManager entityManager, final Method method, Object... args) { + try { + return expected.cast(method.invoke(entityManager, args)); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } catch (InvocationTargetException e) { + final Throwable t = e.getCause(); + if (RuntimeException.class.isInstance(t)) { + throw RuntimeException.class.cast(t); + } + throw new OpenEJBRuntimeException(t.getMessage(), t); } - return query; } public void joinTransaction() { @@ -356,9 +371,7 @@ public class JtaEntityManager implements public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) { final Timer timer = Op.createNamedQuery.start(this); try { - EntityManager entityManager = getEntityManager(); - TypedQuery<T> query = entityManager.createNamedQuery(name, resultClass); - return proxyIfNoTx(entityManager, query); + return typedProxyIfNoTx(CREATE_NAMED_QUERY_FROM_NAME_CLASS, name, resultClass); } finally { timer.stop(); } @@ -369,9 +382,7 @@ public class JtaEntityManager implements public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery) { final Timer timer = Op.createQuery.start(this); try { - EntityManager entityManager = getEntityManager(); - TypedQuery<T> query = entityManager.createQuery(criteriaQuery); - return proxyIfNoTx(entityManager, query); + return typedProxyIfNoTx(CREATE_QUERY_FROM_CRITERIA, criteriaQuery); } finally { timer.stop(); } @@ -382,9 +393,7 @@ public class JtaEntityManager implements public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass) { final Timer timer = Op.createQuery.start(this); try { - EntityManager entityManager = getEntityManager(); - TypedQuery<T> query = entityManager.createQuery(qlString, resultClass); - return proxyIfNoTx(entityManager, query); + return typedProxyIfNoTx(CREATE_QUERY_FROM_NAME_CLASS, qlString, resultClass); } finally { timer.stop(); } Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaQuery.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaQuery.java?rev=1456967&r1=1456966&r2=1456967&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaQuery.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaQuery.java Fri Mar 15 14:31:53 2013 @@ -22,7 +22,10 @@ import javax.persistence.LockModeType; import javax.persistence.Parameter; import javax.persistence.Query; import javax.persistence.TemporalType; +import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Calendar; +import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Map; @@ -33,22 +36,44 @@ import java.util.Set; * when the query is finished. This implementation is only for non-transaction queryies */ public class JtaQuery implements Query { - private final EntityManager entityManager; + private EntityManager entityManager; + private final Object[] args; + private final Method method; private final JtaEntityManager jtaEntityManager; - private final Query query; + private final Collection<QueryOperation> appliedOperations = new ArrayList<QueryOperation>(); - public JtaQuery(EntityManager entityManager, JtaEntityManager jtaEntityManager, Query query) { + private boolean underTx = false; + private Query query = null; + + public JtaQuery(EntityManager entityManager, JtaEntityManager jtaEntityManager, Method method, Object... args) { this.entityManager = entityManager; this.jtaEntityManager = jtaEntityManager; - this.query = query; + this.method = method; + this.args = args; + this.underTx = jtaEntityManager.isTransactionActive(); + createQuery(); + } + + private void createQuery() { + query = jtaEntityManager.createQuery(queryType(), entityManager, method, args); + if (!underTx) { + for (final QueryOperation op : appliedOperations) { + query = op.apply(query); + } + } + } + + protected Class<? extends Query> queryType() { + return Query.class; } private EntityManager getEntityManager() { - EntityManager em = entityManager; - if (!jtaEntityManager.isTransactionActive()) { - em = jtaEntityManager.getEntityManager(); + if (!underTx) { + entityManager = jtaEntityManager.getEntityManager(); + this.underTx = jtaEntityManager.isTransactionActive(); + createQuery(); } - return em; + return entityManager; } public List getResultList() { @@ -78,53 +103,133 @@ public class JtaQuery implements Query { } } - public Query setMaxResults(int i) { + public Query setMaxResults(final int i) { query.setMaxResults(i); + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setMaxResults(i); + } + }); + } return this; } - public Query setFirstResult(int i) { + public Query setFirstResult(final int i) { query.setFirstResult(i); + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setFirstResult(i); + } + }); + } return this; } - public Query setFlushMode(FlushModeType flushModeType) { + public Query setFlushMode(final FlushModeType flushModeType) { query.setFlushMode(flushModeType); + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setFlushMode(flushModeType); + } + }); + } return this; } - public Query setHint(String s, Object o) { + public Query setHint(final String s, final Object o) { query.setHint(s, o); + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setHint(s, o); + } + }); + } return this; } - public Query setParameter(String s, Object o) { + public Query setParameter(final String s, final Object o) { query.setParameter(s, o); + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setParameter(s, o); + } + }); + } return this; } - public Query setParameter(String s, Date date, TemporalType temporalType) { + public Query setParameter(final String s, final Date date, final TemporalType temporalType) { query.setParameter(s, date, temporalType); + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setParameter(s, date, temporalType); + } + }); + } return this; } - public Query setParameter(String s, Calendar calendar, TemporalType temporalType) { + public Query setParameter(final String s, final Calendar calendar, final TemporalType temporalType) { query.setParameter(s, calendar, temporalType); + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setParameter(s, calendar, temporalType); + } + }); + } return this; } - public Query setParameter(int i, Object o) { + public Query setParameter(final int i, final Object o) { query.setParameter(i, o); + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setParameter(i, o); + } + }); + } return this; } - public Query setParameter(int i, Date date, TemporalType temporalType) { + public Query setParameter(final int i, final Date date, final TemporalType temporalType) { query.setParameter(i, date, temporalType); + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setParameter(i, date, temporalType); + } + }); + } return this; } - public Query setParameter(int i, Calendar calendar, TemporalType temporalType) { + public Query setParameter(final int i, final Calendar calendar, final TemporalType temporalType) { query.setParameter(i, calendar, temporalType); + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setParameter(i, calendar, temporalType); + } + }); + } return this; } @@ -230,28 +335,60 @@ public class JtaQuery implements Query { /* (non-Javadoc) * @see javax.persistence.Query#setLockMode(javax.persistence.LockModeType) */ - public Query setLockMode(LockModeType lockMode) { + public Query setLockMode(final LockModeType lockMode) { + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setLockMode(lockMode); + } + }); + } return query.setLockMode(lockMode); } /* (non-Javadoc) * @see javax.persistence.Query#setParameter(javax.persistence.Parameter, java.lang.Object) */ - public <T> Query setParameter(Parameter<T> param, T value) { + public <T> Query setParameter(final Parameter<T> param, final T value) { + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setParameter(param, value); + } + }); + } return query.setParameter(param, value); } /* (non-Javadoc) * @see javax.persistence.Query#setParameter(javax.persistence.Parameter, java.util.Calendar, javax.persistence.TemporalType) */ - public Query setParameter(Parameter<Calendar> param, Calendar value, TemporalType temporalType) { + public Query setParameter(final Parameter<Calendar> param, final Calendar value, final TemporalType temporalType) { + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setParameter(param, value, temporalType); + } + }); + } return query.setParameter(param, value, temporalType); } /* (non-Javadoc) * @see javax.persistence.Query#setParameter(javax.persistence.Parameter, java.util.Date, javax.persistence.TemporalType) */ - public Query setParameter(Parameter<Date> param, Date value, TemporalType temporalType) { + public Query setParameter(final Parameter<Date> param, final Date value, final TemporalType temporalType) { + if (!underTx) { + appliedOperations.add(new QueryOperation() { + @Override + public Query apply(final Query query) { + return query.setParameter(param, value, temporalType); + } + }); + } return query.setParameter(param, value, temporalType); } Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaTypedQuery.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaTypedQuery.java?rev=1456967&r1=1456966&r2=1456967&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaTypedQuery.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaTypedQuery.java Fri Mar 15 14:31:53 2013 @@ -23,6 +23,7 @@ import javax.persistence.Parameter; import javax.persistence.Query; import javax.persistence.TemporalType; import javax.persistence.TypedQuery; +import java.lang.reflect.Method; import java.util.Calendar; import java.util.Date; import java.util.List; @@ -33,8 +34,13 @@ import java.util.List; */ public class JtaTypedQuery<X> extends JtaQuery implements TypedQuery<X> { - public JtaTypedQuery(EntityManager entityManager, JtaEntityManager jtaEm, Query query) { - super(entityManager, jtaEm, query); + public JtaTypedQuery(EntityManager entityManager, JtaEntityManager jtaEm, Method method, Object... args) { + super(entityManager, jtaEm, method, args); + } + + @Override + protected Class<? extends Query> queryType() { + return TypedQuery.class; } @SuppressWarnings("unchecked") @@ -56,7 +62,7 @@ public class JtaTypedQuery<X> extends Jt } @Override - public TypedQuery<X> setFlushMode(FlushModeType flushModeType) { + public TypedQuery<X> setFlushMode(final FlushModeType flushModeType) { super.setFlushMode(flushModeType); return this; } Added: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/QueryOperation.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/QueryOperation.java?rev=1456967&view=auto ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/QueryOperation.java (added) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/persistence/QueryOperation.java Fri Mar 15 14:31:53 2013 @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.openejb.persistence; + +import javax.persistence.Query; + +public interface QueryOperation { + Query apply(final Query query); +} Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/reflection/Reflections.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/reflection/Reflections.java?rev=1456967&r1=1456966&r2=1456967&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/reflection/Reflections.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/reflection/Reflections.java Fri Mar 15 14:31:53 2013 @@ -26,6 +26,14 @@ public final class Reflections { // no-op } + public static Method findMethod(final String name, final Class<?> type, final Class<?>... args) { + try { + return type.getMethod(name, args); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException("Can't find public method " + name + " in " + type.getName()); + } + } + public static Object invokeByReflection(final Object obj, final String mtdName, final Class<?>[] paramTypes, final Object[] args) { Class<?> clazz = obj.getClass(); while (clazz != null) { Added: tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/jpa/JTAPuAndBmtTest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/jpa/JTAPuAndBmtTest.java?rev=1456967&view=auto ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/jpa/JTAPuAndBmtTest.java (added) +++ tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/jpa/JTAPuAndBmtTest.java Fri Mar 15 14:31:53 2013 @@ -0,0 +1,141 @@ +package org.apache.openejb.jpa; + +import org.apache.openejb.jee.Empty; +import org.apache.openejb.jee.StatelessBean; +import org.apache.openejb.jee.jpa.unit.Persistence; +import org.apache.openejb.jee.jpa.unit.PersistenceUnit; +import org.apache.openejb.junit.ApplicationComposer; +import org.apache.openejb.testing.Configuration; +import org.apache.openejb.testing.Module; +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.annotation.Resource; +import javax.ejb.EJB; +import javax.ejb.EJBContext; +import javax.ejb.LocalBean; +import javax.ejb.Stateless; +import javax.ejb.TransactionManagement; +import javax.ejb.TransactionManagementType; +import javax.persistence.Entity; +import javax.persistence.EntityManager; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import java.util.List; +import java.util.Properties; + +import static org.junit.Assert.assertNotNull; + +@RunWith(ApplicationComposer.class) +public class JTAPuAndBmtTest { + @EJB + private BmtManager bmtManager; + + @Configuration + public Properties config() { + final Properties p = new Properties(); + p.put("JTAPuAndBmtTest", "new://Resource?type=DataSource"); + p.put("JTAPuAndBmtTest.JdbcDriver", "org.hsqldb.jdbcDriver"); + p.put("JTAPuAndBmtTest.JdbcUrl", "jdbc:hsqldb:mem:bval"); + return p; + } + + @Module + public StatelessBean app() throws Exception { + final StatelessBean bean = new StatelessBean(BmtManager.class); + bean.setLocalBean(new Empty()); + return bean; + } + + @Module + public Persistence persistence() { + final PersistenceUnit unit = new PersistenceUnit("foo-unit"); + unit.addClass(TheEntity.class); + unit.setProperty("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)"); + unit.getProperties().setProperty("openjpa.RuntimeUnenhancedClasses", "supported"); + unit.setExcludeUnlistedClasses(true); + + final Persistence persistence = new Persistence(unit); + persistence.setVersion("2.0"); + return persistence; + } + + @LocalBean + @Stateless + @TransactionManagement(TransactionManagementType.BEAN) + public static class BmtManager { + @PersistenceContext + private EntityManager em; + + @Resource + private EJBContext ctx; + + public TheEntity persist() { + try { + ctx.getUserTransaction().begin(); + final TheEntity entity = new TheEntity(); + entity.setName("name"); + em.persist(entity); + ctx.getUserTransaction().commit(); + return entity; + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + + public TheEntity findWithJpQl() { + final TypedQuery<TheEntity> query = em.createQuery("select e from JTAPuAndBmtTest$TheEntity e", TheEntity.class); + query.getResultList(); // to ensure we don't break OPENEJB-1443 + return query.getResultList().iterator().next(); + } + + public void update(final TheEntity entity) { + entity.setName("new"); + try { + ctx.getUserTransaction().begin(); + em.merge(entity); + ctx.getUserTransaction().commit(); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + } + + @Entity + public static class TheEntity { + @Id + @GeneratedValue + private long id; + private String name; + + public long getId() { + return id; + } + + public void setId(long i) { + id = i; + } + + public String getName() { + return name; + } + + public void setName(String n) { + name = n; + } + } + + @Test + public void valid() { + assertNotNull(bmtManager.persist()); + + final TheEntity entity = bmtManager.findWithJpQl(); + assertNotNull(entity); + + bmtManager.update(entity); // will throw an exception if any error + } +} Modified: tomee/tomee/trunk/pom.xml URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/pom.xml?rev=1456967&r1=1456966&r2=1456967&view=diff ============================================================================== --- tomee/tomee/trunk/pom.xml (original) +++ tomee/tomee/trunk/pom.xml Fri Mar 15 14:31:53 2013 @@ -97,7 +97,7 @@ <maven-bundle-plugin.version>2.3.7</maven-bundle-plugin.version> <!-- This is used by a manifest classpath entry --> - <xbeanVersion>3.13-SNAPSHOT</xbeanVersion> + <xbeanVersion>3.13</xbeanVersion> <!-- OSGi bundles properties --> <openejb.bundle.activator/>