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*/
}