2013-06-10 50 views
33

JPA (transaction-type = "JTA") kullanan bir java EE projem var, sağlayıcı olarak hazırda bekletme. CRUD şeylerini halletmek için fasulyemi yazıyorum. JBOSS 7 AS'de çalışan program.java.lang.IllegalArgumentException: Ayrılmış bir örneği kaldırma com.test.User # 5

Bir EntityManagerDAO vardır:

@Stateful 
public class EntityManagerDao implements Serializable { 

    @PersistenceContext(unitName = "dtdJpa") 
    private EntityManager entityManager; 

    @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    public Object updateObject(Object object) { 
     object = entityManager.merge(object); 
     return object; 
    } 

    @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    public void createObject(Object object) { 
     entityManager.persist(object); 
    } 

    public void refresh(Object object) { 
     entityManager.refresh(object); 
    } 

    public <T> T find(Class<T> clazz, Long id) { 
     return entityManager.find(clazz, id); 
    } 

    @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    public void deleteObject(Object object) { 
     entityManager.remove(object); 
    } 
} 

ama deleteObject çağırmak zaman, bu istisna çıkar.

java.lang.IllegalArgumentException: müstakil bir örneği com.test.User # 5

Bu nasıl kaynaklanır ve nasıl çözebilir Çıkarma? Yalnızca geçerli işlem/bağlamda yönetilen varlıklar üzerinde çalışır.

cevap

144

EntityManager#remove() Durumunuzda, varlığın önceki bir işlemde geri alınması, HTTP oturumunda saklanması ve ardından farklı bir işlemde/bağlamda kaldırılmasıdır. Bu sadece işe yaramaz.

Varlığın EntityManager#contains() tarafından yönetilip yönetilmediğini ve değilse EntityManager#merge()'u yönetip yönetmediğini kontrol etmeniz gerekir.

Temelde, iş hizmet sınıfının delete() yöntemi şöyle görünmelidir: Ben kullanarak nesneyi silmeye çalışırken

em.remove(em.contains(entity) ? entity : em.merge(entity)); 
+0

@BalusC Em.remove'de (em.contains (varlık)? Varlık: em.merge (varlık)); , em (içeriğindeki (false) false ise, entityToBeRemoved = em.merge (varlık), entityToBeRemoved'i kaldırıyor musunuz? Em.merge (varlık) 'dan hangi getirileri kaldırıyorsunuz? –

+0

Sorduğum sorudaki cevaba göre ihtiyacınız olan: a = em.merge (a); // iliştirilmiş öğeye birleştirme ve atama em.remove (a); // ekli öğeyi kaldır –

+1

İyi çalınmış efendim.Bu çok doğru ve bu iyi bir şey çözüm imho. –

1

Benim durumumda, ben, aynı hatayı aldık

session.delete(obj) 
Bundan önce herhangi bir işlem oluşturmadan

.

Ve sorun nesnesini ilk (session.beginTransaction() işlem oluşturarak ve ardından silerek çözülür. Ben cevabım yardımcı olacağını umuyoruz

birisi :) Bazen

-2

sadece gelen kimliği alabilirsiniz Ayrılmış örnek, daha sonra doğrudan sorguyu veritabanına kullanın. Örneğin

entityManager.createQuery("DELETE FROM Pet pet WHERE id=" + petId).executeUpdate(); 

olarak, ben de aynı sorunla karşı karşıya bağlam

if (em.contains(pet)){ 
    em.remove(pet); 
} 
+1

BTW. Dize birleştirme kullanarak parametrelerin değerlerini ayarlamak iyi bir fikir değildir. Uygulama, SQL enjeksiyon saldırılarına eğilimli olabilir. – Vic

0

temizleyebilir sonra. Ayrılmış varlık yeniden iliştirilmelidir. @BalusC'nin belirtildiği gibi, bağımsız öğeyi eklemek için EntityManager.merge() kullanılmalıdır. EntityManager.merge(), EntityManager.remove()'un gerçekleştirilmesi gereken varlığın geçerli durumunu getiren SQL Sorgusunu üretir. Ama benim durumumda işe yaramadı. Bunun yerine EntityManager.remove(EntityManager.find(Class<T>,arg)) deneyin. Benim için çalıştı.