2010-01-13 3 views
0

Apache DERBY 임베디드 데이터베이스에 연결하는 Java의 SWING 응용 프로그램에서 JPA를 사용하고 있습니다. 내 IDE로 넷빈을 사용하고 "유용한"템플릿을 많이 사용합니다. 내 문제는 간단하지만 설명하기가 어렵습니다. 여기에서 관련 코드를 붙여넣고 하단에 설명하려고합니다.JPA 캐스케이드 업데이트 오류. 내가 잘못하고있는거야?

@Entity 
public class AnioLectivo implements Serializable, Comparable 
{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
... 
    @OneToMany(mappedBy = "anioLectivo", cascade=CascadeType.ALL) 
    private List<Compensatorio> compensatorios; 
... 
} 

@Entity 
public class Compensatorio implements Serializable 
{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
... 
    @ManyToOne 
    private AnioLectivo anioLectivo; 
... 
} 

이 두 내가 계속하고자하는 기관입니다.

public class AnioLectivoJpaController 
{ 

    public void edit(AnioLectivo anioLectivo) throws NonexistentEntityException, 
    Exception 
    { 
     EntityManager em = null; 
     try { 
     em = getEntityManager(); 
     em.getTransaction().begin(); 
     AnioLectivo persistentAnioLectivo = em.find(AnioLectivo.class,  
     anioLectivo.getId()); 
     ... 
     List<Compensatorio> compensatoriosOld = 
     persistentAnioLectivo.getCompensatorios(); 
     List<Compensatorio> compensatoriosNew = anioLectivo.getCompensatorios(); 
     ... 
     List<Compensatorio> attachedCompensatoriosNew = new ArrayList<Compensatorio>(); 
     for (Compensatorio compensatoriosNewCompensatorioToAttach : compensatoriosNew) { 
      compensatoriosNewCompensatorioToAttach = 
      em.getReference(compensatoriosNewCompensatorioToAttach.getClass(), 
      compensatoriosNewCompensatorioToAttach.getId()); 
      attachedCompensatoriosNew.add(compensatoriosNewCompensatorioToAttach); 
     } 
     compensatoriosNew = attachedCompensatoriosNew; 
     anioLectivo.setCompensatorios(compensatoriosNew); 
     ... 
} 

이 제가

전에 접착 엔티티 AnioLectivo의 주석을 사용하여 생성 넷빈즈 클래스이다. 당신이 볼 수 있듯이 문제가있는 netbeans의 디버그 도구 덕택에 간단하게 유지하기 위해 문제와 관련된 코드 만 붙여 넣었습니다. 이제 어떻게되는지 정확히 설명하려고합니다.

나는 프로그램의 한 부분에 AnioLectivo의 인스턴스를 생성하고 그대로 유지합니다. 그런 다음 다른 부분에서 AnioLectivo의 인스턴스에서 Compensatorio의 목록에 Compensatorio의 인스턴스를 만들고 추가해야합니다. 지금은 내가 클래스 AnioLectivoJpaController의 편집 방법을 사용하여 만들어 가정이 수정, 저장할 나는이 오류가 발견

java.lang.IllegalArgumentException: An instance of a null PK has been incorrectly provided for this find operation. 
     at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerImpl.findInternal(EntityManagerImpl.java:309) 
     at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerImpl.getReference(EntityManagerImpl.java:176) 
     at org.sigeb.local.service.dao.jpa.AnioLectivoJpaController.edit(AnioLectivoJpaController.java:113) 
     at org.sigeb.local.views.datosIniciales.AdministrarCursosPopUp.guardarCambios(AdministrarCursosPopUp.java:574) 
     at org.sigeb.local.views.datosIniciales.AdministrarCursosPopUp.jBGuardarCambiosActionPerformed(AdministrarCursosPopUp.java:394) 
     at org.sigeb.local.views.datosIniciales.AdministrarCursosPopUp.access$1000(AdministrarCursosPopUp.java:44) 
     at org.sigeb.local.views.datosIniciales.AdministrarCursosPopUp$11.actionPerformed(AdministrarCursosPopUp.java:204) 
     at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995) 
     at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318) 
... 

문제가, 내가보기 같이 코드이 줄을 발생합니다 AnioLectivoJpaController의 편집 방법 :

em.getReference(compensatoriosNewCompensatorioToAttach.getClass(), 
       compensatoriosNewCompensatorioToAttach.getId()); 

왜? 음, 엔티티를 보면, 모든 엔티티의 ID가 퍼시스턴스 유닛에 의해 생성된다는 것을 정의했지만 엔티티 자체가 존속하도록 지시 될 때만 발생합니다. Compensatorio의 인스턴스를 만들 때 ID를 명시 적으로 설정하지 않았고 내가 인용 한 행에 도착하면 compensatoriosNewCompensatorioToAttach.getId()는 null을 반환합니다.

ORM의 JPA와 마찬가지로 도달 가능성에 의한 지속성이 있습니다. 객체 A가 객체 B와 관련되어 있으면 지속성 A는 B를 계속 유지합니다.하지만이 경우 매우 불편한 방식으로 구현 된 것처럼 보입니다 (적어도 나를 위해) 왜냐하면 그 컬렉션을 소유하고있는 객체를 영속시키는 것이 더 유용 할 때 컬렉션의 모든 객체를 명시 적으로 유지해야하고 그 컬렉션의 객체는 자동으로 영속 될 것이기 때문입니다.

무언가가 있습니까? 내가 잘못하고있는거야?, 아마 다른 각도에서이 문제에 직면해야하지만, 나는, 또는, 어떤 각도로, 어떤 각도 모르겠어요?. netbeans의 사람들은 왜 그런 식으로 템플릿을 만들었습니까? DB의 객체를 검색하여 지속성 컨텍스트에 가져 오기 위해이 메서드를 실행하는 것이 유용한 이유는 무엇입니까? 모든 객체를 직접 유지해야합니까? 지속성이 오직 한 방향으로 만 이루어질 수 있다면 그것은 Reachability에 의한 지속성을 주장하는 이유입니다.

나는 분명히 틀린데, 내가 찾고있는 것은 그 엔티티들 간의 관계를 어떻게 설명해야하는지에 대한 일관된 설명이다. (만약 내가 실제로 그것들을 만든 방식으로 실수를했다면, 책 및 튜토리얼) 내가 그 컬렉션의 모든 개체를 유지할 필요가 없도록 작동하도록 만들거나, netbeans에서 해당 템플릿을 삭제하고 모든 CRUD 작업을위한 코드를 직접 작성해야 할 필요가있는 것처럼 읽습니다. 나는이 경우 진행하는 것이 얼마나 편리한 지에 대한 조언을 듣고 싶습니다.

답변

0

이 코드 전체에 em.merge(anioLectivo)이라고 불리는 것으로 보입니다.

관련 문제