em.merge()未保存到数据库

时间:2014-06-30 20:33:15

标签: java hibernate jpa

我有类似的实体..

@Entity
@Table(name = "FIRST_ENTITY")
class FirstEntity
{
private static final Long serialVersionUid=1L;
@Id
@GeneratedValue
private Long id;
@Column(name="MESSAGE",nullable=false)
private String message;
}

和这个dao类..

@Repository("myFirstDao")
class FirstDaoImpl implements FirstDao
{
@PersistenceContext(unitName="myUnit")
EntityManager em;

           public FirstEntity save(FirstEntity entity)
           {
           return em.merge(entity);
           }

}

和服务类。

@Service("myFirstService")
public class MyFirstServiceImpl implements MyFirstService
{
@Resource(name="myFirstDao")
MyFirstDao myFirstDao;

           public FirstEntity save(FirstEntity entity)
           {
           return myFirstDao.save(entity);
           }
}

注意:实体管理器是容器管理的。

当我试图在另一个服务类中做这样的事情时。

@Service("anotherService")
public class AnotherServiceImpl
{

@Resource(name="myFirstService")
FirstService firstService;

      public void myMeth()
      {
      FirstEntity f=new FirstEntity();
      f.setMessage("Hello");

      FirstEntity f1=firstService.save(f);

      System.out.println("The generated id is "+f1);

      }
}

这里,我获取了生成的id,但实体未存储到数据库中。 当我在FirstDaoImpl - save()

中尝试这样做时
em.getTransaction().begin();
em.save(entity);
em.getTransaction().commit();

我收到以下错误:Cannot call getTransaction() on a container managed bean

当我做这样的事情时......

em.save(entity);
em.flush();

我收到了,没有正在进行的交易错误。

我想知道,我怎么能解决它。提前致谢。希望你能尽快回复。

3 个答案:

答案 0 :(得分:3)

您应该使用声明式,而不是进行Programatic事务管理。所有这些意味着为您的服务添加另一个注释。我不确定您使用的是哪种框架,但如果您使用的是Spring,或者如果您使用的是EJB3,则可能@Transactional添加@TransactionAttribute(TransactionAttributeType.REQUIRED) 。执行此操作后,请取出以下行em.getTransaction().begin();em.getTransaction().commit();您的容器现在应该为您启动/停止交易。更容易!

答案 1 :(得分:1)

使用Spring声明式事务管理可能是一个很好的选择,Spring自行管理。还要检查事务边界,从哪里开始以及如何传播到Service / DAO层。

这可能对你有用

http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#tx-propagation

答案 2 :(得分:0)

我做了以下工作。所需要的只是指定事务管理器的名称。当发生类似“无bean命名的事务管理器”的错误时,很可能事务管理器将使用不同的名称命名。我之前没有注意到。

事务管理器在xml文件中定义,该文件是我正在使用的框架的一部分(它存档在jar文件中,因此我无法知道事务管理器bean名称)。对于该jar中提供的预定义类,未定义@Transactional

@Repository("myFirstDao")
@Transactional(value="myTransactionManager")
class FirstDaoImpl implements FirstDao
{
@PersistenceContext(unitName="myUnit")
EntityManager em;

           @Transactional(value="myTransactionManager")
           public FirstEntity save(FirstEntity entity)
           {
           return em.merge(entity);
           }

}

感谢 @exabrial @ ankur-singhal

的宝贵回复