使用@Transactional保持JPA不起作用

时间:2016-07-16 16:03:41

标签: hibernate jpa jersey transactional

我使用Jersey作为WebService和Hibernate EntityManager来保存我的数据......

如果我这样编写我的方法,持久性将正常工作:

@GET
@Path("/")
public Response test() {

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1");
    EntityManager em = emf.createEntityManager();

    Test product = new Test("desc");

    em.getTransaction().begin();
    if (!em.contains(product)) {
        em.persist(product);
        em.flush();
    }
    em.getTransaction().commit();

    em.close();
    emf.close();

    return Response.status(Response.Status.OK).build();
}

但是,我想使用com.google.inject.persist.Transactional中的@Transactional来使代码更轻松:

@GET
@Transactional
@Path("/")
public Response test() {

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1");
    EntityManager em = emf.createEntityManager();

    Test product = new Test("desc");
        em.persist(product);

    em.close();
    emf.close();

    return Response.status(Response.Status.OK).build();
}

但是使用此代码时,数据不会记录到数据库中!

任何想法

1 个答案:

答案 0 :(得分:1)

在您缺少的代码中

em.flush();

还有两个建议:

1)让Guice管理实体经理。注入它,不要自己创建EntityManager实例。

public class ProductDao {

  @Inject
  private EntityManager em;

  public Product find(Long id) {
      return em.find(Product.class, id);
  }

  @Transactional
  public void save(Product entity) {
      em.persist(entity);
  }

}

注意:我不熟悉Guice,但我知道Spring。

2)使用分层设计。将应用程序代码分成控制器,域,服务和持久层。

持久层用于访问数据。将使用EntityManager方法的所有类移动到持久性(数据访问)层。

服务层用于控制交易。

域层用于实体和特定于实体的业务逻辑。

控制器层用于请求映射和编组。在这里使用请求映射注释@Get,@ Path(“/”)。