Eadel
Eadel

Reputation: 3997

How to detach an entity (JPA 2.0/EclipseLink/JBoss)

I need to detach some entity objects from the database to make them unmanaged. I use EclipseLink persistence provider, which method EntityManager.detach() is exactly one I need. The problem is that JBoss throws at runtime following exception (when execution passes to detach()):

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

Other methods like persist, merge, find work fine. I tried Hibernate and know that its Session provides a special method evict(), which detaches entity, but EclipseLink has no such method. Example of using detach():

@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>

Library with provider data is included into ear archive. EclipseLink version is 2.2.0 (tested with 2.3.2 - no difference), JBoss server version 5.1.0. Any suggestions will be appreciated.

Upvotes: 2

Views: 3633

Answers (2)

Sebastien Lorber
Sebastien Lorber

Reputation: 92210

You compiled your code with JPA 2.0 classes, but you run it with JPA 1.0. This is why the JVM doesn't find the detach method.

In reaction to your comment: no, the detach method is not useless for JPA 1.0 user: it's just it has not been created yet. You can however erase all the L1 cache by calling clean() on the entitymanager, which will detach all your managed entities...

You can still be able to detach an entity by using persistence provider specific code. It is not because the entity manager does not provide a function yet, that the jpa providers hasn't implemented it yet.

If you can couple a little bit your code to your jpa provider: You can call the em.getDelegate() method that will return you an EclipseLink entity manager implementation (check in debug the returned value and cast it) which may perhaps give you the possibility to detach your entity. The method may not be named detach() -> for Hibernate it's evict().

Upvotes: 3

JB Nizet
JB Nizet

Reputation: 692081

This exception shows that you're not using JPA2, but JPA1. You should probably use a more recent version of JBoss, that ships with JPA2.

Upvotes: 3

Related Questions