我有一个JavaFX应用程序,可以在JPA技术的帮助下访问MySQL数据库。
以下是我在应用程序中创建和使用实体管理器的方法:
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class EntityManagerHelper {
private static final EntityManagerFactory emf;
private static final ThreadLocal<EntityManager> threadLocal;
static {
if (InitPersistence.persistenceMap != null && InitPersistence.getNewIP() != null)
emf = Persistence.createEntityManagerFactory("TonalityJPA",
InitPersistence.persistenceMap);
else
emf = Persistence.createEntityManagerFactory("TonalityJPA");
threadLocal = new ThreadLocal<EntityManager>();
}
public static EntityManager getEntityManager() {
EntityManager em = threadLocal.get();
if (em == null) {
em = emf.createEntityManager();
// set your flush mode here
threadLocal.set(em);
}
return em;
}
public static void closeEntityManager() {
EntityManager em = threadLocal.get();
if (em != null) {
em.close();
threadLocal.set(null);
}
}
public static void closeEntityManagerFactory() {
emf.close();
}
public static void begin() {
getEntityManager().getTransaction().begin();
}
public static <T> void remove(T thingToRemove) {
getEntityManager().remove(thingToRemove);
}
public static <T> void persist(T thingToPersist) {
getEntityManager().persist(thingToPersist);
}
public static void rollback() {
getEntityManager().getTransaction().rollback();
}
public static void commit() {
getEntityManager().getTransaction().commit();
}
public static <T> T find(Class<T> a, long id) {
return getEntityManager().find(a, id);
}
}
我从这篇文章JAVA: an EntityManager object in a multithread environment的答案中选择了这个课程,并为其添加了一些功能。
我的应用程序通过DB进行授权,然后显示来自DB的用户列表。 应用程序用户选择其中一个并删除他。 这是如何运作的:
delBtn.setOnAction(event -> {
long id = currentUser.getUserId();
new UserActions().delete(id);
UserLogEntity userLog = new UserLogEntity(UserData.getUser().getUserId(), "deleted user: " +
currentUser.getUserLogin(), 3, new Date());
UserLogActions log_action = new UserLogActions();
log_action.add(userLog);
} else {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Помилка");
alert.setHeaderText("");
alert.setContentText("Оберіть користувача для видалення");
alert.showAndWait();
}
});
以下是UserEntity和UserActions类:
UserEntity:
package com.Model.DataBase.Entities;
import org.mindrot.jbcrypt.BCrypt;
import javax.persistence.*;
/**
* Created by User on 07.03.2016.
*/
@Entity
@Table(name = "user", schema = "newsmonitoringdb")
public class UserEntity {
private Long userId;
private String userLogin;
private String userPass;
private int userAccessLvl;
public UserEntity(){}
public UserEntity(String login, String pass, int accessLvl)
{
this.userLogin = login;
this.userPass = pass;
this.userAccessLvl = accessLvl;
}
@Id
@Column(name = "userID")
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
@Basic
@Column(name = "userLogin")
public String getUserLogin() {
return userLogin;
}
public void setUserLogin(String userLogin) {
this.userLogin = userLogin;
}
@Basic
@Column(name = "userPass")
public String getUserPass() {
return userPass;
}
public void setUserPass(String userPass) {
this.userPass = userPass;
}
@Basic
@Column(name = "userAccessLvl")
public int getUserAccessLvl() {
return userAccessLvl;
}
}
UserAction:
package com.Model.DataBase.EntitiesActions;
import com.Model.DataBase.Entities.UserEntity;
import com.Model.DataBase.EntityManagerHelper;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.List;
public class UserActions{
public List<UserEntity> list() {
Query query = EntityManagerHelper.getEntityManager().createQuery("SELECT a FROM UserEntity a", UserEntity.class);
return (List <UserEntity>) query.getResultList();
}
public void add(UserEntity user) {
try {
EntityManagerHelper.begin();
EntityManagerHelper.persist(user);
EntityManagerHelper.commit();
} catch (Exception ex) {
//entityManager.getTransaction().rollback();
//ex.printStackTrace();
}
}
public void delete(long id) {
try {
UserEntity user = EntityManagerHelper.find(UserEntity.class, id);
EntityManagerHelper.begin();
EntityManagerHelper.remove(user);
EntityManagerHelper.commit();
} catch (Exception ex) {
ex.printStackTrace();
EntityManagerHelper.rollback();
}
}
}
如果我有
EntityManagerHelper.begin();
在delete方法中,我发送到此行的catch块,但有两个例外:
javax.persistence.RollbackException: Transaction marked as rollbackOnly
和
Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: Transaction not active
我理解第一个,但第二个意外。
如果我拿走这一行,我会从行中输入catch块:
EntityManagerHelper.commit();
第一个例外是相同的,第二个例外是 线程中的异常&#34; JavaFX应用程序线程&#34; java.lang.IllegalStateException:事务未激活
如何解决此问题以避免异常?