Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JPA2.1更新数据库实体的正确方法(使用eclipseLink)?_Jpa_Eclipselink - Fatal编程技术网

JPA2.1更新数据库实体的正确方法(使用eclipseLink)?

JPA2.1更新数据库实体的正确方法(使用eclipseLink)?,jpa,eclipselink,Jpa,Eclipselink,我想知道我正在做什么来读取和更新我的数据库,这是一种方法,也是一种良好的做法 运行程序时,我会将数据库加载到内存中: public static void open() { EntityManagerFactory emf = Persistence.createEntityManagerFactory("htTeamManagerPU"); EntityManager em = emf.createEntityManager(); TypedQuery<Season>

我想知道我正在做什么来读取和更新我的数据库,这是一种方法,也是一种良好的做法

运行程序时,我会将数据库加载到内存中:

 public static void open() {
  EntityManagerFactory emf = Persistence.createEntityManagerFactory("htTeamManagerPU");
  EntityManager em = emf.createEntityManager();
  TypedQuery<Season> query = em.createQuery("select s from Season s",Season.class);
  seasons = query.getResultList(); }

这是工作良好,并更新我的数据库。我想知道的是,这是否是正确和最好的方法。谢谢

首先,您没有做两次相同的更改

在EntityManager生命周期内(这是一个简化过程,因为存在事务的超时概念和更多内容),它监视检索的实体发生了什么,因此,如果修改,它们的更改将转换为数据库,但一旦EntityManager生命周期结束,所有监视也将结束。问题是,您习惯于隐式操作(在代码中没有EntityManager的合并、删除或删除函数,所以只有自己的EntityManager才关心如何处理更改),而不是显式操作(使用EntityManager的合并、删除或创建由程序员声明的方法)所以您可能认为,一旦实体被修改,它就会自动提交,但不会:更改由EntityManager处理

由于playerList可能是在EntityManager生命周期之外修改的,所以没有人关心它的实体,所以更改不会在数据库中刷新,这会导致您的问题

在我描述的情况下,这种缺乏刷新是完全正常的。对于未处理的实体,获取实体管理器、开始事务等过程是完全正常的

关于您的问题“我想知道这是否是正确和最好的方法”,我已经解释了这个概念,但我可以提供一些代码改进建议。 例如,我将避免隐式EntityManager操作以避免混淆;使用显式方法,我会这样更改您的方法:

public void modifiedFinishTraining(int id){

/*This three lines are mandatory. You have to get an EntityManager to get access to     database and start a transaction to store your changes*/
EntityManagerFactory emf = Persistence.createEntityManagerFactory("htTeamManagerPU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

/*case 1: use merge method. If you want to update your player or create if it is not at database, use it and avoid the em.find(Player.class, id) step*/
for (Player player: playerList){

if (player.getPlayerId()==id) {
//This way you avoid the step of find by be careful: merge updates existing or creates a new one.
em.merge(player);
}

}
/*case 2: If you want to check if exists and you dont want to create it in other case  do it*/
for (Player player: playerList){
  if (player.getPlayerId()==id) {
      //you find the player in database
       Player p1 = em.find(Player.class, player.getPlayerId());
       //check if player exists and if true, update           
       if(p1  != null){
         p1.setIsTeam((short)0);
         p1.setIsToSell((short)1);

         em.merge(p1);
       }
   }
}

//this would be done at the end of the operation to commit all changes at the same time
em.getTransaction().commit();   
em.close();
emf.close();
/*the upper three lines are mandatory. You must commit your changes because transaction is manually handled and once commited you have to close all to free resources*/

}   

您应该只在应用程序中创建一个
EntityManagerFactory
(可能在启动或缓存时创建)。您的问题的答案如下:
public void modifiedFinishTraining(int id){

/*This three lines are mandatory. You have to get an EntityManager to get access to     database and start a transaction to store your changes*/
EntityManagerFactory emf = Persistence.createEntityManagerFactory("htTeamManagerPU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

/*case 1: use merge method. If you want to update your player or create if it is not at database, use it and avoid the em.find(Player.class, id) step*/
for (Player player: playerList){

if (player.getPlayerId()==id) {
//This way you avoid the step of find by be careful: merge updates existing or creates a new one.
em.merge(player);
}

}
/*case 2: If you want to check if exists and you dont want to create it in other case  do it*/
for (Player player: playerList){
  if (player.getPlayerId()==id) {
      //you find the player in database
       Player p1 = em.find(Player.class, player.getPlayerId());
       //check if player exists and if true, update           
       if(p1  != null){
         p1.setIsTeam((short)0);
         p1.setIsToSell((short)1);

         em.merge(p1);
       }
   }
}

//this would be done at the end of the operation to commit all changes at the same time
em.getTransaction().commit();   
em.close();
emf.close();
/*the upper three lines are mandatory. You must commit your changes because transaction is manually handled and once commited you have to close all to free resources*/

}