2013-05-23 2 views
0

1 년 동안 JPA/EclipseLink로 작업을 해왔지만 일대 다 엔티티에 엔티티를 추가 할 때 관리 대상 엔티티를 업데이트하는 방법을 이해하는 데 여전히 문제점이 있습니다. 관계.JPA/EclipseLink와 1 대 다수의 관계가있는 엔티티

예를 들어, 내 응용 프로그램에서 내부에 여러 가지 분석이있는 프로젝트가 있습니다. 프로젝트가 처음 생성 된 다음 사용자가 분석을 내부에 추가 할 수 있습니다 (하나씩). 내 문제는 : 분석이 잘 관리되고 프로젝트가 업데이트되도록 새 분석 (프로젝트에서 하나를 삭제하는 것과 동일한 질문)을 유지하는 올바른 방법은 무엇입니까? 여기

프로젝트 클래스입니다 :

@Entity 
@Table(name="project") 
public class Project implements Serializable { 


/** The Constant serialVersionUID. */ 
private static final long serialVersionUID = 1L; 

/** The id project. */ 
@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY) 
@Column(name="id_project", unique=true, nullable=false) 
private Integer idProject; 

/** The project name. */ 
@Column(name="project_name", nullable=false, length=50) 
private String projectName; 

//bi-directional many-to-one association to Analysis 
/** The analysis. */ 
@OneToMany(mappedBy="project", cascade={CascadeType.ALL}) 
private Set<Analysis> analysis; 

    ... other stuff 
} 

분석 클래스 :

@Entity 
@Table(name="analyz") 
public class Analysis implements Serializable{ 

/** The Constant serialVersionUID. */ 
private static final long serialVersionUID = 1L; 

/** The id analysis. */ 
@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY) 
@Column(name="id_analysis", unique=true, nullable=false) 
private Integer idAnalysis; 

/** The analysis name. */ 
@Column(name="analysis_name", nullable=false, length=50) 
private String analysisName; 

//bi-directional many-to-one association to Project 
/** The project. */ 
@ManyToOne 
@JoinColumn(name="id_project", nullable=false) 
private Project project; 

    ... other stuff 
} 

나는 새로운 분석을 만드는 데 사용하는 기능 : 나는를 업데이트하는 경우

public void createAnalysis(String name, int projectId) { 

    Project project = daoProject.findById(projectId); 

    Analysis analysis = new Analysis(); 
    analysis.setProject(project); 

    analysis.setNameAnalysis(name); 
    project.getAnalysis().add(analysis); 
    daoProject.update(project);// I also tried daoAnalysis.create(analysis) 
} 

을 프로젝트에서 내 프로젝트 객체는 새 분석으로 최신 상태이지만 분석 객체에는 새 객체가 없습니다. ID ... 그 자체로 분석을 지속하는 경우 나중에 ID를 사용하여 프로젝트 개체를 검색 할 때 업데이트가없고 새 분석이 프로젝트에 없습니다.

분석 삭제와 동일한 문제 : "daoAnalysis.delete (analysis)"를 사용하여 프로젝트를 업데이트하거나 분석 만 제거해야합니까? 귀하의 조언에 미리

public class BasicDAO<T extends Serializable> implements IDao<T> { 

/** The class of the entity to be manipulated. */ 
private Class<T> entityClass; 

/** The entity manager factory. */ 
protected EntityManagerFactory emf; 

/** 
* Instantiates a new abstract dao. 
* 
* @param c the class 
*/ 
public BasicDAO(Class<T> c) { 
    entityClass = c; 
} 

/** 
* Gets the emf. 
* 
* @return the emf 
*/ 
public EntityManagerFactory getEmf() { 
    return emf; 
} 

/** 
* Sets the emf. 
* 
* @param emf the new emf 
*/ 
public void setEmf(EntityManagerFactory emf) { 
    this.emf = emf; 
} 


public T findById(Integer id){ 
    T result = null; 
    EntityManager em = emf.createEntityManager(); 
    if (id == null || id < 1) 
     throw new PersistenceException("Id may not be null or negative"); 
    result = em.find(entityClass, id); 
    em.close(); 
    return result; 
} 


public void create(T entity){ 
    System.out.println("Create de AbstractDAO"); 
    //First we check that the object is not alreadt in database 
    List<T> list = findAll(); 
    if(list.contains(entity)){ 
     return; 
    } 
    EntityManager em = emf.createEntityManager(); 
    em.getTransaction().begin(); 
    if(entity == null) 
     throw new PersistenceException("Entity to persist may not be null");//throw Persistence exception 
    em.persist(entity); 
    em.getTransaction().commit(); 
    em.close(); 
} 


public void delete(T entity){ 
    EntityManager em = emf.createEntityManager(); 
    em.getTransaction().begin(); 
    if (entity == null) 
     throw new PersistenceException("Entity to delete may not be null"); 

    em.remove(em.merge(entity)); 
    em.getTransaction().commit(); 
    em.close(); 
} 


public T update(T entity){ 
    T result = null; 
    if (entity == null){ 
     System.out.println("Exception : entity to update may not be null"); 
     throw new PersistenceException("Entity to update may not be null"); 
    } 
    List<T> list = findAll(); 
    int numberEquals = 0; 
    for(T elem : list){ 
     if(elem.equals(entity)) 
      numberEquals++; 
    } 
    if(numberEquals>1) 
     return null; 
    EntityManager em = emf.createEntityManager(); 
    em.getTransaction().begin(); 
    em.merge(entity); 
    result = entity; 
    em.getTransaction().commit(); 
    em.close(); 
    return result; 
} 

감사 :

이 모든 요소를 ​​제공하기 위해, 여기 내 일반적인 DAO이다 (daoProject 및 daoAnalysis 그것의 인스턴스입니다)!

답변

2

업데이트 방법이 프로젝트에서 병합을 사용한다고 가정합니다. Merge는 객체를 가져 와서 병합 된 변경 사항을 가진 관리 인스턴스를 반환합니다. 객체가 새 객체이면 데이터를 반영하는 새 관리 인스턴스를 만듭니다. 이는 분석 버전에 ID 세트가없는 이유 일 수 있습니다. 전달 된 것보다 병합 된 프로세스를 반환하는 Managed 인스턴스를 사용해야합니다.

Persist는 새 분석에 직접 사용될 수 있지만 프로젝트에 대한 변경 사항을 병합하여 표시해야합니다 캐시. 따라서 분석을 지속하고 프로젝트를 병합합니다. 더 많은 코드가 있지만 병합 통화에 분석이 이미 있는지 확인하지 않아도되므로 더 효율적일 수 있습니다. Persist는 관리되는 엔티티에서 인스턴스를 전달하므로 ID가 설정됩니다.

0

당신이 어려움 이들 3 단계 명심 일대 다 관계의 실체를 업데이트 직면하는 경우 : @OneToMany 목록에

  1. 언급 cascade = CascadeType.ALL,orphanRemoval = true을, 예 :

    @OneToMany(mappedBy = "parentEntity",cascade = CascadeType.ALL,orphanRemoval = true) 
    private List<ChildEntity> childEntityList; 
    
  2. 항상 업데이트를 수행 많은 측면 (나열된 하위 엔티티의 목록이있는 상위 엔티티).

  3. 캐시를 지우려면 매번 업데이트 후 getEntityManager().getEntityManagerFactory().getCache().evict(Class)으로 전화하십시오.

관련 문제