关于Play2和Hibernate的一些问题

时间:2014-09-08 13:02:56

标签: java hibernate jpa playframework-2.0

我是Hibernate4的初学者。我使用Hibernate 4.3.6 entitymanager配置了Play 2.2.4并编写了一个测试应用程序。所以,我有实体类Subject.java

package models.entities;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.Table;

import play.data.validation.Constraints;

@Entity
@Table(name="subjects")
public class Subject {

    @Id
    @Column(name="sub_pcode")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    @Column(name="sub_name")
    @Constraints.Required
    public String name;

    public int getId() {
        return id;
    }

    public Subject() {
        id = 0;
    }

    public void save() {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("testPU");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        if (id == 0) {
            em.persist(this);      
        } else {
            em.merge(this);
        }
        em.getTransaction().commit();
        em.close();     
    }

    public void delete() {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("testPU");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        Subject tmpSubject = em.find(Subject.class, id);
        if (tmpSubject != null) {
            em.remove(tmpSubject);      
        }
        em.getTransaction().commit();
        em.close();     
    }

    public static Subject get(int id) {
        Subject result;
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("testPU");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        result = em.find(Subject.class, id);      
        em.getTransaction().commit();
        em.close();
        return result;
    }

    @SuppressWarnings("unchecked")
    public static List<Subject> fetchAll() {
        List<Subject> result = new ArrayList<>();
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("testPU");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        Query q = em.createQuery("SELECT s FROM Subject s");
        result = q.getResultList();
        em.getTransaction().commit();
        em.close();
        return result;
    }
}

控制器类Application.java

package controllers;

import models.entities.Subject;
import play.mvc.Controller;
import play.mvc.Result;
import views.html.index;
import views.html.list;


public class Application extends Controller {

    public static Result index() {
        return ok(index.render("Your new application is ready."));
    }

    public static Result addSubject() {
        Subject s = new Subject();
        s.name = "test subject";
        s.save();
        return ok(list.render(Subject.fetchAll()));
    }

    public static Result deleteSubject(int id) {
        Subject s = Subject.get(id);
        if (null != s) {
            s.delete();
        }
        return ok(list.render(Subject.fetchAll()));
    }

    public static Result updateSubject(int id) {
        Subject s = Subject.get(id);
        if (null != s) {
            s.name = "new subject";
            s.save();
        }
        return ok(list.render(Subject.fetchAll()));
    }

}

我想要的只是问几个问题:

  1. 为什么我可以合并实体(在save()方法中)而不附加,但是 如果我想删除实体(通过delete()方法) - 我需要 首先查找实体或我有关于删除分离的例外 实体

  2. 似乎来自controller classess我可以使用JPA.em() @Transactional注释简化了hibernate的工作。是的吗? 使用hibernate事务和实体管理器的最简单方法 来自非控制人员classess?

  3. 如果我的代码风格不好,任何人都可以给我很好的策略建议 hibernate用法等等? 最好的祝福。感谢您的建议和解答。

1 个答案:

答案 0 :(得分:2)

  1. 每次都不应创建您的EntityManagerFactory emf。 EntityManagerFactory是线程安全的,您应该将其用作静态。如果每次演出都会下降,请创建它。
  2. 实体不应处理事务,它们仅用于反映数据库数据。使用实体的正确方法是在存储库/ DAO类中。
  3. 为什么在构造函数中执行id = 0;?默认值为0。
  4. 不要在Controller中打开事务。控制器应该只处理进入的项目和项目的内容。如果在其中添加事务,则会增加不必要的复杂性并增加代码的耦合。您可以使用模式OpenSessionInView,EJBs Components或Injection / AOP事务控制器。
  5. 要删除实体,您需要先附加它。您可以使用getReference方法:Entity justId = entityManager.getReference(Entity.class, ID)
  6. 看看这些有助于您了解JPA基础知识的材料:http://uaihebert.com/jpa-mini-book-first-steps-and-detailed-concepts/