2012-11-22 51 views
0

我有一种方法可以在EJB bean中保存新对象。调用此方法时没有错误,但数据库中没有任何更改。我不明白为什么。使用EJB3持久化不起作用

下面是代码:

@Stateless(name = "Ar", mappedName = "ManagementBean") 
public class ManagementBean implements IManagementBeanLocal, IManagementBeanRemote { 
... 
    @Override 
    public int storeRawSms(String raw, String requestUid, String text, String service, boolean correctlyAnalysed, Date receivedTimestamp, 
      boolean toBeAnalysed, String phoneNumber) { 

     // Get phone number, create if it dosn't exist 
     PhoneNumber pn = getOrCreatePhoneNumberPrivate(phoneNumber); 

     // Create rawSMS 
     RawSms rawSms = new RawSms(raw, requestUid, text, service, correctlyAnalysed, receivedTimestamp, toBeAnalysed, pn); 

     // Store and return result 
     em.persist(rawSms); 
     int result = rawSms.getId(); 

     em.flush(); 
     em.clear(); 

     return result; 
    } 

... 

,主叫方:

@PersistenceContext private EntityManager em; 
... 
int rawSmsIs = bean.storeRawSms(raw, requestUid, message, service, false, new Date(), true, sender); 

你有一个想法?

+1

你检查了生成的SQL吗?你能通过调试器中的方法吗? – kostja

+0

将代码添加到注入ManagementBean的位置以及调用方法的位置。另外你注入电子邮件 –

+3

顺便说一句。如果您使用的是事务范围的'EntityManager','flush'和'clear'方法是多余的。 – kostja

回答

-1

看来您的交易从来没有COMMITED,所以请尝试更改事务管理:

@Stateless(name = "Ar", mappedName = "ManagementBean") 
@TransactionManagement(TransactionManagementType.BEAN) 
public class ManagementBean implements IManagementBeanLocal, IManagementBeanRemote { 

     @Resource 
     private UserTransaction utx; 

     @Override 
     public int storeRawSms(..) { 

      try { 
        utx.begin(); 
        .. 
        em.persist(rawSms); 
        int result = rawSms.getId(); 
        utx.commit(); 
      } 
      catch(Exception ex) { 
        //EXCEPTION HANDLING 
        utx.rollback(); 
      } 
     } 
} 
+0

这将是一个很好的实验。如果这有效,那么问题就是容器管理的事务没有被提交。但是,对于一个真正的修复,我认为最好让容器管理的事务正常工作,而不是使用bean管理的事务。不应该有必要使用bean管理的事务,并且维护起来会更困难。 –

+1

我多次见过这种(错误)行为,这就是为什么我建议尝试“手动”事务管理。同意,长期倾向于容器管理的交易会更好。 –

+0

体验之声! –

0

我看到你在客户端注入到EntityManager的引用(不知道为什么),但我没有看到它在会话bean中(可能只是因为你没有在消息中包含该行)。是否有可能忘记在无状态会话bean中使用注解@PersistenceContext?另外,请注意:根据您使用的JPA实施方式和ID的生成策略,您应该在调用getId()之前调用flush(),然后再调用。事实上,如果让数据库生成您的ID,那么在该方法返回值之前,您需要使用flush()来执行此操作。

0

谢谢你,开发的解决方案工作!再次

@Stateless(name = "Ar", mappedName = "ManagementBean") 
@TransactionManagement(TransactionManagementType.CONTAINER) 
public class ManagementBean implements IManagementBeanLocal, IManagementBeanRemote { 
.... 
    @Override 
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    public int storeRawSms(String raw, String requestUid, String text, String service, boolean correctlyAnalysed, Date receivedTimestamp, boolean toBeAnalysed, String phoneNumber) { 
.... 

感谢:

我用的容器管理事务的这个样子!