2010-04-10 3 views
5

이상한 오류 메시지가 표시되며 문제의 원인에 대한 몇 가지 아이디어를 찾고 있습니다. 나는 JPA를 처음 사용하는 사람이다.브레인 스토밍 : 이상한 JPA 문제, 아마도 classpath 또는 jar 버전 문제입니까?

Spring의 Entity Manager Factory (LocalContainerEntityManagerFactoryBean), ORM 공급자 인 EclipseLink, MySQL DB에 연결되어 있고 Maven으로 빌드 된 애플리케이션이 있습니다. 이 문제가 있으면 확실하지 않습니다 .....

이 응용 프로그램을 Glassfish에 배포하면 응용 프로그램이 예상대로 작동합니다.

문제는 GlassFish 외부에서 올바르게 작동하지 않는 독립 실행 형 단위 테스트 세트를 만들었 기 때문입니다. 나는 다음과 같은 오류

com.xyz.abc.services.persistence.entity.MyEntity cannot be cast to com.xyz.abc.services.persistence.entity.MyEntity 

개체가 동일한 유형의 클래스에 캐스트 할 수없는 (I 클래스 이름 좀을 편집 한 )를 얻을? 어떻게 그렇게 될수 있니?

CriteriaQuery cq = entityManager.getCriteriaBuilder().createQuery(); 
cq.select(cq.from(com.xyz.abc.services.persistence.entity.MyEntity.class)); 
List entityObjects = entityManager.createQuery(cq).getResultList(); 
for (Object entityObject: entityObjects) { 
    com.xyz.abc.services.persistence.entity.MyEntity entity = (com.xyz.abc.services.persistence.entity.MyEntity) entityObject; 

이 코드는 질문은 내가 가지고있는 것과 같은 것입니다 : 여기

내가 같은 오류가 발생이 코드를했다

Query q = entityManager.createNamedQuery("MyEntity.findAll"); 
List entityObjects = q.getResultList(); 
for (Object entityObject: entityObjects) { 
    com.xyz.abc.services.persistence.entity.MyEntity entity = (com.xyz.abc.services.persistence.entity.MyEntity) entityObject; 

이전에 오류가 코드의 조각이다 서버에 배포됩니다. 그것은 내가 테스트에 사용하고 있습니다 것보다 다른 글래스 피시에서 내가 사용하고 어떤 병이 있다고 추측하고있어

Caused by: java.lang.ClassCastException: com.xyz.abc.services.persistence.entity.MyEntity cannot be cast to com.xyz.abc.services.persistence.entity.MyEntity 
    at com.xyz.abc.services.persistence.entity.factory.MyEntityFactory.createBeans(MyEntityFactory.java:47) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:115) 
    ... 37 more 

을 도움이된다면

다음은 가장 안쪽의 예외입니다. 나는 내가 "제공 한"것으로 나열한 모든 항아리를 보았으며 그들이 글래스 피시와 똑같은 것이라 확신한다.

이전에 이상한 문제가 발생했는지 또는 해결을위한 아이디어를 알려주십시오.

답변

5

이것은 또한 클래스 로딩 문제 일 수 있습니다. 두 개의 다른 클래스 로더에 의해로드 된 동일한 클래스 정의는 JVM에 의해 다른 클래스로 간주됩니다.

당신은 게임의 클래스 로더에 대한 정보를 얻기 위해이 시도 할 수 :

Query q = entityManager.createNamedQuery("MyEntity.findAll"); 
List entityObjects = q.getResultList(); 

ClassLoader loader1 = 
    com.xyz.abc.services.persistence.entity.MyEntity.getClass().getClassLoader(); 
System.out.println("MyEntity's class loader is " + loader1); 
for (Object entityObject: entityObjects) { 
    ClassLoader loader2 = entityObject.getClass().getClassLoader(); 
    System.out.println("Class loader of entity " + entityObject + " is " + loader2); 
} 

대신 System.out.println은 물론 사용이 선호하는 로깅 프레임 워크를 호출 할 수있다.

여기에 클래스 로딩에 대한 세부 정보가있는 a series of articles입니다.

+0

예 확인해 보니 문제가되는 것 같습니다. 여기 출력은 다음과 같습니다 MyEntity의 클래스 로더입니다 [email protected] MyEntity 개체의 클래스 로더입니다 org.springfr[email protected]16089a5 지금 어떻게 그것을 해결하기 위해 ??? 내가 링크 한 기사를 파헤쳐 보겠습니다. – Vinnie

+1

@Vinnie 불행히도 저는 여러분이 사용하는 도구에 익숙하지 않아보다 구체적인 도움을 드릴 수 없습니다. 행운을 빌어 요 - 당신은 그것을 필요로 할 것입니다 ... –

+1

이것은 신참 실수 일지 모르지만 제안 (그리고 다른 Classloader를 로컬로 사용하는 것에 대한 계시)은 실행 가능한 솔루션으로 이어졌습니다. 다른 Classloader가 있다는 것을 알게되면 Spring의 LocalContainerEntityManagerFactoryBean이 유닛 테스트 중에 올바른 선택이 아니라고 생각했습니다. LocalEntityManagerFactoryBean (DataSource를 삽입 할 수 없기 때문에 새로운 퍼시스턴스 유닛이 필요하다는 것을 의미 함)로 바뀌 었습니다. 이제는 로컬에서 작업하는 것처럼 보입니다. 도와 주셔서 감사합니다! – Vinnie

1

이것은 분명히 ClassLoader 호의 냄새를 풍깁니다 (EclipseLink에서 필요로하는 직조물 때문일 수 있습니다). LoadTimeWeaver을 사용합니까? javaagent 항목을 구성 했습니까? 문제가 Maven 아래의 명령 줄에서 발생합니까? IDE에서? 명확히하십시오.

+0

직조에 대한 좋은 지적이 질문에 언급했다. 글래스 피쉬에서는 org.springframework.context.weaving.DefaultContextLoadTimeWeaver를, 테스트에서는 org.springframework.instrument.classloading.SimpleLoadTimeWeaver를 사용하고 있습니다. 어느 것을 사용해야할지 모르겠으므로 방금 작동하는 것으로 선택했습니다. – Vinnie

+0

BTW - javaagent가 구성되어 있지 않습니다. 그리고 문제는 IDE의 maven 커맨드 라인에서도 발생합니다. 글래스 피시 서버는 문제가없는 유일한 영역입니다. – Vinnie

관련 문제