一对多实体与JPA/EclipseLink的关系已过时
我已经与JPA/EclipseLink合作一年了,但我仍然无法理解在一对多关系中添加实体时,它如何更新托管实体 例如,在我的应用程序中,我有一些项目,其中包含多个分析。首先创建项目,然后用户可以在其中添加分析(一个接一个)。我的问题是:什么是保存新分析(以及从项目中删除一个分析的相同问题)的正确方法,以便更好地管理分析并更新项目? 以下是项目类:一对多实体与JPA/EclipseLink的关系已过时,jpa,persistence,eclipselink,one-to-many,Jpa,Persistence,Eclipselink,One To Many,我已经与JPA/EclipseLink合作一年了,但我仍然无法理解在一对多关系中添加实体时,它如何更新托管实体 例如,在我的应用程序中,我有一些项目,其中包含多个分析。首先创建项目,然后用户可以在其中添加分析(一个接一个)。我的问题是:什么是保存新分析(以及从项目中删除一个分析的相同问题)的正确方法,以便更好地管理分析并更新项目? 以下是项目类: @Entity @Table(name="project") public class Project implements Serializable
@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
}
我用于创建新分析的函数:
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检索项目对象时,我不会得到它的更新,并且新的分析不在项目中
删除分析也有同样的问题:我应该更新项目还是单独删除分析(使用“daoalysis.delete(analysis)”
为了给出所有元素,这里是我的通用DAO(daoProject和DAOPanalysis是它的实例):
公共类基本DAO实现IDao{
/**要操纵的实体的类*/
私有类实体类;
/**实体管理器工厂*/
受保护的实体管理器工厂emf;
/**
*实例化一个新的抽象dao。
*
*@param c类
*/
公共基础设施(c类){
entityClass=c;
}
/**
*获取emf。
*
*@返回emf
*/
公共实体管理器工厂getEmf(){
返回电动势;
}
/**
*设置emf。
*
*@param emf新的emf
*/
public void setEmf(EntityManagerFactory emf){
this.emf=emf;
}
公共T findById(整数id){
T结果=null;
EntityManager em=emf.createEntityManager();
if(id==null | | id<1)
抛出新的PersistenceException(“Id不能为null或负值”);
结果=em.find(entityClass,id);
em.close();
返回结果;
}
公共无效创建(T实体){
System.out.println(“创建抽象DAO”);
//首先,我们检查对象是否不在数据库中
List=findAll();
if(列表包含(实体)){
返回;
}
EntityManager em=emf.createEntityManager();
em.getTransaction().begin();
if(实体==null)
抛出新的PersistenceException(“要持久化的实体可能不为null”);//抛出持久化异常
em.persist(实体);
em.getTransaction().commit();
em.close();
}
公共作废删除(T实体){
EntityManager em=emf.createEntityManager();
em.getTransaction().begin();
if(实体==null)
抛出新的PersistenceException(“要删除的实体可能不为空”);
em.remove(em.merge(entity));
em.getTransaction().commit();
em.close();
}
公共T更新(T实体){
T结果=null;
if(实体==null){
System.out.println(“异常:要更新的实体不能为空”);
抛出新的PersistenceException(“要更新的实体可能不为空”);
}
List=findAll();
int numberquals=0;
对于(T元素:列表){
if(元素等于(实体))
numberquals++;
}
如果(numberquals>1)
返回null;
EntityManager em=emf.createEntityManager();
em.getTransaction().begin();
合并(实体);
结果=实体;
em.getTransaction().commit();
em.close();
返回结果;
}
提前感谢您的建议!我假设您的更新方法在project上使用merge。merge接受对象并返回一个托管实例,其中包含合并的更改。如果对象是新的,它将创建一个新的托管实例以反映数据-这可能是您的分析版本没有设置ID的原因。您需要e受管理的实例返回dorm合并进程,而不是传入的内容
Persist可以直接用于新的分析,但您仍然需要合并对project所做的任何更改,以便它们显示在缓存中。因此,您可以将分析持久化,然后合并project。更多代码,但由于提供程序不需要检查合并调用中是否已存在分析,因此它可能更有效。Persist会使在托管实体中传递状态,因此它将设置ID。如果您在更新一对多关系实体时遇到困难,请记住以下3个步骤:
@OneToMany
列表中提及cascade=CascadeType.ALL,orphanRemoving=true
,示例:
@OneToMany(mappedBy = "parentEntity",cascade = CascadeType.ALL,orphanRemoval = true)
private List< ChildEntity > childEntityList;
@OneToMany(mappedBy=“parentEntity”,cascade=CascadeType.ALL,orphanRemoving=true)
私有列表childEntityList;
getEntityManager().getEntityManagerFactory().getCache().Recit(类)
以清除缓存 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;
}
@OneToMany(mappedBy = "parentEntity",cascade = CascadeType.ALL,orphanRemoval = true)
private List< ChildEntity > childEntityList;