2013-07-07 2 views
0

ORM 작동 방식을 이해하는 데 도움이 필요합니다. 다음은 매우 일반적인 시나리오입니다. 나는 여러 관계에 있어야하는 두 개의 메인 테이블 Organization과 RelatedParty를 가지고있다. 그러나 Organization과 Relatedparty 사이에 어떤 종류의 관계가 존재 하는지를 정의하는 relation_type 속성이있다. 기구 :jpa로 여러 엔티티 업데이트 2

@Entity 
@Table(name = "organization", catalog = "...", schema = "") 
@XmlRootElement 
public class Organization implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "organization_id", nullable = false) 
    private Integer organizationId; 
    @Column(name = "organization_name", nullable = false) 
    private String organizationName; 
    @OneToMany(cascade = {CascadeType.ALL}, mappedBy = "organization") 
    private List<Organdrelatedparty> organdrelatedpartyList; 
... 
//getter setter methods 

Organdrelatedparty : 복합 기본 키 OrgandrelatedpartyPK

@Entity 
@Table(name = "organdrelatedparty", catalog = "...", schema = "") 
@XmlRootElement 
public class Organdrelatedparty implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @EmbeddedId 
    protected OrgandrelatedpartyPK organdrelatedpartyPK; 
    @JoinColumn(name = "relatedParty_id", referencedColumnName = "relatedParty_id", nullable = false, insertable = false, updatable = false) 
    @ManyToOne(optional = false, cascade= {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}) 
    private Relatedparty relatedparty; 
    @JoinColumn(name = "orgRelation_id", referencedColumnName = "orgRelation_id", nullable = false) 
    @ManyToOne(optional = false) 
    private ParOrgrelationtype orgRelationid; 
    @JoinColumn(name = "organization_id", referencedColumnName = "organization_id", nullable = false, insertable = false, updatable = false) 
    @ManyToOne(optional = false) 
    private Organization organization; 
... 
//getter setter methods 

OrgandrelatedpartyPK

,432를 사용하여 여기에

relational database entity model

내 엔티티 클래스입니다 10

RelatedParty : organdRelatedParty 클래스와 단방향 oneToMany 관계입니다. 즉, relatedParty 엔티티는 다른쪽에있는 organdRelatedParty 엔티티에 대한 지식이 없습니다. 나는 새 조직 엔티티가 지속되면 삽입

@Entity 
@Table(name = "relatedparty", catalog = "...", schema = "") 
@XmlRootElement 
public class Relatedparty implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "relatedParty_id", nullable = false) 
    private Integer relatedPartyid; 
    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 100) 
    @Column(name = "firstName", nullable = false, length = 100) 
    private String firstName; 
    @Size(max = 100) 
    @Column(name = "lastName", length = 100) 
    private String lastName; 
    @Basic(optional = false) 
    @NotNull 
    @Column(name = "isForeign", nullable = false) 
    private boolean isForeign; 
... 
//getter setter methods 

, 그것은 폭포는 폭포가 새로운 RelatedParty로 활동을 지속 새로운 OrgandrelatedParty에 활동을 지속. 따라서 모든 관련 엔티티는 지속되고 정상적으로 작동합니다.

업데이트의 경우 사용자는 기존 조직 및 relatedParty 엔티티를 변경하고 새 relatedParty를 조직에 추가해야합니다. 따라서 우리는 모든 OrgandrelatedParties를 먼저 삭제하고 그 후에 새로운 relatedParties와 relatedParties를 다시 추가하는 것을 선호합니다.

은 업데이트를 처리하는 우리의 방법이다 : 우리는 방법에 목록으로 새로운 조직과 모든 신규 및 기존 relatedParties을 통과 : 전나무 우리는 모든 기존 OrgAndRelatedParties을 삭제 우리는 새로운 OrgandrelatedParties으로 목록에 다시 모든 relatedParties을 만들 수 있습니다. 이것은 조직을 업데이트하는 주요 방법입니다.

public void updateOrganization(Organization newOrganization, List<Relatedparty> newShareList) throws ControlException { 
    try{ 
     tx.begin(); 
     this.updateOrgAndRelatedShares(newOrganization, newShareList); 
     customerController.updateOrganization(newOrganization); 
     tx.commit(); 
    }catch(ControlException ex){ 
... 

첫 번째 엔티티 관리자의 찾기 방법으로 오래된기구를 찾을 않습니다 customerController의 updateOrganization 방법은 다음 복사 된 새로운 조직의 모든 속성은 다음 세 조직과 플러시 병합 : 여기

public void updateOrganization(Organization newOrganization) 
{ 
    Organization preOrganization = em.find(Organization.class, newOrganization.getOrganizationId); 
    preOrganization.setOrganizationId(newOrganization.getOrganizationId); 
    preOrganization.setOrganizationName(newOrganization.getOrganizationName); 
    em.merge(preOrganization); 
    em.flush(); 
} 

다른 방법이 있습니다 :

@TransactionAttribute(TransactionAttributeType.REQUIRED) 
private void updateOrgAndRelatedShares(Organization org, List<Relatedparty> shareList) throws ControlException 
{ 

    for(Iterator<Organdrelatedparty> it = org.getOrgandrelatedpartyList().iterator(); it.hasNext();) 
    { 
     Organdrelatedparty op = it.next(); 
     it.remove(); 
     op.setOrganization(null); 
     op.setRelatedparty(null); 
     deleteOrgRelated(op); 
    } 
    org.getOrgandrelatedpartyList().clear(); 


    for(Relatedparty relatedParty: shareList){ 
     int parOrgRelationTypeId = relatedParty.getIsPerson() ? 1:2; 
     createOrgAndRelatedParty(org, relatedParty, parOrgRelationTypeId); 
    } 

} 
@TransactionAttribute(TransactionAttributeType.REQUIRED) 
public void deleteOrgRelated(Organdrelatedparty org) throws ControlException{ 
    try{ 
    org = em.find(Organdrelatedparty.class, org.getOrgandrelatedpartyPK()); 
    em.remove(org); 
    em.flush(); 
    } 
    catch(Exception ex){ 
     Logger.getLogger(RelatedpartyController.class.getName()).log(Level.SEVERE, null, ex); 
     throw new ControlException("Couln't delete org relation", ex); 
    } 
} 
@TransactionAttribute(TransactionAttributeType.REQUIRED) 
private void createOrgAndRelatedParty(Organization org, Relatedparty relatedParty, int parOrgRelationTypeId) throws ControlException{ 
    if(findRelatedPartyByRegNum(relatedParty.getRegisterNumber()) == null || relatedParty.getRelatedPartyid() == null){ 
     createRelated(relatedParty); 
    }else{ 
     relatedParty = updateRelatedParty(relatedParty); 
    } 
     Organdrelatedparty preOrp = new Organdrelatedparty(relatedParty.getRelatedPartyid(), 
     preOrp.setOrganization(org); 
     preOrp.setRelatedparty(relatedParty); 
     preOrp.setOrgRelationid(prepareOrgandRelatedPartyType(parOrgRelationTypeId)); 
     org.getOrgandrelatedpartyList().add(preOrp); 
    } 

내 질문은 내가 조직 엔티티를 새로운 목록 organdrelatedpartyList와 병합 할 때입니다.

eclipseLink는 먼저 작업을 지속하고 작업을 제거한다는 것을 알게되었습니다. 그래서 이전에 데이터베이스에서 삭제되지 않은 엔티티와 동일한 합성 id를 가진 organdrelatedparty 엔티티를 삽입하려고 시도합니다. 나는 옛날 조직의 관계자들을 제거 할 때마다 플러시한다. 그러나 도움이되지 않습니다. 해결 방안은 무엇인가? 어떤 생각이야.

저는 2.0을 사용하고 있습니다. 공급자 및 glassfish로 eclipseLink 3.1.2

답변

0

당신이해야 할 것보다 훨씬 더 복잡하게 만드는 것처럼 보입니다.

삭제 된 Organdrelatedparty를 모두 삭제하지 않고 삭제 한 다음 그 중 일부를 다시 윤기 나 부르는 이유는 무엇입니까? 특히 동일한 거래에서 개체를 윤회시키는 것은 일반적으로 좋지 않습니다.

포함 된 코드에 따라 merge() 오류가 발생했습니다.이 오류는 updateOrgAndRelatedShares()에서 호출 병합 만하므로이 시점에서이 객체가 어떻게 제거되는지 보지 못합니까? 또는 귀하의 코드가 귀하가 제시 한 것과 다른 경우, 예외 스택을 포함하십시오.

당신은 updateOrganization() 메서드가 좋지 않습니다. 절대 수행해서는 안되는 개체 ID를 업데이트합니다. 또한 아무 이유없이 병합을 호출합니다. 이미 개체를 변경했습니다.

또한 일반적으로 EmbeddedId 대신 IdClass를 사용하고 IDENTITY 인 경우 TABLE 또는 SEQUENCE ID 생성을 사용하는 것이 좋습니다.

관련 문제