Hibernate: Как настроить EntityManager в Hibernate? - PullRequest
6 голосов
/ 19 сентября 2011

Я создаю проект гибернации с «инструментами гибернации», предоставленными JBoss для Eclipse.Сгенерированные сущности (POJO), а затем DAO.

Например, таким образом:

@Entity
@Table(name = "area", catalog = "project_schema", uniqueConstraints = @UniqueConstraint(columnNames = "area"))
public class Area implements java.io.Serializable {

    private Integer id;
    private String area;

    public Area() {
    }

    public Area(String area) {
        this.area = area;
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name = "area", unique = true, nullable = false, length = 45)
    public String getArea() {
        return this.area;
    }

    public void setArea(String area) {
        this.area = area;
    }

}

И затем соответствующий класс DAO (также сгенерированный Hibernate Tools):

@Stateless
public class AreaHome {

    private static final Log log = LogFactory.getLog(AreaHome.class);

    @PersistenceContext
    private EntityManager entityManager;

    public void persist(Area transientInstance) {
        log.debug("persisting Area instance");
        try {
            entityManager.persist(transientInstance);
            log.debug("persist successful");
        } catch (RuntimeException re) {
            log.error("persist failed", re);
            throw re;
        }
    }

    public void remove(Area persistentInstance) {
        log.debug("removing Area instance");
        try {
            entityManager.remove(persistentInstance);
            log.debug("remove successful");
        } catch (RuntimeException re) {
            log.error("remove failed", re);
            throw re;
        }
    }

    public Area merge(Area detachedInstance) {
        log.debug("merging Area instance");
        try {
            Area result = entityManager.merge(detachedInstance);
            log.debug("merge successful");
            return result;
        } catch (RuntimeException re) {
            log.error("merge failed", re);
            throw re;
        }
    }

    public Area findById(Integer id) {
        log.debug("getting Area instance with id: " + id);
        try {
            Area instance = entityManager.find(Area.class, id);
            log.debug("get successful");
            return instance;
        } catch (RuntimeException re) {
            log.error("get failed", re);
            throw re;
        }
    }
}

Но когда я пытаюсь вызвать AreaHome.persist(), запускается исключение 'NullPointerException'.

Я настраиваю свой проект с помощью hibernate.cfg.xml и все работает нормально:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password"><password></property>
        <property name="hibernate.connection.url">jdbc:mysql://<hostname>:3306/<schema></property>
        <property name="hibernate.connection.username">root</property>
        <!-- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- SQL -->
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.show_sql">true</property>
        <!-- C3P0 -->
        <property name="hibernate.c3p0.acquire_increment">2</property>
        <property name="hibernate.c3p0.max_size">20</property>
        <property name="hibernate.c3p0.min_size">5</property>
        <property name="hibernate.c3p0.timeout">180</property>
        <property name="hibernate.c3p0.idle_test_period">100</property>
        <!-- Classes -->
        <mapping class="com.suaparte.pojo.Area" />
    </session-factory>
</hibernate-configuration>

Это прекрасно работает, когда я пытаюсь:

public void persist(Area area) throws ExceptionHandler {
    Session session = HibernateUtil.getSessionFactory().openSession();
    try {
        session.beginTransaction();
        session.save(area);
        session.getTransaction().commit();
    } catch (HibernateException he) {
        session.getTransaction().rollback();

        throw new ExceptionHandler(he.getCause());
    } finally {
        if (session != null) {
            session.close();
        }
    }

}

Но я хочу использовать DAO, сгенерированные Hibernate Tools, потому что они имеют EntityManager (который должен быть введен, но не случайно).

Что мне делать?Любая идея ?Извините за длинный вопрос, но я хочу быть очень ясным в своей проблеме.

1 Ответ

3 голосов
/ 01 апреля 2013

Фактически вам необходимо реализовать EntityManagerFactory.

Создать файл persistence.xml, который находится в папке META-INF.

Взгляните на пример

http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html_single/#setup-configuration-packaging

после команд для создания EntityManagerFactory и EntityManager затем:

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("JavaStackOver");
EntityManager entityManager = entityManagerFactory.createEntityManager();

Для разрешения зависимостей я использовал maven:

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>4.0.1.Final</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-entitymanager</artifactId>
  <version>4.0.1.Final</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-annotations</artifactId>
  <version>3.5.6-Final</version>
</dependency>

Inject на вашем Dao JPAи готово!

Преимущество работы с EntityManager заключается в возможности изменять Hibernate в futuro.В противном случае можно использовать сеанс.

...