JPA/EclipseLink を 1 年間使用してきましたが、1 対多の関係でエンティティを追加するときに管理エンティティを更新する方法を理解するのにまだ問題があります。
たとえば、私のアプリケーションには、内部にいくつかの分析があるプロジェクトがあります。プロジェクトが最初に作成され、ユーザーは内部に分析を追加できます (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)」を使用)。
すべての要素を提供するために、ここに私の汎用 DAO を示します (daoProject と daoAnalysis はそのインスタンスです)。
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;
}
アドバイスありがとうございます!