2016-07-13 2 views
1

저는 SpringFramework를 사용하여 웹 애플리케이션을 구축하고 있습니다. 데이터 액세스 레이어에서 Hibernate를 사용하여 MySQL에서 데이터를 쿼리했습니다.이 데이터는 정상적으로 작동합니다.Hibernate와 JPA를 사용하여 EntityManagerFactory 빌드하기

@Bean 
public EntityManagerFactory entityManagerFactory() throws HibernateException { 
    return new org.hibernate.cfg.Configuration() 
      .configure()     
      .buildSessionFactory(); 
} 
: IMO I는 다음에 위의 코드를 변경해야,

public SessionFactory sessionFactory() throws HibernateException { 
    return new org.hibernate.cfg.Configuration() 
      .configure() 
      .buildSessionFactory(); 
} 

오늘은 EntityManagerFactory을 필요로 JPA, 내 데이터 액세스를 통합하는거야 : 내 SessionFactory이 방법에서 구축이다

SessionFactoryEntityManagerFactory으로 확장되기 때문입니다. 그러나 나는 예외를 가지고

java.lang.ClassCastException가 : org.hibernate.internal.SessionFactoryImpl이 캐스트 할 수없는 javax.persistence.EntityManagerFactory

SessionFactoryImplSessionFactory를 구현하기 때문에, 아주 이상한 SessionFactoryEntityManagerFactory까지 확장됩니다. 왜 캐스팅이 실패하는지 나는 모른다.

제 질문은 : 1. 캐스트가 유효하지 않은 이유는 무엇입니까? 2. Hibernate를 사용하여 EntityManagerFactory을 빌드하는 올바른 방법은 무엇입니까?

편집 디버거

factory instanceof SessionFactory   //true 
factory instanceof EntityManagerFactory //false 

나는 위의 모든 EntityManagerFactoryjavax.persistence.EntityManagerFactory을 의미 확신 SessionFactory

public interface SessionFactory extends EntityManagerFactory, HibernateEntityManagerFactory, Referenceable, Serializable, Closeable 

의 소스를 말한다.

+0

왜 그렇게 복잡한 이유가 있을까요? 왜 @PersistenceContext 어노테이션을 사용하여 bean에 entityManager를 주입하지 않습니까? – wallenborn

+0

@wallenborn Java (스프링 프레임 워크는 물론)를 처음 접했을 때 가장 좋은 방법이 무엇인지 알지 못합니다. 내 "오래된 코드"가'SessionFactory'를 제공하기 때문에, 나의 첫 번째 아이디어는 그것을 다시 사용하고있다. –

답변

0

Hmmn, Hibernate 5.2를 사용하지 않는 한, org.hibernate.SessionFactory는 javax.persistence.EntityManagerFactory를 확장하지 않으며, hibernate-entitymanager는 최근에야 hibernate-core로 병합되었습니다. 프로젝트에서 사용중인 버전보다 새로운 버전의 소스 코드를 탐색하고있는 것 같습니다.

JPA로 Hibernate를 사용하는 올바른 방법을 보려면 this link을 참조하십시오.

+0

나는'SessionFactory'가'javax.persistence.EntityManagerFactory'를 확장 했으므로'org.hibernate : hibernate-core : 5.2.1.Final'을 사용하고 있습니다. 그리고 내 프로젝트는'hibernate-core' 의존성 만 있고'hibernate-entitymanager'는 없습니다. –

+0

이 경우, 내 유일한 추측은 Hibernate가 CGLib에 의해 계측 된 클래스를 리턴한다는 것입니다. 반환 된 인스턴스를 인쇄하여 거기에서 디버깅을 시도 할 수 있습니다. 두 경우 모두 JPA에서 Hibernate를 사용하는 올바른 방법을 보려면 [이 링크] (https://docs.jboss.org/hibernate/orm/5.2/quickstart/html_single/#tutorial_jpa)를 참조하십시오. –

0

here 단계를 따라 Session Factory를 재사용하여 Spring에서 SessionFactory 빈을 설정할 수있다.

하지만 EntityManagerFactory에 관해 이미 코딩 했으므로 this tutorial에 설명 된 쉬운 경로를 따라야합니다. 불행히도 독일어로되어 있지만 코드 자체에 대해 설명해야합니다. 당신은 다음과 같이 명시 적으로 정의하거나 할 수는 JNDI 데이터 소스를 컨테이너에 정의 요청 될 수 있습니다 JPA 공급 업체, 공급 업체 및 데이터 소스와 다음의 EntityManagerFactory으로 최대 절전 모드를 선언 :

<jee:jndi-lookup id="dataSource" jndi-name="myDataSource"/> 

그리고 아주 좋다 @Transactional 주석을 허용하는 Spring transactionManager를 선언하여 명시 적 트랜잭션 관리를 처리 할 필요가 없습니다.

그런 다음 당신은 당신의 UserDAO은 다음과 같이 할 수 있습니다 : 사용자는하지만,이 작업을 수행하는 방법에는 여러 가지가있다

@Entity 
@NamedQueries({ @NamedQuery(name="User.findByName", query="select u from User where u.name = :name") }) 
public class User { 
    @Id 
    private Long id; 

    @Column 
    private String name; 
... 
} 

같은 일이

public class UserDAO { 
    @PersistenceContext 
    private EntityManager em; 

    @Transactional 
    public List<User> findUserByName(String name) { 
     return em.createNamedQuery("User.findByName") 
      .setParameter("name", name) 
      .getResultList(); 
    } 
} 

입니다.

관련 문제