我已经使用 JPA/EclipseLink 一年了,但是当您在一对多关系中添加实体时,我仍然无法理解它如何更新托管实体。
例如,在我的应用程序中,我的项目里面有几个分析。首先创建项目,然后用户可以在里面添加分析(一个一个)。我的问题是:坚持新分析的正确方法是什么(以及从项目中删除分析的相同问题)以便分析得到妥善管理并更新项目?
这是项目类:
@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(分析)”)?
为了给出所有元素,这是我的通用 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;
}
提前感谢您的建议!