问题描述
我陷入困难的局面一会儿。问题是:我必须使用NativeQuery在JTA上下文(EJB)中删除和/或更新某些DB记录。
我的JPA persistence.xml看起来像:
< persistence-unit name =OzsscJPANBPUtransaction-类型= JTA >
< provider> org.eclipse.persistence.jpa.PersistenceProvider< / provider>
< jta-data-source> jdbc / postgres_ozssc< / jta-data-source>
< mapping-file> com / longz / ozssc / model / PostcodeEntity.xml< / mapping-file>
< class> com.longz.ozssc.model.CustomerEntity< / class>
...
如果我以这种方式使用delete语句: p>
@Override
public void remove(SmsdOutboxEntity toberemoved){
em.createNativeQuery(从发件箱中删除其中\\ \\ID\=+ toberemoved.getId())。executeUpdate();
抛出TransactionRequiredException:
根本原因
javax.persistence.TransactionRequiredException:
异常说明:当前没有活动活动
这样没有交易存在。
如果我们手动使用交易:
@Override
public void remove(SmsdOutboxEntity toberemoved){
em.getTransaction()。
em.createNativeQuery(从发件箱中删除\ID\=+ toberemoved.getId())。executeUpdate();
/*em.flush();*/
em.getTransaction()。commit();
抛出IllegalStateException:
根本原因
javax.ejb.EJBException:EJB异常:;嵌套异常是:
java.lang.IllegalStateException:方法public abstract javax.persistence.EntityTransaction javax.persistence.EntityManager.getTransaction()不能在JTA EntityManager的上下文中调用。
似乎我不能手动使用交易,因为JTA将管理交易自己。
所以我的问题是:如何使用Native Query删除/更新JTA管理上下文中的记录?
请指教
对于JTA,事务由容器提供,您不应该自己创建。要在JTA中获取交易,您必须以资源的形式访问它:
@Resource public UserTransaction utx;
@Resource public EntityManagerFactory工厂;
@Override
public void remove(SmsdOutboxEntity toberemoved){
EntityManager em = factory.createEntityManager();
尝试{
em.createNativeQuery(从发件箱中删除其中\ID\=+ toberemoved.getId())。executeUpdate();
utx.commit();
catch(RuntimeException e){
if(utx!= null)utx.rollback();
throw e; //或显示错误消息
}
finally {
em.close();
}
如果要省略您提交/回滚交易的部分你自己,你需要让你的事务管理一些容器如EJB3。为此,您可以使用无状态/状态ejb bean。
更新:
对于WebLogic,请尝试使用其用户,而不是 javax.transaction.UserTransaction 一>。正如该文档所示:
I was stuck in very hard situation for a moment.
The problem is: I have to use NativeQuery to delete and/or update some DB records in a JTA context (EJB).
my JPA persistence.xml looks like:
<persistence-unit name="OzsscJPANBPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/postgres_ozssc</jta-data-source>
<mapping-file>com/longz/ozssc/model/PostcodeEntity.xml</mapping-file>
<class>com.longz.ozssc.model.CustomerEntity</class>
......
If I use delete statement in this way:
@Override
public void remove(SmsdOutboxEntity toberemoved){
em.createNativeQuery("Delete from outbox where \"ID\" = " + toberemoved.getId()).executeUpdate();
TransactionRequiredException thrown:
root cause
javax.persistence.TransactionRequiredException:
Exception Description: No transaction is currently active
Such there is no transaction existing.
If we use transaction manually as:
@Override
public void remove(SmsdOutboxEntity toberemoved){
em.getTransaction().begin();
em.createNativeQuery("Delete from outbox where \"ID\" = " + toberemoved.getId()).executeUpdate();
/*em.flush();*/
em.getTransaction().commit();
IllegalStateException thrown:
root cause
javax.ejb.EJBException: EJB Exception: ; nested exception is:
java.lang.IllegalStateException: The method public abstract javax.persistence.EntityTransaction javax.persistence.EntityManager.getTransaction() cannot be invoked in the context of a JTA EntityManager.
Seems I can't use transaction manually, as JTA will manage transaction their self.
So my question is: How I can use Native Query to delete/update records in a JTA managed context?
Please advise.
For JTA the transaction is provided by the container and you should not create it by yourself. To obtain the transaction in JTA, you have to access it as a resource:
@Resource public UserTransaction utx;
@Resource public EntityManagerFactory factory;
@Override
public void remove(SmsdOutboxEntity toberemoved){
EntityManager em = factory.createEntityManager();
try {
em.createNativeQuery("Delete from outbox where \"ID\" = " + toberemoved.getId()).executeUpdate();
utx.commit();
catch (RuntimeException e) {
if (utx != null) utx.rollback();
throw e; // or display error message
}
finally {
em.close();
}
If you want to omit the part where you have commit/rollback the transaction by yourself, you need to have your transaction managed by some container like EJB3. For that you can use stateless/stateful ejb beans.
UPDATE:
For WebLogic, try to use its user weblogic.transaction.UserTransaction instead of javax.transaction.UserTransaction. As the doc says:
这篇关于使用Nativequery删除/更新JTA中的记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!