Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa 为什么交易可以';t在带有@REQUIRES\u新注释的自调用ejb方法中提交_Jpa_Ejb_Java Ee 6_Jta_Jboss6.x - Fatal编程技术网

Jpa 为什么交易可以';t在带有@REQUIRES\u新注释的自调用ejb方法中提交

Jpa 为什么交易可以';t在带有@REQUIRES\u新注释的自调用ejb方法中提交,jpa,ejb,java-ee-6,jta,jboss6.x,Jpa,Ejb,Java Ee 6,Jta,Jboss6.x,首先,我想解释在这种情况下我的自调用ejb方法。我有一个有状态会话bean,它有一个启动新事务的方法(由@REQUIRES\u new注释)。为了在bean内部调用此方法并使注释有效,我使用SessionContext#getBusinessObject()来实现@EJB的效果(@EJB这里导致堆栈溢出?!)。我的代码如下所示: @Stateful @Local public class TransactionTest implements ITransactionTest { @Pers

首先,我想解释在这种情况下我的自调用ejb方法。我有一个有状态会话bean,它有一个启动新事务的方法(由
@REQUIRES\u new
注释)。为了在bean内部调用此方法并使注释有效,我使用
SessionContext#getBusinessObject()
来实现
@EJB
的效果(
@EJB
这里导致堆栈溢出?!
)。我的代码如下所示:

@Stateful
@Local
public class TransactionTest implements ITransactionTest {

  @PersistenceContext(unitName="Table",Type=PersistenceContextType.EXTENDED)

  private EntityManager manager;

  @Resource
  SessionContext sc;

  ITransactionTest me;

  @PostConstruct
  public void init(){
    me = this.sc.getBusinessObject(ITransactionTest.class);
  }

  public void generateRecord(int i) throws RuntimeException{
    Record record = new Record();
    record.setId(i+"");
    record.status(1);
    manager.persist(record);
    manager.flush();  //If not flush, result is correct. Why? 
    me.updateRecord(i);
  }

  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public void updateRecord(int i) throws RuntimeException{
    try {
      Record record = manager.find(Record.class, i+"");
      record.setStatus(2);
      manager.flush();
    } catch(Exception e) {
      e.printStackTrace();
      throw new RuntimeException();
    }
  }
}
而,
generateRecord()
运行正常。控制台显示它毫无例外地执行“插入”和“更新”HQL(我使用Hibernate作为JPA提供程序)。但是,“更新”结果不会出现在数据库中为什么?
updateRecord()是否正确提交?

此外,我还尝试了两种替代方法:第一种是在另一个bean中连续调用
generateRecord()
(它将不再调用
updateRecord()
)和
updateRecord()
。它可以给我正确的结果

第二个是删除第一个
flush()
。然后,将在第二次
flush()
时执行“插入”和“更新”HQL。这种方法也能产生正确的结果

我的程序在JBOSS 6.1.0-Final下运行,数据库是Oracle

致以最良好的祝愿


Kajelas

我觉得你的设置很奇怪-你为什么要用SessionContext做这些事情?首先,如果您使用的是JEE6,那么本地EJB的接口就没有用了。第二,对EJB的每个调用都自动包装在一个事务中,如果成功完成,将提交。第三,如果您使用托管实体,则无需进行刷新,因为所有方法都使用同一个实体管理器,并且在完成调用后,其他方法也可以使用同一个实体管理器。最后,您应该始终能够从create方法调用update方法,而无需任何样板代码。谢谢您的建议!首先,您的意思是我应该使用JNDI查找方法来获取本地EJB吗?它是否与我的代码有任何性能差异?关于你的其他观点,我理解你所说的,并且我在一开始就按照你的建议做了。然而,它没有起作用。e、 我的ejb方法已成功完成,但我的数据库没有任何问题。所以我修改了我的代码。因此,我希望知道我的代码中是否有遗漏或完全错误的地方?不,您不需要摆弄JNDI-在JEE6中,您有EJB3.1,并且您不需要为您的EJB提供任何接口,所有公共方法都可以由其他本地EJB自动访问。如果您需要获得对另一个EJB的引用,只需注释@Inject就可以了。关于性能,这样您就不必通过网络堆栈返回到您自己的应用程序但是在您的情况下,不需要所有这些,因为您在一个EJB中工作,那么为什么您要尝试获取对您自己的引用呢?您可以使用自己的对象。啊,我必须说我需要自引用,因为我希望使用
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
注释来启动新事务。如果该方法不作为EJB方法调用,则无法工作。