2011-12-18 2 views
2

엔티티 개체를 데이터베이스에서 분리하여 관리되지 않게해야합니다. 필자는 EntityManager.detach() 메소드가 필요한 바로 하나 인 EclipseLink Persistence Provider를 사용한다. 문제는 (실행이 분리 통과 할 때()) JBoss의 예외 다음 실행시에 발생한다는 것입니다 : 잘 작동을 발견, 병합, 계속 같은엔티티를 분리하는 방법 (JPA 2.0/EclipseLink/JBoss)

javax.ejb.EJBTransactionRolledbackException: Unexpected Error 
java.lang.NoSuchMethodError: javax.persistence.EntityManager.detach(Ljava/lang/Object;)V 

다른 방법. 나는 Hibernate를 시도했고 그것의 Session이 엔티티를 분리하는 특별한 메소드 evict()를 제공한다는 것을 알고 있지만, EclipseLink는 그러한 메소드를 가지고 있지 않다. 분리()를 사용하는 예 :

@PersistenceContext(unitName="Course7-ejbPU") 
protected EntityManager manager; 
(...) 
Query query; 
List<Message> resultList; 
query = manager.createNamedQuery("Message.getUserInputMessageList"); 
query.setParameter("login", login); 
query.setMaxResults(5); 
resultList = query.getResultList(); 
for (Message message : resultList) 
    if (message.getContent().length() > 50) 
    { 
     manager.detach(message);    
     message.setContent(message.getContent().substring(0, 50) + "..."); 
    } 

의 persistence.xml : 제공자 데이터

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
    <persistence-unit name="Course7-ejbPU" transaction-type="JTA"> 
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
    <jta-data-source>java:/Course7ds</jta-data-source> 
    <exclude-unlisted-classes>false</exclude-unlisted-classes> 
    <properties> 
     <property name="eclipselink.target-server" value="JBoss"/> 
    </properties> 
    </persistence-unit> 
</persistence> 

도서관은 귀 아카이브에 포함되어 있습니다. EclipseLink 버전은 2.2.0 (테스트 된 2.3.2 - 차이 없음), JBoss 서버 버전 5.1.0입니다. 모든 제안을 주시면 감사하겠습니다.

답변

3

이 예외는 사용자가 JPA2가 아니라 JPA1을 사용하고 있음을 보여줍니다. JPA2와 함께 제공되는보다 최신 버전의 JBoss를 사용해야합니다.

+0

JBoss가 어떤 JPA 버전을 사용하는지 확인할 수 있습니까? 영구적 인 제공자의 라이브러리 버전 만 생각했습니다. 필자는이 버전 (5.1.0.GA)에 프로젝트를 배포해야하기 때문에보다 최신 JBoss 버전을 사용할 수 없습니다. – Eadel

+0

그건 그렇고, 프로젝트가 Glassfish 3.1.1에 배포되었을 때 detach()는 정상적으로 작동했습니다. 그러나 EclipseLink 라이브러리를 요구하지 않았습니다. – Eadel

+0

ejb3-persistence.jar은 JBoss 5.1은 javax.persistence 클래스를 포함하고 있습니다. 이것을 열면 JPA1에 도입 된 클래스가 포함되어 있지 않음을 알 수 있습니다. 포함 된 라이센스 파일에는 JPA 1.0이 포함되어있는 Enterprise JavaBeans v.3.0에 대해서도 언급되어 있습니다. –

2

JPA 2.0 클래스로 코드를 컴파일했지만 JPA 1.0을 사용하여 코드를 실행했습니다. 이것이 JVM이 분리 메소드를 찾지 못하는 이유입니다.

귀하의 의견에 반발하여 : 아니오, 분리 방법은 JPA 1.0 사용자에게는 쓸모가 없습니다. 아직 작성되지 않았습니다. 그러나 엔티티 관리자에서 clean()을 호출하여 모든 L1 캐시를 지울 수 있습니다. 그러면 관리 대상 엔티티가 모두 분리됩니다 ...

지속성 공급자 특정 코드를 사용하여 엔티티를 분리 할 수 ​​있습니다. 엔티티 관리자가 아직 기능을 제공하지 않아서 jpa 제공자가 아직 기능을 구현하지 않았기 때문이 아닙니다.

약간의 코드를 jpa 제공자에 연결할 수있는 경우 : EclipseLink 엔티티 관리자 구현을 리턴하는 em.getDelegate() 메소드를 호출 할 수 있습니다 (반환 된 값을 체크인하고 캐스트). 아마도 당신에게 당신의 주체를 분리시킬 수있는 가능성을 줄 것입니다. Hibernate에 대해 evict() 메소드의 이름을 detach() -> 지정하지 않아도됩니다.

+0

org.eclipse.persistence.sessions.Session 클래스에서 유사한 메소드를 찾았습니다.이 객체는 EntityManager.getDelegate에 의해 반환됩니다.) 메서드를 사용할 수 있지만 맞는 것은 찾지 못했습니다. 그러나 엔티티 개체를 수동으로 복사 (new 연산자를 사용하여 new를 만들고 모든 속성을 하나씩 복사)하여 문제를 해결했습니다. 하지만 꽤 unpretty 보인다 :) 당신의 설명 주셔서 감사합니다! – Eadel

+0

실제로 반환 된 델리게이트는 (실제로 JPA 2.0에서 사용되는) detach 메서드를 제공하는 org.eclipse.persistence.internal.jpa.EntityManagerImpl에 의해 구현 된 JpaEntityManager 인 것으로 보입니다. 그래서 ((JpaEntityManager) em.getDelegate() 호출).detach (엔티티)가 잘 작동 할 것입니다. –

+0

불행하게도이 방법으로 같은 오류가 발생했습니다. 예기치 않은 오류가 발생했습니다. 예를 들어 java.lang.NoSuchMethodError : org.eclipse.persistence.jpa.JpaEntityManager.detach (Ljava/lang/Object;) V – Eadel

관련 문제